@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,399 @@
1
+ // SPEC-074, SPEC-100 — manta build command
2
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { join, relative, resolve } from 'node:path';
4
+ const VALID_PRESETS = ['node', 'vercel', 'aws-lambda', 'cloudflare', 'bun'];
5
+ /**
6
+ * manta build — Build the project for deployment.
7
+ * Does NOT connect to DB. Does NOT validate secrets.
8
+ * Generates manifest in .manta/manifest/ then runs Nitro build.
9
+ */
10
+ export async function buildCommand(options = {}, cwd = process.cwd()) {
11
+ const result = { exitCode: 0, errors: [], warnings: [] };
12
+ const preset = options.preset ?? 'node';
13
+ // Validate preset
14
+ if (!VALID_PRESETS.includes(preset)) {
15
+ result.exitCode = 1;
16
+ result.errors.push(`Unknown preset '${preset}'. Available presets: ${VALID_PRESETS.join(', ')}`);
17
+ return result;
18
+ }
19
+ // Scan filesystem and generate manifest
20
+ const manifestDir = resolve(cwd, '.manta', 'manifest');
21
+ mkdirSync(manifestDir, { recursive: true });
22
+ const routes = scanRoutes(cwd);
23
+ const subscribers = scanSubscribers(cwd);
24
+ const workflows = scanWorkflows(cwd);
25
+ const jobs = scanJobs(cwd);
26
+ const links = scanLinks(cwd);
27
+ const modules = scanModules(cwd);
28
+ const portabilityErrors = scanForbiddenRuntimeImports(cwd);
29
+ if (portabilityErrors.length > 0) {
30
+ result.exitCode = 1;
31
+ result.errors.push(...portabilityErrors);
32
+ return result;
33
+ }
34
+ // Write manifest files
35
+ writeFileSync(join(manifestDir, 'routes.json'), JSON.stringify({ routes }, null, 2));
36
+ writeFileSync(join(manifestDir, 'subscribers.json'), JSON.stringify({ subscribers }, null, 2));
37
+ writeFileSync(join(manifestDir, 'workflows.json'), JSON.stringify({ workflows }, null, 2));
38
+ writeFileSync(join(manifestDir, 'jobs.json'), JSON.stringify({ jobs }, null, 2));
39
+ writeFileSync(join(manifestDir, 'links.json'), JSON.stringify({ links }, null, 2));
40
+ writeFileSync(join(manifestDir, 'modules.json'), JSON.stringify({ modules }, null, 2));
41
+ // BC-F18 — Record the preset used so `manta start` can refuse to run a
42
+ // non-node build. This is a minimal build-metadata file: just the preset and
43
+ // a timestamp. Not a full manifest system.
44
+ writeFileSync(join(manifestDir, 'build-info.json'), JSON.stringify({ preset, builtAt: new Date().toISOString() }, null, 2));
45
+ result.manifest = { routes, subscribers, workflows, jobs, links, modules };
46
+ // Auto-detect SPAs from src/spa/{name}/ + merge defaults with config overrides
47
+ const { discoverResources } = await import('../resource-loader');
48
+ const resources = await discoverResources(cwd);
49
+ // Load config for SPA overrides (optional)
50
+ let spaOverrides = {};
51
+ try {
52
+ const { loadConfig } = await import('../config/load-config');
53
+ const loadedConfig = await loadConfig(cwd);
54
+ spaOverrides = loadedConfig.spa ?? {};
55
+ }
56
+ catch {
57
+ // No config — use defaults
58
+ }
59
+ // Run codegen BEFORE the SPA build. The SPA routes.ts imports command-schemas
60
+ // for frontend form validation. In dev mode this is generated by the codegen
61
+ // watcher, but during a fresh `manta build` (e.g. on Vercel CI) no watcher runs.
62
+ // Without this, the Vite build fails with "Could not resolve '../../command-schemas'".
63
+ try {
64
+ const { generateCommand } = await import('./generate');
65
+ await generateCommand(cwd);
66
+ }
67
+ catch (err) {
68
+ console.warn(` ⚠ Codegen failed: ${err instanceof Error ? err.message : String(err)}`);
69
+ }
70
+ if (resources.spas.length > 0) {
71
+ const { generateSpaArtifacts } = await import('../spa/generate-spa');
72
+ const { SPA_DEFAULTS } = await import('@mantajs/core');
73
+ for (const spa of resources.spas) {
74
+ const override = spaOverrides[spa.name] ?? {};
75
+ const dashboard = override.dashboard === null ? undefined : (override.dashboard ?? SPA_DEFAULTS.dashboard);
76
+ const presetPkg = override.preset === null ? undefined : (override.preset ?? SPA_DEFAULTS.preset);
77
+ console.log(` Building SPA: ${spa.name} (${spa.pages.length} pages)...`);
78
+ try {
79
+ const viteConfig = generateSpaArtifacts({
80
+ cwd,
81
+ spa,
82
+ dashboard,
83
+ preset: presetPkg,
84
+ });
85
+ const { spawnSync } = await import('node:child_process');
86
+ const spaOutDir = resolve(cwd, 'public', spa.name);
87
+ const buildResult = spawnSync('npx', ['vite', 'build', '--config', viteConfig, '--outDir', spaOutDir], {
88
+ cwd,
89
+ stdio: 'inherit',
90
+ env: { ...process.env, NODE_ENV: 'production' },
91
+ });
92
+ if (buildResult.status !== 0) {
93
+ throw new Error(`Vite build for SPA "${spa.name}" exited with code ${buildResult.status}`);
94
+ }
95
+ console.log(` ✓ SPA "${spa.name}" built`);
96
+ }
97
+ catch (err) {
98
+ result.exitCode = 1;
99
+ result.errors.push(`Failed to build SPA "${spa.name}": ${err instanceof Error ? err.message : String(err)}`);
100
+ }
101
+ }
102
+ }
103
+ // Generate build-time manifest for serverless: static imports of all user files.
104
+ // This replaces runtime filesystem discovery (readdirSync + jiti) which is incompatible
105
+ // with Vercel/Lambda/Cloudflare where the function directory is read-only and source
106
+ // files aren't available as individual .ts files on disk.
107
+ if (preset === 'vercel' || preset === 'cloudflare' || preset === 'aws-lambda') {
108
+ try {
109
+ const { generateBuildManifest } = await import('../build/generate-manifest');
110
+ const { resolvePlugins } = await import('../plugins/resolve-plugins');
111
+ const { loadConfig } = await import('../config/load-config');
112
+ // Discover plugin resources at build time
113
+ let pluginResources = [];
114
+ try {
115
+ const config = await loadConfig(cwd);
116
+ const plugins = resolvePlugins(config, cwd);
117
+ const pluginResults = await Promise.all(plugins.map(async (p) => ({
118
+ name: p.name,
119
+ resources: await discoverResources(p.rootDir),
120
+ rootDir: p.rootDir,
121
+ })));
122
+ pluginResources = pluginResults;
123
+ }
124
+ catch (pluginErr) {
125
+ console.warn(` ⚠ Plugin discovery failed: ${pluginErr.message}`);
126
+ }
127
+ generateBuildManifest(cwd, resources, pluginResources);
128
+ }
129
+ catch (manifestErr) {
130
+ console.warn(` ⚠ Manifest generation failed: ${manifestErr.message}`);
131
+ }
132
+ }
133
+ // Generate vercel.json for Vercel preset
134
+ if (preset === 'vercel') {
135
+ generateVercelConfig(cwd, jobs, resources.spas);
136
+ }
137
+ // Delegate to Nitro build via @mantajs/host-nitro (only if nitro.config.ts exists)
138
+ const nitroConfigPath = join(cwd, 'nitro.config.ts');
139
+ if (existsSync(nitroConfigPath)) {
140
+ console.log(`\n Building for preset: ${preset}...`);
141
+ try {
142
+ const { buildForProduction } = await import('@mantajs/host-nitro');
143
+ await buildForProduction({ cwd, preset });
144
+ console.log(' ✓ Nitro build complete');
145
+ // Patch Vercel config.json to add SPA rewrites for static SPA fallbacks.
146
+ // Nitro's Build Output API generates config.json with routes that bypass vercel.json
147
+ // rewrites entirely. Without this patch, /{spa} falls through to the serverless
148
+ // catch-all and 404s because Nitro has no handler for it (the SPA is static).
149
+ if (preset === 'vercel') {
150
+ const configPath = join(cwd, '.vercel', 'output', 'config.json');
151
+ if (existsSync(configPath)) {
152
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
153
+ const routes = config.routes ?? [];
154
+ if (resources.spas.length === 1) {
155
+ const [spa] = resources.spas;
156
+ routes.unshift({ src: '^/$', status: 307, headers: { Location: `/${spa.name}` } }, { src: '^/login/?$', status: 307, headers: { Location: `/${spa.name}/login` } }, { src: '^/reset-password/?$', status: 307, headers: { Location: `/${spa.name}/reset-password` } }, { src: '^/accept-invite/?$', status: 307, headers: { Location: `/${spa.name}/accept-invite` } });
157
+ }
158
+ // Insert the SPA fallback AFTER 'handle: filesystem' so that
159
+ // /{spa}/assets/*.js is served by the filesystem handler first,
160
+ // and only bare /{spa}/* paths (no matching file) get the index.html.
161
+ const fsIdx = routes.findIndex((r) => r.handle === 'filesystem');
162
+ if (fsIdx >= 0) {
163
+ const spaRoutes = resources.spas.map((spa) => ({
164
+ src: `/${spa.name}(/.*)?`,
165
+ dest: `/${spa.name}/index.html`,
166
+ status: 200,
167
+ }));
168
+ routes.splice(fsIdx + 1, 0, ...spaRoutes);
169
+ }
170
+ config.routes = routes;
171
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
172
+ console.log(' ✓ Vercel config.json patched (SPA fallbacks)');
173
+ }
174
+ // NOTE: source files are NOT copied to the function directory anymore.
175
+ // The build-time manifest (manifest.ts) statically imports all user modules
176
+ // at build time → Nitro/rolldown bundles them into the function. No jiti,
177
+ // no readdirSync, no filesystem access at runtime.
178
+ }
179
+ }
180
+ catch (err) {
181
+ result.exitCode = 1;
182
+ result.errors.push(`Nitro build failed: ${err instanceof Error ? err.message : String(err)}`);
183
+ }
184
+ }
185
+ return result;
186
+ }
187
+ // ──────────────────────────────────────────────
188
+ // Vercel-specific config generation
189
+ // ──────────────────────────────────────────────
190
+ function generateVercelConfig(cwd, jobs, spas = []) {
191
+ // NOTE: do NOT include `buildCommand` here — it creates a "Production Override" in Vercel
192
+ // that takes precedence over the Project Settings build command, making it impossible to
193
+ // change from the Vercel UI. Let the user configure their build command in Vercel settings.
194
+ const redirects = [];
195
+ const rewrites = [];
196
+ if (spas.length === 1) {
197
+ const [spa] = spas;
198
+ redirects.push({ source: '/', destination: `/${spa.name}`, permanent: false }, { source: '/login', destination: `/${spa.name}/login`, permanent: false }, { source: '/reset-password', destination: `/${spa.name}/reset-password`, permanent: false }, { source: '/accept-invite', destination: `/${spa.name}/accept-invite`, permanent: false });
199
+ rewrites.push({ source: `/${spa.name}`, destination: `/${spa.name}/index.html` }, { source: `/${spa.name}/:path*`, destination: `/${spa.name}/index.html` });
200
+ }
201
+ else {
202
+ for (const spa of spas) {
203
+ rewrites.push({ source: `/${spa.name}`, destination: `/${spa.name}/index.html` }, { source: `/${spa.name}/:path*`, destination: `/${spa.name}/index.html` });
204
+ }
205
+ }
206
+ const vercelJson = {
207
+ $schema: 'https://openapi.vercel.sh/vercel.json',
208
+ framework: null,
209
+ redirects,
210
+ rewrites,
211
+ };
212
+ if (jobs.length > 0) {
213
+ vercelJson.crons = jobs.map((job) => ({
214
+ path: `/api/crons/${job.id}`,
215
+ schedule: job.schedule || '0 */6 * * *',
216
+ }));
217
+ }
218
+ // Trailing newline keeps Biome / EditorConfig formatters happy on
219
+ // commit-time hooks. JSON.stringify omits it.
220
+ writeFileSync(resolve(cwd, 'vercel.json'), `${JSON.stringify(vercelJson, null, 2)}\n`);
221
+ console.log(' ✓ vercel.json generated');
222
+ }
223
+ function scanForbiddenRuntimeImports(cwd) {
224
+ const srcDir = resolve(cwd, 'src');
225
+ if (!existsSync(srcDir))
226
+ return [];
227
+ const forbidden = [
228
+ { id: 'postgres', reason: 'use IDatabasePort/getPool() so Neon HTTP can run on Workers/serverless' },
229
+ { id: 'pg', reason: 'use IDatabasePort instead of a concrete PostgreSQL transport' },
230
+ { id: '@neondatabase/serverless', reason: 'wire Neon through the database adapter, not app code' },
231
+ { id: 'resend', reason: 'use INotificationPort instead of importing the provider SDK in app code' },
232
+ { id: '@vercel/blob', reason: 'use IFilePort instead of importing a platform SDK in app code' },
233
+ { id: '@upstash/redis', reason: 'use ICachePort/IEventBusPort instead of importing the provider SDK in app code' },
234
+ { id: '@upstash/qstash', reason: 'use IQueuePort instead of importing the provider SDK in app code' },
235
+ ];
236
+ const errors = [];
237
+ for (const file of walkTsFiles(srcDir)) {
238
+ const text = readFileSync(file, 'utf-8');
239
+ for (const entry of forbidden) {
240
+ const escaped = entry.id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
241
+ const importRe = new RegExp(`(?:import\\s+(?:type\\s+)?[^'"]*?from\\s*['"]${escaped}['"]|import\\s*\\(\\s*['"]${escaped}['"]\\s*\\)|require\\s*\\(\\s*['"]${escaped}['"]\\s*\\))`);
242
+ if (importRe.test(text)) {
243
+ errors.push(`Forbidden runtime import in ${relative(cwd, file)}: "${entry.id}" — ${entry.reason}.`);
244
+ }
245
+ }
246
+ }
247
+ return errors;
248
+ }
249
+ function walkTsFiles(dir) {
250
+ const files = [];
251
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
252
+ if (entry.name.startsWith('.'))
253
+ continue;
254
+ const path = resolve(dir, entry.name);
255
+ if (entry.isDirectory()) {
256
+ files.push(...walkTsFiles(path));
257
+ }
258
+ else if (entry.isFile() && /\.(ts|tsx|mts|cts)$/.test(entry.name) && !entry.name.endsWith('.d.ts')) {
259
+ files.push(path);
260
+ }
261
+ }
262
+ return files;
263
+ }
264
+ // ──────────────────────────────────────────────
265
+ // Filesystem scanning
266
+ // ──────────────────────────────────────────────
267
+ function scanRoutes(cwd) {
268
+ const routes = [];
269
+ const apiDir = resolve(cwd, 'src', 'api');
270
+ if (!existsSync(apiDir))
271
+ return routes;
272
+ scanRoutesRecursive(apiDir, apiDir, routes);
273
+ return routes;
274
+ }
275
+ function scanRoutesRecursive(dir, apiDir, routes) {
276
+ if (!existsSync(dir))
277
+ return;
278
+ const entries = readdirSync(dir, { withFileTypes: true });
279
+ for (const entry of entries) {
280
+ const fullPath = join(dir, entry.name);
281
+ if (entry.isDirectory()) {
282
+ scanRoutesRecursive(fullPath, apiDir, routes);
283
+ }
284
+ else if (entry.name === 'route.ts' || entry.name === 'route.js') {
285
+ const relDir = relative(apiDir, dir);
286
+ const pathSegments = relDir.split('/').filter(Boolean);
287
+ const namespace = pathSegments[0] ?? 'root';
288
+ const routePath = `/${pathSegments.join('/')}`;
289
+ routes.push({
290
+ path: routePath,
291
+ methods: ['GET', 'POST'], // simplified — real impl would parse exports
292
+ file: relative(resolve(apiDir, '..', '..'), fullPath),
293
+ namespace,
294
+ middlewares: [],
295
+ });
296
+ }
297
+ }
298
+ }
299
+ function scanSubscribers(cwd) {
300
+ return scanSimpleDir(cwd, 'src/subscribers').map((file) => ({
301
+ id: file
302
+ .replace(/\.(ts|js)$/, '')
303
+ .split('/')
304
+ .pop(),
305
+ file,
306
+ events: [], // Would parse from file
307
+ }));
308
+ }
309
+ function scanWorkflows(cwd) {
310
+ return scanSimpleDir(cwd, 'src/workflows').map((file) => ({
311
+ id: file
312
+ .replace(/\.(ts|js)$/, '')
313
+ .split('/')
314
+ .pop(),
315
+ file,
316
+ steps: [], // Would parse from file
317
+ }));
318
+ }
319
+ function scanJobs(cwd) {
320
+ return scanSimpleDir(cwd, 'src/jobs').map((file) => ({
321
+ id: file
322
+ .replace(/\.(ts|js)$/, '')
323
+ .split('/')
324
+ .pop(),
325
+ file,
326
+ schedule: extractJobSchedule(resolve(cwd, file)),
327
+ }));
328
+ }
329
+ /**
330
+ * Extract the cron schedule from a `defineJob('name', 'schedule', handler)` call.
331
+ *
332
+ * The signature is stable (defineJob is a global with positional args), so a
333
+ * regex over the source file is enough — we deliberately avoid an AST parser
334
+ * for build-time speed and to keep the CLI bundle dep-free.
335
+ *
336
+ * Returns the schedule string, or an empty string if not found. The empty
337
+ * string is the legacy default that `generateVercelConfig` falls back on
338
+ * (`'0 [slash-star]/6 [slash-star] [slash-star]'`, written here without the
339
+ * literal slash-star sequence to keep esbuild's JSDoc parser happy).
340
+ */
341
+ function extractJobSchedule(filePath) {
342
+ if (!existsSync(filePath))
343
+ return '';
344
+ let source;
345
+ try {
346
+ source = readFileSync(filePath, 'utf-8');
347
+ }
348
+ catch {
349
+ return '';
350
+ }
351
+ // Match: defineJob(<whitespace> 'name' <whitespace> , <whitespace> 'schedule'
352
+ // The schedule literal is captured as group 2. Both single and double
353
+ // quotes (and backticks for the schedule) are supported.
354
+ const match = source.match(/defineJob\s*\(\s*(?:'[^']*'|"[^"]*"|`[^`]*`)\s*,\s*(['"`])([^'"`]+)\1/);
355
+ return match?.[2] ?? '';
356
+ }
357
+ function scanLinks(cwd) {
358
+ return scanSimpleDir(cwd, 'src/links').map((file) => ({
359
+ id: file
360
+ .replace(/\.(ts|js)$/, '')
361
+ .split('/')
362
+ .pop(),
363
+ file,
364
+ modules: [],
365
+ table: '',
366
+ }));
367
+ }
368
+ function scanModules(cwd) {
369
+ const modulesDir = resolve(cwd, 'src', 'modules');
370
+ if (!existsSync(modulesDir))
371
+ return [];
372
+ const entries = readdirSync(modulesDir, { withFileTypes: true });
373
+ return entries
374
+ .filter((e) => e.isDirectory())
375
+ .filter((e) => {
376
+ const indexPath = resolve(modulesDir, e.name, 'index.ts');
377
+ return existsSync(indexPath);
378
+ })
379
+ .map((e) => ({
380
+ name: e.name,
381
+ file: `src/modules/${e.name}/index.ts`,
382
+ models: [],
383
+ service: '',
384
+ }));
385
+ }
386
+ function scanSimpleDir(cwd, relPath) {
387
+ const dir = resolve(cwd, relPath);
388
+ if (!existsSync(dir))
389
+ return [];
390
+ const files = [];
391
+ const entries = readdirSync(dir, { withFileTypes: true });
392
+ for (const entry of entries) {
393
+ if (entry.isFile() && (entry.name.endsWith('.ts') || entry.name.endsWith('.js'))) {
394
+ files.push(`${relPath}/${entry.name}`);
395
+ }
396
+ }
397
+ return files;
398
+ }
399
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { CreateDeps } from './types';
2
+ export interface CreateCommandResult {
3
+ exitCode: number;
4
+ errors: string[];
5
+ created: boolean;
6
+ dbName: string;
7
+ }
8
+ /**
9
+ * Extract the database name from a PostgreSQL URL.
10
+ */
11
+ export declare function extractDbName(url: string): string;
12
+ /**
13
+ * manta db:create — Create the database if it doesn't exist.
14
+ * Accepts injectable deps for testability (hexagonal architecture).
15
+ */
16
+ export declare function createCommand(databaseUrl: string, deps: CreateDeps): Promise<CreateCommandResult>;
17
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/db/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAejD;AAkBD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoDvG"}
@@ -0,0 +1,94 @@
1
+ // SPEC-070 — manta db:create command
2
+ /**
3
+ * Extract the database name from a PostgreSQL URL.
4
+ */
5
+ export function extractDbName(url) {
6
+ try {
7
+ // postgresql://user:pass@host:port/dbname
8
+ const parsed = new URL(url);
9
+ const pathname = parsed.pathname;
10
+ return pathname.startsWith('/') ? pathname.slice(1) : pathname;
11
+ }
12
+ catch {
13
+ // Fallback: extract last path segment
14
+ const lastSlash = url.lastIndexOf('/');
15
+ if (lastSlash === -1)
16
+ return '';
17
+ const dbPart = url.slice(lastSlash + 1);
18
+ // Remove query params
19
+ const qIndex = dbPart.indexOf('?');
20
+ return qIndex === -1 ? dbPart : dbPart.slice(0, qIndex);
21
+ }
22
+ }
23
+ /**
24
+ * Build the maintenance URL (connect to 'postgres' database instead of target).
25
+ */
26
+ function buildMaintenanceUrl(originalUrl) {
27
+ try {
28
+ const parsed = new URL(originalUrl);
29
+ parsed.pathname = '/postgres';
30
+ return parsed.toString();
31
+ }
32
+ catch {
33
+ // Fallback: replace last path segment
34
+ const lastSlash = originalUrl.lastIndexOf('/');
35
+ if (lastSlash === -1)
36
+ return originalUrl;
37
+ return `${originalUrl.slice(0, lastSlash)}/postgres`;
38
+ }
39
+ }
40
+ /**
41
+ * manta db:create — Create the database if it doesn't exist.
42
+ * Accepts injectable deps for testability (hexagonal architecture).
43
+ */
44
+ export async function createCommand(databaseUrl, deps) {
45
+ const dbName = extractDbName(databaseUrl);
46
+ const result = {
47
+ exitCode: 0,
48
+ errors: [],
49
+ created: false,
50
+ dbName,
51
+ };
52
+ if (!dbName) {
53
+ result.exitCode = 1;
54
+ result.errors.push('Cannot extract database name from URL');
55
+ return result;
56
+ }
57
+ // Validate database name against strict pattern to prevent SQL injection
58
+ // (database names cannot be parameterized in DDL statements)
59
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(dbName)) {
60
+ result.exitCode = 1;
61
+ result.errors.push(`Invalid database name: "${dbName}". Must match /^[a-zA-Z_][a-zA-Z0-9_]*$/`);
62
+ return result;
63
+ }
64
+ let client;
65
+ try {
66
+ // Connect to maintenance DB (postgres)
67
+ const maintenanceUrl = buildMaintenanceUrl(databaseUrl);
68
+ client = await deps.connectMaintenance(maintenanceUrl);
69
+ // Check if DB exists — dbName is validated above
70
+ const rows = await client.query(`SELECT datname FROM pg_database WHERE datname = '${dbName}'`);
71
+ if (rows.length > 0) {
72
+ // Already exists
73
+ result.created = false;
74
+ }
75
+ else {
76
+ // Create the database
77
+ await client.execute(`CREATE DATABASE "${dbName}"`);
78
+ result.created = true;
79
+ }
80
+ }
81
+ catch (err) {
82
+ result.exitCode = 1;
83
+ const message = err instanceof Error ? err.message : String(err);
84
+ result.errors.push(`Failed to create database: ${message}`);
85
+ result.created = false;
86
+ }
87
+ finally {
88
+ if (client) {
89
+ await client.close();
90
+ }
91
+ }
92
+ return result;
93
+ }
94
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/db/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { DiffDeps } from './types';
2
+ export interface DiffOptions {
3
+ json?: boolean;
4
+ }
5
+ export interface DiffEntry {
6
+ type: 'missing' | 'extra' | 'changed';
7
+ entity: 'table' | 'column' | 'index' | 'trigger';
8
+ name: string;
9
+ detail?: string;
10
+ }
11
+ export interface DiffCommandResult {
12
+ exitCode: number;
13
+ errors: string[];
14
+ diffs: DiffEntry[];
15
+ notifications: DiffEntry[];
16
+ }
17
+ /**
18
+ * Compare expected schema with introspected schema.
19
+ */
20
+ export declare function compareSchemas(expected: Array<{
21
+ table: string;
22
+ columns: string[];
23
+ }>, actual: Array<{
24
+ table: string;
25
+ columns: string[];
26
+ }>): {
27
+ diffs: DiffEntry[];
28
+ notifications: DiffEntry[];
29
+ };
30
+ /**
31
+ * manta db:diff — Compare DML schema vs actual DB (read-only).
32
+ * Uses information_schema + pg_indexes + pg_trigger.
33
+ * Accepts injectable deps for testability (hexagonal architecture).
34
+ */
35
+ export declare function diffCommand(_options: DiffOptions | undefined, expectedSchema: Array<{
36
+ table: string;
37
+ columns: string[];
38
+ }>, deps: DiffDeps): Promise<DiffCommandResult>;
39
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/commands/db/diff.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAA;IACrC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,aAAa,EAAE,SAAS,EAAE,CAAA;CAC3B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,EACrD,MAAM,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,GAClD;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,aAAa,EAAE,SAAS,EAAE,CAAA;CAAE,CA6CpD;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,WAAW,YAAK,EAC1B,cAAc,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,EAC3D,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,iBAAiB,CAAC,CAiC5B"}