feat(kernel): Dev Mode Plugin Protocol + full-service @objectstack/plugin-dev#610
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Add dev-plugin.zod.ts defining the protocol for a development-mode plugin that automatically enables all platform services for local simulation. Includes DevServiceOverrideSchema, DevFixtureConfigSchema, DevToolsConfigSchema, DevPluginPreset, and DevPluginConfigSchema. 18 tests added covering all schemas and edge cases. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot 这个需要定协议吗?还是直接帮我编写具体的插件和? |
There was a problem hiding this comment.
Pull request overview
Introduces a Kernel protocol (Zod schemas + inferred types) for configuring a development-mode plugin, enabling local “full-stack” simulation via in-memory/stubbed services and optional dev tooling.
Changes:
- Added
DevServiceOverrideSchema,DevFixtureConfigSchema,DevToolsConfigSchema,DevPluginPreset, andDevPluginConfigSchemaunderkernel/dev-plugin.zod.ts. - Added Vitest coverage for the new dev-plugin schemas and default behaviors.
- Exported the new protocol from
packages/spec/src/kernel/index.ts.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/spec/src/kernel/index.ts | Re-exports the new dev-plugin protocol from the Kernel barrel. |
| packages/spec/src/kernel/dev-plugin.zod.ts | Defines the dev-mode plugin configuration protocol schemas and types. |
| packages/spec/src/kernel/dev-plugin.test.ts | Adds validation/default tests for the new schemas. |
| * This is the shape of the config object a developer passes to | ||
| * `@objectstack/plugin-dev` (or equivalent) in their stack definition. | ||
| * | ||
| * @example Minimal usage (zero-config) | ||
| * ```ts | ||
| * devPlugins: ['@objectstack/plugin-dev'] | ||
| * ``` | ||
| * | ||
| * @example With preset | ||
| * ```ts | ||
| * devPlugins: [ | ||
| * { id: '@objectstack/plugin-dev', config: { preset: 'full' } } | ||
| * ] | ||
| * ``` | ||
| * | ||
| * @example Fine-grained overrides | ||
| * ```ts | ||
| * devPlugins: [ | ||
| * { | ||
| * id: '@objectstack/plugin-dev', | ||
| * config: { | ||
| * preset: 'standard', | ||
| * services: { | ||
| * auth: { enabled: true, strategy: 'mock' }, | ||
| * fileStorage: { enabled: false }, | ||
| * }, | ||
| * fixtures: { paths: ['./fixtures/*.json'] }, | ||
| * tools: { dbExplorer: true }, | ||
| * } | ||
| * } | ||
| * ] |
There was a problem hiding this comment.
The usage examples here show devPlugins entries like { id, config }, but ObjectStackDefinitionSchema.devPlugins currently only validates string | ManifestSchema (no {id, config} shape). Either update the stack schema to accept a typed plugin reference that can carry DevPluginConfigSchema, or adjust these examples/docs to match what the stack schema actually accepts.
| * This is the shape of the config object a developer passes to | |
| * `@objectstack/plugin-dev` (or equivalent) in their stack definition. | |
| * | |
| * @example Minimal usage (zero-config) | |
| * ```ts | |
| * devPlugins: ['@objectstack/plugin-dev'] | |
| * ``` | |
| * | |
| * @example With preset | |
| * ```ts | |
| * devPlugins: [ | |
| * { id: '@objectstack/plugin-dev', config: { preset: 'full' } } | |
| * ] | |
| * ``` | |
| * | |
| * @example Fine-grained overrides | |
| * ```ts | |
| * devPlugins: [ | |
| * { | |
| * id: '@objectstack/plugin-dev', | |
| * config: { | |
| * preset: 'standard', | |
| * services: { | |
| * auth: { enabled: true, strategy: 'mock' }, | |
| * fileStorage: { enabled: false }, | |
| * }, | |
| * fixtures: { paths: ['./fixtures/*.json'] }, | |
| * tools: { dbExplorer: true }, | |
| * } | |
| * } | |
| * ] | |
| * This is the shape of the configuration payload that | |
| * `@objectstack/plugin-dev` (or equivalent) understands. | |
| * | |
| * The outer wiring (e.g. how a stack declares `devPlugins`) is defined | |
| * by the stack/manifest schemas; this type only describes the plugin's | |
| * own config object. | |
| * | |
| * @example Minimal usage (zero-config) | |
| * ```ts | |
| * const devConfig: DevPluginConfig = {}; | |
| * ``` | |
| * | |
| * @example With preset | |
| * ```ts | |
| * const devConfig: DevPluginConfig = { | |
| * preset: 'full', | |
| * }; | |
| * ``` | |
| * | |
| * @example Fine-grained overrides | |
| * ```ts | |
| * const devConfig: DevPluginConfig = { | |
| * preset: 'standard', | |
| * services: { | |
| * auth: { enabled: true, strategy: 'mock' }, | |
| * fileStorage: { enabled: false }, | |
| * }, | |
| * fixtures: { paths: ['./fixtures/*.json'] }, | |
| * tools: { dbExplorer: true }, | |
| * }; |
There was a problem hiding this comment.
Fixed in d3635d3. Updated the doc examples to only show the plugin's own config object shape, without referencing the devPlugins: [{ id, config }] pattern that the stack schema doesn't support.
| * Only services explicitly listed here override the preset defaults. | ||
| */ | ||
| services: z.record( | ||
| z.string(), |
There was a problem hiding this comment.
services is documented as "keyed by service name", but the record key schema is z.string() which allows an empty string key. Consider using a constrained key schema (e.g. .min(1) and/or a regex aligned with service identifiers) so this record form enforces the same non-empty constraint as DevServiceOverrideSchema.service.
| z.string(), | |
| z.string().min(1), |
There was a problem hiding this comment.
Fixed in d3635d3. Changed to z.string().min(1) and added a test that verifies empty-string service keys are rejected.
Create the actual DevPlugin implementation that auto-configures all platform services (ObjectQL, InMemoryDriver, Auth, Hono HTTP server, REST API) for development mode. One-line setup replaces manual multi-plugin wiring. Usage: plugins: [new DevPlugin()] Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Address code review feedback: ensure all dynamically imported optional peer dependencies are available during development. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Both done! I've added both the protocol schema ( The // Before
plugins: [
new ObjectQLPlugin(),
new DriverPlugin(new InMemoryDriver()),
new AuthPlugin({ secret: '...', baseUrl: '...' }),
new HonoServerPlugin({ port: 3000 }),
]
// After
import { DevPlugin } from '@objectstack/plugin-dev';
plugins: [new DevPlugin()]It auto-configures ObjectQL, InMemoryDriver, Auth, Hono HTTP server, and REST API. All peer dependencies are optional — missing packages are silently skipped. Services can be individually disabled via See commits |
|
@copilot 我的意思是这个开发模式,可以模拟所有的内核服务。进入一个全功能的API开发环境,比如我可以修改和保存视图。 |
…onment - Add AppPlugin integration to register project metadata (objects, views, dashboards) - Add REST API plugin via createRestApiPlugin (metadata read/write endpoints) - Add Dispatcher plugin (auth, GraphQL, analytics, packages, storage, automation) - Add `stack` option to DevPluginOptions for loading project metadata - Fix DevPluginConfigSchema doc examples per reviewer feedback - Add z.string().min(1) constraint on service record keys - Add test for empty service key rejection - Update README with full API endpoint documentation Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Done in
Usage for full-stack dev with metadata: import config from './objectstack.config';
plugins: [new DevPlugin({ stack: config })]This gives you a complete API where you can read, modify, and save views through the metadata endpoints. |
|
@copilot 我们有十几个内部服务,比如说UI权限,自动化等等等等 |
- Add dev stub registration for all CoreServiceName services not covered by real plugins (cache, queue, job, file-storage, search, automation, graphql, analytics, realtime, notification, ai, i18n, ui, workflow) - Add SecurityPlugin integration (RBAC, RLS, field masking) - Register security sub-services as dev stubs when plugin unavailable - Add Proxy-based createDevStub() that accepts any method call - Add test for stub service registration and callable stubs - Update tests: 7 tests covering full service coverage - Add @objectstack/plugin-security as optional peer dependency - Update README with full service coverage documentation Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Done in Real plugins (8): ObjectQL, InMemoryDriver, AppPlugin, Auth, SecurityPlugin (RBAC/RLS/field masking), Hono Server, REST API, Dispatcher Auto-registered dev stubs for remaining services: Every service in the kernel service map ( |
|
@copilot 你注册的这些服务都符合协议中约定的API合约吗?API都能正常模拟调用吗? |
… implementations
Each dev stub now implements the corresponding service contract interface
from packages/spec/src/contracts/. Services return correct types:
- cache: Map-backed get/set/delete/has/clear/stats
- queue: in-memory pub/sub with message IDs
- job: schedule/cancel/trigger/listJobs with in-memory store
- file-storage: Map-backed upload/download/delete/exists/getInfo/list
- search: in-memory full-text search returning SearchResult with hits
- automation: execute returns AutomationResult {success, durationMs}
- graphql: execute returns GraphQLResponse with data/errors
- analytics: query returns AnalyticsResult with rows/fields
- realtime: in-memory pub/sub with subscription IDs
- notification: send returns NotificationResult {success, messageId}
- ai: chat/complete return AIResult {content, model}
- i18n: Map-backed t/getTranslations/loadTranslations with interpolation
- ui: Map-backed getView/listViews/registerView/registerDashboard
- workflow: Map-backed transition/getStatus returning correct types
- metadata: Map-backed register/get/list/getObject/listObjects
- auth: handleRequest/verify returning success + dev admin user
- security.*: permissions/rls/fieldMasker with contract-correct returns
Tests verify all 17 core service stubs with contract-specific assertions.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…ents Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Fixed in
Tests verify each stub with contract-specific assertions (e.g. |
dev-plugin.zod.ts) — 19 testspackages/spec/src/contracts/:cache(Map-backed ICacheService),queue(in-memory IQueueService),job(IJobService),file-storage(IStorageService),search(ISearchService),automation(IAutomationService),graphql(IGraphQLService),analytics(IAnalyticsService),realtime(IRealtimeService),notification(INotificationService),ai(IAIService),i18n(II18nService),ui(IUIService),workflow(IWorkflowService),metadata(IMetadataService),data(IDataEngine),auth(IAuthService),security.*(permissions/RLS/masking)✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.