@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.
- package/bin/manta.mjs +20 -0
- package/bin/manta.ts +13 -0
- package/dist/admin/generate-admin-config.d.ts +8 -0
- package/dist/admin/generate-admin-config.d.ts.map +1 -0
- package/dist/admin/generate-admin-config.js +127 -0
- package/dist/admin/generate-admin-config.js.map +1 -0
- package/dist/ai/chat-handler.d.ts +10 -0
- package/dist/ai/chat-handler.d.ts.map +1 -0
- package/dist/ai/chat-handler.js +1353 -0
- package/dist/ai/chat-handler.js.map +1 -0
- package/dist/bootstrap/boot.d.ts +25 -0
- package/dist/bootstrap/boot.d.ts.map +1 -0
- package/dist/bootstrap/boot.js +344 -0
- package/dist/bootstrap/boot.js.map +1 -0
- package/dist/bootstrap/bootstrap-app.d.ts +71 -0
- package/dist/bootstrap/bootstrap-app.d.ts.map +1 -0
- package/dist/bootstrap/bootstrap-app.js +308 -0
- package/dist/bootstrap/bootstrap-app.js.map +1 -0
- package/dist/bootstrap/bootstrap-context.d.ts +76 -0
- package/dist/bootstrap/bootstrap-context.d.ts.map +1 -0
- package/dist/bootstrap/bootstrap-context.js +4 -0
- package/dist/bootstrap/bootstrap-context.js.map +1 -0
- package/dist/bootstrap/bootstrap-helpers.d.ts +71 -0
- package/dist/bootstrap/bootstrap-helpers.d.ts.map +1 -0
- package/dist/bootstrap/bootstrap-helpers.js +373 -0
- package/dist/bootstrap/bootstrap-helpers.js.map +1 -0
- package/dist/bootstrap/generate-types.d.ts +7 -0
- package/dist/bootstrap/generate-types.d.ts.map +1 -0
- package/dist/bootstrap/generate-types.js +832 -0
- package/dist/bootstrap/generate-types.js.map +1 -0
- package/dist/bootstrap/phases/assemble/index.d.ts +5 -0
- package/dist/bootstrap/phases/assemble/index.d.ts.map +1 -0
- package/dist/bootstrap/phases/assemble/index.js +5 -0
- package/dist/bootstrap/phases/assemble/index.js.map +1 -0
- package/dist/bootstrap/phases/assemble/load-links.d.ts +3 -0
- package/dist/bootstrap/phases/assemble/load-links.d.ts.map +1 -0
- package/dist/bootstrap/phases/assemble/load-links.js +160 -0
- package/dist/bootstrap/phases/assemble/load-links.js.map +1 -0
- package/dist/bootstrap/phases/assemble/load-modules.d.ts +3 -0
- package/dist/bootstrap/phases/assemble/load-modules.d.ts.map +1 -0
- package/dist/bootstrap/phases/assemble/load-modules.js +163 -0
- package/dist/bootstrap/phases/assemble/load-modules.js.map +1 -0
- package/dist/bootstrap/phases/assemble/load-resources.d.ts +3 -0
- package/dist/bootstrap/phases/assemble/load-resources.d.ts.map +1 -0
- package/dist/bootstrap/phases/assemble/load-resources.js +270 -0
- package/dist/bootstrap/phases/assemble/load-resources.js.map +1 -0
- package/dist/bootstrap/phases/assemble/wire-commands.d.ts +3 -0
- package/dist/bootstrap/phases/assemble/wire-commands.d.ts.map +1 -0
- package/dist/bootstrap/phases/assemble/wire-commands.js +408 -0
- package/dist/bootstrap/phases/assemble/wire-commands.js.map +1 -0
- package/dist/bootstrap/phases/assemble-modules.d.ts +3 -0
- package/dist/bootstrap/phases/assemble-modules.d.ts.map +1 -0
- package/dist/bootstrap/phases/assemble-modules.js +14 -0
- package/dist/bootstrap/phases/assemble-modules.js.map +1 -0
- package/dist/bootstrap/phases/build-app.d.ts +3 -0
- package/dist/bootstrap/phases/build-app.d.ts.map +1 -0
- package/dist/bootstrap/phases/build-app.js +15 -0
- package/dist/bootstrap/phases/build-app.js.map +1 -0
- package/dist/bootstrap/phases/discover-resources.d.ts +3 -0
- package/dist/bootstrap/phases/discover-resources.d.ts.map +1 -0
- package/dist/bootstrap/phases/discover-resources.js +60 -0
- package/dist/bootstrap/phases/discover-resources.js.map +1 -0
- package/dist/bootstrap/phases/index.d.ts +7 -0
- package/dist/bootstrap/phases/index.d.ts.map +1 -0
- package/dist/bootstrap/phases/index.js +7 -0
- package/dist/bootstrap/phases/index.js.map +1 -0
- package/dist/bootstrap/phases/init-infra.d.ts +3 -0
- package/dist/bootstrap/phases/init-infra.d.ts.map +1 -0
- package/dist/bootstrap/phases/init-infra.js +193 -0
- package/dist/bootstrap/phases/init-infra.js.map +1 -0
- package/dist/bootstrap/phases/seed-dev-users.d.ts +3 -0
- package/dist/bootstrap/phases/seed-dev-users.d.ts.map +1 -0
- package/dist/bootstrap/phases/seed-dev-users.js +93 -0
- package/dist/bootstrap/phases/seed-dev-users.js.map +1 -0
- package/dist/bootstrap/phases/wire/auth-helpers.d.ts +12 -0
- package/dist/bootstrap/phases/wire/auth-helpers.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/auth-helpers.js +25 -0
- package/dist/bootstrap/phases/wire/auth-helpers.js.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/context-registry.d.ts +4 -0
- package/dist/bootstrap/phases/wire/contexts/context-registry.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/context-registry.js +96 -0
- package/dist/bootstrap/phases/wire/contexts/context-registry.js.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/cqrs-routes.d.ts +3 -0
- package/dist/bootstrap/phases/wire/contexts/cqrs-routes.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/cqrs-routes.js +138 -0
- package/dist/bootstrap/phases/wire/contexts/cqrs-routes.js.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/index.d.ts +6 -0
- package/dist/bootstrap/phases/wire/contexts/index.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/index.js +6 -0
- package/dist/bootstrap/phases/wire/contexts/index.js.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/query-endpoints.d.ts +3 -0
- package/dist/bootstrap/phases/wire/contexts/query-endpoints.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/query-endpoints.js +116 -0
- package/dist/bootstrap/phases/wire/contexts/query-endpoints.js.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/spa-warnings.d.ts +3 -0
- package/dist/bootstrap/phases/wire/contexts/spa-warnings.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/spa-warnings.js +17 -0
- package/dist/bootstrap/phases/wire/contexts/spa-warnings.js.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/user-routes.d.ts +3 -0
- package/dist/bootstrap/phases/wire/contexts/user-routes.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/contexts/user-routes.js +83 -0
- package/dist/bootstrap/phases/wire/contexts/user-routes.js.map +1 -0
- package/dist/bootstrap/phases/wire/index.d.ts +5 -0
- package/dist/bootstrap/phases/wire/index.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/index.js +5 -0
- package/dist/bootstrap/phases/wire/index.js.map +1 -0
- package/dist/bootstrap/phases/wire/wire-adapter.d.ts +12 -0
- package/dist/bootstrap/phases/wire/wire-adapter.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/wire-adapter.js +156 -0
- package/dist/bootstrap/phases/wire/wire-adapter.js.map +1 -0
- package/dist/bootstrap/phases/wire/wire-auth.d.ts +3 -0
- package/dist/bootstrap/phases/wire/wire-auth.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/wire-auth.js +46 -0
- package/dist/bootstrap/phases/wire/wire-auth.js.map +1 -0
- package/dist/bootstrap/phases/wire/wire-contexts.d.ts +3 -0
- package/dist/bootstrap/phases/wire/wire-contexts.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/wire-contexts.js +15 -0
- package/dist/bootstrap/phases/wire/wire-contexts.js.map +1 -0
- package/dist/bootstrap/phases/wire/wire-cron-routes.d.ts +3 -0
- package/dist/bootstrap/phases/wire/wire-cron-routes.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/wire-cron-routes.js +102 -0
- package/dist/bootstrap/phases/wire/wire-cron-routes.js.map +1 -0
- package/dist/bootstrap/phases/wire/wire-extras.d.ts +3 -0
- package/dist/bootstrap/phases/wire/wire-extras.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/wire-extras.js +305 -0
- package/dist/bootstrap/phases/wire/wire-extras.js.map +1 -0
- package/dist/bootstrap/phases/wire/wire-workflow-routes.d.ts +3 -0
- package/dist/bootstrap/phases/wire/wire-workflow-routes.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire/wire-workflow-routes.js +212 -0
- package/dist/bootstrap/phases/wire/wire-workflow-routes.js.map +1 -0
- package/dist/bootstrap/phases/wire-http.d.ts +3 -0
- package/dist/bootstrap/phases/wire-http.d.ts.map +1 -0
- package/dist/bootstrap/phases/wire-http.js +10 -0
- package/dist/bootstrap/phases/wire-http.js.map +1 -0
- package/dist/bootstrap/validate-generated-ts.d.ts +6 -0
- package/dist/bootstrap/validate-generated-ts.d.ts.map +1 -0
- package/dist/bootstrap/validate-generated-ts.js +26 -0
- package/dist/bootstrap/validate-generated-ts.js.map +1 -0
- package/dist/build/generate-manifest.d.ts +10 -0
- package/dist/build/generate-manifest.d.ts.map +1 -0
- package/dist/build/generate-manifest.js +138 -0
- package/dist/build/generate-manifest.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +421 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/build.d.ts +21 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +399 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/db/create.d.ts +17 -0
- package/dist/commands/db/create.d.ts.map +1 -0
- package/dist/commands/db/create.js +94 -0
- package/dist/commands/db/create.js.map +1 -0
- package/dist/commands/db/diff.d.ts +39 -0
- package/dist/commands/db/diff.d.ts.map +1 -0
- package/dist/commands/db/diff.js +81 -0
- package/dist/commands/db/diff.js.map +1 -0
- package/dist/commands/db/generate.d.ts +58 -0
- package/dist/commands/db/generate.d.ts.map +1 -0
- package/dist/commands/db/generate.js +138 -0
- package/dist/commands/db/generate.js.map +1 -0
- package/dist/commands/db/migrate.d.ts +29 -0
- package/dist/commands/db/migrate.d.ts.map +1 -0
- package/dist/commands/db/migrate.js +118 -0
- package/dist/commands/db/migrate.js.map +1 -0
- package/dist/commands/db/pg-deps.d.ts +30 -0
- package/dist/commands/db/pg-deps.d.ts.map +1 -0
- package/dist/commands/db/pg-deps.js +178 -0
- package/dist/commands/db/pg-deps.js.map +1 -0
- package/dist/commands/db/rollback.d.ts +21 -0
- package/dist/commands/db/rollback.d.ts.map +1 -0
- package/dist/commands/db/rollback.js +85 -0
- package/dist/commands/db/rollback.js.map +1 -0
- package/dist/commands/db/types.d.ts +113 -0
- package/dist/commands/db/types.d.ts.map +1 -0
- package/dist/commands/db/types.js +4 -0
- package/dist/commands/db/types.js.map +1 -0
- package/dist/commands/dev.d.ts +12 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +79 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/exec.d.ts +21 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +148 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/generate.d.ts +11 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +19 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +476 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/start.d.ts +15 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +121 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/user.d.ts +19 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/commands/user.js +125 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/config/load-config.d.ts +23 -0
- package/dist/config/load-config.d.ts.map +1 -0
- package/dist/config/load-config.js +105 -0
- package/dist/config/load-config.js.map +1 -0
- package/dist/config/load-env.d.ts +11 -0
- package/dist/config/load-env.d.ts.map +1 -0
- package/dist/config/load-env.js +61 -0
- package/dist/config/load-env.js.map +1 -0
- package/dist/config/resolve-adapters.d.ts +23 -0
- package/dist/config/resolve-adapters.d.ts.map +1 -0
- package/dist/config/resolve-adapters.js +96 -0
- package/dist/config/resolve-adapters.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/jiti.d.ts +2 -0
- package/dist/jiti.d.ts.map +1 -0
- package/dist/jiti.js +2 -0
- package/dist/jiti.js.map +1 -0
- package/dist/openapi/generate-spec.d.ts +56 -0
- package/dist/openapi/generate-spec.d.ts.map +1 -0
- package/dist/openapi/generate-spec.js +491 -0
- package/dist/openapi/generate-spec.js.map +1 -0
- package/dist/openapi/index.d.ts +4 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +3 -0
- package/dist/openapi/index.js.map +1 -0
- package/dist/openapi/swagger-html.d.ts +2 -0
- package/dist/openapi/swagger-html.d.ts.map +1 -0
- package/dist/openapi/swagger-html.js +29 -0
- package/dist/openapi/swagger-html.js.map +1 -0
- package/dist/plugins/merge-resources.d.ts +18 -0
- package/dist/plugins/merge-resources.d.ts.map +1 -0
- package/dist/plugins/merge-resources.js +76 -0
- package/dist/plugins/merge-resources.js.map +1 -0
- package/dist/plugins/resolve-plugins.d.ts +14 -0
- package/dist/plugins/resolve-plugins.d.ts.map +1 -0
- package/dist/plugins/resolve-plugins.js +73 -0
- package/dist/plugins/resolve-plugins.js.map +1 -0
- package/dist/resource-loader.d.ts +151 -0
- package/dist/resource-loader.d.ts.map +1 -0
- package/dist/resource-loader.js +456 -0
- package/dist/resource-loader.js.map +1 -0
- package/dist/route-discovery.d.ts +33 -0
- package/dist/route-discovery.d.ts.map +1 -0
- package/dist/route-discovery.js +69 -0
- package/dist/route-discovery.js.map +1 -0
- package/dist/server-bootstrap.d.ts +38 -0
- package/dist/server-bootstrap.d.ts.map +1 -0
- package/dist/server-bootstrap.js +21 -0
- package/dist/server-bootstrap.js.map +1 -0
- package/dist/spa/generate-spa.d.ts +15 -0
- package/dist/spa/generate-spa.d.ts.map +1 -0
- package/dist/spa/generate-spa.js +357 -0
- package/dist/spa/generate-spa.js.map +1 -0
- package/dist/templates/agent/nextjs.md +129 -0
- package/dist/templates/agent/nuxt.md +98 -0
- package/dist/templates/agent/standalone.md +498 -0
- package/dist/types.d.ts +145 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/colors.d.ts +7 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +8 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/prompts.d.ts +6 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +28 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/spinner.d.ts +7 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +20 -0
- package/dist/utils/spinner.js.map +1 -0
- 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"}
|