@objectstack/plugin-msw
v3.0.6
Published
MSW (Mock Service Worker) Plugin for ObjectStack Runtime
Readme
@objectstack/plugin-msw
MSW (Mock Service Worker) Plugin for ObjectStack Runtime. This plugin enables seamless integration with Mock Service Worker for testing and development environments.
🤖 AI Development Context
Role: Test Mocking Adapter Usage:
- Intercepts network requests in tests (Browser/Node).
- Simulates a real ObjectStack backend.
Plugin Capabilities
This plugin implements the ObjectStack plugin capability protocol:
- Protocol:
com.objectstack.protocol.testing.mock.v1(full conformance) - Protocol:
com.objectstack.protocol.api.rest.v1(full conformance) - Provides:
ObjectStackServerinterface for mock API operations - Requires:
com.objectstack.engine.objectqlfor data operations
See objectstack.config.ts for the complete capability manifest.
Features
- 🎯 Unified Dispatcher: Uses
@objectstack/runtime'sHttpDispatcherto ensure mocks behave exactly like the real server. - 🔄 Full Protocol Support: Mocks all Runtime endpoints:
- Auth (
/auth) - Metadata (
/metadata) - Data (
/data- with filtering, batching, relations) - Storage (
/storage) - Analytics (
/analytics) - Automation (
/automation)
- Auth (
- 🌐 Universal Support: Works in Browser (Service Worker) and Node.js (Interceptor).
- 🎨 Custom Handlers: Easily inject custom MSW handlers that take precedence.
- 📝 TypeScript First: Fully typed configuration.
Installation
pnpm add @objectstack/plugin-msw mswUsage
With ObjectStack Runtime
import { MSWPlugin } from '@objectstack/plugin-msw';
import { ObjectKernel } from '@objectstack/runtime';
const kernel = new ObjectKernel();
// The MSW Plugin will initialize the HttpDispatcher and intercept requests
kernel.use(new MSWPlugin({
enableBrowser: true,
baseUrl: '/api/v1',
logRequests: true
}));
await kernel.start();Architecture
The plugin uses the HttpDispatcher from the Runtime to process requests intercepted by MSW. This means your mock server runs the actual ObjectStack business logic (permissions, validation, flow execution) in-memory, providing a high-fidelity simulation of the backend.
}));
await kernel.bootstrap();
### Standalone Usage (Browser)
```typescript
import { setupWorker } from 'msw/browser';
import { http, HttpResponse } from 'msw';
import { ObjectStackServer } from '@objectstack/plugin-msw';
// 1. Initialize the mock server
ObjectStackServer.init(protocol);
// 2. Define your handlers
const handlers = [
// Intercept GET /api/user/:id
http.get('/api/user/:id', async ({ params }) => {
const result = await ObjectStackServer.getData('user', params.id as string);
return HttpResponse.json(result.data, { status: result.status });
}),
// Intercept POST /api/user
http.post('/api/user', async ({ request }) => {
const body = await request.json();
const result = await ObjectStackServer.createData('user', body);
return HttpResponse.json(result.data, { status: result.status });
}),
];
// 3. Create and start the worker
const worker = setupWorker(...handlers);
await worker.start();With Custom Handlers
import { MSWPlugin } from '@objectstack/plugin-msw';
import { http, HttpResponse } from 'msw';
const customHandlers = [
http.get('/api/custom/:id', ({ params }) => {
return HttpResponse.json({ id: params.id, custom: true });
})
];
const plugin = new MSWPlugin({
customHandlers,
baseUrl: '/api/v1'
});API Reference
MSWPlugin
The main plugin class that implements the ObjectStack Runtime Plugin interface.
Options
interface MSWPluginOptions {
/**
* Enable MSW in the browser environment
* @default true
*/
enableBrowser?: boolean;
/**
* Custom handlers to add to MSW
*/
customHandlers?: Array<any>;
/**
* Base URL for API endpoints
* @default '/api/v1'
*/
baseUrl?: string;
/**
* Whether to log requests
* @default true
*/
logRequests?: boolean;
}ObjectStackServer
The mock server that handles ObjectStack API calls.
Static Methods
init(protocol, logger?)- Initialize the mock server with an ObjectStack protocol instancefindData(object, params?)- Find records for an objectgetData(object, id)- Get a single record by IDcreateData(object, data)- Create a new recordupdateData(object, id, data)- Update an existing recorddeleteData(object, id)- Delete a recordgetUser(id)- Legacy method for getting user (alias forgetData('user', id))createUser(data)- Legacy method for creating user (alias forcreateData('user', data))
Mocked Endpoints
The plugin automatically mocks the following ObjectStack API endpoints:
Discovery
GET /api/v1- Get API discovery information
Metadata
GET /api/v1/meta- Get available metadata typesGET /api/v1/meta/:type- Get metadata items for a typeGET /api/v1/meta/:type/:name- Get specific metadata item
Data Operations
GET /api/v1/data/:object- Find recordsGET /api/v1/data/:object/:id- Get record by IDPOST /api/v1/data/:object- Create recordPATCH /api/v1/data/:object/:id- Update recordDELETE /api/v1/data/:object/:id- Delete record
UI Protocol
GET /api/v1/ui/view/:object- Get UI view configuration
Example: Testing with Vitest
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { setupWorker } from 'msw/browser';
import { ObjectStackServer } from '@objectstack/plugin-msw';
import { http, HttpResponse } from 'msw';
describe('User API', () => {
let worker: any;
beforeAll(async () => {
// Initialize mock server
ObjectStackServer.init(protocol);
// Setup handlers
const handlers = [
http.get('/api/user/:id', async ({ params }) => {
const result = await ObjectStackServer.getData('user', params.id as string);
return HttpResponse.json(result.data, { status: result.status });
})
];
worker = setupWorker(...handlers);
await worker.start({ onUnhandledRequest: 'bypass' });
});
afterAll(() => {
worker.stop();
});
it('should get user by id', async () => {
const response = await fetch('/api/user/123');
const data = await response.json();
expect(response.status).toBe(200);
expect(data).toBeDefined();
});
});License
Apache-2.0
Related Packages
- @objectstack/runtime - ObjectStack Runtime
- @objectstack/spec - ObjectStack Specifications
- msw - Mock Service Worker
