@mantajs/core 0.2.0-beta.0 → 0.2.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/auth-mock.d.ts +3 -3
- package/dist/adapters/auth-mock.d.ts.map +1 -1
- package/dist/adapters/cache-memory.d.ts +1 -1
- package/dist/adapters/cache-memory.d.ts.map +1 -1
- package/dist/adapters/database-memory.d.ts +1 -1
- package/dist/adapters/database-memory.d.ts.map +1 -1
- package/dist/adapters/database-memory.js +1 -1
- package/dist/adapters/database-memory.js.map +1 -1
- package/dist/adapters/eventbus-memory.d.ts +1 -1
- package/dist/adapters/eventbus-memory.d.ts.map +1 -1
- package/dist/adapters/eventbus-memory.js +1 -1
- package/dist/adapters/eventbus-memory.js.map +1 -1
- package/dist/adapters/file-memory.d.ts +2 -5
- package/dist/adapters/file-memory.d.ts.map +1 -1
- package/dist/adapters/file-memory.js +2 -2
- package/dist/adapters/file-memory.js.map +1 -1
- package/dist/adapters/http-memory.d.ts +1 -1
- package/dist/adapters/http-memory.d.ts.map +1 -1
- package/dist/adapters/http-memory.js +1 -1
- package/dist/adapters/http-memory.js.map +1 -1
- package/dist/adapters/index.d.ts +13 -13
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +13 -13
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/job-scheduler-memory.d.ts +2 -2
- package/dist/adapters/job-scheduler-memory.d.ts.map +1 -1
- package/dist/adapters/job-scheduler-memory.js +1 -1
- package/dist/adapters/job-scheduler-memory.js.map +1 -1
- package/dist/adapters/locking-memory.d.ts +1 -1
- package/dist/adapters/locking-memory.d.ts.map +1 -1
- package/dist/adapters/locking-memory.js +1 -1
- package/dist/adapters/locking-memory.js.map +1 -1
- package/dist/adapters/logger-test.d.ts +1 -1
- package/dist/adapters/logger-test.d.ts.map +1 -1
- package/dist/adapters/notification-memory.d.ts +1 -1
- package/dist/adapters/notification-memory.d.ts.map +1 -1
- package/dist/adapters/notification-memory.js +1 -1
- package/dist/adapters/notification-memory.js.map +1 -1
- package/dist/adapters/relational-query-memory.d.ts +1 -1
- package/dist/adapters/relational-query-memory.d.ts.map +1 -1
- package/dist/adapters/repository-factory-memory.d.ts +3 -3
- package/dist/adapters/repository-factory-memory.d.ts.map +1 -1
- package/dist/adapters/repository-factory-memory.js +1 -1
- package/dist/adapters/repository-factory-memory.js.map +1 -1
- package/dist/adapters/repository-memory.d.ts +1 -1
- package/dist/adapters/repository-memory.d.ts.map +1 -1
- package/dist/adapters/repository-memory.js +1 -1
- package/dist/adapters/repository-memory.js.map +1 -1
- package/dist/ai/index.js +1 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/app/index.d.ts +10 -10
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +3 -3
- package/dist/app/index.js.map +1 -1
- package/dist/auth/auth-module-service.d.ts +3 -3
- package/dist/auth/auth-module-service.d.ts.map +1 -1
- package/dist/auth/auth-module-service.js +1 -1
- package/dist/auth/auth-module-service.js.map +1 -1
- package/dist/auth/index.d.ts +6 -6
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +4 -4
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/middleware.d.ts +2 -2
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +1 -1
- package/dist/auth/middleware.js.map +1 -1
- package/dist/auth/models/auth-identity.d.ts +8 -8
- package/dist/auth/models/auth-identity.js +1 -1
- package/dist/auth/models/auth-identity.js.map +1 -1
- package/dist/auth/providers/emailpass.d.ts +1 -1
- package/dist/auth/providers/emailpass.d.ts.map +1 -1
- package/dist/auth/providers/emailpass.js.map +1 -1
- package/dist/command/define-command-graph.d.ts +1 -1
- package/dist/command/define-command-graph.d.ts.map +1 -1
- package/dist/command/define-command-graph.js +1 -1
- package/dist/command/define-command-graph.js.map +1 -1
- package/dist/command/dml-to-zod.d.ts +1 -1
- package/dist/command/dml-to-zod.d.ts.map +1 -1
- package/dist/command/dml-to-zod.js +1 -1
- package/dist/command/dml-to-zod.js.map +1 -1
- package/dist/command/generate-entity-commands.d.ts +3 -3
- package/dist/command/generate-entity-commands.d.ts.map +1 -1
- package/dist/command/generate-entity-commands.js +2 -2
- package/dist/command/generate-entity-commands.js.map +1 -1
- package/dist/command/index.d.ts +9 -9
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +5 -5
- package/dist/command/index.js.map +1 -1
- package/dist/command/types.d.ts +5 -5
- package/dist/command/types.d.ts.map +1 -1
- package/dist/config/built-in-presets.d.ts +1 -1
- package/dist/config/built-in-presets.d.ts.map +1 -1
- package/dist/config/built-in-presets.js +1 -1
- package/dist/config/built-in-presets.js.map +1 -1
- package/dist/config/config-manager.d.ts +1 -1
- package/dist/config/config-manager.d.ts.map +1 -1
- package/dist/config/config-manager.js +2 -2
- package/dist/config/config-manager.js.map +1 -1
- package/dist/config/define-config.d.ts +1 -1
- package/dist/config/define-config.d.ts.map +1 -1
- package/dist/config/define-config.js +2 -2
- package/dist/config/define-config.js.map +1 -1
- package/dist/config/index.d.ts +8 -8
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +6 -6
- package/dist/config/index.js.map +1 -1
- package/dist/config/presets.js +1 -1
- package/dist/config/presets.js.map +1 -1
- package/dist/config/types.d.ts +37 -17
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +4 -2
- package/dist/config/types.js.map +1 -1
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +2 -2
- package/dist/context/index.js.map +1 -1
- package/dist/context/registry.d.ts +1 -1
- package/dist/context/registry.d.ts.map +1 -1
- package/dist/context/registry.js +1 -1
- package/dist/context/registry.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/dml/entity.js +1 -1
- package/dist/dml/entity.js.map +1 -1
- package/dist/dml/from-zod.js +2 -2
- package/dist/dml/from-zod.js.map +1 -1
- package/dist/dml/generator/index.js +1 -1
- package/dist/dml/generator/index.js.map +1 -1
- package/dist/dml/index.d.ts +10 -10
- package/dist/dml/index.d.ts.map +1 -1
- package/dist/dml/index.js +8 -8
- package/dist/dml/index.js.map +1 -1
- package/dist/dml/infer.d.ts +1 -1
- package/dist/dml/infer.d.ts.map +1 -1
- package/dist/dml/model.d.ts +2 -2
- package/dist/dml/model.d.ts.map +1 -1
- package/dist/dml/model.js +12 -12
- package/dist/dml/model.js.map +1 -1
- package/dist/dml/modifiers.d.ts +1 -1
- package/dist/dml/modifiers.d.ts.map +1 -1
- package/dist/dml/properties/array.d.ts +1 -1
- package/dist/dml/properties/array.d.ts.map +1 -1
- package/dist/dml/properties/array.js +1 -1
- package/dist/dml/properties/array.js.map +1 -1
- package/dist/dml/properties/autoincrement.d.ts +1 -1
- package/dist/dml/properties/autoincrement.d.ts.map +1 -1
- package/dist/dml/properties/autoincrement.js +1 -1
- package/dist/dml/properties/autoincrement.js.map +1 -1
- package/dist/dml/properties/base.js +2 -2
- package/dist/dml/properties/base.js.map +1 -1
- package/dist/dml/properties/big-number.d.ts +1 -1
- package/dist/dml/properties/big-number.d.ts.map +1 -1
- package/dist/dml/properties/big-number.js +1 -1
- package/dist/dml/properties/big-number.js.map +1 -1
- package/dist/dml/properties/boolean.d.ts +1 -1
- package/dist/dml/properties/boolean.d.ts.map +1 -1
- package/dist/dml/properties/boolean.js +1 -1
- package/dist/dml/properties/boolean.js.map +1 -1
- package/dist/dml/properties/computed.d.ts +1 -1
- package/dist/dml/properties/computed.d.ts.map +1 -1
- package/dist/dml/properties/computed.js +1 -1
- package/dist/dml/properties/computed.js.map +1 -1
- package/dist/dml/properties/date-time.d.ts +1 -1
- package/dist/dml/properties/date-time.d.ts.map +1 -1
- package/dist/dml/properties/date-time.js +1 -1
- package/dist/dml/properties/date-time.js.map +1 -1
- package/dist/dml/properties/enum.d.ts +2 -2
- package/dist/dml/properties/enum.d.ts.map +1 -1
- package/dist/dml/properties/enum.js +1 -1
- package/dist/dml/properties/enum.js.map +1 -1
- package/dist/dml/properties/float.d.ts +1 -1
- package/dist/dml/properties/float.d.ts.map +1 -1
- package/dist/dml/properties/float.js +1 -1
- package/dist/dml/properties/float.js.map +1 -1
- package/dist/dml/properties/index.d.ts +14 -14
- package/dist/dml/properties/index.d.ts.map +1 -1
- package/dist/dml/properties/index.js +14 -14
- package/dist/dml/properties/index.js.map +1 -1
- package/dist/dml/properties/json.d.ts +1 -1
- package/dist/dml/properties/json.d.ts.map +1 -1
- package/dist/dml/properties/json.js +1 -1
- package/dist/dml/properties/json.js.map +1 -1
- package/dist/dml/properties/nullable.d.ts +1 -1
- package/dist/dml/properties/nullable.d.ts.map +1 -1
- package/dist/dml/properties/number.d.ts +2 -2
- package/dist/dml/properties/number.d.ts.map +1 -1
- package/dist/dml/properties/number.js +2 -2
- package/dist/dml/properties/number.js.map +1 -1
- package/dist/dml/properties/primary-key.d.ts +1 -1
- package/dist/dml/properties/primary-key.d.ts.map +1 -1
- package/dist/dml/properties/text.d.ts +2 -2
- package/dist/dml/properties/text.d.ts.map +1 -1
- package/dist/dml/properties/text.js +2 -2
- package/dist/dml/properties/text.js.map +1 -1
- package/dist/dml/relations/belongs-to.d.ts +1 -1
- package/dist/dml/relations/belongs-to.d.ts.map +1 -1
- package/dist/dml/relations/has-many.d.ts +1 -1
- package/dist/dml/relations/has-many.d.ts.map +1 -1
- package/dist/dml/relations/has-one.d.ts +1 -1
- package/dist/dml/relations/has-one.d.ts.map +1 -1
- package/dist/dml/relations/many-to-many.d.ts +1 -1
- package/dist/dml/relations/many-to-many.d.ts.map +1 -1
- package/dist/events/index.d.ts +2 -2
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +1 -1
- package/dist/events/index.js.map +1 -1
- package/dist/events/message-aggregator.d.ts +1 -1
- package/dist/events/message-aggregator.d.ts.map +1 -1
- package/dist/events/types.d.ts +1 -1
- package/dist/events/types.d.ts.map +1 -1
- package/dist/index.d.ts +54 -54
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -30
- package/dist/index.js.map +1 -1
- package/dist/job/index.d.ts +4 -4
- package/dist/job/index.d.ts.map +1 -1
- package/dist/job/index.js +1 -1
- package/dist/job/index.js.map +1 -1
- package/dist/link/index.js +1 -1
- package/dist/link/index.js.map +1 -1
- package/dist/middleware/define-middleware.js +1 -1
- package/dist/middleware/define-middleware.js.map +1 -1
- package/dist/middleware/index.d.ts +3 -3
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/middleware/index.js.map +1 -1
- package/dist/module/index.d.ts +1 -1
- package/dist/module/index.d.ts.map +1 -1
- package/dist/module/versioning.d.ts +1 -1
- package/dist/module/versioning.d.ts.map +1 -1
- package/dist/naming.js +1 -1
- package/dist/naming.js.map +1 -1
- package/dist/ports/auth.d.ts +2 -2
- package/dist/ports/auth.d.ts.map +1 -1
- package/dist/ports/database.d.ts +1 -1
- package/dist/ports/database.d.ts.map +1 -1
- package/dist/ports/event-bus.d.ts +2 -2
- package/dist/ports/event-bus.d.ts.map +1 -1
- package/dist/ports/file.d.ts +9 -5
- package/dist/ports/file.d.ts.map +1 -1
- package/dist/ports/in-memory-progress-channel.d.ts +1 -1
- package/dist/ports/in-memory-progress-channel.d.ts.map +1 -1
- package/dist/ports/in-memory-queue.d.ts +1 -1
- package/dist/ports/in-memory-queue.d.ts.map +1 -1
- package/dist/ports/index.d.ts +26 -26
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +3 -3
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/job-scheduler.d.ts +2 -2
- package/dist/ports/job-scheduler.d.ts.map +1 -1
- package/dist/ports/repository-factory.d.ts +1 -1
- package/dist/ports/repository-factory.d.ts.map +1 -1
- package/dist/ports/repository.d.ts +1 -1
- package/dist/ports/repository.d.ts.map +1 -1
- package/dist/ports/schema-generator.d.ts +1 -1
- package/dist/ports/schema-generator.d.ts.map +1 -1
- package/dist/ports/types.d.ts +2 -2
- package/dist/ports/types.d.ts.map +1 -1
- package/dist/query/define-query-graph.d.ts +1 -1
- package/dist/query/define-query-graph.d.ts.map +1 -1
- package/dist/query/define-query-graph.js +1 -1
- package/dist/query/define-query-graph.js.map +1 -1
- package/dist/query/define-query.d.ts +20 -4
- package/dist/query/define-query.d.ts.map +1 -1
- package/dist/query/define-query.js +1 -1
- package/dist/query/define-query.js.map +1 -1
- package/dist/query/extend-query-graph.d.ts +2 -2
- package/dist/query/extend-query-graph.d.ts.map +1 -1
- package/dist/query/index.d.ts +10 -10
- package/dist/query/index.d.ts.map +1 -1
- package/dist/query/index.js +11 -5
- package/dist/query/index.js.map +1 -1
- package/dist/service/define.d.ts +14 -6
- package/dist/service/define.d.ts.map +1 -1
- package/dist/service/define.js +1 -1
- package/dist/service/define.js.map +1 -1
- package/dist/service/index.d.ts +6 -6
- package/dist/service/index.d.ts.map +1 -1
- package/dist/service/index.js +4 -4
- package/dist/service/index.js.map +1 -1
- package/dist/service/instantiate.d.ts +11 -5
- package/dist/service/instantiate.d.ts.map +1 -1
- package/dist/service/instantiate.js +11 -4
- package/dist/service/instantiate.js.map +1 -1
- package/dist/service/snapshot-repository.d.ts +1 -1
- package/dist/service/snapshot-repository.d.ts.map +1 -1
- package/dist/service/types.d.ts +1 -1
- package/dist/service/types.d.ts.map +1 -1
- package/dist/strict-mode/index.js +1 -1
- package/dist/strict-mode/index.js.map +1 -1
- package/dist/subscriber/index.d.ts +5 -5
- package/dist/subscriber/index.d.ts.map +1 -1
- package/dist/subscriber/index.js +1 -1
- package/dist/subscriber/index.js.map +1 -1
- package/dist/testing/relational-query-suite.d.ts +1 -1
- package/dist/testing/relational-query-suite.d.ts.map +1 -1
- package/dist/user/auto-routes.d.ts +12 -6
- package/dist/user/auto-routes.d.ts.map +1 -1
- package/dist/user/auto-routes.js +70 -8
- package/dist/user/auto-routes.js.map +1 -1
- package/dist/user/define-user.d.ts +2 -2
- package/dist/user/define-user.d.ts.map +1 -1
- package/dist/user/define-user.js +6 -6
- package/dist/user/define-user.js.map +1 -1
- package/dist/user/index.d.ts +6 -6
- package/dist/user/index.d.ts.map +1 -1
- package/dist/user/index.js +4 -4
- package/dist/user/index.js.map +1 -1
- package/dist/user/models/user.d.ts +12 -12
- package/dist/user/models/user.js +1 -1
- package/dist/user/models/user.js.map +1 -1
- package/dist/user/user-module-service.d.ts +2 -2
- package/dist/user/user-module-service.d.ts.map +1 -1
- package/dist/user/user-module-service.js +1 -1
- package/dist/user/user-module-service.js.map +1 -1
- package/dist/workflows/ai-step.js +1 -1
- package/dist/workflows/ai-step.js.map +1 -1
- package/dist/workflows/create-step.d.ts +1 -1
- package/dist/workflows/create-step.d.ts.map +1 -1
- package/dist/workflows/create-step.js +4 -4
- package/dist/workflows/create-step.js.map +1 -1
- package/dist/workflows/create-workflow.d.ts +1 -1
- package/dist/workflows/create-workflow.d.ts.map +1 -1
- package/dist/workflows/define-workflow.d.ts +1 -1
- package/dist/workflows/define-workflow.d.ts.map +1 -1
- package/dist/workflows/define-workflow.js +1 -1
- package/dist/workflows/define-workflow.js.map +1 -1
- package/dist/workflows/emit-event-step.d.ts +1 -1
- package/dist/workflows/emit-event-step.d.ts.map +1 -1
- package/dist/workflows/for-each.d.ts +1 -1
- package/dist/workflows/for-each.d.ts.map +1 -1
- package/dist/workflows/for-each.js +1 -1
- package/dist/workflows/for-each.js.map +1 -1
- package/dist/workflows/index.d.ts +14 -14
- package/dist/workflows/index.d.ts.map +1 -1
- package/dist/workflows/index.js +10 -10
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/manager.d.ts +5 -5
- package/dist/workflows/manager.d.ts.map +1 -1
- package/dist/workflows/manager.js +4 -4
- package/dist/workflows/manager.js.map +1 -1
- package/dist/workflows/orphan-reaper.d.ts +3 -3
- package/dist/workflows/orphan-reaper.d.ts.map +1 -1
- package/dist/workflows/progress-helper.d.ts +2 -2
- package/dist/workflows/progress-helper.d.ts.map +1 -1
- package/dist/workflows/progress-helper.js +1 -1
- package/dist/workflows/progress-helper.js.map +1 -1
- package/dist/workflows/step.d.ts +1 -1
- package/dist/workflows/step.d.ts.map +1 -1
- package/dist/workflows/step.js +8 -8
- package/dist/workflows/step.js.map +1 -1
- package/dist/workflows/types.d.ts +4 -4
- package/dist/workflows/types.d.ts.map +1 -1
- package/docs/00-overview.md +9 -10
- package/docs/01-getting-started.md +26 -29
- package/docs/03-services.md +23 -5
- package/docs/04-users.md +47 -3
- package/docs/05-commands.md +1 -1
- package/docs/06-queries.md +54 -23
- package/docs/10-spa.md +63 -1
- package/docs/11-config.md +158 -39
- package/docs/14-adapters.md +52 -2
- package/docs/15-hosts.md +17 -2
- package/docs/16-reference.md +32 -3
- package/docs/17-dashboard.md +4 -2
- package/docs/AGENT.md +51 -4
- package/package.json +5 -3
- package/skills/mantajs/SKILL.md +67 -0
- package/skills/mantajs/agents/openai.yaml +3 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## Prerequisites
|
|
4
4
|
|
|
5
5
|
- Node.js 18+ (AsyncLocalStorage required)
|
|
6
|
+
- Manta packages require Node.js 20+ in published projects
|
|
6
7
|
- PostgreSQL (local or cloud — Neon, Supabase, etc.)
|
|
7
8
|
- pnpm
|
|
8
9
|
|
|
@@ -26,8 +27,11 @@ my-app/
|
|
|
26
27
|
│ ├── subscribers/
|
|
27
28
|
│ ├── jobs/
|
|
28
29
|
│ ├── links/
|
|
29
|
-
│ └──
|
|
30
|
+
│ └── spa/
|
|
30
31
|
├── drizzle/migrations/
|
|
32
|
+
├── AGENT.md
|
|
33
|
+
├── .codex/skills/mantajs/
|
|
34
|
+
├── .claude/skills/mantajs/
|
|
31
35
|
└── tsconfig.json
|
|
32
36
|
```
|
|
33
37
|
|
|
@@ -86,7 +90,7 @@ This gives you 8 CRUD methods for free + the custom `publish` method. No imports
|
|
|
86
90
|
|
|
87
91
|
## Step 4 — Define a command
|
|
88
92
|
|
|
89
|
-
Create `src/commands/create-post.ts`:
|
|
93
|
+
Create `src/commands/admin/create-post.ts`:
|
|
90
94
|
|
|
91
95
|
```typescript
|
|
92
96
|
export default defineCommand({
|
|
@@ -131,21 +135,14 @@ export default defineSubscriber({
|
|
|
131
135
|
})
|
|
132
136
|
```
|
|
133
137
|
|
|
134
|
-
## Step 6 —
|
|
138
|
+
## Step 6 — Expose reads for the admin context
|
|
135
139
|
|
|
136
|
-
|
|
140
|
+
In Manta V2, the context is the folder name under `src/commands/{context}` and `src/queries/{context}`. `src/commands/admin/create-post.ts` creates `POST /api/admin/command/create-post`.
|
|
141
|
+
|
|
142
|
+
Create `src/queries/admin/graph.ts` so the dashboard and SDK can read blog data:
|
|
137
143
|
|
|
138
144
|
```typescript
|
|
139
|
-
export default
|
|
140
|
-
name: 'admin',
|
|
141
|
-
basePath: '/api/admin',
|
|
142
|
-
actors: ['admin'],
|
|
143
|
-
modules: {
|
|
144
|
-
blog: { expose: '*' },
|
|
145
|
-
},
|
|
146
|
-
commands: ['create-post'],
|
|
147
|
-
ai: { enabled: true },
|
|
148
|
-
})
|
|
145
|
+
export default defineQueryGraph('*')
|
|
149
146
|
```
|
|
150
147
|
|
|
151
148
|
## Step 7 — Generate migrations and run
|
|
@@ -163,14 +160,13 @@ manta dev
|
|
|
163
160
|
|
|
164
161
|
Output:
|
|
165
162
|
```
|
|
166
|
-
[codegen] .manta/
|
|
163
|
+
[codegen] .manta/generated.d.ts (1 entities, 1 commands, 0 agents, 1 actors, 3 events)
|
|
167
164
|
Module: blog (Post) ✓
|
|
168
165
|
Subscriber: post.created → post-created ✓
|
|
169
|
-
Command: create-post ✓
|
|
170
|
-
Context: admin → /api/admin ✓
|
|
166
|
+
Command: admin/create-post ✓
|
|
171
167
|
|
|
172
168
|
Server running at http://localhost:9000
|
|
173
|
-
|
|
169
|
+
OpenAPI at http://localhost:9000/api/openapi.json
|
|
174
170
|
```
|
|
175
171
|
|
|
176
172
|
## Step 9 — Test it
|
|
@@ -188,37 +184,38 @@ curl -X POST http://localhost:9000/api/admin/command/create-post \
|
|
|
188
184
|
}'
|
|
189
185
|
```
|
|
190
186
|
|
|
191
|
-
Query posts:
|
|
187
|
+
Query posts through the graph:
|
|
192
188
|
```bash
|
|
193
|
-
curl -X POST http://localhost:9000/api/admin/
|
|
189
|
+
curl -X POST http://localhost:9000/api/admin/graph \
|
|
194
190
|
-H "Content-Type: application/json" \
|
|
195
191
|
-H "Authorization: Bearer <jwt>" \
|
|
196
|
-
-d '{"filters":
|
|
192
|
+
-d '{"entity":"post","filters":{"status":"published"}}'
|
|
197
193
|
```
|
|
198
194
|
|
|
199
195
|
View API docs:
|
|
200
196
|
```
|
|
201
|
-
open http://localhost:9000/api/
|
|
197
|
+
open http://localhost:9000/api/openapi.json
|
|
202
198
|
```
|
|
203
199
|
|
|
204
200
|
## What happened automatically
|
|
205
201
|
|
|
206
|
-
From your
|
|
202
|
+
From your files (model, service, command, query graph), Manta generated:
|
|
207
203
|
|
|
208
204
|
- PostgreSQL table `posts` with all columns + indexes
|
|
209
205
|
- 8 CRUD methods on `app.modules.blog`
|
|
210
206
|
- HTTP endpoint `POST /api/admin/command/create-post`
|
|
211
|
-
- HTTP endpoint `POST /api/admin/
|
|
207
|
+
- HTTP endpoint `POST /api/admin/graph`
|
|
212
208
|
- AI tool schema for `create-post` (Zod → JSON Schema)
|
|
213
209
|
- OpenAPI spec with full schema documentation
|
|
214
|
-
- TypeScript types for autocomplete (`.manta/
|
|
210
|
+
- TypeScript types for autocomplete (`.manta/generated.d.ts`)
|
|
215
211
|
- Event wiring for `post.created` subscriber
|
|
216
212
|
- Compensation logic (if create-post fails, the post is deleted)
|
|
213
|
+
- Codex and Claude skills pointing to `node_modules/@mantajs/core/docs/`
|
|
217
214
|
|
|
218
215
|
## Next steps
|
|
219
216
|
|
|
220
217
|
- Add more modules (see [Models](./02-models.md) and [Services](./03-services.md))
|
|
221
|
-
- Add cross-module relations (see [Links](./
|
|
222
|
-
- Add scheduled tasks (see [Events](./
|
|
223
|
-
- Expose a storefront API (see [
|
|
224
|
-
- Deploy to production (see [Config](./
|
|
218
|
+
- Add cross-module relations (see [Links](./08-links.md))
|
|
219
|
+
- Add scheduled tasks (see [Events](./07-events.md))
|
|
220
|
+
- Expose a storefront API with `src/commands/store/` and `src/queries/store/` (see [Queries](./06-queries.md))
|
|
221
|
+
- Deploy to production (see [Config](./11-config.md))
|
package/docs/03-services.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**1 entity = 1 service. Always.**
|
|
6
6
|
|
|
7
|
-
A service defines the mutations (writes) for **one** entity.
|
|
7
|
+
A service defines the mutations (writes) for **one** entity. It receives the generated repository for compensated CRUD and the schema-aware Drizzle client for explicit SQL-shaped writes. A service should own one entity's invariants; if you need to coordinate multiple entities, write a command that orchestrates the services or use a transaction deliberately.
|
|
8
8
|
|
|
9
9
|
A module can have multiple entities, and therefore multiple services. If you need to mutate two entities together, write a module command that orchestrates them.
|
|
10
10
|
|
|
@@ -13,23 +13,26 @@ If you don't have an entity, you don't have a module. Use `app.infra.*` for infr
|
|
|
13
13
|
## defineService()
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
|
|
16
|
+
import { eq } from 'drizzle-orm'
|
|
17
|
+
|
|
18
|
+
export default defineService('product', ({ db, drizzle, schema, log }) => ({
|
|
17
19
|
activate: async (id: string) => {
|
|
18
|
-
await
|
|
20
|
+
await drizzle.update(schema.products).set({ status: 'active' }).where(eq(schema.products.id, id))
|
|
19
21
|
log.info(`Product ${id} activated`)
|
|
20
22
|
},
|
|
21
23
|
|
|
22
24
|
archive: async (id: string) => {
|
|
25
|
+
// Generated repository remains useful for simple compensated CRUD.
|
|
23
26
|
await db.update({ id, status: 'archived' })
|
|
24
27
|
log.info(`Product ${id} archived`)
|
|
25
28
|
},
|
|
26
29
|
}))
|
|
27
30
|
```
|
|
28
31
|
|
|
29
|
-
**Signature:** `defineService(entityName: string, factory: ({ db, log }) => Methods, options?)`
|
|
32
|
+
**Signature:** `defineService(entityName: string, factory: ({ db, drizzle, schema, database, sql, log }) => Methods, options?)`
|
|
30
33
|
|
|
31
34
|
- `entityName` — Entity name as a string (autocompletes from codegen)
|
|
32
|
-
- `factory` — Receives
|
|
35
|
+
- `factory` — Receives the typed repository, Drizzle runtime, generated schema, database adapter, SQL helper, and logger
|
|
33
36
|
- `options.publicMethods` — (optional) Array of method names visible to other modules
|
|
34
37
|
|
|
35
38
|
No imports needed — `defineService` is a global. Compensation is automatic — the repo snapshots state before every mutation. No `service.method()` wrapper needed.
|
|
@@ -67,6 +70,21 @@ activate: async (id: string) => {
|
|
|
67
70
|
|
|
68
71
|
**How it works:** The framework auto-snapshots repository state before every mutation. In a workflow, if step 3 fails, steps 1 and 2 are automatically rolled back using the snapshots. You don't write compensation logic — the framework handles it.
|
|
69
72
|
|
|
73
|
+
## Data APIs in services
|
|
74
|
+
|
|
75
|
+
Use `drizzle`, `schema`, and `sql` when the mutation is easier to express as SQL/Drizzle, needs custom predicates, bulk operations, joins, or transaction-shaped code.
|
|
76
|
+
|
|
77
|
+
Use `db` for simple generated CRUD that should participate in the repository snapshot compensation path.
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
const products = schema.products
|
|
81
|
+
|
|
82
|
+
await drizzle
|
|
83
|
+
.update(products)
|
|
84
|
+
.set({ status: 'archived', updated_at: new Date() })
|
|
85
|
+
.where(eq(products.id, id))
|
|
86
|
+
```
|
|
87
|
+
|
|
70
88
|
## TypedRepository — the db API
|
|
71
89
|
|
|
72
90
|
The `db` parameter is a `TypedRepository<T>` where `T` is the inferred entity type:
|
package/docs/04-users.md
CHANGED
|
@@ -63,7 +63,7 @@ All on `/api/admin/`:
|
|
|
63
63
|
| Route | Method | Auth | Description |
|
|
64
64
|
|-------|--------|------|-------------|
|
|
65
65
|
| `/login` | POST | Public | Email/password → JWT (`{ id, type: 'admin' }`) |
|
|
66
|
-
| `/logout` | DELETE | Public |
|
|
66
|
+
| `/logout` | DELETE | Public | Clears auth cookies/local credentials and attempts server-side token revocation |
|
|
67
67
|
| `/refresh` | POST | Public | Exchange refresh token for new JWT |
|
|
68
68
|
| `/forgot-password` | POST | Public | Generates reset token |
|
|
69
69
|
| `/reset-password` | POST | Public | Validates token + resets password |
|
|
@@ -80,8 +80,52 @@ All on `/api/admin/`:
|
|
|
80
80
|
|
|
81
81
|
All `/api/admin/*` routes (except public auth routes):
|
|
82
82
|
1. Verify JWT Bearer token
|
|
83
|
-
2.
|
|
84
|
-
3.
|
|
83
|
+
2. Reject tokens present in `auth:blacklist:{auth_identity_id}` when a durable cache is reachable
|
|
84
|
+
3. Check `auth.type === 'admin'`
|
|
85
|
+
4. Reject with 401/403 if invalid
|
|
86
|
+
|
|
87
|
+
### Logout and token revocation
|
|
88
|
+
|
|
89
|
+
`DELETE /api/{context}/logout` always clears framework auth cookies and returns a successful logout response for the browser. If a Bearer/access token is present, Manta also writes `auth:blacklist:{auth_identity_id}` to `ICachePort` for 30 days.
|
|
90
|
+
|
|
91
|
+
Response shape:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{ "success": true, "revoked": true }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If the cache backend is temporarily unreachable, the route still clears cookies and returns:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{ "success": true, "revoked": false, "warning": "TOKEN_REVOCATION_FAILED" }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
In that degraded case, a JWT already issued remains valid until its normal expiry unless the client discards it. Production deployments that use `defineUserModel()` therefore need a durable, reachable `ICachePort`.
|
|
104
|
+
|
|
105
|
+
Supported durable cache choices:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// Default Vercel/Cloudflare-style production cache
|
|
109
|
+
adapters: {
|
|
110
|
+
ICachePort: {
|
|
111
|
+
adapter: '@mantajs/adapter-cache-upstash',
|
|
112
|
+
options: {
|
|
113
|
+
url: process.env.UPSTASH_REDIS_REST_URL,
|
|
114
|
+
token: process.env.UPSTASH_REDIS_REST_TOKEN,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Durable Postgres fallback, reusing the configured IDatabasePort connection
|
|
122
|
+
adapters: {
|
|
123
|
+
ICachePort: {
|
|
124
|
+
adapter: '@mantajs/adapter-database-pg/cache',
|
|
125
|
+
options: { tableName: 'manta_cache' },
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
```
|
|
85
129
|
|
|
86
130
|
### Dev seed
|
|
87
131
|
|
package/docs/05-commands.md
CHANGED
|
@@ -95,7 +95,7 @@ await step.service.inventory.adjustQuantity(inventoryId, -1)
|
|
|
95
95
|
Every `step.service.*` call is:
|
|
96
96
|
- **Checkpointed** — saved to storage, skipped on retry
|
|
97
97
|
- **Compensated** — rollback registered in LIFO order
|
|
98
|
-
- **Typed** — autocomplete from codegen (`.manta/
|
|
98
|
+
- **Typed** — autocomplete from codegen (`.manta/generated.d.ts`)
|
|
99
99
|
|
|
100
100
|
### step.service.MODULE.link — Create links
|
|
101
101
|
|
package/docs/06-queries.md
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
# Queries — defineQuery()
|
|
1
|
+
# Queries — Drizzle-first defineQuery()
|
|
2
2
|
|
|
3
|
-
Queries are the CQRS read side. They expose data as GET endpoints.
|
|
3
|
+
Queries are the CQRS read side. They expose data as GET endpoints.
|
|
4
4
|
|
|
5
|
-
- `defineQuery()`
|
|
6
|
-
- `defineQueryGraph()`
|
|
5
|
+
- `defineQuery()` is the primary application API. New code should query with the schema-aware Drizzle client.
|
|
6
|
+
- `defineQueryGraph()` is reserved for generated/admin/dynamic surfaces that need entity-level browsing.
|
|
7
|
+
|
|
8
|
+
Manta does not try to replace SQL. `defineModel()` generates the Drizzle schema and migrations; `defineQuery()` gives handlers the Drizzle client, generated schema, tagged SQL helper, auth context, logging, and request headers.
|
|
7
9
|
|
|
8
10
|
## defineQuery()
|
|
9
11
|
|
|
10
12
|
```typescript
|
|
11
13
|
// src/queries/admin/list-products.ts
|
|
14
|
+
import { eq } from 'drizzle-orm'
|
|
12
15
|
import { z } from 'zod'
|
|
13
16
|
|
|
14
17
|
export default defineQuery({
|
|
@@ -18,12 +21,19 @@ export default defineQuery({
|
|
|
18
21
|
status: z.string().optional(),
|
|
19
22
|
...listParams(),
|
|
20
23
|
}),
|
|
21
|
-
handler: async (input, {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
handler: async (input, { drizzle, schema, sql }) => {
|
|
25
|
+
const products = schema.products
|
|
26
|
+
return drizzle
|
|
27
|
+
.select({
|
|
28
|
+
id: products.id,
|
|
29
|
+
title: products.title,
|
|
30
|
+
status: products.status,
|
|
31
|
+
totalVariants: sql<number>`count(*) over()::int`,
|
|
32
|
+
})
|
|
33
|
+
.from(products)
|
|
34
|
+
.where(input.status ? eq(products.status, input.status) : undefined)
|
|
35
|
+
.limit(input.limit)
|
|
36
|
+
.offset(input.offset)
|
|
27
37
|
},
|
|
28
38
|
})
|
|
29
39
|
```
|
|
@@ -43,14 +53,21 @@ defineQuery({
|
|
|
43
53
|
|
|
44
54
|
```typescript
|
|
45
55
|
{
|
|
46
|
-
|
|
56
|
+
drizzle: unknown, // schema-aware Drizzle client
|
|
57
|
+
db: unknown, // alias for drizzle
|
|
58
|
+
schema: Record<string, unknown>, // generated Drizzle tables
|
|
59
|
+
sql: typeof import('drizzle-orm').sql, // tagged SQL helper
|
|
60
|
+
database: IDatabasePort, // raw SQL, pool, transactions
|
|
61
|
+
query: QueryService, // generated/admin query graph
|
|
47
62
|
log: ILoggerPort, // Structured logging
|
|
48
63
|
auth: AuthContext | null, // Authenticated user
|
|
49
64
|
headers: Record<string, string | undefined>, // Raw request headers
|
|
50
65
|
}
|
|
51
66
|
```
|
|
52
67
|
|
|
53
|
-
|
|
68
|
+
Prefer Drizzle for all application reads, including simple lists, dashboards, analytics, counts, search, and joins. Use `sql` fragments when a PostgreSQL feature is clearer than query-builder syntax.
|
|
69
|
+
|
|
70
|
+
`query.graph()` remains available for generated admin screens and dynamic entity browsing. It must not be used to hide analytical work in JavaScript. If a query needs `COUNT`, `SUM`, `GROUP BY`, `FILTER`, CTEs, window functions, full-text search, or dashboard KPIs, write it as Drizzle/SQL in `defineQuery()`.
|
|
54
71
|
|
|
55
72
|
### Routing
|
|
56
73
|
|
|
@@ -65,6 +82,18 @@ Query parameters are passed as URL query string:
|
|
|
65
82
|
GET /api/admin/list-products?status=active&limit=10&offset=0
|
|
66
83
|
```
|
|
67
84
|
|
|
85
|
+
### Serverless fast routes
|
|
86
|
+
|
|
87
|
+
For serverless and worker builds, Manta generates route-level functions for compatible `defineQuery()` files. These fast routes do not import `bootstrapApp()`, jobs, workflows, AI, command registries, or the catch-all Manta adapter.
|
|
88
|
+
|
|
89
|
+
Fast routes are generated when:
|
|
90
|
+
|
|
91
|
+
- the project uses filesystem V2 contexts (`src/queries/{context}`), not legacy `src/contexts/*.ts`
|
|
92
|
+
- the file exports `defineQuery()`, not `defineQueryGraph()`
|
|
93
|
+
- the query does not call `query.graph()`, `query.graphAndCount()`, `query.index()`, or `query.gql()`
|
|
94
|
+
|
|
95
|
+
Pure synthetic queries do not initialize the database or generated schema. Queries that reference `drizzle`, `db`, `schema`, or `database` initialize only the DB adapter and generated Drizzle schema needed by the handler.
|
|
96
|
+
|
|
68
97
|
### Input helpers
|
|
69
98
|
|
|
70
99
|
```typescript
|
|
@@ -85,22 +114,24 @@ z.object({
|
|
|
85
114
|
### Auth in queries
|
|
86
115
|
|
|
87
116
|
```typescript
|
|
88
|
-
handler: async (input, {
|
|
117
|
+
handler: async (input, { drizzle, schema, auth }) => {
|
|
89
118
|
// auth.id — user ID
|
|
90
119
|
// auth.type — context ('admin', 'customer')
|
|
91
120
|
// auth.email — user email
|
|
92
121
|
|
|
93
122
|
// Example: only return MY orders
|
|
94
|
-
return
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
123
|
+
return drizzle
|
|
124
|
+
.select()
|
|
125
|
+
.from(schema.orders)
|
|
126
|
+
.where(eq(schema.orders.customer_id, auth!.id))
|
|
98
127
|
}
|
|
99
128
|
```
|
|
100
129
|
|
|
101
130
|
## defineQueryGraph()
|
|
102
131
|
|
|
103
|
-
Exposes the query graph to the frontend. The frontend can compose
|
|
132
|
+
Exposes the query graph to the frontend. The frontend can compose entity browsing queries for generated/admin screens.
|
|
133
|
+
|
|
134
|
+
Do not use the graph as the main application query language. It is intentionally less expressive than SQL. Complex reads belong in `defineQuery()` with Drizzle.
|
|
104
135
|
|
|
105
136
|
### Wildcard — full access (admin/AI)
|
|
106
137
|
|
|
@@ -163,11 +194,11 @@ POST /api/admin/graph
|
|
|
163
194
|
|
|
164
195
|
| Use case | Primitive | Why |
|
|
165
196
|
|----------|-----------|-----|
|
|
166
|
-
|
|
|
167
|
-
| Storefront
|
|
168
|
-
|
|
|
169
|
-
|
|
|
170
|
-
| API
|
|
197
|
+
| Generated admin entity table | `defineQueryGraph('*')` | Dynamic browsing over known entities |
|
|
198
|
+
| Storefront catalog | `defineQuery` | Stable contract, optimized Drizzle query |
|
|
199
|
+
| Customer orders | `defineQuery` | Auth-scoped SQL with explicit filters |
|
|
200
|
+
| Dashboard / analytics | `defineQuery` | Aggregations run in Postgres |
|
|
201
|
+
| Third-party API | `defineQuery` | Fixed contract, no graph exposure |
|
|
171
202
|
|
|
172
203
|
## extendQueryGraph() — external entity resolvers
|
|
173
204
|
|
package/docs/10-spa.md
CHANGED
|
@@ -34,7 +34,13 @@ src/spa/admin/
|
|
|
34
34
|
- **`.ts`** — exports `definePage()` or `defineForm()` spec (declarative, no React)
|
|
35
35
|
- **`.tsx`** — exports a React component (full control, for complex cases)
|
|
36
36
|
|
|
37
|
-
**Defaults**: `@mantajs/dashboard` shell + `@mantajs/ui` preset.
|
|
37
|
+
**Defaults**: `@mantajs/dashboard` shell + `@mantajs/ui` preset. The generated entry imports the public stylesheet export:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import '@mantajs/dashboard/index.css'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Override in config if needed:
|
|
38
44
|
|
|
39
45
|
```typescript
|
|
40
46
|
// manta.config.ts — optional, only for overrides
|
|
@@ -46,6 +52,62 @@ export default defineConfig({
|
|
|
46
52
|
})
|
|
47
53
|
```
|
|
48
54
|
|
|
55
|
+
### Mount path
|
|
56
|
+
|
|
57
|
+
By default, a SPA named `admin` is mounted at `/admin`:
|
|
58
|
+
|
|
59
|
+
| Generated setting | Default for `src/spa/admin` |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| React Router basename | `/admin` |
|
|
62
|
+
| Vite `base` | `/admin/` |
|
|
63
|
+
| Static output | `public/admin` |
|
|
64
|
+
| Vercel SPA rewrite | `/admin/:path*` → `/admin/index.html` |
|
|
65
|
+
|
|
66
|
+
Use `mountPath: '/'` for a dashboard on a dedicated subdomain, such as `admin.fancypalas.com/paniers`:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// manta.config.ts
|
|
70
|
+
export default defineConfig({
|
|
71
|
+
spa: {
|
|
72
|
+
admin: { mountPath: '/' },
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
With `mountPath: '/'`, React Router uses `basename="/"`, Vite uses `base: '/'`, the SPA builds into `public/`, and generated Vercel rewrites exclude `/api/*`.
|
|
78
|
+
|
|
79
|
+
### Dev Vite port
|
|
80
|
+
|
|
81
|
+
`manta dev` starts one Vite server per detected SPA. Ports default to `5200`, then increment for additional SPAs.
|
|
82
|
+
|
|
83
|
+
Configure the port in `manta.config.ts` when another project already uses the default:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
export default defineConfig({
|
|
87
|
+
spa: {
|
|
88
|
+
admin: { vitePort: 5310 },
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Environment overrides are also supported:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
MANTA_VITE_PORT=5310 manta dev
|
|
97
|
+
MANTA_VITE_PORT_ADMIN=5311 manta dev
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The SPA-specific variable wins over the global one. The suffix uses the SPA name uppercased with non-alphanumeric characters replaced by `_`.
|
|
101
|
+
|
|
102
|
+
### Local production fallback
|
|
103
|
+
|
|
104
|
+
`manta build` writes a SPA fallback manifest into `.manta/server/spa-manifest.ts`. For the Node preset, `manta start` uses it to mirror the Vercel SPA behavior locally:
|
|
105
|
+
|
|
106
|
+
- `/` redirects to the single SPA mount path when the SPA is not mounted at `/`
|
|
107
|
+
- `/login`, `/reset-password`, and `/accept-invite` redirect under that mount path
|
|
108
|
+
- `/admin/*` and other configured SPA mount paths serve the built `index.html`
|
|
109
|
+
- `/api/*` and asset URLs remain server-side/static and are not swallowed by the SPA fallback
|
|
110
|
+
|
|
49
111
|
---
|
|
50
112
|
|
|
51
113
|
## SPA Configuration — defineSpa()
|