Skip to content

Commit a153187

Browse files
committed
build fixes & license
1 parent e60cd5f commit a153187

10 files changed

+823
-31
lines changed

.cursorrules

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
You are an expert developer working on LitePost, a modern API client application built with Tauri and React. The tech stack includes:
1+
You are an expert Typescript, Rust, and React developer working on LitePost, a modern API client application built with Tauri and React. The tech stack includes:
22

33
Frontend:
44
- React 18 with TypeScript
@@ -16,6 +16,9 @@ Backend (Tauri):
1616
- Tauri plugins: fs, http, opener
1717
- Cross-platform desktop capabilities
1818

19+
To run tests:
20+
- Run `pnpm test:run` to ensure tests exit properly
21+
1922
Project Structure:
2023
- /src: React frontend code
2124
- /components: React components including UI elements

LICENSE

+661
Large diffs are not rendered by default.

TODO.md

+128
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,131 @@ The most critical missing features that would significantly improve usability ar
197197
1. Nested Collection Organization - for better request organization
198198
2. Advanced Cookie Management - for better session handling across domains
199199
3. Collection-level Testing - for automated API testing workflows
200+
201+
202+
Based on the codebase, here are some quality-of-life and nice-to-have features that could enhance the user experience:
203+
204+
1. **Request Templates**
205+
```typescript:src/components/RequestPanel.tsx
206+
// Add a new button next to Save to create/use templates
207+
<RequestUrlBar
208+
method={method}
209+
url={url}
210+
loading={loading}
211+
onMethodChange={onMethodChange}
212+
onUrlChange={onUrlChange}
213+
onSend={onSend}
214+
onSave={onSave}
215+
onTemplate={() => setTemplateDialogOpen(true)} // New prop
216+
/>
217+
```
218+
219+
2. **Environment Variable Preview**
220+
- Show resolved environment variables inline in the URL/headers/body
221+
- Add a toggle to switch between raw and resolved views
222+
223+
3. **Request Chaining**
224+
- Allow requests to use previous response data
225+
- Add variables like `{{prevResponse.body.id}}` that get replaced at runtime
226+
227+
4. **Bulk Operations**
228+
```typescript:src/components/CollectionsPanel.tsx
229+
// Add bulk import/export/delete for requests within collections
230+
const handleBulkExport = (collectionId: string) => {
231+
const collection = collections.find(c => c.id === collectionId);
232+
// Export logic
233+
}
234+
```
235+
236+
5. **Request History Search Improvements**
237+
- Add filters by status code, date range, collection
238+
- Add ability to save searches
239+
- Group by domain/endpoint
240+
241+
6. **Response Diffs**
242+
- Allow comparing responses between two requests
243+
- Highlight changes in JSON/headers
244+
245+
7. **Request Queue/Batch Requests**
246+
- Queue multiple requests to run in sequence
247+
- Run collection requests as a batch
248+
249+
8. **Advanced Auth**
250+
- OAuth 2.0 flow support
251+
- Token management/refresh
252+
- Session handling
253+
254+
9. **Response Transformations**
255+
```typescript:src/types.ts
256+
interface ResponseTransform {
257+
id: string;
258+
name: string;
259+
type: 'json' | 'xml' | 'text';
260+
script: string;
261+
}
262+
```
263+
264+
10. **Request Documentation**
265+
- Add markdown documentation to requests
266+
- Generate API documentation from collections
267+
268+
11. **Performance Metrics**
269+
- Track timing details (DNS, TLS, TTFB)
270+
- Show historical performance graphs
271+
272+
12. **Cookie Manager**
273+
- Domain-based cookie management
274+
- Import/export cookies
275+
- Cookie jar feature
276+
277+
13. **WebSocket Support**
278+
```typescript:src/components/WebSocketPanel.tsx
279+
interface WebSocketPanelProps {
280+
url: string;
281+
onMessage: (data: any) => void;
282+
onSend: (data: any) => void;
283+
}
284+
```
285+
286+
14. **Request Scheduling**
287+
- Schedule requests to run at specific times
288+
- Periodic health checks
289+
290+
15. **Response Validation**
291+
- JSON Schema validation
292+
- Custom validation rules
293+
- Contract testing
294+
295+
16. **Local Mock Server**
296+
```typescript:src/services/mockServer.ts
297+
interface MockRoute {
298+
method: string;
299+
path: string;
300+
response: any;
301+
statusCode: number;
302+
delay?: number;
303+
}
304+
```
305+
306+
17. **Request Sharing**
307+
- Generate shareable links
308+
- Export as curl/wget commands
309+
- Team collaboration features
310+
311+
18. **Advanced Testing**
312+
- Load testing capabilities
313+
- Test scenarios/flows
314+
- Response time assertions
315+
316+
19. **Security Testing**
317+
- Basic security checks
318+
- Headers analysis
319+
- SSL/TLS verification
320+
321+
20. **UI Improvements**
322+
- Customizable themes
323+
- Keyboard shortcuts
324+
- Split view modes
325+
- Request tabs reordering
326+
327+

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "litepost",
33
"private": true,
4-
"version": "0.1.0",
4+
"version": "0.2.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src-tauri/tauri.conf.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "litepost",
4-
"version": "0.1.1",
4+
"version": "0.2.0",
55
"identifier": "com.litepost.app",
66
"build": {
77
"beforeDevCommand": "pnpm dev",

src/store/environments.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ interface EnvironmentState {
1818
getVariable: (key: string) => string | undefined
1919
}
2020

21+
interface PersistedEnvironmentState {
22+
environments: Environment[]
23+
activeEnvironmentId: string | null
24+
}
25+
2126
const ENVIRONMENTS_FILE = 'environments.json'
22-
const defaultData = {
27+
const defaultData: PersistedEnvironmentState = {
2328
environments: [],
2429
activeEnvironmentId: null
2530
}
@@ -63,11 +68,11 @@ export const useEnvironmentStore = create<EnvironmentState>()(
6368
name: 'environment-storage',
6469
storage: {
6570
getItem: async () => {
66-
const data = await loadFromFile<EnvironmentState>(ENVIRONMENTS_FILE, defaultData)
67-
return data
71+
const data = await loadFromFile<PersistedEnvironmentState>(ENVIRONMENTS_FILE, defaultData)
72+
return { state: data }
6873
},
6974
setItem: async (_, value) => {
70-
await saveToFile(ENVIRONMENTS_FILE, value)
75+
await saveToFile(ENVIRONMENTS_FILE, value.state as PersistedEnvironmentState)
7176
},
7277
removeItem: () => {}
7378
}

src/store/settings.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { create } from 'zustand'
22
import { persist } from 'zustand/middleware'
33
import { loadFromFile, saveToFile } from '@/utils/persistence'
44

5-
interface JSONViewerSettings {
5+
export interface JSONViewerSettings {
66
maxAutoExpandDepth: number
77
maxAutoExpandArraySize: number
88
maxAutoExpandObjectSize: number

src/test/ResponsePanel.test.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ vi.mock('lucide-react', () => ({
1010
ChevronDown: () => <div data-testid="chevron-down" />,
1111
ZoomIn: () => <div data-testid="zoom-in" />,
1212
ZoomOut: () => <div data-testid="zoom-out" />,
13-
RotateCw: () => <div data-testid="rotate-cw" />
13+
RotateCw: () => <div data-testid="rotate-cw" />,
14+
Send: () => <div data-testid="send" />
1415
}))
1516

1617
// Mock react-syntax-highlighter
@@ -39,7 +40,7 @@ vi.mock('@/components/CopyButton', () => ({
3940

4041
// Mock settings store
4142
vi.mock('@/store/settings', () => ({
42-
useSettings: () => ({
43+
useSettingsStore: () => ({
4344
jsonViewer: {
4445
maxAutoExpandDepth: 2,
4546
maxAutoExpandArraySize: 10,

src/test/SettingsPanel.test.tsx

+10-16
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
22
import { render, screen, fireEvent, act } from '@testing-library/react'
33
import { SettingsPanel } from '@/components/SettingsPanel'
44
import { useSettingsStore } from '@/store/settings'
5-
import type { SettingsState } from '@/store/settings'
65
import { checkForUpdatesManually } from '@/components/UpdateChecker'
76

8-
const mockUseSettings = useSettings as unknown as ReturnType<typeof vi.fn>
9-
107
// Mock the settings store
118
vi.mock('@/store/settings', () => ({
12-
useSettings: vi.fn()
9+
useSettingsStore: vi.fn(() => ({
10+
jsonViewer: {
11+
maxAutoExpandDepth: 2,
12+
maxAutoExpandArraySize: 50,
13+
maxAutoExpandObjectSize: 20,
14+
},
15+
updateJSONViewerSettings: vi.fn()
16+
}))
1317
}))
1418

1519
// Mock the update checker
@@ -18,18 +22,8 @@ vi.mock('@/components/UpdateChecker', () => ({
1822
}))
1923

2024
describe('SettingsPanel', () => {
21-
const mockSettings: Partial<SettingsState> = {
22-
jsonViewer: {
23-
maxAutoExpandDepth: 2,
24-
maxAutoExpandArraySize: 50,
25-
maxAutoExpandObjectSize: 20,
26-
},
27-
updateJSONViewerSettings: vi.fn(),
28-
}
29-
3025
beforeEach(() => {
3126
vi.clearAllMocks()
32-
mockUseSettings.mockReturnValue(mockSettings)
3327
})
3428

3529
afterEach(() => {
@@ -75,7 +69,7 @@ describe('SettingsPanel', () => {
7569
},
7670
updateJSONViewerSettings: vi.fn()
7771
}
78-
vi.mocked(useSettings).mockReturnValue(mockSettings)
72+
vi.mocked(useSettingsStore).mockReturnValue(mockSettings)
7973

8074
await act(async () => {
8175
render(<SettingsPanel open={true} onOpenChange={() => {}} />)
@@ -123,7 +117,7 @@ describe('SettingsPanel', () => {
123117
render(<SettingsPanel open={true} onOpenChange={() => {}} />)
124118
})
125119
const comingSoonElements = screen.getAllByText(/coming soon/i)
126-
expect(comingSoonElements).toHaveLength(2)
120+
expect(comingSoonElements).toHaveLength(1)
127121
})
128122

129123
it('applies correct styling to sheet content', async () => {

src/utils/url.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ export function getRequestNameFromUrl(url: string): string {
33
// Try to parse the URL
44
const parsedUrl = new URL(url);
55

6-
// Get the pathname without leading/trailing slashes
7-
const path = parsedUrl.pathname.replace(/^\/+|\/+$/g, '');
6+
// Get the pathname without leading/trailing slashes and decode it
7+
const path = decodeURIComponent(parsedUrl.pathname.replace(/^\/+|\/+$/g, ''));
88

99
// If there's no path, return 'Unnamed Request'
1010
if (!path) {
1111
return 'Unnamed Request';
1212
}
1313

14-
// Return the path
14+
// Return the decoded path
1515
return path;
1616
} catch {
1717
// If URL parsing fails, try to extract path portion
@@ -24,8 +24,8 @@ export function getRequestNameFromUrl(url: string): string {
2424
// Remove query parameters and hash
2525
const pathOnly = withoutDomain.split(/[?#]/)[0];
2626

27-
// Remove leading/trailing slashes
28-
const cleanPath = pathOnly.replace(/^\/+|\/+$/g, '');
27+
// Remove leading/trailing slashes and decode
28+
const cleanPath = decodeURIComponent(pathOnly.replace(/^\/+|\/+$/g, ''));
2929

3030
return cleanPath || 'Unnamed Request';
3131
}

0 commit comments

Comments
 (0)