Skip to content

Commit d976e96

Browse files
Copilothotlong
andcommitted
Add MSW plugin package with full implementation
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 4236b86 commit d976e96

7 files changed

Lines changed: 984 additions & 7 deletions

File tree

packages/plugin-msw/CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# @objectstack/plugin-msw
2+
3+
## 0.3.1
4+
5+
### Added
6+
7+
- Initial release of MSW plugin for ObjectStack
8+
- `MSWPlugin` class implementing RuntimePlugin interface
9+
- `ObjectStackServer` mock server for handling API calls
10+
- Automatic generation of MSW handlers for ObjectStack API endpoints
11+
- Support for browser and Node.js environments
12+
- Custom handler support
13+
- Comprehensive documentation and examples
14+
- TypeScript type definitions
15+
16+
### Features
17+
18+
- Discovery endpoint mocking
19+
- Metadata endpoint mocking
20+
- Data CRUD operation mocking
21+
- UI protocol endpoint mocking
22+
- Request logging support
23+
- Configurable base URL
24+
- Integration with ObjectStack Runtime Protocol

packages/plugin-msw/README.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# @objectstack/plugin-msw
2+
3+
MSW (Mock Service Worker) Plugin for ObjectStack Runtime. This plugin enables seamless integration with [Mock Service Worker](https://mswjs.io/) for testing and development environments.
4+
5+
## Features
6+
7+
- 🎯 **Automatic API Mocking**: Automatically generates MSW handlers for all ObjectStack API endpoints
8+
- 🔄 **Runtime Integration**: Seamlessly integrates with ObjectStack Runtime Protocol
9+
- 🧪 **Testing Ready**: Perfect for unit tests, integration tests, and development
10+
- 🌐 **Browser & Node Support**: Works in both browser and Node.js environments
11+
- 🎨 **Custom Handlers**: Easily add custom MSW handlers alongside standard ones
12+
- 📝 **TypeScript First**: Fully typed with TypeScript
13+
14+
## Installation
15+
16+
```bash
17+
pnpm add @objectstack/plugin-msw msw
18+
```
19+
20+
## Usage
21+
22+
### With ObjectStack Runtime
23+
24+
```typescript
25+
import { MSWPlugin } from '@objectstack/plugin-msw';
26+
import { ObjectStackRuntime } from '@objectstack/runtime';
27+
28+
const runtime = new ObjectStackRuntime({
29+
plugins: [
30+
new MSWPlugin({
31+
enableBrowser: true,
32+
baseUrl: '/api/v1',
33+
logRequests: true
34+
})
35+
]
36+
});
37+
38+
await runtime.start();
39+
```
40+
41+
### Standalone Usage (Browser)
42+
43+
```typescript
44+
import { setupWorker } from 'msw/browser';
45+
import { http, HttpResponse } from 'msw';
46+
import { ObjectStackServer } from '@objectstack/plugin-msw';
47+
48+
// 1. Initialize the mock server
49+
ObjectStackServer.init(protocol);
50+
51+
// 2. Define your handlers
52+
const handlers = [
53+
// Intercept GET /api/user/:id
54+
http.get('/api/user/:id', async ({ params }) => {
55+
const result = await ObjectStackServer.getData('user', params.id as string);
56+
return HttpResponse.json(result.data, { status: result.status });
57+
}),
58+
59+
// Intercept POST /api/user
60+
http.post('/api/user', async ({ request }) => {
61+
const body = await request.json();
62+
const result = await ObjectStackServer.createData('user', body);
63+
return HttpResponse.json(result.data, { status: result.status });
64+
}),
65+
];
66+
67+
// 3. Create and start the worker
68+
const worker = setupWorker(...handlers);
69+
await worker.start();
70+
```
71+
72+
### With Custom Handlers
73+
74+
```typescript
75+
import { MSWPlugin } from '@objectstack/plugin-msw';
76+
import { http, HttpResponse } from 'msw';
77+
78+
const customHandlers = [
79+
http.get('/api/custom/:id', ({ params }) => {
80+
return HttpResponse.json({ id: params.id, custom: true });
81+
})
82+
];
83+
84+
const plugin = new MSWPlugin({
85+
customHandlers,
86+
baseUrl: '/api/v1'
87+
});
88+
```
89+
90+
## API Reference
91+
92+
### MSWPlugin
93+
94+
The main plugin class that implements the ObjectStack Runtime Plugin interface.
95+
96+
#### Options
97+
98+
```typescript
99+
interface MSWPluginOptions {
100+
/**
101+
* Enable MSW in the browser environment
102+
* @default true
103+
*/
104+
enableBrowser?: boolean;
105+
106+
/**
107+
* Custom handlers to add to MSW
108+
*/
109+
customHandlers?: Array<any>;
110+
111+
/**
112+
* Base URL for API endpoints
113+
* @default '/api/v1'
114+
*/
115+
baseUrl?: string;
116+
117+
/**
118+
* Whether to log requests
119+
* @default true
120+
*/
121+
logRequests?: boolean;
122+
}
123+
```
124+
125+
### ObjectStackServer
126+
127+
The mock server that handles ObjectStack API calls.
128+
129+
#### Static Methods
130+
131+
- `init(protocol, logger?)` - Initialize the mock server with an ObjectStack protocol instance
132+
- `findData(object, params?)` - Find records for an object
133+
- `getData(object, id)` - Get a single record by ID
134+
- `createData(object, data)` - Create a new record
135+
- `updateData(object, id, data)` - Update an existing record
136+
- `deleteData(object, id)` - Delete a record
137+
- `getUser(id)` - Legacy method for getting user (alias for `getData('user', id)`)
138+
- `createUser(data)` - Legacy method for creating user (alias for `createData('user', data)`)
139+
140+
## Mocked Endpoints
141+
142+
The plugin automatically mocks the following ObjectStack API endpoints:
143+
144+
### Discovery
145+
- `GET /api/v1` - Get API discovery information
146+
147+
### Metadata
148+
- `GET /api/v1/meta` - Get available metadata types
149+
- `GET /api/v1/meta/:type` - Get metadata items for a type
150+
- `GET /api/v1/meta/:type/:name` - Get specific metadata item
151+
152+
### Data Operations
153+
- `GET /api/v1/data/:object` - Find records
154+
- `GET /api/v1/data/:object/:id` - Get record by ID
155+
- `POST /api/v1/data/:object` - Create record
156+
- `PATCH /api/v1/data/:object/:id` - Update record
157+
- `DELETE /api/v1/data/:object/:id` - Delete record
158+
159+
### UI Protocol
160+
- `GET /api/v1/ui/view/:object` - Get UI view configuration
161+
162+
## Example: Testing with Vitest
163+
164+
```typescript
165+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
166+
import { setupWorker } from 'msw/browser';
167+
import { ObjectStackServer } from '@objectstack/plugin-msw';
168+
import { http, HttpResponse } from 'msw';
169+
170+
describe('User API', () => {
171+
let worker: any;
172+
173+
beforeAll(async () => {
174+
// Initialize mock server
175+
ObjectStackServer.init(protocol);
176+
177+
// Setup handlers
178+
const handlers = [
179+
http.get('/api/user/:id', async ({ params }) => {
180+
const result = await ObjectStackServer.getData('user', params.id as string);
181+
return HttpResponse.json(result.data, { status: result.status });
182+
})
183+
];
184+
185+
worker = setupWorker(...handlers);
186+
await worker.start({ onUnhandledRequest: 'bypass' });
187+
});
188+
189+
afterAll(() => {
190+
worker.stop();
191+
});
192+
193+
it('should get user by id', async () => {
194+
const response = await fetch('/api/user/123');
195+
const data = await response.json();
196+
197+
expect(response.status).toBe(200);
198+
expect(data).toBeDefined();
199+
});
200+
});
201+
```
202+
203+
## License
204+
205+
Apache-2.0
206+
207+
## Related Packages
208+
209+
- [@objectstack/runtime](../runtime) - ObjectStack Runtime
210+
- [@objectstack/spec](../spec) - ObjectStack Specifications
211+
- [msw](https://mswjs.io/) - Mock Service Worker

packages/plugin-msw/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "@objectstack/plugin-msw",
3+
"version": "0.3.1",
4+
"description": "MSW (Mock Service Worker) Plugin for ObjectStack Runtime",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
7+
"scripts": {
8+
"build": "tsc"
9+
},
10+
"dependencies": {
11+
"@objectstack/spec": "workspace:*",
12+
"@objectstack/types": "workspace:*",
13+
"msw": "^2.0.0"
14+
},
15+
"devDependencies": {
16+
"@objectstack/runtime": "workspace:*",
17+
"@types/node": "^20.0.0",
18+
"typescript": "^5.0.0"
19+
},
20+
"peerDependencies": {
21+
"@objectstack/runtime": "^0.3.1"
22+
}
23+
}

packages/plugin-msw/src/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @objectstack/plugin-msw
3+
*
4+
* MSW (Mock Service Worker) Plugin for ObjectStack Runtime
5+
*
6+
* This plugin enables seamless integration with Mock Service Worker for
7+
* testing and development environments. It automatically generates MSW
8+
* handlers for all ObjectStack API endpoints.
9+
*
10+
* @example
11+
* ```typescript
12+
* import { MSWPlugin, ObjectStackServer } from '@objectstack/plugin-msw';
13+
* import { ObjectStackRuntime } from '@objectstack/runtime';
14+
*
15+
* // Use with runtime
16+
* const runtime = new ObjectStackRuntime({
17+
* plugins: [
18+
* new MSWPlugin({
19+
* enableBrowser: true,
20+
* baseUrl: '/api/v1'
21+
* })
22+
* ]
23+
* });
24+
*
25+
* // Or use standalone in browser
26+
* import { setupWorker, http } from 'msw/browser';
27+
*
28+
* ObjectStackServer.init(protocol);
29+
*
30+
* const handlers = [
31+
* http.get('/api/user/:id', async ({ params }) => {
32+
* const result = await ObjectStackServer.getData('user', params.id);
33+
* return HttpResponse.json(result.data, { status: result.status });
34+
* })
35+
* ];
36+
*
37+
* const worker = setupWorker(...handlers);
38+
* await worker.start();
39+
* ```
40+
*/
41+
42+
export { MSWPlugin, ObjectStackServer } from './msw-plugin';
43+
export type { MSWPluginOptions } from './msw-plugin';
44+
45+
// Re-export MSW types for convenience
46+
export type { HttpHandler, HttpResponse } from 'msw';

0 commit comments

Comments
 (0)