@mantajs/cli 0.2.0-beta.0

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.
Files changed (282) hide show
  1. package/bin/manta.mjs +20 -0
  2. package/bin/manta.ts +13 -0
  3. package/dist/admin/generate-admin-config.d.ts +8 -0
  4. package/dist/admin/generate-admin-config.d.ts.map +1 -0
  5. package/dist/admin/generate-admin-config.js +127 -0
  6. package/dist/admin/generate-admin-config.js.map +1 -0
  7. package/dist/ai/chat-handler.d.ts +10 -0
  8. package/dist/ai/chat-handler.d.ts.map +1 -0
  9. package/dist/ai/chat-handler.js +1353 -0
  10. package/dist/ai/chat-handler.js.map +1 -0
  11. package/dist/bootstrap/boot.d.ts +25 -0
  12. package/dist/bootstrap/boot.d.ts.map +1 -0
  13. package/dist/bootstrap/boot.js +344 -0
  14. package/dist/bootstrap/boot.js.map +1 -0
  15. package/dist/bootstrap/bootstrap-app.d.ts +71 -0
  16. package/dist/bootstrap/bootstrap-app.d.ts.map +1 -0
  17. package/dist/bootstrap/bootstrap-app.js +308 -0
  18. package/dist/bootstrap/bootstrap-app.js.map +1 -0
  19. package/dist/bootstrap/bootstrap-context.d.ts +76 -0
  20. package/dist/bootstrap/bootstrap-context.d.ts.map +1 -0
  21. package/dist/bootstrap/bootstrap-context.js +4 -0
  22. package/dist/bootstrap/bootstrap-context.js.map +1 -0
  23. package/dist/bootstrap/bootstrap-helpers.d.ts +71 -0
  24. package/dist/bootstrap/bootstrap-helpers.d.ts.map +1 -0
  25. package/dist/bootstrap/bootstrap-helpers.js +373 -0
  26. package/dist/bootstrap/bootstrap-helpers.js.map +1 -0
  27. package/dist/bootstrap/generate-types.d.ts +7 -0
  28. package/dist/bootstrap/generate-types.d.ts.map +1 -0
  29. package/dist/bootstrap/generate-types.js +832 -0
  30. package/dist/bootstrap/generate-types.js.map +1 -0
  31. package/dist/bootstrap/phases/assemble/index.d.ts +5 -0
  32. package/dist/bootstrap/phases/assemble/index.d.ts.map +1 -0
  33. package/dist/bootstrap/phases/assemble/index.js +5 -0
  34. package/dist/bootstrap/phases/assemble/index.js.map +1 -0
  35. package/dist/bootstrap/phases/assemble/load-links.d.ts +3 -0
  36. package/dist/bootstrap/phases/assemble/load-links.d.ts.map +1 -0
  37. package/dist/bootstrap/phases/assemble/load-links.js +160 -0
  38. package/dist/bootstrap/phases/assemble/load-links.js.map +1 -0
  39. package/dist/bootstrap/phases/assemble/load-modules.d.ts +3 -0
  40. package/dist/bootstrap/phases/assemble/load-modules.d.ts.map +1 -0
  41. package/dist/bootstrap/phases/assemble/load-modules.js +163 -0
  42. package/dist/bootstrap/phases/assemble/load-modules.js.map +1 -0
  43. package/dist/bootstrap/phases/assemble/load-resources.d.ts +3 -0
  44. package/dist/bootstrap/phases/assemble/load-resources.d.ts.map +1 -0
  45. package/dist/bootstrap/phases/assemble/load-resources.js +270 -0
  46. package/dist/bootstrap/phases/assemble/load-resources.js.map +1 -0
  47. package/dist/bootstrap/phases/assemble/wire-commands.d.ts +3 -0
  48. package/dist/bootstrap/phases/assemble/wire-commands.d.ts.map +1 -0
  49. package/dist/bootstrap/phases/assemble/wire-commands.js +408 -0
  50. package/dist/bootstrap/phases/assemble/wire-commands.js.map +1 -0
  51. package/dist/bootstrap/phases/assemble-modules.d.ts +3 -0
  52. package/dist/bootstrap/phases/assemble-modules.d.ts.map +1 -0
  53. package/dist/bootstrap/phases/assemble-modules.js +14 -0
  54. package/dist/bootstrap/phases/assemble-modules.js.map +1 -0
  55. package/dist/bootstrap/phases/build-app.d.ts +3 -0
  56. package/dist/bootstrap/phases/build-app.d.ts.map +1 -0
  57. package/dist/bootstrap/phases/build-app.js +15 -0
  58. package/dist/bootstrap/phases/build-app.js.map +1 -0
  59. package/dist/bootstrap/phases/discover-resources.d.ts +3 -0
  60. package/dist/bootstrap/phases/discover-resources.d.ts.map +1 -0
  61. package/dist/bootstrap/phases/discover-resources.js +60 -0
  62. package/dist/bootstrap/phases/discover-resources.js.map +1 -0
  63. package/dist/bootstrap/phases/index.d.ts +7 -0
  64. package/dist/bootstrap/phases/index.d.ts.map +1 -0
  65. package/dist/bootstrap/phases/index.js +7 -0
  66. package/dist/bootstrap/phases/index.js.map +1 -0
  67. package/dist/bootstrap/phases/init-infra.d.ts +3 -0
  68. package/dist/bootstrap/phases/init-infra.d.ts.map +1 -0
  69. package/dist/bootstrap/phases/init-infra.js +193 -0
  70. package/dist/bootstrap/phases/init-infra.js.map +1 -0
  71. package/dist/bootstrap/phases/seed-dev-users.d.ts +3 -0
  72. package/dist/bootstrap/phases/seed-dev-users.d.ts.map +1 -0
  73. package/dist/bootstrap/phases/seed-dev-users.js +93 -0
  74. package/dist/bootstrap/phases/seed-dev-users.js.map +1 -0
  75. package/dist/bootstrap/phases/wire/auth-helpers.d.ts +12 -0
  76. package/dist/bootstrap/phases/wire/auth-helpers.d.ts.map +1 -0
  77. package/dist/bootstrap/phases/wire/auth-helpers.js +25 -0
  78. package/dist/bootstrap/phases/wire/auth-helpers.js.map +1 -0
  79. package/dist/bootstrap/phases/wire/contexts/context-registry.d.ts +4 -0
  80. package/dist/bootstrap/phases/wire/contexts/context-registry.d.ts.map +1 -0
  81. package/dist/bootstrap/phases/wire/contexts/context-registry.js +96 -0
  82. package/dist/bootstrap/phases/wire/contexts/context-registry.js.map +1 -0
  83. package/dist/bootstrap/phases/wire/contexts/cqrs-routes.d.ts +3 -0
  84. package/dist/bootstrap/phases/wire/contexts/cqrs-routes.d.ts.map +1 -0
  85. package/dist/bootstrap/phases/wire/contexts/cqrs-routes.js +138 -0
  86. package/dist/bootstrap/phases/wire/contexts/cqrs-routes.js.map +1 -0
  87. package/dist/bootstrap/phases/wire/contexts/index.d.ts +6 -0
  88. package/dist/bootstrap/phases/wire/contexts/index.d.ts.map +1 -0
  89. package/dist/bootstrap/phases/wire/contexts/index.js +6 -0
  90. package/dist/bootstrap/phases/wire/contexts/index.js.map +1 -0
  91. package/dist/bootstrap/phases/wire/contexts/query-endpoints.d.ts +3 -0
  92. package/dist/bootstrap/phases/wire/contexts/query-endpoints.d.ts.map +1 -0
  93. package/dist/bootstrap/phases/wire/contexts/query-endpoints.js +116 -0
  94. package/dist/bootstrap/phases/wire/contexts/query-endpoints.js.map +1 -0
  95. package/dist/bootstrap/phases/wire/contexts/spa-warnings.d.ts +3 -0
  96. package/dist/bootstrap/phases/wire/contexts/spa-warnings.d.ts.map +1 -0
  97. package/dist/bootstrap/phases/wire/contexts/spa-warnings.js +17 -0
  98. package/dist/bootstrap/phases/wire/contexts/spa-warnings.js.map +1 -0
  99. package/dist/bootstrap/phases/wire/contexts/user-routes.d.ts +3 -0
  100. package/dist/bootstrap/phases/wire/contexts/user-routes.d.ts.map +1 -0
  101. package/dist/bootstrap/phases/wire/contexts/user-routes.js +83 -0
  102. package/dist/bootstrap/phases/wire/contexts/user-routes.js.map +1 -0
  103. package/dist/bootstrap/phases/wire/index.d.ts +5 -0
  104. package/dist/bootstrap/phases/wire/index.d.ts.map +1 -0
  105. package/dist/bootstrap/phases/wire/index.js +5 -0
  106. package/dist/bootstrap/phases/wire/index.js.map +1 -0
  107. package/dist/bootstrap/phases/wire/wire-adapter.d.ts +12 -0
  108. package/dist/bootstrap/phases/wire/wire-adapter.d.ts.map +1 -0
  109. package/dist/bootstrap/phases/wire/wire-adapter.js +156 -0
  110. package/dist/bootstrap/phases/wire/wire-adapter.js.map +1 -0
  111. package/dist/bootstrap/phases/wire/wire-auth.d.ts +3 -0
  112. package/dist/bootstrap/phases/wire/wire-auth.d.ts.map +1 -0
  113. package/dist/bootstrap/phases/wire/wire-auth.js +46 -0
  114. package/dist/bootstrap/phases/wire/wire-auth.js.map +1 -0
  115. package/dist/bootstrap/phases/wire/wire-contexts.d.ts +3 -0
  116. package/dist/bootstrap/phases/wire/wire-contexts.d.ts.map +1 -0
  117. package/dist/bootstrap/phases/wire/wire-contexts.js +15 -0
  118. package/dist/bootstrap/phases/wire/wire-contexts.js.map +1 -0
  119. package/dist/bootstrap/phases/wire/wire-cron-routes.d.ts +3 -0
  120. package/dist/bootstrap/phases/wire/wire-cron-routes.d.ts.map +1 -0
  121. package/dist/bootstrap/phases/wire/wire-cron-routes.js +102 -0
  122. package/dist/bootstrap/phases/wire/wire-cron-routes.js.map +1 -0
  123. package/dist/bootstrap/phases/wire/wire-extras.d.ts +3 -0
  124. package/dist/bootstrap/phases/wire/wire-extras.d.ts.map +1 -0
  125. package/dist/bootstrap/phases/wire/wire-extras.js +305 -0
  126. package/dist/bootstrap/phases/wire/wire-extras.js.map +1 -0
  127. package/dist/bootstrap/phases/wire/wire-workflow-routes.d.ts +3 -0
  128. package/dist/bootstrap/phases/wire/wire-workflow-routes.d.ts.map +1 -0
  129. package/dist/bootstrap/phases/wire/wire-workflow-routes.js +212 -0
  130. package/dist/bootstrap/phases/wire/wire-workflow-routes.js.map +1 -0
  131. package/dist/bootstrap/phases/wire-http.d.ts +3 -0
  132. package/dist/bootstrap/phases/wire-http.d.ts.map +1 -0
  133. package/dist/bootstrap/phases/wire-http.js +10 -0
  134. package/dist/bootstrap/phases/wire-http.js.map +1 -0
  135. package/dist/bootstrap/validate-generated-ts.d.ts +6 -0
  136. package/dist/bootstrap/validate-generated-ts.d.ts.map +1 -0
  137. package/dist/bootstrap/validate-generated-ts.js +26 -0
  138. package/dist/bootstrap/validate-generated-ts.js.map +1 -0
  139. package/dist/build/generate-manifest.d.ts +10 -0
  140. package/dist/build/generate-manifest.d.ts.map +1 -0
  141. package/dist/build/generate-manifest.js +138 -0
  142. package/dist/build/generate-manifest.js.map +1 -0
  143. package/dist/cli.d.ts +3 -0
  144. package/dist/cli.d.ts.map +1 -0
  145. package/dist/cli.js +421 -0
  146. package/dist/cli.js.map +1 -0
  147. package/dist/commands/build.d.ts +21 -0
  148. package/dist/commands/build.d.ts.map +1 -0
  149. package/dist/commands/build.js +399 -0
  150. package/dist/commands/build.js.map +1 -0
  151. package/dist/commands/db/create.d.ts +17 -0
  152. package/dist/commands/db/create.d.ts.map +1 -0
  153. package/dist/commands/db/create.js +94 -0
  154. package/dist/commands/db/create.js.map +1 -0
  155. package/dist/commands/db/diff.d.ts +39 -0
  156. package/dist/commands/db/diff.d.ts.map +1 -0
  157. package/dist/commands/db/diff.js +81 -0
  158. package/dist/commands/db/diff.js.map +1 -0
  159. package/dist/commands/db/generate.d.ts +58 -0
  160. package/dist/commands/db/generate.d.ts.map +1 -0
  161. package/dist/commands/db/generate.js +138 -0
  162. package/dist/commands/db/generate.js.map +1 -0
  163. package/dist/commands/db/migrate.d.ts +29 -0
  164. package/dist/commands/db/migrate.d.ts.map +1 -0
  165. package/dist/commands/db/migrate.js +118 -0
  166. package/dist/commands/db/migrate.js.map +1 -0
  167. package/dist/commands/db/pg-deps.d.ts +30 -0
  168. package/dist/commands/db/pg-deps.d.ts.map +1 -0
  169. package/dist/commands/db/pg-deps.js +178 -0
  170. package/dist/commands/db/pg-deps.js.map +1 -0
  171. package/dist/commands/db/rollback.d.ts +21 -0
  172. package/dist/commands/db/rollback.d.ts.map +1 -0
  173. package/dist/commands/db/rollback.js +85 -0
  174. package/dist/commands/db/rollback.js.map +1 -0
  175. package/dist/commands/db/types.d.ts +113 -0
  176. package/dist/commands/db/types.d.ts.map +1 -0
  177. package/dist/commands/db/types.js +4 -0
  178. package/dist/commands/db/types.js.map +1 -0
  179. package/dist/commands/dev.d.ts +12 -0
  180. package/dist/commands/dev.d.ts.map +1 -0
  181. package/dist/commands/dev.js +79 -0
  182. package/dist/commands/dev.js.map +1 -0
  183. package/dist/commands/exec.d.ts +21 -0
  184. package/dist/commands/exec.d.ts.map +1 -0
  185. package/dist/commands/exec.js +148 -0
  186. package/dist/commands/exec.js.map +1 -0
  187. package/dist/commands/generate.d.ts +11 -0
  188. package/dist/commands/generate.d.ts.map +1 -0
  189. package/dist/commands/generate.js +19 -0
  190. package/dist/commands/generate.js.map +1 -0
  191. package/dist/commands/init.d.ts +14 -0
  192. package/dist/commands/init.d.ts.map +1 -0
  193. package/dist/commands/init.js +476 -0
  194. package/dist/commands/init.js.map +1 -0
  195. package/dist/commands/start.d.ts +15 -0
  196. package/dist/commands/start.d.ts.map +1 -0
  197. package/dist/commands/start.js +121 -0
  198. package/dist/commands/start.js.map +1 -0
  199. package/dist/commands/user.d.ts +19 -0
  200. package/dist/commands/user.d.ts.map +1 -0
  201. package/dist/commands/user.js +125 -0
  202. package/dist/commands/user.js.map +1 -0
  203. package/dist/config/load-config.d.ts +23 -0
  204. package/dist/config/load-config.d.ts.map +1 -0
  205. package/dist/config/load-config.js +105 -0
  206. package/dist/config/load-config.js.map +1 -0
  207. package/dist/config/load-env.d.ts +11 -0
  208. package/dist/config/load-env.d.ts.map +1 -0
  209. package/dist/config/load-env.js +61 -0
  210. package/dist/config/load-env.js.map +1 -0
  211. package/dist/config/resolve-adapters.d.ts +23 -0
  212. package/dist/config/resolve-adapters.d.ts.map +1 -0
  213. package/dist/config/resolve-adapters.js +96 -0
  214. package/dist/config/resolve-adapters.js.map +1 -0
  215. package/dist/index.d.ts +18 -0
  216. package/dist/index.d.ts.map +1 -0
  217. package/dist/index.js +19 -0
  218. package/dist/index.js.map +1 -0
  219. package/dist/jiti.d.ts +2 -0
  220. package/dist/jiti.d.ts.map +1 -0
  221. package/dist/jiti.js +2 -0
  222. package/dist/jiti.js.map +1 -0
  223. package/dist/openapi/generate-spec.d.ts +56 -0
  224. package/dist/openapi/generate-spec.d.ts.map +1 -0
  225. package/dist/openapi/generate-spec.js +491 -0
  226. package/dist/openapi/generate-spec.js.map +1 -0
  227. package/dist/openapi/index.d.ts +4 -0
  228. package/dist/openapi/index.d.ts.map +1 -0
  229. package/dist/openapi/index.js +3 -0
  230. package/dist/openapi/index.js.map +1 -0
  231. package/dist/openapi/swagger-html.d.ts +2 -0
  232. package/dist/openapi/swagger-html.d.ts.map +1 -0
  233. package/dist/openapi/swagger-html.js +29 -0
  234. package/dist/openapi/swagger-html.js.map +1 -0
  235. package/dist/plugins/merge-resources.d.ts +18 -0
  236. package/dist/plugins/merge-resources.d.ts.map +1 -0
  237. package/dist/plugins/merge-resources.js +76 -0
  238. package/dist/plugins/merge-resources.js.map +1 -0
  239. package/dist/plugins/resolve-plugins.d.ts +14 -0
  240. package/dist/plugins/resolve-plugins.d.ts.map +1 -0
  241. package/dist/plugins/resolve-plugins.js +73 -0
  242. package/dist/plugins/resolve-plugins.js.map +1 -0
  243. package/dist/resource-loader.d.ts +151 -0
  244. package/dist/resource-loader.d.ts.map +1 -0
  245. package/dist/resource-loader.js +456 -0
  246. package/dist/resource-loader.js.map +1 -0
  247. package/dist/route-discovery.d.ts +33 -0
  248. package/dist/route-discovery.d.ts.map +1 -0
  249. package/dist/route-discovery.js +69 -0
  250. package/dist/route-discovery.js.map +1 -0
  251. package/dist/server-bootstrap.d.ts +38 -0
  252. package/dist/server-bootstrap.d.ts.map +1 -0
  253. package/dist/server-bootstrap.js +21 -0
  254. package/dist/server-bootstrap.js.map +1 -0
  255. package/dist/spa/generate-spa.d.ts +15 -0
  256. package/dist/spa/generate-spa.d.ts.map +1 -0
  257. package/dist/spa/generate-spa.js +357 -0
  258. package/dist/spa/generate-spa.js.map +1 -0
  259. package/dist/templates/agent/nextjs.md +129 -0
  260. package/dist/templates/agent/nuxt.md +98 -0
  261. package/dist/templates/agent/standalone.md +498 -0
  262. package/dist/types.d.ts +145 -0
  263. package/dist/types.d.ts.map +1 -0
  264. package/dist/types.js +3 -0
  265. package/dist/types.js.map +1 -0
  266. package/dist/utils/colors.d.ts +7 -0
  267. package/dist/utils/colors.d.ts.map +1 -0
  268. package/dist/utils/colors.js +8 -0
  269. package/dist/utils/colors.js.map +1 -0
  270. package/dist/utils/logger.d.ts +10 -0
  271. package/dist/utils/logger.d.ts.map +1 -0
  272. package/dist/utils/logger.js +27 -0
  273. package/dist/utils/logger.js.map +1 -0
  274. package/dist/utils/prompts.d.ts +6 -0
  275. package/dist/utils/prompts.d.ts.map +1 -0
  276. package/dist/utils/prompts.js +28 -0
  277. package/dist/utils/prompts.js.map +1 -0
  278. package/dist/utils/spinner.d.ts +7 -0
  279. package/dist/utils/spinner.d.ts.map +1 -0
  280. package/dist/utils/spinner.js +20 -0
  281. package/dist/utils/spinner.js.map +1 -0
  282. package/package.json +80 -0
@@ -0,0 +1,193 @@
1
+ // Phase 1: Initialize infrastructure — resolve preset, adapters, logger, DB, builder.
2
+ import { DbProgressChannel, DrizzlePgAdapter, DrizzleWorkflowStorage, DrizzleWorkflowStore, } from '@mantajs/adapter-database-pg';
3
+ import { createApp, InMemoryCacheAdapter, InMemoryEventBusAdapter, InMemoryFileAdapter, InMemoryLockingAdapter, InMemoryProgressChannel, MantaError, } from '@mantajs/core';
4
+ import { resolveAdapters, resolvePreset } from '../../config/resolve-adapters';
5
+ import { ADAPTER_FACTORIES, ConsoleLoggerAdapter } from '../bootstrap-app';
6
+ import { ensureFrameworkSchema } from '../bootstrap-helpers';
7
+ /**
8
+ * Structural check: returns a Drizzle client when `db` is a known Postgres-compatible
9
+ * adapter (DrizzlePgAdapter or NeonDrizzleAdapter), else null. Uses a dynamic import
10
+ * for the Neon adapter so `@mantajs/cli` stays free of a hard dep on it (matches the
11
+ * pattern in bootstrap-app.ts::ADAPTER_FACTORIES).
12
+ *
13
+ * The returned client is typed as PostgresJsDatabase — Neon HTTP returns a
14
+ * NeonHttpDatabase at runtime, but `connection.ts` already casts it to
15
+ * PostgresJsDatabase because both drivers expose the same Drizzle ORM surface
16
+ * (insert/select/update/transaction).
17
+ */
18
+ async function resolveDrizzleClient(db) {
19
+ if (db instanceof DrizzlePgAdapter) {
20
+ return db.getClient();
21
+ }
22
+ try {
23
+ const { NeonDrizzleAdapter } = await import('@mantajs/adapter-database-neon');
24
+ if (db instanceof NeonDrizzleAdapter) {
25
+ return db.getClient();
26
+ }
27
+ }
28
+ catch {
29
+ // Package not installed — db cannot be a Neon adapter, fall through.
30
+ }
31
+ return null;
32
+ }
33
+ export async function initializeInfra(ctx, _appRef) {
34
+ const { config, mode, verbose } = ctx;
35
+ // [1] Resolve preset and adapters
36
+ const preset = resolvePreset(config);
37
+ const resolvedAdapters = resolveAdapters(config, preset);
38
+ // [2] Initialize logger
39
+ const loggerEntry = resolvedAdapters.find((a) => a.port === 'ILoggerPort');
40
+ const loggerOpts = { level: verbose ? 'debug' : 'info', pretty: mode === 'dev', ...loggerEntry?.options };
41
+ const loggerFactory = ADAPTER_FACTORIES[loggerEntry?.adapter ?? '@mantajs/adapter-logger-pino'];
42
+ const logger = (loggerFactory ? await loggerFactory(loggerOpts) : new ConsoleLoggerAdapter(loggerOpts));
43
+ ctx.logger = logger;
44
+ // [3] Initialize database
45
+ logger.info('Connecting to database...');
46
+ const dbEntry = resolvedAdapters.find((a) => a.port === 'IDatabasePort');
47
+ const dbFactory = dbEntry ? ADAPTER_FACTORIES[dbEntry.adapter] : undefined;
48
+ const db = (dbFactory ? await dbFactory(dbEntry.options) : new DrizzlePgAdapter());
49
+ ctx.db = db;
50
+ await db.initialize({
51
+ url: config.database.url,
52
+ pool: config.database?.pool,
53
+ });
54
+ const healthy = await db.healthCheck();
55
+ if (healthy) {
56
+ logger.info('Database connected');
57
+ }
58
+ else {
59
+ logger.error('Database initialized but readiness probe failed; continuing boot and reporting /health/ready as not_ready');
60
+ }
61
+ // [4] Framework schema — versioned migration, safe on every boot (serverless
62
+ // cold starts serialize on a Postgres advisory lock, and a version gate
63
+ // skips DDL when already applied).
64
+ //
65
+ // Hardened against serverless weirdness: a migration failure here
66
+ // (timeout, pooler quirk, transient DB error) must NOT crash the whole
67
+ // app — other endpoints would go dark for cold-start reasons unrelated
68
+ // to their own concerns. Log loudly and continue; the migration retries
69
+ // on the next cold start, and framework-dependent endpoints surface the
70
+ // real problem on their first hit.
71
+ if (healthy) {
72
+ try {
73
+ await ensureFrameworkSchema(db.getPool(), logger);
74
+ }
75
+ catch (err) {
76
+ logger.error(`[manta-schema] framework migration failed; continuing boot — ${err.message}`);
77
+ }
78
+ }
79
+ else {
80
+ logger.warn('[manta-schema] skipped framework migration because database readiness failed');
81
+ }
82
+ // [5] Collect infra adapters, then build app via MantaAppBuilder
83
+ const infraMap = new Map();
84
+ infraMap.set('ILoggerPort', logger);
85
+ infraMap.set('IDatabasePort', db);
86
+ // Register WorkflowStorage when any Postgres-compatible DB adapter is active
87
+ // (DrizzlePgAdapter OR NeonDrizzleAdapter). Without this, WorkflowManager falls
88
+ // back to MemoryStorage — checkpoints die between serverless invocations,
89
+ // breaking retry/resume across HTTP requests.
90
+ const drizzleClient = await resolveDrizzleClient(db);
91
+ if (drizzleClient) {
92
+ infraMap.set('IWorkflowStoragePort', new DrizzleWorkflowStorage(drizzleClient));
93
+ infraMap.set('IWorkflowStorePort', new DrizzleWorkflowStore(drizzleClient));
94
+ }
95
+ ctx.infraMap = infraMap;
96
+ // Register remaining adapters (sorted: IJobSchedulerPort last)
97
+ const sortedAdapters = [...resolvedAdapters].sort((a, b) => {
98
+ if (a.port === 'IJobSchedulerPort')
99
+ return 1;
100
+ if (b.port === 'IJobSchedulerPort')
101
+ return -1;
102
+ return 0;
103
+ });
104
+ for (const entry of sortedAdapters) {
105
+ if (['ILoggerPort', 'IDatabasePort', 'IHttpPort'].includes(entry.port))
106
+ continue;
107
+ const factory = ADAPTER_FACTORIES[entry.adapter];
108
+ if (!factory) {
109
+ throw new MantaError('UNKNOWN_MODULES', `No factory for adapter "${entry.adapter}" (port: ${entry.port}). Is the package installed?`);
110
+ }
111
+ const instance = await factory(entry.options, infraMap);
112
+ infraMap.set(entry.port, instance);
113
+ logger.info(` ${entry.port} → ${entry.adapter}`);
114
+ }
115
+ // [5a] Auto-select the workflow progress channel (WORKFLOW_PROGRESS.md §9.2).
116
+ // Preference: UpstashProgressChannel > DbProgressChannel > InMemoryProgressChannel.
117
+ // Detection is structural (instanceof) — users never configure this explicitly.
118
+ await selectProgressChannel(infraMap, logger);
119
+ // [5b] Create the repository factory
120
+ const { DrizzleRepositoryFactory } = await import('@mantajs/adapter-database-pg');
121
+ const repoFactory = db
122
+ ? (infraMap.get('IRepositoryFactory') ?? new DrizzleRepositoryFactory({ db }))
123
+ : new (await import('@mantajs/core')).InMemoryRepositoryFactory();
124
+ infraMap.set('IRepositoryFactory', repoFactory);
125
+ ctx.repoFactory = repoFactory;
126
+ // Build the MantaApp using the builder
127
+ const builder = createApp({
128
+ infra: {
129
+ eventBus: (infraMap.get('IEventBusPort') ?? new InMemoryEventBusAdapter()),
130
+ logger,
131
+ cache: (infraMap.get('ICachePort') ?? new InMemoryCacheAdapter()),
132
+ locking: (infraMap.get('ILockingPort') ?? new InMemoryLockingAdapter()),
133
+ file: (infraMap.get('IFilePort') ?? new InMemoryFileAdapter()),
134
+ notification: infraMap.get('INotificationPort'),
135
+ db: db.getClient(),
136
+ },
137
+ });
138
+ ctx.builder = builder;
139
+ // Register extra infra keys
140
+ builder.registerInfra('IDatabasePort', db);
141
+ builder.registerInfra('pgPool', db.getPool());
142
+ for (const [key, value] of infraMap) {
143
+ if (!['ILoggerPort', 'IDatabasePort', 'db', 'IEventBusPort', 'ICachePort', 'ILockingPort', 'IFilePort'].includes(key)) {
144
+ builder.registerInfra(key, value);
145
+ }
146
+ }
147
+ }
148
+ /**
149
+ * Auto-select the progress channel adapter based on already-registered infra.
150
+ * Called after ICachePort and IDatabasePort are in `infraMap`.
151
+ *
152
+ * - If an Upstash cache adapter is present → UpstashProgressChannel (sub-ms, default).
153
+ * - Else if a Postgres DB is present → DbProgressChannel (throttled 500ms fallback).
154
+ * - Else → InMemoryProgressChannel (test containers).
155
+ */
156
+ async function selectProgressChannel(infraMap, logger) {
157
+ const cache = infraMap.get('ICachePort');
158
+ const db = infraMap.get('IDatabasePort');
159
+ // Structural detection for the Upstash cache adapter. We import dynamically
160
+ // so the cli stays free of a hard dependency on @mantajs/adapter-cache-upstash
161
+ // (same pattern as ADAPTER_FACTORIES in bootstrap-app.ts). If the package
162
+ // isn't installed, `cache` cannot be an Upstash adapter anyway.
163
+ let isUpstashCache = false;
164
+ let UpstashProgressChannelCtor;
165
+ if (cache) {
166
+ try {
167
+ const mod = await import('@mantajs/adapter-cache-upstash');
168
+ isUpstashCache = cache instanceof mod.UpstashCacheAdapter;
169
+ UpstashProgressChannelCtor = mod.UpstashProgressChannel;
170
+ }
171
+ catch {
172
+ // Package not installed — cache cannot be Upstash, fall through.
173
+ }
174
+ }
175
+ let channel;
176
+ const drizzleClient = await resolveDrizzleClient(db);
177
+ if (isUpstashCache && UpstashProgressChannelCtor) {
178
+ // UpstashProgressChannel falls back to the same env vars the cache uses,
179
+ // so sharing credentials "just works" without surgery on the cache adapter.
180
+ channel = new UpstashProgressChannelCtor({}, { logger });
181
+ logger.debug('Progress channel: Upstash (via cache adapter)');
182
+ }
183
+ else if (drizzleClient) {
184
+ channel = new DbProgressChannel(drizzleClient, { logger });
185
+ logger.debug('Progress channel: Postgres fallback (throttled)');
186
+ }
187
+ else {
188
+ channel = new InMemoryProgressChannel();
189
+ logger.debug('Using in-memory progress channel (no upstash cache or pg database available)');
190
+ }
191
+ infraMap.set('IProgressChannelPort', channel);
192
+ }
193
+ //# sourceMappingURL=init-infra.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-infra.js","sourceRoot":"","sources":["../../../src/bootstrap/phases/init-infra.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AppRef, BootstrapContext } from '../bootstrap-context';
2
+ export declare function seedDevUsers(ctx: BootstrapContext, _appRef: AppRef): Promise<void>;
3
+ //# sourceMappingURL=seed-dev-users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-dev-users.d.ts","sourceRoot":"","sources":["../../../src/bootstrap/phases/seed-dev-users.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAepE,wBAAsB,YAAY,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiFxF"}
@@ -0,0 +1,93 @@
1
+ // Phase 5e: Seed initial admin user.
2
+ //
3
+ // If MANTA_ADMIN_EMAIL + MANTA_ADMIN_PASSWORD are set, create the user
4
+ // in auth_identities, provider_identities, AND the admin user table.
5
+ // Idempotent: fills any missing table while skipping what already exists.
6
+ // Like Medusa's USER_INITIAL_EMAIL / USER_INITIAL_PASSWORD.
7
+ import { randomBytes, scryptSync } from 'node:crypto';
8
+ import { entityToTableKey } from '../bootstrap-helpers';
9
+ function hashPassword(password) {
10
+ const salt = randomBytes(16).toString('hex');
11
+ const hash = scryptSync(password, salt, 64).toString('hex');
12
+ return `${salt}:${hash}`;
13
+ }
14
+ function uuid() {
15
+ return randomBytes(16)
16
+ .toString('hex')
17
+ .replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, '$1-$2-$3-$4-$5');
18
+ }
19
+ export async function seedDevUsers(ctx, _appRef) {
20
+ const email = process.env.MANTA_ADMIN_EMAIL;
21
+ const password = process.env.MANTA_ADMIN_PASSWORD;
22
+ if (!email || !password)
23
+ return;
24
+ const { logger, db, userDefinitions } = ctx;
25
+ if (!db) {
26
+ logger.warn('[seed] MANTA_ADMIN_EMAIL set but no database — cannot seed');
27
+ return;
28
+ }
29
+ // Resolve the admin user table name from the first userDefinition (e.g. 'Admin' → 'admins')
30
+ const adminDef = userDefinitions?.find((u) => u.contextName === 'admin');
31
+ const adminTableName = adminDef?.def?.model?.name ? entityToTableKey(adminDef.def.model.name) : 'admins';
32
+ logger.info(`[seed] Initial user: ${email} (table: ${adminTableName})`);
33
+ // --- 1. provider_identities ---
34
+ let hasAuth = false;
35
+ try {
36
+ const rows = await db.raw("SELECT id FROM provider_identities WHERE entity_id = $1 AND provider = 'emailpass' LIMIT 1", [email]);
37
+ if (rows.length > 0) {
38
+ hasAuth = true;
39
+ logger.info('[seed] provider_identity exists — OK');
40
+ }
41
+ }
42
+ catch (err) {
43
+ logger.error(`[seed] Cannot query provider_identities: ${err.message}`);
44
+ return;
45
+ }
46
+ if (!hasAuth) {
47
+ const authIdentityId = uuid();
48
+ try {
49
+ await db.raw('INSERT INTO auth_identities (id, app_metadata) VALUES ($1, $2)', [
50
+ authIdentityId,
51
+ '{"user_type":"admin"}',
52
+ ]);
53
+ logger.info(`[seed] auth_identity created: ${authIdentityId}`);
54
+ }
55
+ catch (err) {
56
+ logger.error(`[seed] Cannot insert auth_identity: ${err.message}`);
57
+ return;
58
+ }
59
+ const providerId = uuid();
60
+ const hashedPassword = hashPassword(password);
61
+ try {
62
+ await db.raw(`INSERT INTO provider_identities (id, entity_id, provider, auth_identity_id, user_metadata, provider_metadata)
63
+ VALUES ($1, $2, 'emailpass', $3, $4, $5)`, [providerId, email, authIdentityId, JSON.stringify({ email }), JSON.stringify({ password: hashedPassword })]);
64
+ logger.info(`[seed] provider_identity created: ${providerId}`);
65
+ }
66
+ catch (err) {
67
+ logger.error(`[seed] Cannot insert provider_identity: ${err.message}`);
68
+ return;
69
+ }
70
+ }
71
+ // --- 2. User table — ALWAYS ensure the row exists ---
72
+ try {
73
+ const userRows = await db.raw(`SELECT id FROM ${adminTableName} WHERE email = $1 LIMIT 1`, [email]);
74
+ if (userRows.length > 0) {
75
+ logger.info(`[seed] ${adminTableName} row exists — OK`);
76
+ }
77
+ else {
78
+ const userId = uuid();
79
+ await db.raw(`INSERT INTO ${adminTableName} (id, email, first_name, last_name) VALUES ($1, $2, $3, $4)`, [
80
+ userId,
81
+ email,
82
+ 'Admin',
83
+ 'User',
84
+ ]);
85
+ logger.info(`[seed] ${adminTableName} row created: ${userId}`);
86
+ }
87
+ }
88
+ catch (err) {
89
+ logger.error(`[seed] Cannot create ${adminTableName} row: ${err.message}`);
90
+ }
91
+ logger.info(`[seed] Done — login with ${email}`);
92
+ }
93
+ //# sourceMappingURL=seed-dev-users.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-dev-users.js","sourceRoot":"","sources":["../../../src/bootstrap/phases/seed-dev-users.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { AuthContext } from '@mantajs/core';
2
+ import type { BootstrapContext } from '../../bootstrap-context';
3
+ /**
4
+ * Parse a `Bearer <token>` authorization header and verify it through the
5
+ * bootstrap's AuthModuleService. Returns the verified AuthContext or `null`
6
+ * if the header is absent or the token fails verification.
7
+ *
8
+ * Mirrors the original inline blocks verbatim: no header → null, bad token →
9
+ * null (error swallowed), no exceptions propagated to the caller.
10
+ */
11
+ export declare function parseBearer(ctx: BootstrapContext, req: Request): Promise<AuthContext | null>;
12
+ //# sourceMappingURL=auth-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-helpers.d.ts","sourceRoot":"","sources":["../../../../src/bootstrap/phases/wire/auth-helpers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE/D;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAUlG"}
@@ -0,0 +1,25 @@
1
+ // Shared auth helpers for wire-phase route handlers.
2
+ // Extracted from the duplicated Bearer-token parsing blocks in cqrs-routes
3
+ // and query-endpoints (previously marked [13e], [13f], [13g]).
4
+ /**
5
+ * Parse a `Bearer <token>` authorization header and verify it through the
6
+ * bootstrap's AuthModuleService. Returns the verified AuthContext or `null`
7
+ * if the header is absent or the token fails verification.
8
+ *
9
+ * Mirrors the original inline blocks verbatim: no header → null, bad token →
10
+ * null (error swallowed), no exceptions propagated to the caller.
11
+ */
12
+ export async function parseBearer(ctx, req) {
13
+ const authHeader = req.headers.get('authorization');
14
+ const token = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;
15
+ if (!token)
16
+ return null;
17
+ try {
18
+ const payload = await ctx.authService.verifyToken(token, ctx.jwtSecret);
19
+ return payload;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ //# sourceMappingURL=auth-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-helpers.js","sourceRoot":"","sources":["../../../../src/bootstrap/phases/wire/auth-helpers.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,2EAA2E;AAC3E,+DAA+D;AAK/D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAqB,EAAE,GAAY;IACnE,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IACnD,MAAM,KAAK,GAAG,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC5E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;QACvE,OAAO,OAAiC,CAAA;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { ContextRegistry } from '@mantajs/core';
2
+ import type { AppRef, BootstrapContext } from '../../../bootstrap-context';
3
+ export declare function buildContextRegistry(ctx: BootstrapContext, _appRef: AppRef): Promise<ContextRegistry>;
4
+ //# sourceMappingURL=context-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-registry.d.ts","sourceRoot":"","sources":["../../../../../src/bootstrap/phases/wire/contexts/context-registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAoB,MAAM,eAAe,CAAA;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAE1E,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAsH3G"}
@@ -0,0 +1,96 @@
1
+ // [13d] Load contexts (src/contexts/*.ts).
2
+ import { ContextRegistry, isCommandAllowed } from '@mantajs/core';
3
+ export async function buildContextRegistry(ctx, _appRef) {
4
+ const { logger, resources, doImport, entityRegistry, entityCommandRegistry, explicitCommandNames, commandGraphDefs, userDefinitions, moduleScopedCommandNames, cmdRegistry, } = ctx;
5
+ // [13d] Load contexts (src/contexts/*.ts)
6
+ const contextRegistry = new ContextRegistry();
7
+ const moduleNames = [
8
+ ...resources.modules.map((m) => m.name),
9
+ ...Array.from(entityRegistry.keys()).map((k) => k.toLowerCase()),
10
+ ];
11
+ const commandNames = cmdRegistry ? cmdRegistry.list().map((e) => e.name) : [];
12
+ // Helper: resolve entity commands visible for a context based on its command graph
13
+ const isEntityCmdAllowed = isCommandAllowed;
14
+ const resolveEntityCommandsForContext = (ctxName) => {
15
+ const graphDef = commandGraphDefs.get(ctxName);
16
+ if (!graphDef)
17
+ return [];
18
+ const visibleEntityCmds = [];
19
+ for (const [cmdName, entityCmd] of entityCommandRegistry.entries()) {
20
+ if (explicitCommandNames.has(cmdName))
21
+ continue;
22
+ if (isEntityCmdAllowed(graphDef, entityCmd.__module, entityCmd.__operation)) {
23
+ visibleEntityCmds.push(cmdName);
24
+ }
25
+ }
26
+ return visibleEntityCmds;
27
+ };
28
+ if (resources.contexts.length > 0) {
29
+ // V1 path: explicit defineContext files
30
+ for (const ctxInfo of resources.contexts) {
31
+ try {
32
+ const imported = await doImport(ctxInfo.path);
33
+ // biome-ignore lint/suspicious/noExplicitAny: context definition shape varies
34
+ const def = imported.default;
35
+ if (def?.name && def?.basePath && def?.actors) {
36
+ const entityCmds = resolveEntityCommandsForContext(def.name);
37
+ if (entityCmds.length > 0) {
38
+ def.commands = [...(def.commands ?? []), ...entityCmds];
39
+ }
40
+ contextRegistry.register(def, moduleNames, [...commandNames, ...entityCmds]);
41
+ logger.info(` Context: ${def.name} (${def.basePath}) [V1 explicit]${entityCmds.length > 0 ? ` +${entityCmds.length} entity commands` : ''}`);
42
+ }
43
+ }
44
+ catch (err) {
45
+ logger.warn(`Failed to load context '${ctxInfo.id}': ${err instanceof Error ? err.message : String(err)}`);
46
+ }
47
+ }
48
+ }
49
+ else if (resources.users.length > 0 ||
50
+ resources.queries.length > 0 ||
51
+ resources.commands.some((c) => c.context)) {
52
+ // V2 path: derive contexts from filesystem structure
53
+ const derivedContexts = new Set();
54
+ for (const cmd of resources.commands) {
55
+ if (cmd.context)
56
+ derivedContexts.add(cmd.context);
57
+ }
58
+ for (const q of resources.queries) {
59
+ derivedContexts.add(q.context);
60
+ }
61
+ for (const u of userDefinitions) {
62
+ derivedContexts.add(u.contextName);
63
+ }
64
+ const commandGraphIds = new Set();
65
+ for (const cmd of resources.commands) {
66
+ if (cmd.context && commandGraphDefs.has(cmd.context) && cmd.id === 'graph') {
67
+ commandGraphIds.add(`${cmd.context}:${cmd.id}`);
68
+ }
69
+ }
70
+ const kebabToCamel = (s) => s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
71
+ for (const ctxName of derivedContexts) {
72
+ const ctxCommands = resources.commands
73
+ .filter((c) => c.context === ctxName && !commandGraphIds.has(`${c.context}:${c.id}`))
74
+ .map((c) => kebabToCamel(c.id));
75
+ const flatCommands = resources.commands.filter((c) => !c.context).map((c) => kebabToCamel(c.id));
76
+ const entityCmds = resolveEntityCommandsForContext(ctxName);
77
+ const allCtxCommands = [...ctxCommands, ...flatCommands, ...entityCmds, ...moduleScopedCommandNames];
78
+ const hasUser = userDefinitions.some((u) => u.contextName === ctxName);
79
+ const actors = hasUser ? [ctxName] : [];
80
+ contextRegistry.register({
81
+ name: ctxName,
82
+ basePath: `/api/${ctxName}`,
83
+ actors,
84
+ modules: Object.fromEntries(moduleNames.map((m) => [m, { expose: '*' }])),
85
+ commands: allCtxCommands,
86
+ }, moduleNames, [...commandNames, ...entityCmds]);
87
+ logger.info(` Context: ${ctxName} (/api/${ctxName}) [V2 filesystem-derived]${entityCmds.length > 0 ? ` +${entityCmds.length} entity commands` : ''}`);
88
+ }
89
+ }
90
+ else {
91
+ contextRegistry.registerDefault(moduleNames, commandNames);
92
+ logger.info(' Context: admin (implicit, /api/admin)');
93
+ }
94
+ return contextRegistry;
95
+ }
96
+ //# sourceMappingURL=context-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-registry.js","sourceRoot":"","sources":["../../../../../src/bootstrap/phases/wire/contexts/context-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AppRef, BootstrapContext } from '../../../bootstrap-context';
2
+ export declare function cqrsRoutes(ctx: BootstrapContext, appRef: AppRef): Promise<void>;
3
+ //# sourceMappingURL=cqrs-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cqrs-routes.d.ts","sourceRoot":"","sources":["../../../../../src/bootstrap/phases/wire/contexts/cqrs-routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAI1E,wBAAsB,UAAU,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgKrF"}
@@ -0,0 +1,138 @@
1
+ // [13e] Register context-aware CQRS endpoints.
2
+ import { getRequestBody } from '../../../../server-bootstrap';
3
+ import { parseBearer } from '../auth-helpers';
4
+ import { handleQueryRequest } from '../wire-adapter';
5
+ export async function cqrsRoutes(ctx, appRef) {
6
+ const { logger, adapter, contextRegistry } = ctx;
7
+ // [13e] Register context-aware CQRS endpoints
8
+ for (const ctx2 of contextRegistry.list()) {
9
+ // POST {basePath}/command/:name — filtered by context
10
+ adapter.registerRoute('POST', `${ctx2.basePath}/command/:name`, async (req) => {
11
+ try {
12
+ const url = new URL(req.url, 'http://localhost');
13
+ const segments = url.pathname.split('/');
14
+ const nameIdx = segments.indexOf('command') + 1;
15
+ const name = segments[nameIdx];
16
+ const camelName = name.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
17
+ if (!ctx2.commands.has(name) && !ctx2.commands.has(camelName)) {
18
+ return Response.json({ type: 'NOT_FOUND', message: `Command "${name}" not found in context "${ctx2.name}"` }, { status: 404 });
19
+ }
20
+ const cmds = appRef.current.commands;
21
+ const callable = cmds[name] ?? cmds[camelName];
22
+ if (!callable) {
23
+ return Response.json({ type: 'NOT_FOUND', message: `Command "${name}" not found` }, { status: 404 });
24
+ }
25
+ const body = await getRequestBody(req);
26
+ const cmdAuth = await parseBearer(ctx, req);
27
+ const reqHeaders = {};
28
+ req.headers.forEach((v, k) => {
29
+ reqHeaders[k] = v;
30
+ });
31
+ const result = await callable(body, { auth: cmdAuth, headers: reqHeaders });
32
+ // Running-envelope detection: the command callable may return
33
+ // { runId, status: 'running' } when the workflow lost the 300ms race
34
+ // in wire-commands.ts. Surface this with HTTP 202 so clients know
35
+ // to start polling /api/admin/_workflow/:id. See WORKFLOW_PROGRESS.md
36
+ // §6.1 and §6.5.
37
+ if (result &&
38
+ typeof result === 'object' &&
39
+ result.status === 'running' &&
40
+ typeof result.runId === 'string') {
41
+ const runId = result.runId;
42
+ return Response.json({ data: { runId, status: 'running', href: `/api/admin/_workflow/${runId}` } }, { status: 202 });
43
+ }
44
+ return Response.json({ data: result });
45
+ }
46
+ catch (err) {
47
+ if (err.name === 'ZodError') {
48
+ return Response.json({ type: 'INVALID_DATA', message: 'Validation failed', details: err.issues }, { status: 400 });
49
+ }
50
+ const message = err.message;
51
+ logger.error(`[command] ${message}`);
52
+ return Response.json({ type: 'UNEXPECTED_STATE', message }, { status: 500 });
53
+ }
54
+ });
55
+ // POST {basePath}/query/:entity — filtered by context
56
+ adapter.registerRoute('POST', `${ctx2.basePath}/query/:entity`, async (req) => {
57
+ try {
58
+ const url = new URL(req.url, 'http://localhost');
59
+ const segments = url.pathname.split('/');
60
+ const entityIdx = segments.indexOf('query') + 1;
61
+ const entity = segments[entityIdx];
62
+ if (!entity) {
63
+ return Response.json({ type: 'INVALID_DATA', message: 'entity is required in URL' }, { status: 400 });
64
+ }
65
+ const entityNormalized = entity.toLowerCase();
66
+ if (!ctx2.modules.has(entity) && !ctx2.modules.has(entityNormalized)) {
67
+ return Response.json({ type: 'NOT_FOUND', message: `Entity "${entity}" not available in context "${ctx2.name}"` }, { status: 404 });
68
+ }
69
+ let service = null;
70
+ const modules = appRef.current.modules;
71
+ try {
72
+ service = appRef.current.resolve(`${entity}ModuleService`);
73
+ }
74
+ catch {
75
+ service = modules[entity] ?? modules[entityNormalized] ?? null;
76
+ }
77
+ if (!service) {
78
+ return Response.json({ type: 'NOT_FOUND', message: `Entity "${entity}" not found` }, { status: 404 });
79
+ }
80
+ const body = await getRequestBody(req);
81
+ const qs = (() => {
82
+ try {
83
+ return appRef.current.resolve('queryService');
84
+ }
85
+ catch {
86
+ return null;
87
+ }
88
+ })();
89
+ if (qs && typeof qs.graphAndCount === 'function') {
90
+ const { fields, filters, limit, offset, order, q, id } = body;
91
+ if (id) {
92
+ return handleQueryRequest(service, entity, body, {
93
+ contextName: ctx2.name,
94
+ exposedModules: new Set(ctx2.modules.keys()),
95
+ logger,
96
+ });
97
+ }
98
+ const sortObj = order && typeof order === 'string'
99
+ ? { [order.startsWith('-') ? order.slice(1) : order]: order.startsWith('-') ? 'desc' : 'asc' }
100
+ : undefined;
101
+ const [data, count] = await qs.graphAndCount({
102
+ entity,
103
+ fields: fields,
104
+ filters: filters,
105
+ sort: sortObj,
106
+ pagination: { limit: limit ?? 15, offset: offset ?? 0 },
107
+ q: q,
108
+ });
109
+ return Response.json({ data, count });
110
+ }
111
+ return handleQueryRequest(service, entity, body, {
112
+ contextName: ctx2.name,
113
+ exposedModules: new Set(ctx2.modules.keys()),
114
+ logger,
115
+ });
116
+ }
117
+ catch (err) {
118
+ return Response.json({ type: 'UNEXPECTED_STATE', message: err.message }, { status: 500 });
119
+ }
120
+ });
121
+ // GET {basePath}/tools — AI tool discovery (filtered by context)
122
+ if (ctx2.ai.enabled) {
123
+ adapter.registerRoute('GET', `${ctx2.basePath}/tools`, async () => {
124
+ try {
125
+ const registry = appRef.current.resolve('commandRegistry');
126
+ const aiCommands = ctx2.ai.commands;
127
+ const filtered = registry.toToolSchemas().filter((t) => aiCommands.includes(t.name));
128
+ return Response.json({ tools: filtered });
129
+ }
130
+ catch {
131
+ return Response.json({ tools: [] });
132
+ }
133
+ });
134
+ }
135
+ logger.info(`[context] ${ctx2.name}: ${ctx2.basePath} (actors: ${ctx2.actors.join(', ')}, modules: ${[...ctx2.modules.keys()].join(', ')})`);
136
+ }
137
+ }
138
+ //# sourceMappingURL=cqrs-routes.js.map