nymbal 1.0.0 → 1.2.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/version.ts","../src/commands/dev.ts","../src/utils/project.ts","../src/utils/spawn.ts","../src/utils/port.ts","../src/utils/template-runner.ts","../src/commands/migrate.ts","../src/admin.ts","../src/utils/shutdown.ts","../src/commands/build.ts","../src/commands/seed.ts","../src/commands/import.ts","../src/commands/config-validate.ts","../src/commands/test.ts"],"sourcesContent":["import { defineCommand, runMain } from 'citty'\nimport { getCliVersion } from './utils/version.js'\nimport { devCommand } from './commands/dev.js'\nimport { buildCommand } from './commands/build.js'\nimport { migrateCommand } from './commands/migrate.js'\nimport { seedCommand } from './commands/seed.js'\nimport { importCommand } from './commands/import.js'\nimport { configValidateCommand } from './commands/config-validate.js'\nimport {\n testAllCommand,\n testCommand,\n testContractsCommand,\n testE2eCommand,\n testPerformanceCommand,\n testVisualCommand,\n} from './commands/test.js'\n\nexport { resolveAdminRoot } from './admin.js'\n\nconst main = defineCommand({\n meta: {\n name: 'nymbal',\n version: getCliVersion(),\n description: 'Nymbal developer CLI',\n },\n subCommands: {\n dev: devCommand,\n build: buildCommand,\n migrate: migrateCommand,\n seed: seedCommand,\n import: importCommand,\n 'config:validate': configValidateCommand,\n test: testCommand,\n 'test:e2e': testE2eCommand,\n 'test:visual': testVisualCommand,\n 'test:contracts': testContractsCommand,\n 'test:performance': testPerformanceCommand,\n 'test:all': testAllCommand,\n },\n})\n\n// citty prints --version through consola, which prefixes `[log]` when CI is set; scripts need the bare version.\nconst [flag, ...rest] = process.argv.slice(2)\nif (rest.length === 0 && (flag === '--version' || flag === '-v')) {\n process.stdout.write(`${getCliVersion()}\\n`)\n} else {\n runMain(main)\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst CLI_PACKAGE_NAME = 'nymbal'\n\nlet cached: string | null = null\n\n/**\n * Walks up from this module to the CLI's own package.json (found by name, so a nested or unrelated package.json\n * never answers). That is `dist/` in the workspace and in `node_modules/nymbal`, and `src/utils/` under Vitest.\n */\nfunction readOwnVersion(): string | undefined {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as {\n name?: string\n version?: string\n }\n if (pkg.name === CLI_PACKAGE_NAME) return pkg.version\n } catch {\n // No readable package.json in this directory: keep walking.\n }\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport function getCliVersion(): string {\n cached ??= readOwnVersion() ?? '0.0.0'\n return cached\n}\n","import { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport { loadProject } from '../utils/project.js'\nimport { createApp, runSeed } from '@nymbalhq/platform'\nimport { createHttpServer } from '@nymbalhq/http'\nimport { run } from '../utils/spawn.js'\nimport { getCliVersion } from '../utils/version.js'\nimport { findFreePort } from '../utils/port.js'\nimport { planTemplateLaunch } from '../utils/template-runner.js'\nimport { migrateProject } from './migrate.js'\nimport { resolveAdminRoot } from '../admin.js'\nimport { runShutdown, SHUTDOWN_BOUND_MS, type ShutdownStep } from '../utils/shutdown.js'\n\n/** Default storefront dev-server port per template (matches the scaffold scripts). */\nexport function defaultStorefrontPort(template: 'astro' | 'nextjs'): number {\n return template === 'astro' ? 4321 : 3000\n}\n\n/**\n * Resolve the *preferred* storefront port from (in priority order):\n * 1. --storefront-port flag\n * 2. NYMBAL_STOREFRONT_PORT env var\n * 3. the template default (Astro 4321 / Next.js 3000)\n * The value returned here is only the starting point; the dev command then\n * probes upward for a genuinely free port so a busy default never hard-fails.\n */\nexport function preferredStorefrontPort(\n template: 'astro' | 'nextjs',\n flagPort: number | undefined,\n env: NodeJS.ProcessEnv,\n): number {\n if (typeof flagPort === 'number' && Number.isFinite(flagPort)) return flagPort\n const fromEnv = env['NYMBAL_STOREFRONT_PORT']\n if (fromEnv && fromEnv.trim() !== '') {\n const parsed = Number(fromEnv)\n if (Number.isInteger(parsed) && parsed > 0) return parsed\n }\n return defaultStorefrontPort(template)\n}\n\n/**\n * The environment the storefront dev server starts with. The client-side variables must be set before it starts, and\n * both templates skip Stripe when the payments provider variable says `native-stub`, which is every provider but\n * `stripe`.\n */\nexport function storefrontEnv(\n config: NymbalConfig,\n apiUrl: string,\n storefrontPort: number,\n baseEnv: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n const stubPayments =\n config.commerce.payments.provider === 'stripe'\n ? {}\n : {\n PUBLIC_NYMBAL_PAYMENTS_PROVIDER: 'native-stub', // Astro\n NEXT_PUBLIC_NYMBAL_PAYMENTS_PROVIDER: 'native-stub', // Next.js\n }\n return {\n ...baseEnv,\n NYMBAL_API_URL: apiUrl,\n PUBLIC_NYMBAL_API_URL: apiUrl, // Astro\n NEXT_PUBLIC_NYMBAL_API_URL: apiUrl, // Next.js\n // The framework also reads the port flag; the env var keeps the scaffold\n // config (astro.config.mjs) in sync when it honours NYMBAL_STOREFRONT_PORT.\n NYMBAL_STOREFRONT_PORT: String(storefrontPort),\n ...stubPayments,\n }\n}\n\n/** The API port: `--port` when given, else the config's `http.port`. */\nfunction apiPort(config: NymbalConfig, flagPort: string | undefined): number {\n if (flagPort === undefined || flagPort.trim() === '') return config.http.port\n const port = Number(flagPort)\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`--port must be an integer from 1 to 65535, got \"${flagPort}\"`)\n }\n return port\n}\n\nexport const devCommand = defineCommand({\n meta: {\n name: 'dev',\n description: 'Start the API server and the configured storefront template with HMR',\n },\n args: {\n seed: {\n type: 'boolean',\n description: 'Run seed before starting (default: true if empty)',\n default: true,\n },\n apiOnly: {\n type: 'boolean',\n // `alias` is required: citty 0.1.6 registers the camelCase key `apiOnly`\n // with mri and applies `default: false`. Without this alias a kebab\n // `--api-only` flag lands on `args['api-only']`, but `args.apiOnly`\n // resolves to the `false` default first (`??` does not fall through on\n // `false`), so the flag is silently ignored. The alias makes mri map\n // `--api-only` straight to `apiOnly`. Both forms now work.\n alias: 'api-only',\n description: 'Start only the API server (skip template dev server)',\n default: false,\n },\n port: {\n type: 'string',\n description: \"Port for the API server (default: the config's http.port)\",\n },\n storefrontPort: {\n type: 'string',\n alias: 'storefront-port',\n description:\n 'Port for the storefront dev server (default: 4321 Astro / 3000 Next.js). ' +\n 'If busy, the next free port is used. Also settable via NYMBAL_STOREFRONT_PORT.',\n },\n },\n async run({ args }) {\n const loaded = await loadProject()\n const { projectRoot } = loaded\n const port = apiPort(loaded.config, args.port)\n const config: NymbalConfig = { ...loaded.config, http: { ...loaded.config.http, port } }\n const version = getCliVersion()\n\n // Auto-migrate on startup so a fresh clone works without running `nymbal migrate` first\n await migrateProject(config, projectRoot)\n\n const app = await createApp(config, { version })\n const { platform } = app\n\n if (args.seed) {\n const existing = await platform.documentStore.query('products', {\n partitionKey: { field: 'storeId', value: config.store.name },\n limit: 1,\n })\n if (existing.items.length === 0) {\n platform.logger.info({}, 'Seeding demo content (first run)')\n await runSeed({\n config,\n commandStore: platform.commandStore,\n documentStore: platform.documentStore,\n eventBus: platform.eventBus,\n logger: platform.logger,\n version,\n })\n }\n }\n\n const http = createHttpServer({\n config,\n logger: platform.logger,\n documentStore: platform.documentStore,\n version,\n })\n const adminRoot = resolveAdminRoot()\n if (adminRoot === null) {\n // eslint-disable-next-line no-console\n console.log(\n pc.yellow(\n '→ The admin is not built, so /admin/ answers 404: run `pnpm --filter @nymbalhq/admin build`.',\n ),\n )\n }\n await app.attachHttp(http.adapter, { adminRoot })\n await http.start()\n\n const stopApi: ShutdownStep[] = [\n { name: 'http.stop', run: () => http.stop() },\n { name: 'app.stop', run: () => app.stop() },\n ]\n const shutdownWith = (steps: ShutdownStep[]): Promise<never> =>\n runShutdown(steps, {\n boundMs: SHUTDOWN_BOUND_MS,\n logger: platform.logger,\n exit: (code) => process.exit(code),\n })\n\n if (args.apiOnly) {\n const shutdown = (signal: string) => {\n platform.logger.info({ signal }, 'Shutting down API')\n return shutdownWith(stopApi)\n }\n process.on('SIGINT', () => void shutdown('SIGINT'))\n process.on('SIGTERM', () => void shutdown('SIGTERM'))\n // Keep process alive — Playwright webServer will kill it when done\n return\n }\n\n // Resolve a free storefront port. The preferred port is configurable but may\n // be taken (a developer commonly has another project on 4321/3000), so we\n // probe upward for a free one instead of hard-failing.\n const flagPortRaw = args.storefrontPort\n const flagPort =\n typeof flagPortRaw === 'string' && flagPortRaw.trim() !== '' ? Number(flagPortRaw) : undefined\n const preferred = preferredStorefrontPort(config.template, flagPort, process.env)\n const storefrontPort = await findFreePort(preferred)\n if (storefrontPort !== preferred) {\n // eslint-disable-next-line no-console\n console.log(\n pc.yellow(\n `→ Storefront port ${preferred} is busy; using free port ${pc.bold(String(storefrontPort))} instead.`,\n ),\n )\n }\n\n // Plan how to launch the storefront. A flat scaffold (create-nymbal-app\n // output) runs the framework dev server directly in the project root; a\n // monorepo layout falls back to a pnpm --filter on the template package.\n const launch = planTemplateLaunch(projectRoot, config.template, storefrontPort)\n\n const apiUrl = `http://localhost:${config.http.port}`\n const storefrontUrl = `http://localhost:${storefrontPort}`\n // eslint-disable-next-line no-console\n console.log(\n pc.cyan(\n `→ Starting storefront (${pc.bold(config.template)}, ${launch.mode}) on ${pc.bold(storefrontUrl)}`,\n ),\n )\n // eslint-disable-next-line no-console\n console.log(pc.dim(` API: ${apiUrl}`))\n\n const templateProc = run(launch.command, launch.args, {\n cwd: launch.cwd,\n env: storefrontEnv(config, apiUrl, storefrontPort),\n })\n\n let shuttingDown = false\n const shutdown = (signal: string) => {\n shuttingDown = true\n platform.logger.info({ signal }, 'Shutting down')\n return shutdownWith([\n {\n name: 'storefront.kill',\n run: async () => {\n templateProc.child.kill('SIGINT')\n },\n },\n ...stopApi,\n ])\n }\n process.on('SIGINT', () => void shutdown('SIGINT'))\n process.on('SIGTERM', () => void shutdown('SIGTERM'))\n\n const templateExit = await templateProc.done\n platform.logger.info({ code: templateExit }, 'Template process exited')\n // A Ctrl-C reaches the storefront too, so it exits during the signal's own shutdown, which ends the process.\n // Calling `runShutdown` again would count as a repeat signal and exit 1 at once.\n if (shuttingDown) return\n await shutdown('template-exit')\n },\n})\n","import { existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { findConfigFile, loadConfig, type LoadedConfig } from '@nymbalhq/config'\n\n/**\n * Loads `<projectRoot>/.env` into the process environment, then the project's config, so `env()` calls in\n * `nymbal.config.ts` see it. A variable already set in the environment is kept: `process.loadEnvFile` never overrides.\n */\nexport async function loadProject(startDir: string = process.cwd()): Promise<LoadedConfig> {\n const configPath = findConfigFile(startDir)\n if (configPath) {\n const envFile = resolve(dirname(configPath), '.env')\n if (existsSync(envFile)) process.loadEnvFile(envFile)\n }\n return loadConfig(startDir)\n}\n","import { spawn, type ChildProcess, type SpawnOptions } from 'node:child_process'\n\nexport interface RunOptions extends SpawnOptions {\n name?: string\n}\n\nexport function run(\n command: string,\n args: string[],\n options: RunOptions = {},\n): { child: ChildProcess; done: Promise<number> } {\n const child = spawn(command, args, {\n stdio: 'inherit',\n shell: false,\n ...options,\n })\n const done = new Promise<number>((resolve, reject) => {\n child.on('error', reject)\n child.on('exit', (code) => resolve(code ?? 0))\n })\n return { child, done }\n}\n\nexport async function runOrFail(\n command: string,\n args: string[],\n options: RunOptions = {},\n): Promise<void> {\n const { done } = run(command, args, options)\n const code = await done\n if (code !== 0) {\n throw new Error(`${command} ${args.join(' ')} exited with code ${code}`)\n }\n}\n","import { createServer } from 'node:net'\n\n/**\n * Resolve a usable storefront port.\n *\n * The headline `nymbal dev` flow must not hard-fail when the preferred port is\n * already taken (a developer commonly has another project on 4321/3000). We\n * probe the preferred port first and, if it is busy, increment until we find a\n * free one — exactly how the underlying dev servers (Astro, Next.js) behave on\n * their own, but here we resolve the port *before* spawning so we can tell the\n * storefront which port to bind and tell the user where to open the browser.\n */\nexport async function isPortFree(port: number, host?: string): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const server = createServer()\n server.once('error', (err: NodeJS.ErrnoException) => {\n // EADDRINUSE / EACCES → not usable. Any other error → treat as not free\n // rather than silently swallowing it; the caller will skip this port.\n if (err.code !== 'EADDRINUSE' && err.code !== 'EACCES') {\n // eslint-disable-next-line no-console\n console.error(`[dev] unexpected error probing port ${port}:`, err.message)\n }\n resolve(false)\n })\n server.once('listening', () => {\n server.close(() => resolve(true))\n })\n // Bind across all interfaces (no explicit host) so a port already held on\n // IPv6 (e.g. another dev server on [::1]) is correctly seen as busy. A\n // 127.0.0.1-only probe would miss an IPv6 listener and wrongly report free,\n // then the framework — which binds dual-stack — would fail on that port.\n if (host) {\n server.listen(port, host)\n } else {\n server.listen(port)\n }\n })\n}\n\n/**\n * Find a free port starting at `preferred`, scanning upward up to `maxAttempts`\n * times. Throws an actionable error if no port in the range is free.\n */\nexport async function findFreePort(\n preferred: number,\n maxAttempts = 20,\n host?: string,\n): Promise<number> {\n if (!Number.isInteger(preferred) || preferred < 1 || preferred > 65535) {\n throw new Error(\n `Invalid storefront port \"${preferred}\". Set a valid port (1–65535) via --storefront-port or NYMBAL_STOREFRONT_PORT.`,\n )\n }\n for (let i = 0; i < maxAttempts; i++) {\n const candidate = preferred + i\n if (candidate > 65535) break\n if (await isPortFree(candidate, host)) {\n return candidate\n }\n }\n throw new Error(\n `No free storefront port found in range ${preferred}–${Math.min(preferred + maxAttempts - 1, 65535)}. ` +\n `Free a port in that range or pass an explicit free port via --storefront-port.`,\n )\n}\n","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { NymbalConfig } from '@nymbalhq/config'\n\nexport type TemplateName = 'astro' | 'nextjs'\n\nexport interface TemplateLaunch {\n /** Working directory the storefront dev server runs in. */\n cwd: string\n /** Command + args to start the storefront dev server. */\n command: string\n args: string[]\n /**\n * How the storefront was located. `flat` = the project root IS the storefront\n * (create-nymbal-app output). `filter` = a sub-package in a monorepo layout.\n */\n mode: 'flat' | 'filter'\n}\n\nexport function templateFilterFor(template: NymbalConfig['template']): string {\n return template === 'astro' ? '@nymbalhq/template-astro' : '@nymbalhq/template-nextjs'\n}\n\n/**\n * A flat scaffold (create-nymbal-app output) places the storefront AT the\n * project root: the framework config and a `dev` script live in projectRoot.\n * In that layout we must run the dev server in projectRoot directly — NOT via\n * `pnpm --filter @nymbalhq/template-astro`, which would match the workspace\n * template package (the wrong directory) inside a monorepo, or match nothing at\n * all outside one.\n */\nexport function isFlatScaffold(projectRoot: string, template: TemplateName): boolean {\n const marker = template === 'astro' ? 'astro.config.mjs' : 'next.config.mjs'\n const altMarker = template === 'astro' ? 'astro.config.ts' : 'next.config.ts'\n return existsSync(resolve(projectRoot, marker)) || existsSync(resolve(projectRoot, altMarker))\n}\n\n/**\n * Resolve the framework's local CLI bin inside the project's node_modules.\n * We spawn the local bin directly (rather than the package-manager `run dev`\n * script) so we can inject the resolved free port via `--port`, overriding the\n * hardcoded port baked into the scaffold's `dev` script. Returns null when the\n * bin is not present (deps not installed) so the caller can produce an\n * actionable error.\n */\nexport function resolveLocalBin(projectRoot: string, bin: string): string | null {\n const binPath = resolve(projectRoot, 'node_modules', '.bin', bin)\n return existsSync(binPath) ? binPath : null\n}\n\n/**\n * Build the storefront dev launch plan.\n *\n * @param storefrontPort - the resolved (free) port the storefront must bind to.\n * Passed to the framework via flag so we control where it listens, instead of\n * relying on the framework's hardcoded default which may already be taken.\n */\nexport function planTemplateLaunch(\n projectRoot: string,\n template: TemplateName,\n storefrontPort: number,\n): TemplateLaunch {\n if (isFlatScaffold(projectRoot, template)) {\n // Run the framework dev server directly in the project root. We pass the\n // port explicitly so the framework binds where we resolved a free port,\n // overriding any hardcoded port in the scaffold's package.json script.\n const binName = template === 'astro' ? 'astro' : 'next'\n const localBin = resolveLocalBin(projectRoot, binName)\n if (!localBin) {\n throw new Error(\n `Cannot find the ${binName} dev server in ${projectRoot}/node_modules/.bin. ` +\n `Install dependencies first (e.g. \\`pnpm install\\`), then re-run \\`nymbal dev\\`.`,\n )\n }\n return {\n cwd: projectRoot,\n command: localBin,\n args: ['dev', '--port', String(storefrontPort), ...foregroundArgs(template)],\n mode: 'flat',\n }\n }\n\n // Monorepo layout fallback: the storefront lives in a workspace sub-package.\n const filter = templateFilterFor(template)\n return {\n cwd: projectRoot,\n command: 'pnpm',\n args: ['--filter', filter, 'dev', ...foregroundArgs(template)],\n mode: 'filter',\n }\n}\n\n/**\n * Astro 7 backgrounds `astro dev` when it detects an AI agent, so the launcher would see its child exit while the\n * server lives on detached; --ignore-lock keeps it in the foreground. `next dev` rejects unknown options.\n */\nfunction foregroundArgs(template: TemplateName): string[] {\n return template === 'astro' ? ['--ignore-lock'] : []\n}\n","import { defineCommand } from 'citty'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport { loadProject } from '../utils/project.js'\nimport { createCommandStore, runMigrations } from '@nymbalhq/platform'\nimport { dirname, resolve } from 'node:path'\nimport { existsSync } from 'node:fs'\n\nexport const migrateCommand = defineCommand({\n meta: { name: 'migrate', description: 'Run database migrations (Drizzle)' },\n async run() {\n const { config, projectRoot } = await loadProject()\n const kind = await migrateProject(config, projectRoot)\n // eslint-disable-next-line no-console\n console.log(`✓ migrations applied (${kind})`)\n },\n})\n\n/** Applies the project's migrations to its command store; the store is closed again before returning. */\nexport async function migrateProject(config: NymbalConfig, projectRoot: string): Promise<string> {\n const store = createCommandStore(config)\n try {\n await runMigrations(store, { migrationsRoot: resolveMigrations(projectRoot) })\n return store.kind\n } finally {\n await store.close()\n }\n}\n\nexport function resolveMigrations(projectRoot: string): string {\n // 1. Project-local override (scaffolded projects or custom migrations)\n const local = resolve(projectRoot, 'migrations')\n if (existsSync(local)) return local\n\n // 2. Monorepo workspace: packages/platform/migrations (for CI and fresh clones)\n const monorepoDev = resolve(projectRoot, 'packages/platform/migrations')\n if (existsSync(monorepoDev)) return monorepoDev\n\n // 3. Published package: node_modules/@nymbalhq/platform/migrations\n //\n // We must NOT use `require.resolve('@nymbalhq/platform/package.json')` nor\n // `require.resolve('@nymbalhq/platform')`: the package's `exports` map is\n // ESM-only and does not expose `./package.json`, so CJS resolution throws\n // (ERR_PACKAGE_PATH_NOT_EXPORTED / \"No exports main defined\"). Instead we\n // locate the installed package directory directly under node_modules, which\n // is independent of the exports map and works for symlinked (pnpm workspace)\n // and flat installs alike.\n const pkgDir = resolvePackageDir(projectRoot, '@nymbalhq/platform')\n if (pkgDir) {\n const pkgMigrations = resolve(pkgDir, 'migrations')\n if (existsSync(pkgMigrations)) return pkgMigrations\n }\n\n return local\n}\n\n/**\n * Resolve the on-disk root directory of an installed package from `fromRoot`,\n * by walking up the directory tree looking for `node_modules/<pkgName>`. This\n * does not depend on the package's `exports` map (which may be ESM-only and not\n * expose `./package.json`), and resolves correctly for pnpm symlinked workspace\n * installs as well as flat node_modules. Returns null when not found.\n */\nexport function resolvePackageDir(fromRoot: string, pkgName: string): string | null {\n let dir = resolve(fromRoot)\n for (let i = 0; i < 24; i++) {\n const candidate = resolve(dir, 'node_modules', pkgName)\n if (existsSync(resolve(candidate, 'package.json'))) {\n return candidate\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { dirname, join } from 'node:path'\n\nfunction hasIndex(dir: string): boolean {\n return existsSync(join(dir, 'index.html'))\n}\n\n/**\n * The admin dist to serve: `NYMBAL_ADMIN_DIST` when it holds `index.html` (read per call), else the installed\n * `@nymbalhq/admin` dist when built, else null.\n */\nexport function resolveAdminRoot(): string | null {\n const override = process.env['NYMBAL_ADMIN_DIST']\n if (override && hasIndex(override)) return override\n try {\n const manifest = createRequire(import.meta.url).resolve('@nymbalhq/admin/package.json')\n const dist = join(dirname(manifest), 'dist')\n return hasIndex(dist) ? dist : null\n } catch {\n return null\n }\n}\n","/**\n * The CLI's own bound on a signal shutdown. Below the E2E wrapper's `DEFAULT_SHUTDOWN_MS` (`scripts/e2e-server.mjs`),\n * so the pending step is logged before the wrapper's SIGKILL lands.\n */\nexport const SHUTDOWN_BOUND_MS = 3000\n\nexport interface ShutdownStep {\n name: string\n run: () => Promise<void>\n}\n\nexport interface ShutdownOptions {\n boundMs: number\n logger: { info: (obj: unknown, msg?: string) => void; error: (obj: unknown, msg?: string) => void }\n exit: (code: number) => never\n}\n\nlet running = false\n\n/**\n * Runs the steps in order, then exits 0. A step that throws is logged and the rest still run, then it exits 1. A step\n * still pending at `boundMs` is named in the log and it exits 1, so no client can hold the process open. A second call\n * while one runs (a repeat signal) exits 1 at once.\n */\nexport async function runShutdown(steps: ShutdownStep[], opts: ShutdownOptions): Promise<never> {\n if (running) {\n opts.logger.error({}, 'Shutdown already running; exiting now')\n return opts.exit(1)\n }\n running = true\n\n let pending: string | undefined\n let failed = false\n const work = (async () => {\n for (const step of steps) {\n pending = step.name\n try {\n await step.run()\n } catch (err) {\n failed = true\n opts.logger.error({ err, step: step.name }, `Shutdown step \"${step.name}\" failed`)\n }\n }\n pending = undefined\n })()\n\n let timer: ReturnType<typeof setTimeout> | undefined\n const bound = new Promise<'bound'>((resolve) => {\n timer = setTimeout(() => resolve('bound'), opts.boundMs)\n })\n const outcome = await Promise.race([work.then(() => 'done' as const), bound])\n clearTimeout(timer)\n\n if (outcome === 'bound') {\n opts.logger.error(\n { step: pending, boundMs: opts.boundMs },\n `Shutdown step \"${pending}\" did not finish within ${opts.boundMs} ms; exiting`,\n )\n return opts.exit(1)\n }\n return opts.exit(failed ? 1 : 0)\n}\n","import { defineCommand } from 'citty'\nimport { loadProject } from '../utils/project.js'\nimport { runOrFail } from '../utils/spawn.js'\nimport { isFlatScaffold, resolveLocalBin, templateFilterFor } from '../utils/template-runner.js'\n\nexport const buildCommand = defineCommand({\n meta: { name: 'build', description: 'Production build of the configured template' },\n async run() {\n const { config, projectRoot } = await loadProject()\n if (!isFlatScaffold(projectRoot, config.template)) {\n // Inside this monorepo the storefront is a workspace package.\n await runOrFail('pnpm', ['--filter', templateFilterFor(config.template), 'build'], {\n cwd: projectRoot,\n })\n return\n }\n const binName = config.template === 'astro' ? 'astro' : 'next'\n const bin = resolveLocalBin(projectRoot, binName)\n if (!bin) {\n throw new Error(\n `Cannot find the ${binName} binary in ${projectRoot}/node_modules/.bin. ` +\n 'Install dependencies first, then re-run `nymbal build`.',\n )\n }\n await runOrFail(bin, ['build'], { cwd: projectRoot })\n },\n})\n","import { defineCommand } from 'citty'\nimport { loadProject } from '../utils/project.js'\nimport { createPlatform, runSeed } from '@nymbalhq/platform'\nimport { getCliVersion } from '../utils/version.js'\nimport { migrateProject } from './migrate.js'\n\nexport const seedCommand = defineCommand({\n meta: { name: 'seed', description: 'Re-seed demo content (products, categories)' },\n async run() {\n const { config, projectRoot } = await loadProject()\n // A fresh project has no tables yet; `nymbal dev` migrates before it seeds, and so does this.\n await migrateProject(config, projectRoot)\n const platform = createPlatform(config)\n try {\n const result = await runSeed({\n config,\n commandStore: platform.commandStore,\n documentStore: platform.documentStore,\n eventBus: platform.eventBus,\n logger: platform.logger,\n version: getCliVersion(),\n })\n // eslint-disable-next-line no-console\n console.log(\n result.alreadySeeded\n ? '✓ demo content already present, nothing to seed'\n : `✓ seeded ${result.products} products across ${result.categories} categories`,\n )\n } finally {\n await platform.close()\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport { intro, outro, text, select, spinner, isCancel, cancel } from '@clack/prompts'\nimport * as p from 'picocolors'\nimport { loadProject } from '../utils/project.js'\nimport { createApp } from '@nymbalhq/platform'\nimport { runWooCommerceImport, writeReport, type ImportEntity, type ProgressEvent } from '@nymbalhq/importers'\nimport { join } from 'node:path'\nimport { getCliVersion } from '../utils/version.js'\n\nexport const importCommand = defineCommand({\n meta: {\n name: 'import',\n description: 'Migrate content from WooCommerce (or other sources) into Nymbal',\n },\n args: {\n source: {\n type: 'string',\n description: 'Import source (woocommerce)',\n },\n url: {\n type: 'string',\n description: 'Store URL (e.g. https://mystore.com)',\n },\n key: {\n type: 'string',\n description: 'WooCommerce Consumer Key (or set WOOCOMMERCE_KEY env var)',\n },\n secret: {\n type: 'string',\n description: 'WooCommerce Consumer Secret (or set WOOCOMMERCE_SECRET env var)',\n },\n entities: {\n type: 'string',\n description: 'Comma-separated list: products,customers,orders,reviews (default: products,customers,orders)',\n },\n ai: {\n type: 'boolean',\n description: 'Enable AI enrichment (default: true)',\n default: true,\n },\n gdpr: {\n type: 'boolean',\n description: 'Anonymise customer PII (default: true)',\n default: true,\n },\n fresh: {\n type: 'boolean',\n description: 'Ignore previous progress and re-import',\n default: false,\n },\n concurrency: {\n type: 'string',\n description: 'Parallel import workers (default: 4)',\n },\n },\n async run({ args }) {\n const { config } = await loadProject()\n const projectRoot = process.cwd()\n const statePath = join(projectRoot, '.nymbal-migration.json')\n const isTTY = process.stdin.isTTY ?? false\n\n intro(p.bold('Nymbal Import'))\n\n // ── Resolve source ────────────────────────────────────────────────────────\n let source = args.source\n if (!source) {\n if (!isTTY) {\n console.error('--source is required (woocommerce)')\n process.exit(1)\n }\n const picked = await select({\n message: 'Source platform?',\n options: [{ value: 'woocommerce', label: 'WooCommerce' }],\n })\n if (isCancel(picked)) { cancel('Import cancelled'); process.exit(0) }\n source = String(picked)\n }\n if (source !== 'woocommerce') {\n console.error(`Unsupported source: ${source}. Only 'woocommerce' is supported.`)\n process.exit(1)\n }\n\n // ── Resolve credentials ───────────────────────────────────────────────────\n let storeUrl = args.url\n if (!storeUrl) {\n if (!isTTY) { console.error('--url is required'); process.exit(1) }\n const val = await text({ message: 'Store URL?', placeholder: 'https://mystore.com', validate: (v) => v.startsWith('http') ? undefined : 'Must be a URL' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n storeUrl = String(val)\n }\n\n let consumerKey = args.key ?? process.env['WOOCOMMERCE_KEY'] ?? ''\n if (!consumerKey) {\n if (!isTTY) { console.error('--key or WOOCOMMERCE_KEY is required'); process.exit(1) }\n const val = await text({ message: 'Consumer Key?', placeholder: 'ck_...' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n consumerKey = String(val)\n }\n\n let consumerSecret = args.secret ?? process.env['WOOCOMMERCE_SECRET'] ?? ''\n if (!consumerSecret) {\n if (!isTTY) { console.error('--secret or WOOCOMMERCE_SECRET is required'); process.exit(1) }\n const val = await text({ message: 'Consumer Secret?', placeholder: 'cs_...' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n consumerSecret = String(val)\n }\n\n // ── Resolve entity list ───────────────────────────────────────────────────\n let entityList: ImportEntity[]\n if (args.entities) {\n entityList = args.entities.split(',').map((e) => e.trim()) as ImportEntity[]\n } else {\n entityList = ['categories', 'products', 'customers', 'orders']\n }\n\n const concurrency = parseInt(String(args.concurrency ?? '4'), 10)\n const aiEnabled = args.ai !== false\n const gdprEnabled = args.gdpr !== false\n\n // ── Bootstrap app ─────────────────────────────────────────────────────────\n const loadSpin = spinner()\n loadSpin.start('Starting platform…')\n const app = await createApp(config, { version: getCliVersion() })\n loadSpin.stop('Platform ready')\n\n try {\n const report = await runWooCommerceImport(\n {\n credentials: { url: storeUrl, consumerKey, consumerSecret },\n entities: entityList,\n ai: aiEnabled,\n gdpr: gdprEnabled,\n fresh: args.fresh,\n concurrency,\n projectRoot,\n currency: config.store.currency,\n statePath,\n },\n {\n services: app.services,\n repos: app.repos,\n adapters: { ai: app.adapters.ai, reviews: app.adapters.reviews },\n onProgress(event: ProgressEvent) {\n if (event.kind === 'phase') {\n console.log(p.cyan(` → ${event.phase}`))\n } else if (event.kind === 'progress') {\n const pct = Math.round((event.done / event.total) * 100)\n process.stdout.write(`\\r ${event.entity}: ${event.done}/${event.total} (${pct}%) `)\n if (event.done === event.total) process.stdout.write('\\n')\n } else if (event.kind === 'error') {\n console.log(p.red(` ✗ ${event.phase} [${event.id}]: ${event.message}`))\n }\n },\n },\n )\n\n const reportPath = await writeReport(report, projectRoot, config.store.name)\n\n outro(\n [\n p.green('✓ Import complete'),\n ` Products: ${report.imported.products}`,\n ` Customers: ${report.imported.customers}`,\n ` Orders: ${report.imported.orders}`,\n ` Categories: ${report.imported.categories}`,\n ...(aiEnabled ? [` AI enriched: ${report.enriched.enriched} products`] : []),\n ...(report.errors.length > 0 ? [p.yellow(` ⚠ ${report.errors.length} errors — see report`)] : []),\n ``,\n ` Report: ${reportPath}`,\n ` Next: ${p.bold('nymbal dev')}`,\n ].join('\\n'),\n )\n } finally {\n await app.stop()\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport { loadProject } from '../utils/project.js'\nimport { NymbalError } from '@nymbalhq/types'\n\nexport const configValidateCommand = defineCommand({\n meta: { name: 'config:validate', description: 'Validate nymbal.config.ts' },\n async run() {\n try {\n const { config, path } = await loadProject()\n // eslint-disable-next-line no-console\n console.log(pc.green(`✓ config valid`) + ` (${path})`)\n // eslint-disable-next-line no-console\n console.log(\n ` template: ${config.template}, cloud: ${config.infrastructure.cloud}, commandStore: ${config.infrastructure.commandStore}`,\n )\n process.exit(0)\n } catch (err) {\n if (err instanceof NymbalError) {\n // eslint-disable-next-line no-console\n console.error(pc.red('✗ config invalid'))\n // eslint-disable-next-line no-console\n console.error(err.message)\n } else {\n // eslint-disable-next-line no-console\n console.error(err)\n }\n process.exit(1)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport { loadConfig } from '@nymbalhq/config'\nimport { run, runOrFail } from '../utils/spawn.js'\n\nexport const testCommand = defineCommand({\n meta: { name: 'test', description: 'Run unit + integration tests (vitest)' },\n async run() {\n await runOrFail('pnpm', ['vitest', 'run'])\n },\n})\n\nexport const testE2eCommand = defineCommand({\n meta: { name: 'test:e2e', description: 'Run Playwright E2E against the configured template' },\n async run() {\n const { config } = await loadConfig()\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep-invert', '@visual|@a11y',\n ])\n },\n})\n\nexport const testVisualCommand = defineCommand({\n meta: { name: 'test:visual', description: 'Run visual regression tests (Playwright toHaveScreenshot)' },\n args: {\n 'update-baselines': {\n type: 'boolean',\n description: 'Regenerate screenshot baselines',\n default: false,\n },\n },\n async run({ args }) {\n const { config } = await loadConfig()\n const isCI = !!process.env.CI\n const updateBaselines = args['update-baselines']\n\n if (updateBaselines && !isCI) {\n // Run in Docker for Linux-consistent baselines\n const dockerImage = 'mcr.microsoft.com/playwright:v1.50-jammy'\n const cwd = process.cwd()\n await runOrFail('docker', [\n 'run', '--rm', '-v', `${cwd}:${cwd}`, '-w', cwd,\n dockerImage, 'sh', '-c',\n `pnpm --filter @nymbalhq/e2e exec playwright test --project ${config.template} --grep \"@visual\" --update-snapshots`,\n ])\n } else {\n const pwArgs = [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep', '@visual',\n ]\n if (updateBaselines) pwArgs.push('--update-snapshots')\n await runOrFail('pnpm', pwArgs)\n }\n },\n})\n\nexport const testContractsCommand = defineCommand({\n meta: { name: 'test:contracts', description: 'Run adapter contract tests' },\n args: {\n adapter: { type: 'string', description: 'Run only contracts for a specific adapter (e.g. payments, email)' },\n },\n async run({ args }) {\n const vArgs = [\n 'vitest', 'run',\n '--project', 'contracts-native',\n ]\n if (args.adapter) {\n // Pass the specific file path as additional argument\n vArgs.push(`tests/contracts/${String(args.adapter)}.test.ts`)\n }\n await runOrFail('pnpm', vArgs)\n },\n})\n\nexport const testPerformanceCommand = defineCommand({\n meta: { name: 'test:performance', description: 'Run Lighthouse CI against the configured template' },\n async run() {\n const { config } = await loadConfig()\n const port = config.template === 'nextjs' ? 3000 : 4321\n await runOrFail('pnpm', ['lhci', 'autorun'], {\n env: {\n ...process.env,\n NYMBAL_TEMPLATE: config.template,\n NYMBAL_TEMPLATE_PORT: String(port),\n },\n })\n },\n})\n\nexport const testAllCommand = defineCommand({\n meta: { name: 'test:all', description: 'Run unit, contract, e2e, visual, and performance tests' },\n async run() {\n const steps: Array<{ name: string; args: string[] }> = [\n { name: 'unit', args: ['vitest', 'run'] },\n { name: 'contracts', args: ['vitest', 'run', '--project', 'contracts-native'] },\n ]\n\n for (const step of steps) {\n const { done } = run('pnpm', step.args)\n const code = await done\n if (code !== 0) {\n // eslint-disable-next-line no-console\n console.error(`✗ ${step.name} failed`)\n process.exit(code)\n }\n }\n\n const { config } = await loadConfig()\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep-invert', '@visual|@a11y',\n ])\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep', '@visual',\n ])\n await runOrFail('pnpm', ['lhci', 'autorun'], {\n env: { ...process.env, NYMBAL_TEMPLATE: config.template },\n })\n },\n})\n"],"mappings":"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","names":["defineCommand","defineCommand","dirname","resolve","resolve","existsSync","resolve","dirname","resolve","existsSync","existsSync","dirname","join","resolve","defineCommand","shutdown","defineCommand","defineCommand","defineCommand","runSeed","defineCommand","runSeed","defineCommand","createApp","join","defineCommand","join","createApp","defineCommand","pc","defineCommand","pc","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/version.ts","../src/commands/dev.ts","../src/utils/project.ts","../src/utils/spawn.ts","../src/utils/port.ts","../src/utils/template-runner.ts","../src/commands/migrate.ts","../src/admin.ts","../src/utils/shutdown.ts","../src/commands/dev-summary.ts","../src/commands/build.ts","../src/commands/seed.ts","../src/commands/import.ts","../src/commands/config-validate.ts","../src/commands/add.ts","../src/recipes/holders.ts","../src/recipes/config-edit.ts","../src/recipes/env-example.ts","../src/commands/doctor.ts","../src/commands/doctor-report.ts","../src/commands/secrets.ts","../src/commands/events.ts","../src/commands/audit.ts","../src/commands/replay.ts","../src/commands/security.ts","../src/commands/test.ts","../src/commands/test-contracts.ts"],"sourcesContent":["import { defineCommand, runMain } from 'citty'\nimport { getCliVersion } from './utils/version.js'\nimport { devCommand } from './commands/dev.js'\nimport { buildCommand } from './commands/build.js'\nimport { migrateCommand } from './commands/migrate.js'\nimport { seedCommand } from './commands/seed.js'\nimport { importCommand } from './commands/import.js'\nimport { configValidateCommand } from './commands/config-validate.js'\nimport { addCommand } from './commands/add.js'\nimport { doctorCommand } from './commands/doctor.js'\nimport { secretsCommand } from './commands/secrets.js'\nimport { eventsCommand } from './commands/events.js'\nimport { auditCommand } from './commands/audit.js'\nimport { replayCommand } from './commands/replay.js'\nimport {\n securityApplyCommand,\n securityDriftCommand,\n securityInspectCommand,\n securityPlanCommand,\n} from './commands/security.js'\nimport {\n testAllCommand,\n testCommand,\n testContractsCommand,\n testE2eCommand,\n testPerformanceCommand,\n testVisualCommand,\n} from './commands/test.js'\n\nexport { resolveAdminRoot } from './admin.js'\n\nconst main = defineCommand({\n meta: {\n name: 'nymbal',\n version: getCliVersion(),\n description: 'Nymbal developer CLI',\n },\n subCommands: {\n dev: devCommand,\n build: buildCommand,\n migrate: migrateCommand,\n seed: seedCommand,\n import: importCommand,\n 'config:validate': configValidateCommand,\n add: addCommand,\n doctor: doctorCommand,\n 'security:plan': securityPlanCommand,\n 'security:apply': securityApplyCommand,\n 'security:drift': securityDriftCommand,\n 'security:inspect': securityInspectCommand,\n secrets: secretsCommand,\n events: eventsCommand,\n audit: auditCommand,\n replay: replayCommand,\n test: testCommand,\n 'test:e2e': testE2eCommand,\n 'test:visual': testVisualCommand,\n 'test:contracts': testContractsCommand,\n 'test:performance': testPerformanceCommand,\n 'test:all': testAllCommand,\n },\n})\n\n// citty prints --version through consola, which prefixes `[log]` when CI is set; scripts need the bare version.\nconst [flag, ...rest] = process.argv.slice(2)\nif (rest.length === 0 && (flag === '--version' || flag === '-v')) {\n process.stdout.write(`${getCliVersion()}\\n`)\n} else {\n runMain(main)\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst CLI_PACKAGE_NAME = 'nymbal'\n\nlet cached: string | null = null\n\n/**\n * Walks up from this module to the CLI's own package.json (found by name, so a nested or unrelated package.json\n * never answers). That is `dist/` in the workspace and in `node_modules/nymbal`, and `src/utils/` under Vitest.\n */\nfunction readOwnVersion(): string | undefined {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as {\n name?: string\n version?: string\n }\n if (pkg.name === CLI_PACKAGE_NAME) return pkg.version\n } catch {\n // No readable package.json in this directory: keep walking.\n }\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport function getCliVersion(): string {\n cached ??= readOwnVersion() ?? '0.0.0'\n return cached\n}\n","import { resolve } from 'node:path'\nimport { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport { KNOWN_PROVIDERS, type NymbalConfig } from '@nymbalhq/config'\nimport type { CommerceSlot } from '@nymbalhq/types'\nimport { loadProject } from '../utils/project.js'\nimport { createApp, createLogger, runSeed, sqliteFile, type NymbalApp } from '@nymbalhq/platform'\nimport { createHttpServer } from '@nymbalhq/http'\nimport { run } from '../utils/spawn.js'\nimport { getCliVersion } from '../utils/version.js'\nimport { findFreePort } from '../utils/port.js'\nimport { planTemplateLaunch } from '../utils/template-runner.js'\nimport { migrateProject } from './migrate.js'\nimport { resolveAdminRoot } from '../admin.js'\nimport { runShutdown, SHUTDOWN_BOUND_MS, type ShutdownStep } from '../utils/shutdown.js'\nimport { renderDevSummary, type DevSummaryInfo } from './dev-summary.js'\n\n/** Default storefront dev-server port per template (matches the scaffold scripts). */\nexport function defaultStorefrontPort(template: 'astro' | 'nextjs'): number {\n return template === 'astro' ? 4321 : 3000\n}\n\n/**\n * Resolve the *preferred* storefront port from (in priority order):\n * 1. --storefront-port flag\n * 2. NYMBAL_STOREFRONT_PORT env var\n * 3. the template default (Astro 4321 / Next.js 3000)\n * The value returned here is only the starting point; the dev command then\n * probes upward for a genuinely free port so a busy default never hard-fails.\n */\nexport function preferredStorefrontPort(\n template: 'astro' | 'nextjs',\n flagPort: number | undefined,\n env: NodeJS.ProcessEnv,\n): number {\n if (typeof flagPort === 'number' && Number.isFinite(flagPort)) return flagPort\n const fromEnv = env['NYMBAL_STOREFRONT_PORT']\n if (fromEnv && fromEnv.trim() !== '') {\n const parsed = Number(fromEnv)\n if (Number.isInteger(parsed) && parsed > 0) return parsed\n }\n return defaultStorefrontPort(template)\n}\n\n/**\n * The environment the storefront dev server starts with. The client-side variables must be set before it starts. It\n * says nothing about the adapters: a storefront learns what the store can do from GET /api/capabilities.\n */\nexport function storefrontEnv(\n _config: NymbalConfig,\n apiUrl: string,\n storefrontPort: number,\n baseEnv: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n return {\n ...baseEnv,\n NYMBAL_API_URL: apiUrl,\n PUBLIC_NYMBAL_API_URL: apiUrl, // Astro\n NEXT_PUBLIC_NYMBAL_API_URL: apiUrl, // Next.js\n // The framework also reads the port flag; the env var keeps the scaffold\n // config (astro.config.mjs) in sync when it honours NYMBAL_STOREFRONT_PORT.\n NYMBAL_STOREFRONT_PORT: String(storefrontPort),\n }\n}\n\n/** dev logs at info, so it prints the summary and not every projection; `LOG_LEVEL` wins over `--verbose`. */\nexport function devLogLevel(verbose: boolean, env: NodeJS.ProcessEnv): string {\n const fromEnv = env['LOG_LEVEL']\n if (fromEnv !== undefined && fromEnv !== '') return fromEnv\n return verbose ? 'debug' : 'info'\n}\n\n/** The summary's facts, from the running app: no URL here carries anything but what the config gave. */\nfunction summaryInfo(\n config: NymbalConfig,\n app: NymbalApp,\n apiUrl: string,\n storefront: DevSummaryInfo['storefront'],\n adminBuilt: boolean,\n): DevSummaryInfo {\n const report = app.capabilities()\n return {\n store: config.store.name,\n apiUrl,\n storefront,\n admin: adminBuilt ? { url: `${apiUrl}/admin/` } : null,\n commandStore:\n config.infrastructure.commandStore === 'sqlite'\n ? { kind: 'sqlite', path: resolve(sqliteFile()) }\n : { kind: 'postgres', url: process.env['DATABASE_URL'] ?? '' },\n slots: (Object.keys(KNOWN_PROVIDERS) as CommerceSlot[]).map((slot) => ({\n slot,\n provider: report[slot].provider,\n capabilities: report[slot].capabilities,\n })),\n primitives: (['documentStore', 'eventBus', 'media'] as const).map((name) => ({\n name,\n provider: report[name].provider,\n })),\n }\n}\n\n/** The API port: `--port` when given, else the config's `http.port`. */\nfunction apiPort(config: NymbalConfig, flagPort: string | undefined): number {\n if (flagPort === undefined || flagPort.trim() === '') return config.http.port\n const port = Number(flagPort)\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`--port must be an integer from 1 to 65535, got \"${flagPort}\"`)\n }\n return port\n}\n\nexport const devCommand = defineCommand({\n meta: {\n name: 'dev',\n description: 'Start the API server and the configured storefront template with HMR',\n },\n args: {\n seed: {\n type: 'boolean',\n description: 'Run seed before starting (default: true if empty)',\n default: true,\n },\n apiOnly: {\n type: 'boolean',\n // `alias` is required: citty 0.1.6 registers the camelCase key `apiOnly`\n // with mri and applies `default: false`. Without this alias a kebab\n // `--api-only` flag lands on `args['api-only']`, but `args.apiOnly`\n // resolves to the `false` default first (`??` does not fall through on\n // `false`), so the flag is silently ignored. The alias makes mri map\n // `--api-only` straight to `apiOnly`. Both forms now work.\n alias: 'api-only',\n description: 'Start only the API server (skip template dev server)',\n default: false,\n },\n port: {\n type: 'string',\n description: \"Port for the API server (default: the config's http.port)\",\n },\n storefrontPort: {\n type: 'string',\n alias: 'storefront-port',\n description:\n 'Port for the storefront dev server (default: 4321 Astro / 3000 Next.js). ' +\n 'If busy, the next free port is used. Also settable via NYMBAL_STOREFRONT_PORT.',\n },\n verbose: {\n type: 'boolean',\n description: 'Log at debug (LOG_LEVEL, when set, wins)',\n default: false,\n },\n },\n async run({ args }) {\n const loaded = await loadProject()\n const { projectRoot } = loaded\n const port = apiPort(loaded.config, args.port)\n const config: NymbalConfig = { ...loaded.config, http: { ...loaded.config.http, port } }\n const version = getCliVersion()\n\n // Auto-migrate on startup so a fresh clone works without running `nymbal migrate` first\n await migrateProject(config, projectRoot)\n\n const logger = createLogger({\n base: { store: config.store.name },\n level: devLogLevel(args.verbose, process.env),\n })\n const app = await createApp(config, {\n version,\n logger,\n ...(loaded.adapters !== undefined && { adapters: loaded.adapters }),\n })\n const { platform } = app\n\n if (args.seed) {\n const existing = await platform.documentStore.query('products', {\n partitionKey: { field: 'storeId', value: config.store.name },\n limit: 1,\n })\n if (existing.items.length === 0) {\n platform.logger.info({}, 'Seeding demo content (first run)')\n await runSeed({\n config,\n commandStore: platform.commandStore,\n documentStore: platform.documentStore,\n eventBus: platform.eventBus,\n logger: platform.logger,\n version,\n search: app.adapters.search,\n })\n }\n }\n\n const http = createHttpServer({\n config,\n logger: platform.logger,\n documentStore: platform.documentStore,\n version,\n })\n const adminRoot = resolveAdminRoot()\n await app.attachHttp(http.adapter, { adminRoot })\n await http.start()\n const apiUrl = `http://localhost:${config.http.port}`\n const printSummary = (storefront: DevSummaryInfo['storefront']) => {\n // eslint-disable-next-line no-console\n console.log(\n renderDevSummary(summaryInfo(config, app, apiUrl, storefront, adminRoot !== null)),\n )\n }\n\n const stopApi: ShutdownStep[] = [\n { name: 'http.stop', run: () => http.stop() },\n { name: 'app.stop', run: () => app.stop() },\n ]\n const shutdownWith = (steps: ShutdownStep[]): Promise<never> =>\n runShutdown(steps, {\n boundMs: SHUTDOWN_BOUND_MS,\n logger: platform.logger,\n exit: (code) => process.exit(code),\n })\n\n if (args.apiOnly) {\n printSummary(null)\n const shutdown = (signal: string) => {\n platform.logger.info({ signal }, 'Shutting down API')\n return shutdownWith(stopApi)\n }\n process.on('SIGINT', () => void shutdown('SIGINT'))\n process.on('SIGTERM', () => void shutdown('SIGTERM'))\n // Keep process alive — Playwright webServer will kill it when done\n return\n }\n\n // Resolve a free storefront port. The preferred port is configurable but may\n // be taken (a developer commonly has another project on 4321/3000), so we\n // probe upward for a free one instead of hard-failing.\n const flagPortRaw = args.storefrontPort\n const flagPort =\n typeof flagPortRaw === 'string' && flagPortRaw.trim() !== '' ? Number(flagPortRaw) : undefined\n const preferred = preferredStorefrontPort(config.template, flagPort, process.env)\n const storefrontPort = await findFreePort(preferred)\n if (storefrontPort !== preferred) {\n // eslint-disable-next-line no-console\n console.log(\n pc.yellow(\n `→ Storefront port ${preferred} is busy; using free port ${pc.bold(String(storefrontPort))} instead.`,\n ),\n )\n }\n\n // Plan how to launch the storefront. A flat scaffold (create-nymbal-app\n // output) runs the framework dev server directly in the project root; a\n // monorepo layout falls back to a pnpm --filter on the template package.\n const launch = planTemplateLaunch(projectRoot, config.template, storefrontPort)\n\n const storefrontUrl = `http://localhost:${storefrontPort}`\n const templateProc = run(launch.command, launch.args, {\n cwd: launch.cwd,\n env: storefrontEnv(config, apiUrl, storefrontPort),\n })\n printSummary({ template: `${config.template}, ${launch.mode}`, url: storefrontUrl })\n\n let shuttingDown = false\n const shutdown = (signal: string) => {\n shuttingDown = true\n platform.logger.info({ signal }, 'Shutting down')\n return shutdownWith([\n {\n name: 'storefront.kill',\n run: async () => {\n templateProc.child.kill('SIGINT')\n },\n },\n ...stopApi,\n ])\n }\n process.on('SIGINT', () => void shutdown('SIGINT'))\n process.on('SIGTERM', () => void shutdown('SIGTERM'))\n\n const templateExit = await templateProc.done\n platform.logger.info({ code: templateExit }, 'Template process exited')\n // A Ctrl-C reaches the storefront too, so it exits during the signal's own shutdown, which ends the process.\n // Calling `runShutdown` again would count as a repeat signal and exit 1 at once.\n if (shuttingDown) return\n await shutdown('template-exit')\n },\n})\n","import { existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { findConfigFile, loadConfig, type LoadedConfig } from '@nymbalhq/config'\n\n/**\n * Loads `<projectRoot>/.env` into the process environment, then the project's config, so `env()` calls in\n * `nymbal.config.ts` see it. A variable already set in the environment is kept: `process.loadEnvFile` never overrides.\n */\nexport async function loadProject(startDir: string = process.cwd()): Promise<LoadedConfig> {\n const configPath = findConfigFile(startDir)\n if (configPath) {\n const envFile = resolve(dirname(configPath), '.env')\n if (existsSync(envFile)) process.loadEnvFile(envFile)\n }\n return loadConfig(startDir)\n}\n","import { spawn, type ChildProcess, type SpawnOptions } from 'node:child_process'\n\nexport interface RunOptions extends SpawnOptions {\n name?: string\n}\n\nexport function run(\n command: string,\n args: string[],\n options: RunOptions = {},\n): { child: ChildProcess; done: Promise<number> } {\n const child = spawn(command, args, {\n stdio: 'inherit',\n shell: false,\n ...options,\n })\n const done = new Promise<number>((resolve, reject) => {\n child.on('error', reject)\n child.on('exit', (code) => resolve(code ?? 0))\n })\n return { child, done }\n}\n\nexport async function runOrFail(\n command: string,\n args: string[],\n options: RunOptions = {},\n): Promise<void> {\n const { done } = run(command, args, options)\n const code = await done\n if (code !== 0) {\n throw new Error(`${command} ${args.join(' ')} exited with code ${code}`)\n }\n}\n","import { createServer } from 'node:net'\n\n/**\n * Resolve a usable storefront port.\n *\n * The headline `nymbal dev` flow must not hard-fail when the preferred port is\n * already taken (a developer commonly has another project on 4321/3000). We\n * probe the preferred port first and, if it is busy, increment until we find a\n * free one — exactly how the underlying dev servers (Astro, Next.js) behave on\n * their own, but here we resolve the port *before* spawning so we can tell the\n * storefront which port to bind and tell the user where to open the browser.\n */\nexport async function isPortFree(port: number, host?: string): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const server = createServer()\n server.once('error', (err: NodeJS.ErrnoException) => {\n // EADDRINUSE / EACCES → not usable. Any other error → treat as not free\n // rather than silently swallowing it; the caller will skip this port.\n if (err.code !== 'EADDRINUSE' && err.code !== 'EACCES') {\n // eslint-disable-next-line no-console\n console.error(`[dev] unexpected error probing port ${port}:`, err.message)\n }\n resolve(false)\n })\n server.once('listening', () => {\n server.close(() => resolve(true))\n })\n // Bind across all interfaces (no explicit host) so a port already held on\n // IPv6 (e.g. another dev server on [::1]) is correctly seen as busy. A\n // 127.0.0.1-only probe would miss an IPv6 listener and wrongly report free,\n // then the framework — which binds dual-stack — would fail on that port.\n if (host) {\n server.listen(port, host)\n } else {\n server.listen(port)\n }\n })\n}\n\n/**\n * Find a free port starting at `preferred`, scanning upward up to `maxAttempts`\n * times. Throws an actionable error if no port in the range is free.\n */\nexport async function findFreePort(\n preferred: number,\n maxAttempts = 20,\n host?: string,\n): Promise<number> {\n if (!Number.isInteger(preferred) || preferred < 1 || preferred > 65535) {\n throw new Error(\n `Invalid storefront port \"${preferred}\". Set a valid port (1–65535) via --storefront-port or NYMBAL_STOREFRONT_PORT.`,\n )\n }\n for (let i = 0; i < maxAttempts; i++) {\n const candidate = preferred + i\n if (candidate > 65535) break\n if (await isPortFree(candidate, host)) {\n return candidate\n }\n }\n throw new Error(\n `No free storefront port found in range ${preferred}–${Math.min(preferred + maxAttempts - 1, 65535)}. ` +\n `Free a port in that range or pass an explicit free port via --storefront-port.`,\n )\n}\n","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { NymbalConfig } from '@nymbalhq/config'\n\nexport type TemplateName = 'astro' | 'nextjs'\n\nexport interface TemplateLaunch {\n /** Working directory the storefront dev server runs in. */\n cwd: string\n /** Command + args to start the storefront dev server. */\n command: string\n args: string[]\n /**\n * How the storefront was located. `flat` = the project root IS the storefront\n * (create-nymbal-app output). `filter` = a sub-package in a monorepo layout.\n */\n mode: 'flat' | 'filter'\n}\n\nexport function templateFilterFor(template: NymbalConfig['template']): string {\n return template === 'astro' ? '@nymbalhq/template-astro' : '@nymbalhq/template-nextjs'\n}\n\n/**\n * A flat scaffold (create-nymbal-app output) places the storefront AT the\n * project root: the framework config and a `dev` script live in projectRoot.\n * In that layout we must run the dev server in projectRoot directly — NOT via\n * `pnpm --filter @nymbalhq/template-astro`, which would match the workspace\n * template package (the wrong directory) inside a monorepo, or match nothing at\n * all outside one.\n */\nexport function isFlatScaffold(projectRoot: string, template: TemplateName): boolean {\n const marker = template === 'astro' ? 'astro.config.mjs' : 'next.config.mjs'\n const altMarker = template === 'astro' ? 'astro.config.ts' : 'next.config.ts'\n return existsSync(resolve(projectRoot, marker)) || existsSync(resolve(projectRoot, altMarker))\n}\n\n/**\n * Resolve the framework's local CLI bin inside the project's node_modules.\n * We spawn the local bin directly (rather than the package-manager `run dev`\n * script) so we can inject the resolved free port via `--port`, overriding the\n * hardcoded port baked into the scaffold's `dev` script. Returns null when the\n * bin is not present (deps not installed) so the caller can produce an\n * actionable error.\n */\nexport function resolveLocalBin(projectRoot: string, bin: string): string | null {\n const binPath = resolve(projectRoot, 'node_modules', '.bin', bin)\n return existsSync(binPath) ? binPath : null\n}\n\n/**\n * Build the storefront dev launch plan.\n *\n * @param storefrontPort - the resolved (free) port the storefront must bind to.\n * Passed to the framework via flag so we control where it listens, instead of\n * relying on the framework's hardcoded default which may already be taken.\n */\nexport function planTemplateLaunch(\n projectRoot: string,\n template: TemplateName,\n storefrontPort: number,\n): TemplateLaunch {\n if (isFlatScaffold(projectRoot, template)) {\n // Run the framework dev server directly in the project root. We pass the\n // port explicitly so the framework binds where we resolved a free port,\n // overriding any hardcoded port in the scaffold's package.json script.\n const binName = template === 'astro' ? 'astro' : 'next'\n const localBin = resolveLocalBin(projectRoot, binName)\n if (!localBin) {\n throw new Error(\n `Cannot find the ${binName} dev server in ${projectRoot}/node_modules/.bin. ` +\n `Install dependencies first (e.g. \\`pnpm install\\`), then re-run \\`nymbal dev\\`.`,\n )\n }\n return {\n cwd: projectRoot,\n command: localBin,\n args: ['dev', '--port', String(storefrontPort), ...foregroundArgs(template)],\n mode: 'flat',\n }\n }\n\n // Monorepo layout fallback: the storefront lives in a workspace sub-package.\n const filter = templateFilterFor(template)\n return {\n cwd: projectRoot,\n command: 'pnpm',\n args: ['--filter', filter, 'dev', ...foregroundArgs(template)],\n mode: 'filter',\n }\n}\n\n/**\n * Astro 7 backgrounds `astro dev` when it detects an AI agent, so the launcher would see its child exit while the\n * server lives on detached; --ignore-lock keeps it in the foreground. `next dev` rejects unknown options.\n */\nfunction foregroundArgs(template: TemplateName): string[] {\n return template === 'astro' ? ['--ignore-lock'] : []\n}\n","import { defineCommand } from 'citty'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport { loadProject } from '../utils/project.js'\nimport { createCommandStore, runMigrations } from '@nymbalhq/platform'\nimport { dirname, resolve } from 'node:path'\nimport { existsSync } from 'node:fs'\n\nexport const migrateCommand = defineCommand({\n meta: { name: 'migrate', description: 'Run database migrations (Drizzle)' },\n async run() {\n const { config, projectRoot } = await loadProject()\n const kind = await migrateProject(config, projectRoot)\n // eslint-disable-next-line no-console\n console.log(`✓ migrations applied (${kind})`)\n },\n})\n\n/** Applies the project's migrations to its command store; the store is closed again before returning. */\nexport async function migrateProject(config: NymbalConfig, projectRoot: string): Promise<string> {\n const store = createCommandStore(config)\n try {\n await runMigrations(store, { migrationsRoot: resolveMigrations(projectRoot) })\n return store.kind\n } finally {\n await store.close()\n }\n}\n\nexport function resolveMigrations(projectRoot: string): string {\n // 1. Project-local override (scaffolded projects or custom migrations)\n const local = resolve(projectRoot, 'migrations')\n if (existsSync(local)) return local\n\n // 2. Monorepo workspace: packages/platform/migrations (for CI and fresh clones)\n const monorepoDev = resolve(projectRoot, 'packages/platform/migrations')\n if (existsSync(monorepoDev)) return monorepoDev\n\n // 3. Published package: node_modules/@nymbalhq/platform/migrations\n //\n // We must NOT use `require.resolve('@nymbalhq/platform/package.json')` nor\n // `require.resolve('@nymbalhq/platform')`: the package's `exports` map is\n // ESM-only and does not expose `./package.json`, so CJS resolution throws\n // (ERR_PACKAGE_PATH_NOT_EXPORTED / \"No exports main defined\"). Instead we\n // locate the installed package directory directly under node_modules, which\n // is independent of the exports map and works for symlinked (pnpm workspace)\n // and flat installs alike.\n const pkgDir = resolvePackageDir(projectRoot, '@nymbalhq/platform')\n if (pkgDir) {\n const pkgMigrations = resolve(pkgDir, 'migrations')\n if (existsSync(pkgMigrations)) return pkgMigrations\n }\n\n return local\n}\n\n/**\n * Resolve the on-disk root directory of an installed package from `fromRoot`,\n * by walking up the directory tree looking for `node_modules/<pkgName>`. This\n * does not depend on the package's `exports` map (which may be ESM-only and not\n * expose `./package.json`), and resolves correctly for pnpm symlinked workspace\n * installs as well as flat node_modules. Returns null when not found.\n */\nexport function resolvePackageDir(fromRoot: string, pkgName: string): string | null {\n let dir = resolve(fromRoot)\n for (let i = 0; i < 24; i++) {\n const candidate = resolve(dir, 'node_modules', pkgName)\n if (existsSync(resolve(candidate, 'package.json'))) {\n return candidate\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { dirname, join } from 'node:path'\n\nfunction hasIndex(dir: string): boolean {\n return existsSync(join(dir, 'index.html'))\n}\n\n/**\n * The admin dist to serve: `NYMBAL_ADMIN_DIST` when it holds `index.html` (read per call), else the installed\n * `@nymbalhq/admin` dist when built, else null.\n */\nexport function resolveAdminRoot(): string | null {\n const override = process.env['NYMBAL_ADMIN_DIST']\n if (override && hasIndex(override)) return override\n try {\n const manifest = createRequire(import.meta.url).resolve('@nymbalhq/admin/package.json')\n const dist = join(dirname(manifest), 'dist')\n return hasIndex(dist) ? dist : null\n } catch {\n return null\n }\n}\n","/**\n * The CLI's own bound on a signal shutdown. Below the E2E wrapper's `DEFAULT_SHUTDOWN_MS` (`scripts/e2e-server.mjs`),\n * so the pending step is logged before the wrapper's SIGKILL lands.\n */\nexport const SHUTDOWN_BOUND_MS = 3000\n\nexport interface ShutdownStep {\n name: string\n run: () => Promise<void>\n}\n\nexport interface ShutdownOptions {\n boundMs: number\n logger: { info: (obj: unknown, msg?: string) => void; error: (obj: unknown, msg?: string) => void }\n exit: (code: number) => never\n}\n\nlet running = false\n\n/**\n * Runs the steps in order, then exits 0. A step that throws is logged and the rest still run, then it exits 1. A step\n * still pending at `boundMs` is named in the log and it exits 1, so no client can hold the process open. A second call\n * while one runs (a repeat signal) exits 1 at once.\n */\nexport async function runShutdown(steps: ShutdownStep[], opts: ShutdownOptions): Promise<never> {\n if (running) {\n opts.logger.error({}, 'Shutdown already running; exiting now')\n return opts.exit(1)\n }\n running = true\n\n let pending: string | undefined\n let failed = false\n const work = (async () => {\n for (const step of steps) {\n pending = step.name\n try {\n await step.run()\n } catch (err) {\n failed = true\n opts.logger.error({ err, step: step.name }, `Shutdown step \"${step.name}\" failed`)\n }\n }\n pending = undefined\n })()\n\n let timer: ReturnType<typeof setTimeout> | undefined\n const bound = new Promise<'bound'>((resolve) => {\n timer = setTimeout(() => resolve('bound'), opts.boundMs)\n })\n const outcome = await Promise.race([work.then(() => 'done' as const), bound])\n clearTimeout(timer)\n\n if (outcome === 'bound') {\n opts.logger.error(\n { step: pending, boundMs: opts.boundMs },\n `Shutdown step \"${pending}\" did not finish within ${opts.boundMs} ms; exiting`,\n )\n return opts.exit(1)\n }\n return opts.exit(failed ? 1 : 0)\n}\n","import { displayUrl } from '@nymbalhq/types'\n\n/** What `nymbal dev` reports once it is up. */\nexport type DevSummaryInfo = {\n store: string\n apiUrl: string\n /** null under `--api-only`. */\n storefront: { template: string; url: string } | null\n /** null when the admin is not built. */\n admin: { url: string } | null\n commandStore: { kind: 'sqlite'; path: string } | { kind: 'postgres'; url: string }\n slots: Array<{ slot: string; provider: string; capabilities: readonly string[] }>\n primitives: Array<{ name: 'documentStore' | 'eventBus' | 'media'; provider: string }>\n}\n\n/** A terminal this narrow still shows every line whole. */\nconst WIDTH = 100\nconst LABEL = 14\n/** Slot and provider names longer than this push the capability column no further. */\nconst NAME_COLUMN = 20\n\n/** Columns as a terminal counts them: one per code point. */\nconst columns = (text: string) => [...text].length\n\nfunction fit(text: string, width = WIDTH): string {\n return columns(text) <= width ? text : `${[...text].slice(0, width - 1).join('')}…`\n}\n\nfunction row(label: string, value: string): string {\n return fit(` ${label.padEnd(LABEL)} ${value}`)\n}\n\n/** The capabilities that fit in `width`, whole and in order; the rest are counted, as `… (+n)`. */\nfunction capabilityList(capabilities: readonly string[], width: number): string {\n if (capabilities.length === 0) return '—'\n const all = capabilities.join(', ')\n if (columns(all) <= width) return all\n for (let shown = capabilities.length - 1; shown > 0; shown--) {\n const text = `${capabilities.slice(0, shown).join(', ')}, … (+${capabilities.length - shown})`\n if (columns(text) <= width) return text\n }\n return `… (+${capabilities.length})`\n}\n\n/**\n * The screen `nymbal dev` prints once the store is up: the store, its URLs, the command store, each commerce slot's\n * provider and capabilities, and each primitive's provider. At most 30 lines of at most 100 columns, and never a\n * credential: a Postgres URL is shown as `scheme://host:port/db`.\n */\nexport function renderDevSummary(info: DevSummaryInfo): string {\n const slotWidth = Math.min(NAME_COLUMN, Math.max(...info.slots.map((s) => columns(s.slot)), 0))\n const providerWidth = Math.min(\n NAME_COLUMN,\n Math.max(...info.slots.map((s) => columns(s.provider)), 0),\n )\n const slotLines = info.slots.map(({ slot, provider, capabilities }) => {\n const lead = ` ${slot.padEnd(slotWidth)} ${provider.padEnd(providerWidth)} `\n return fit(`${lead}${capabilityList(capabilities, WIDTH - columns(lead))}`)\n })\n const commandStore =\n info.commandStore.kind === 'sqlite'\n ? `sqlite ${info.commandStore.path}`\n : `postgres ${displayUrl(info.commandStore.url)}`\n const lines = [\n fit(` ${info.store}`),\n '',\n row('API', info.apiUrl),\n row(\n 'storefront',\n info.storefront === null\n ? 'not started (--api-only)'\n : `${info.storefront.url} (${info.storefront.template})`,\n ),\n row(\n 'admin',\n info.admin === null ? 'not built — run pnpm --filter @nymbalhq/admin build' : info.admin.url,\n ),\n row('command store', commandStore),\n '',\n ...slotLines,\n '',\n ...info.primitives.map(({ name, provider }) => row(name, provider)),\n '',\n ' Debug logs: run with --verbose (or LOG_LEVEL=debug).',\n ]\n return `${lines.join('\\n')}\\n`\n}\n","import { defineCommand } from 'citty'\nimport { loadProject } from '../utils/project.js'\nimport { runOrFail } from '../utils/spawn.js'\nimport { isFlatScaffold, resolveLocalBin, templateFilterFor } from '../utils/template-runner.js'\n\nexport const buildCommand = defineCommand({\n meta: { name: 'build', description: 'Production build of the configured template' },\n async run() {\n const { config, projectRoot } = await loadProject()\n if (!isFlatScaffold(projectRoot, config.template)) {\n // Inside this monorepo the storefront is a workspace package.\n await runOrFail('pnpm', ['--filter', templateFilterFor(config.template), 'build'], {\n cwd: projectRoot,\n })\n return\n }\n const binName = config.template === 'astro' ? 'astro' : 'next'\n const bin = resolveLocalBin(projectRoot, binName)\n if (!bin) {\n throw new Error(\n `Cannot find the ${binName} binary in ${projectRoot}/node_modules/.bin. ` +\n 'Install dependencies first, then re-run `nymbal build`.',\n )\n }\n await runOrFail(bin, ['build'], { cwd: projectRoot })\n },\n})\n","import { defineCommand } from 'citty'\nimport { loadProject } from '../utils/project.js'\nimport { createPlatform, resolvePrimitives, runSeed } from '@nymbalhq/platform'\nimport { getCliVersion } from '../utils/version.js'\nimport { migrateProject } from './migrate.js'\n\nexport const seedCommand = defineCommand({\n meta: { name: 'seed', description: 'Re-seed demo content (products, categories)' },\n args: {\n localImages: {\n type: 'boolean',\n // citty registers the camelCase key only; the alias maps the kebab flag onto it (see `dev --api-only`).\n alias: 'local-images',\n description:\n \"Write the product images through the store's media slot instead of linking a placeholder host\",\n default: false,\n },\n mediaRoot: {\n type: 'string',\n alias: 'media-root',\n description: 'Where local-fs media is written (default: public/imported-media)',\n },\n },\n async run({ args }) {\n const { config, projectRoot } = await loadProject()\n // A fresh project has no tables yet; `nymbal dev` migrates before it seeds, and so does this.\n await migrateProject(config, projectRoot)\n const mediaRoot =\n typeof args.mediaRoot === 'string' && args.mediaRoot !== '' ? args.mediaRoot : undefined\n const platform = createPlatform(\n config,\n await resolvePrimitives(config, mediaRoot === undefined ? {} : { mediaRoot }),\n )\n try {\n const result = await runSeed({\n config,\n commandStore: platform.commandStore,\n documentStore: platform.documentStore,\n eventBus: platform.eventBus,\n logger: platform.logger,\n version: getCliVersion(),\n ...(args.localImages && { media: platform.media }),\n })\n // eslint-disable-next-line no-console\n console.log(\n result.alreadySeeded\n ? '✓ demo content already present, nothing to seed'\n : `✓ seeded ${result.products} products across ${result.categories} categories`,\n )\n } finally {\n await platform.close()\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport { intro, outro, text, select, spinner, isCancel, cancel } from '@clack/prompts'\nimport p from 'picocolors'\nimport { loadProject } from '../utils/project.js'\nimport { createApp, newCorrelationId, runAsActor, runWithCorrelation } from '@nymbalhq/platform'\nimport { runWooCommerceImport, writeReport, type ImportEntity, type ProgressEvent } from '@nymbalhq/importers'\nimport { join } from 'node:path'\nimport { getCliVersion } from '../utils/version.js'\n\nexport const importCommand = defineCommand({\n meta: {\n name: 'import',\n description: 'Migrate content from WooCommerce (or other sources) into Nymbal',\n },\n args: {\n source: {\n type: 'string',\n description: 'Import source (woocommerce)',\n },\n url: {\n type: 'string',\n description: 'Store URL (e.g. https://mystore.com)',\n },\n key: {\n type: 'string',\n description: 'WooCommerce Consumer Key (or set WOOCOMMERCE_KEY env var)',\n },\n secret: {\n type: 'string',\n description: 'WooCommerce Consumer Secret (or set WOOCOMMERCE_SECRET env var)',\n },\n entities: {\n type: 'string',\n description: 'Comma-separated list: products,customers,orders,reviews (default: products,customers,orders)',\n },\n ai: {\n type: 'boolean',\n description: 'Enable AI enrichment (default: true)',\n default: true,\n },\n gdpr: {\n type: 'boolean',\n description: 'Anonymise customer PII (default: true)',\n default: true,\n },\n fresh: {\n type: 'boolean',\n description: 'Ignore previous progress and re-import',\n default: false,\n },\n concurrency: {\n type: 'string',\n description: 'Parallel import workers (default: 4)',\n },\n },\n async run({ args }) {\n const { config } = await loadProject()\n const projectRoot = process.cwd()\n const statePath = join(projectRoot, '.nymbal-migration.json')\n const isTTY = process.stdin.isTTY ?? false\n\n intro(p.bold('Nymbal Import'))\n\n // ── Resolve source ────────────────────────────────────────────────────────\n let source = args.source\n if (!source) {\n if (!isTTY) {\n console.error('--source is required (woocommerce)')\n process.exit(1)\n }\n const picked = await select({\n message: 'Source platform?',\n options: [{ value: 'woocommerce', label: 'WooCommerce' }],\n })\n if (isCancel(picked)) { cancel('Import cancelled'); process.exit(0) }\n source = String(picked)\n }\n if (source !== 'woocommerce') {\n console.error(`Unsupported source: ${source}. Only 'woocommerce' is supported.`)\n process.exit(1)\n }\n\n // ── Resolve credentials ───────────────────────────────────────────────────\n let storeUrl = args.url\n if (!storeUrl) {\n if (!isTTY) { console.error('--url is required'); process.exit(1) }\n const val = await text({ message: 'Store URL?', placeholder: 'https://mystore.com', validate: (v) => v.startsWith('http') ? undefined : 'Must be a URL' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n storeUrl = String(val)\n }\n\n let consumerKey = args.key ?? process.env['WOOCOMMERCE_KEY'] ?? ''\n if (!consumerKey) {\n if (!isTTY) { console.error('--key or WOOCOMMERCE_KEY is required'); process.exit(1) }\n const val = await text({ message: 'Consumer Key?', placeholder: 'ck_...' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n consumerKey = String(val)\n }\n\n let consumerSecret = args.secret ?? process.env['WOOCOMMERCE_SECRET'] ?? ''\n if (!consumerSecret) {\n if (!isTTY) { console.error('--secret or WOOCOMMERCE_SECRET is required'); process.exit(1) }\n const val = await text({ message: 'Consumer Secret?', placeholder: 'cs_...' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n consumerSecret = String(val)\n }\n\n // ── Resolve entity list ───────────────────────────────────────────────────\n let entityList: ImportEntity[]\n if (args.entities) {\n entityList = args.entities.split(',').map((e) => e.trim()) as ImportEntity[]\n } else {\n entityList = ['categories', 'products', 'customers', 'orders']\n }\n\n const concurrency = parseInt(String(args.concurrency ?? '4'), 10)\n const aiEnabled = args.ai !== false\n const gdprEnabled = args.gdpr !== false\n\n // ── Bootstrap app ─────────────────────────────────────────────────────────\n const loadSpin = spinner()\n loadSpin.start('Starting platform…')\n const app = await createApp(config, { version: getCliVersion() })\n loadSpin.stop('Platform ready')\n\n try {\n // One run is one operation: every event the import causes carries one id, and every write it makes is the\n // import's, one audit entry per record written.\n const report = await runWithCorrelation(newCorrelationId('import:woocommerce'), () =>\n runAsActor({ kind: 'import', id: 'woocommerce' }, () => runWooCommerceImport(\n {\n credentials: { url: storeUrl, consumerKey, consumerSecret },\n entities: entityList,\n ai: aiEnabled,\n gdpr: gdprEnabled,\n fresh: args.fresh,\n concurrency,\n projectRoot,\n currency: config.store.currency,\n statePath,\n },\n {\n services: app.services,\n repos: app.repos,\n adapters: { ai: app.adapters.ai, reviews: app.adapters.reviews },\n media: app.platform.media,\n onProgress(event: ProgressEvent) {\n if (event.kind === 'phase') {\n console.log(p.cyan(` → ${event.phase}`))\n } else if (event.kind === 'progress') {\n const pct = Math.round((event.done / event.total) * 100)\n process.stdout.write(`\\r ${event.entity}: ${event.done}/${event.total} (${pct}%) `)\n if (event.done === event.total) process.stdout.write('\\n')\n } else if (event.kind === 'error') {\n console.log(p.red(` ✗ ${event.phase} [${event.id}]: ${event.message}`))\n }\n },\n },\n )),\n )\n\n const reportPath = await writeReport(report, projectRoot, config.store.name)\n\n outro(\n [\n p.green('✓ Import complete'),\n ` Products: ${report.imported.products}`,\n ` Customers: ${report.imported.customers}`,\n ` Orders: ${report.imported.orders}`,\n ` Categories: ${report.imported.categories}`,\n ...(aiEnabled ? [` AI enriched: ${report.enriched.enriched} products`] : []),\n ...(report.errors.length > 0 ? [p.yellow(` ⚠ ${report.errors.length} errors — see report`)] : []),\n ``,\n ` Report: ${reportPath}`,\n ` Next: ${p.bold('nymbal dev')}`,\n ].join('\\n'),\n )\n } finally {\n await app.stop()\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport { loadProject } from '../utils/project.js'\nimport { NymbalError } from '@nymbalhq/types'\n\nexport const configValidateCommand = defineCommand({\n meta: { name: 'config:validate', description: 'Validate nymbal.config.ts' },\n async run() {\n try {\n const { config, path } = await loadProject()\n // eslint-disable-next-line no-console\n console.log(pc.green(`✓ config valid`) + ` (${path})`)\n // eslint-disable-next-line no-console\n console.log(\n ` template: ${config.template}, commandStore: ${config.infrastructure.commandStore}, documentStore: ${config.infrastructure.documentStore}, eventBus: ${config.infrastructure.eventBus}`,\n )\n process.exit(0)\n } catch (err) {\n if (err instanceof NymbalError) {\n // eslint-disable-next-line no-console\n console.error(pc.red('✗ config invalid'))\n // eslint-disable-next-line no-console\n console.error(err.message)\n } else {\n // eslint-disable-next-line no-console\n console.error(err)\n }\n process.exit(1)\n }\n },\n})\n","import { spawnSync } from 'node:child_process'\nimport { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { parseEnv } from 'node:util'\nimport { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport { findConfigFile, loadConfig } from '@nymbalhq/config'\nimport { installLine } from '@nymbalhq/platform'\nimport type { Recipe } from '@nymbalhq/types'\nimport {\n RECIPE_HOLDERS,\n appendRecipeEnv,\n applyRecipeToConfig,\n envCalls,\n isInstalled,\n isKnownRecipe,\n knownRecipes,\n missingEnv,\n readRecipe,\n recipeFile,\n settingsEnv,\n} from '../recipes/index.js'\n\nexport interface AddOptions {\n recipe: string\n install: boolean\n force: boolean\n dryRun: boolean\n}\n\nconst out = (line = ''): void => void process.stdout.write(`${line}\\n`)\nconst err = (line: string): void => void process.stderr.write(`${line}\\n`)\n\nfunction fail(message: string): number {\n err(pc.red(`✗ ${message}`))\n return 1\n}\n\n/** Runs an install line in the project, its output passed through; whether it succeeded. */\nfunction runInstall(line: string, root: string): boolean {\n out(pc.dim(`$ ${line}`))\n const [command, ...args] = line.split(' ')\n const result = spawnSync(command!, args, {\n cwd: root,\n stdio: 'inherit',\n shell: process.platform === 'win32',\n })\n return result.status === 0\n}\n\n/** The variables `.env` sets to something, which `nymbal dev` loads before the config. */\nfunction dotEnv(root: string): Record<string, string> {\n const file = join(root, '.env')\n return existsSync(file) ? (parseEnv(readFileSync(file, 'utf8')) as Record<string, string>) : {}\n}\n\nconst isSet = (name: string, fromFile: Record<string, string>): boolean =>\n (process.env[name] ?? '') !== '' || (fromFile[name] ?? '') !== ''\n\n/**\n * Why the candidate config would not run, without connecting to anything: a recipe package the project does not\n * resolve, or a config `loadConfig` refuses (the schema and its cross-slot rules). The candidate is loaded as\n * `nymbal.config.ts` from a temp directory under the project, so `@nymbalhq/config` resolves as the real one does. For\n * that load only, every variable an `env()` call names takes its `.env` value as `nymbal dev` would, and one still\n * unset gets a placeholder unless its calls have a default, which is what runs.\n */\nasync function problemsWith(\n candidate: string,\n recipe: Recipe,\n root: string,\n fromFile: Record<string, string>,\n): Promise<string[]> {\n const problems: string[] = []\n const missing = recipe.install.filter((pkg) => !isInstalled(pkg, root))\n if (missing.length > 0) {\n problems.push(\n `${missing.join(', ')} ${missing.length === 1 ? 'is' : 'are'} not installed: ${installLine(missing, process.env, root)}`,\n )\n }\n const saved = new Map<string, string | undefined>()\n for (const { name, defaulted } of envCalls(candidate)) {\n if ((process.env[name] ?? '') !== '') continue\n const value = fromFile[name] || (defaulted ? undefined : `nymbal-add-placeholder-${name}`)\n if (value === undefined) continue\n saved.set(name, process.env[name])\n process.env[name] = value\n }\n const dir = mkdtempSync(join(root, '.nymbal-add-'))\n try {\n writeFileSync(join(dir, 'nymbal.config.ts'), candidate)\n await loadConfig(dir)\n } catch (error) {\n problems.push((error as Error).message)\n } finally {\n rmSync(dir, { recursive: true, force: true })\n for (const [name, value] of saved) {\n if (value === undefined) delete process.env[name]\n else process.env[name] = value\n }\n }\n return problems\n}\n\n/** The lines of `after` that `before` lacks (`+`) and the reverse (`-`), by a longest common subsequence. */\nfunction lineDiff(before: string, after: string): string[] {\n const a = before.split('\\n')\n const b = after.split('\\n')\n const t = Array.from({ length: a.length + 1 }, () => new Array<number>(b.length + 1).fill(0))\n for (let i = a.length - 1; i >= 0; i--)\n for (let j = b.length - 1; j >= 0; j--)\n t[i]![j] = a[i] === b[j] ? t[i + 1]![j + 1]! + 1 : Math.max(t[i + 1]![j]!, t[i]![j + 1]!)\n const lines: string[] = []\n let i = 0\n let j = 0\n while (i < a.length || j < b.length) {\n if (i < a.length && j < b.length && a[i] === b[j]) {\n i++\n j++\n } else if (j < b.length && (i === a.length || t[i]![j + 1]! >= t[i + 1]![j]!)) {\n lines.push(pc.green(`+ ${b[j++]}`))\n } else {\n lines.push(pc.red(`- ${a[i++]}`))\n }\n }\n return lines\n}\n\nconst show = (value: unknown): string =>\n typeof value === 'string' ? `'${value}'` : JSON.stringify(value)\n\nexport async function add(opts: AddOptions, cwd: string = process.cwd()): Promise<number> {\n const name = opts.recipe\n if (!isKnownRecipe(name)) {\n return fail(`unknown recipe '${name}'. The recipes are: ${knownRecipes().join(', ')}`)\n }\n const configPath = findConfigFile(cwd)\n if (configPath === null) return fail(`no nymbal.config.ts in ${cwd} or any parent directory`)\n const root = dirname(configPath)\n const holder = RECIPE_HOLDERS[name]!\n\n const installed: string[] = []\n if (recipeFile(name, root) === null) {\n const line = installLine([holder], process.env, root)\n if (!opts.install || opts.dryRun) {\n return fail(\n `the ${name} recipe ships in ${holder}, which is not installed. Install it: ${line}`,\n )\n }\n if (!runInstall(line, root)) return fail(`${line} failed`)\n installed.push(holder)\n }\n const recipe = await readRecipe(name, root)\n\n const source = readFileSync(configPath, 'utf8')\n let edited: { source: string; changed: string[] }\n try {\n const applied = applyRecipeToConfig(source, recipe, { force: opts.force })\n if ('conflict' in applied) {\n const { path, current, wanted } = applied.conflict\n return fail(\n `${path} is ${show(current)} in nymbal.config.ts, and the ${name} recipe sets it to ${show(wanted)}. ` +\n 'nymbal.config.ts is unchanged: edit it by hand, or re-run with --force to overwrite it.',\n )\n }\n edited = applied\n } catch (error) {\n return fail((error as Error).message)\n }\n const examplePath = join(root, '.env.example')\n const example = existsSync(examplePath) ? readFileSync(examplePath, 'utf8') : ''\n const nextExample = appendRecipeEnv(example, recipe)\n\n if (opts.dryRun) {\n out(pc.bold(`nymbal add ${name} --dry-run: nothing is written`))\n out()\n out(\n recipe.install.length > 0\n ? `install: ${installLine(recipe.install, process.env, root)}`\n : 'install: nothing',\n )\n out()\n out('nymbal.config.ts:')\n const diff = lineDiff(source, edited.source)\n for (const line of diff.length > 0 ? diff : ['(already set)']) out(` ${line}`)\n out()\n out('.env.example:')\n const added = nextExample\n .slice(example.length)\n .split(/\\r?\\n/)\n .filter((l) => l !== '')\n for (const line of added.length > 0 ? added : ['(every variable already listed)'])\n out(` ${line}`)\n return 0\n }\n\n const pending = recipe.install.filter((pkg) => !isInstalled(pkg, root))\n if (pending.length > 0 && opts.install) {\n const line = installLine(pending, process.env, root)\n if (!runInstall(line, root)) return fail(`${line} failed`)\n installed.push(...pending)\n }\n\n const fromFile = dotEnv(root)\n const problems = await problemsWith(edited.source, recipe, root, fromFile)\n if (problems.length > 0) {\n return fail(\n `the ${name} recipe would leave a config that does not load, so nymbal.config.ts is unchanged:\\n ${problems.join('\\n ')}`,\n )\n }\n\n const written: string[] = []\n if (installed.length > 0) written.push(`package.json and its lockfile (${installed.join(', ')})`)\n if (edited.source !== source) {\n writeFileSync(configPath, edited.source)\n written.push(`nymbal.config.ts (${edited.changed.join(', ')})`)\n }\n if (nextExample !== example) {\n writeFileSync(examplePath, nextExample)\n written.push(\n `.env.example (${missingEnv(example, recipe)\n .map((v) => v.name)\n .join(', ')})`,\n )\n }\n\n out(pc.green(`✓ ${name}: ${recipe.summary}`))\n out(written.length > 0 ? ` changed ${written.join(', ')}` : ' already added: nothing changed')\n const unset = recipe.env.filter((v) => v.required && !isSet(v.name, fromFile))\n if (unset.length > 0 || recipe.next.length > 0) {\n out()\n out('Next:')\n const fromSettings = unset.length > 0 ? await settingsEnv(recipe.install, root) : new Set()\n for (const v of unset) {\n out(\n fromSettings.has(v.name)\n ? ` - set ${v.name} in .env or in the admin's Settings`\n : ` - set ${v.name} in .env`,\n )\n }\n for (const line of recipe.next) out(` - ${line}`)\n }\n return 0\n}\n\nexport const addCommand = defineCommand({\n meta: {\n name: 'add',\n description: `Put the store on a service: ${knownRecipes().join(', ')}`,\n },\n args: {\n recipe: { type: 'positional', required: true, description: knownRecipes().join(', ') },\n install: {\n type: 'boolean',\n default: true,\n description: 'Install the packages (--no-install: they must already be installed)',\n },\n force: {\n type: 'boolean',\n default: false,\n description: 'Overwrite a config value the recipe conflicts with',\n },\n 'dry-run': {\n type: 'boolean',\n default: false,\n description:\n 'Print the config change, the .env.example lines and the install line, and write nothing',\n },\n },\n async run({ args }) {\n process.exitCode = await add({\n recipe: args.recipe,\n install: args.install,\n force: args.force,\n dryRun: args['dry-run'],\n })\n },\n})\n","import { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { dirname, join, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport type { Recipe } from '@nymbalhq/types'\n\n/**\n * Each recipe `nymbal add` knows, and the package that ships it as `recipes/<name>.json`. The recipe itself is data in\n * that package, so a package brings its own recipe; this table only says where to look.\n */\nexport const RECIPE_HOLDERS: Readonly<Record<string, string>> = {\n cloudflare: '@nymbalhq/security-cloudflare',\n postgres: '@nymbalhq/platform',\n redis: '@nymbalhq/doc-store-redis',\n s3: '@nymbalhq/media-s3',\n stripe: '@nymbalhq/adapter-stripe',\n}\n\nexport function knownRecipes(): string[] {\n return Object.keys(RECIPE_HOLDERS).sort()\n}\n\nexport function isKnownRecipe(name: string): boolean {\n return Object.hasOwn(RECIPE_HOLDERS, name)\n}\n\nfunction unknownRecipe(name: string): Error {\n return new Error(`unknown recipe '${name}': the recipes are ${knownRecipes().join(', ')}`)\n}\n\n/**\n * The directory of `pkg` in the `node_modules` of the project or a directory above it, as Node looks for it, or null.\n * Node's global fallbacks are left out: pnpm's shims put its whole store on NODE_PATH, which is no install.\n */\nfunction packageDir(pkg: string, projectRoot: string): string | null {\n let dir = resolve(projectRoot)\n while (true) {\n const candidate = join(dir, 'node_modules', pkg)\n if (existsSync(join(candidate, 'package.json'))) return candidate\n const parent = dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n}\n\n/** Where the project resolves `<holder>/recipes/<name>.json`, or null when the holder is not installed there. */\nexport function recipeFile(name: string, projectRoot: string): string | null {\n const holder = RECIPE_HOLDERS[name]\n if (holder === undefined || !isKnownRecipe(name)) throw unknownRecipe(name)\n const dir = packageDir(holder, projectRoot)\n if (dir === null) return null\n try {\n // From the holder's own manifest the specifier resolves through its `exports`, as from the project.\n return createRequire(join(dir, 'package.json')).resolve(`${holder}/recipes/${name}.json`)\n } catch (error) {\n const code = (error as { code?: unknown }).code\n if (code === 'MODULE_NOT_FOUND' || code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') return null\n throw error\n }\n}\n\nexport function isInstalled(pkg: string, projectRoot: string): boolean {\n return packageDir(pkg, projectRoot) !== null\n}\n\n/** The recipe the holder installed in the project ships, read through Node resolution from the project root. */\nexport async function readRecipe(name: string, projectRoot: string): Promise<Recipe> {\n const file = recipeFile(name, projectRoot)\n if (file === null) {\n throw new Error(\n `${RECIPE_HOLDERS[name]} is not installed in ${projectRoot}, so its ${name} recipe cannot be read`,\n )\n }\n const recipe = JSON.parse(await readFile(file, 'utf8')) as Recipe\n const malformed =\n recipe === null ||\n typeof recipe !== 'object' ||\n recipe.name !== name ||\n !Array.isArray(recipe.install) ||\n !Array.isArray(recipe.set) ||\n !Array.isArray(recipe.env) ||\n !Array.isArray(recipe.next)\n if (malformed) throw new Error(`${file} is not a ${name} recipe`)\n return recipe\n}\n\n/** The ESM entry of a package directory: its `exports['.']` import condition, else `module`, else `main`. */\nfunction entryOf(dir: string, manifest: Record<string, unknown>): string | null {\n const exportsField = manifest['exports'] as Record<string, unknown> | string | undefined\n const root = typeof exportsField === 'object' ? exportsField['.'] : exportsField\n const entry =\n typeof root === 'string'\n ? root\n : typeof root === 'object' && root !== null\n ? ((root as Record<string, unknown>)['import'] ??\n (root as Record<string, unknown>)['default'])\n : (manifest['module'] ?? manifest['main'])\n return typeof entry === 'string' ? join(dir, entry) : null\n}\n\n/**\n * The environment variables the Nymbal packages in `packages` declare as settings (their `settings` export), as the\n * project has them installed: a variable the admin's Settings can fill as well as `.env`. A package that is not\n * installed, or whose SDK is not yet, declares nothing here.\n */\nexport async function settingsEnv(\n packages: readonly string[],\n projectRoot: string,\n): Promise<Set<string>> {\n const names = new Set<string>()\n for (const pkg of packages.filter((p) => p.startsWith('@nymbalhq/'))) {\n const dir = packageDir(pkg, projectRoot)\n if (dir === null) continue\n const manifest = JSON.parse(await readFile(join(dir, 'package.json'), 'utf8')) as Record<\n string,\n unknown\n >\n const entry = entryOf(dir, manifest)\n if (entry === null || !existsSync(entry)) continue\n let mod: { settings?: unknown }\n try {\n mod = (await import(pathToFileURL(entry).href)) as { settings?: unknown }\n } catch (error) {\n // `--no-install` may leave the provider's SDK out; the hint then names `.env` alone.\n if ((error as { code?: unknown }).code === 'ERR_MODULE_NOT_FOUND') continue\n throw error\n }\n if (!Array.isArray(mod.settings)) continue\n for (const setting of mod.settings as Array<{ env?: unknown }>) {\n if (typeof setting?.env === 'string') names.add(setting.env)\n }\n }\n return names\n}\n","import { parseModule } from 'magicast'\nimport type { Recipe, RecipeValue } from '@nymbalhq/types'\n\n/** What the scaffold writes into the slots a recipe sets: replacing one of these is no conflict. */\nexport const SCAFFOLD_DEFAULTS: readonly string[] = [\n 'sqlite',\n 'in-memory',\n 'in-process',\n 'local-fs',\n 'native',\n 'middleware',\n]\n\nconst CONFIG_MODULE = '@nymbalhq/config'\n\nexport type Conflict = { path: string; current: unknown; wanted: unknown }\nexport type AppliedRecipe = { source: string; changed: string[] } | { conflict: Conflict }\n\n/** The parts of a Babel node this module reads. */\ninterface Node {\n type: string\n start: number\n end: number\n [key: string]: unknown\n}\n\nconst child = (node: Node, key: string): Node => node[key] as Node\nconst children = (node: Node, key: string): Node[] => node[key] as Node[]\n\n/** Parses LF text only: recast's offsets count a line break as one character, so CRLF text goes through `lfCopy`. */\nfunction parse(lf: string): Node {\n // Recast expands tabs to `tabWidth` columns before Babel parses: at 1 every offset still points into `lf`.\n return parseModule(lf, { tabWidth: 1 }).$ast as unknown as Node\n}\n\nconst lfCopy = (source: string): string => source.replace(/\\r\\n/g, '\\n')\n\nfunction unwrap(node: Node | undefined): Node | undefined {\n let at = node\n while (\n at !== undefined &&\n (at.type === 'TSAsExpression' ||\n at.type === 'TSSatisfiesExpression' ||\n at.type === 'TSNonNullExpression' ||\n at.type === 'ParenthesizedExpression')\n ) {\n at = child(at, 'expression')\n }\n return at\n}\n\nfunction nameOf(node: Node): string | undefined {\n if (node.type === 'Identifier') return node['name'] as string\n if (node.type === 'StringLiteral') return node['value'] as string\n if (node.type === 'NumericLiteral') return String(node['value'])\n return undefined\n}\n\ninterface ConfigModule {\n program: Node\n /** The object literal `defineConfig` is called with, or the default export itself. */\n config: Node\n /** The local name `env` is imported under from @nymbalhq/config, if it is. */\n envName: string | undefined\n /** Whether a top-level import or declaration binds the name `env`. */\n envBound: boolean\n /** The first value import from @nymbalhq/config that names its imports. */\n namedImport: Node | undefined\n}\n\nfunction configImports(program: Node): Node[] {\n return children(program, 'body').filter(\n (n) =>\n n.type === 'ImportDeclaration' &&\n child(n, 'source')['value'] === CONFIG_MODULE &&\n n['importKind'] !== 'type',\n )\n}\n\nfunction importedAs(program: Node, imported: string): string | undefined {\n for (const decl of configImports(program)) {\n for (const spec of children(decl, 'specifiers')) {\n if (spec.type !== 'ImportSpecifier' || spec['importKind'] === 'type') continue\n if (nameOf(child(spec, 'imported')) === imported)\n return child(spec, 'local')['name'] as string\n }\n }\n return undefined\n}\n\nfunction bindsEnv(program: Node): boolean {\n const bound = (id: Node | undefined): boolean => id?.type === 'Identifier' && id['name'] === 'env'\n return children(program, 'body').some((n) => {\n const decl = n.type === 'ExportNamedDeclaration' ? child(n, 'declaration') : n\n if (decl === null || decl === undefined) return false\n if (decl.type === 'ImportDeclaration')\n return children(decl, 'specifiers').some((s) => bound(child(s, 'local')))\n if (decl.type === 'VariableDeclaration')\n return children(decl, 'declarations').some((d) => bound(child(d, 'id')))\n return bound(child(decl, 'id'))\n })\n}\n\n/** The config literal of `source`, the LF copy of a nymbal.config.ts. */\nfunction locate(source: string): ConfigModule | undefined {\n const program = parse(source)\n const exported = children(program, 'body').find((n) => n.type === 'ExportDefaultDeclaration')\n if (exported === undefined) return undefined\n let config = unwrap(child(exported, 'declaration'))\n if (config?.type === 'CallExpression') {\n const callee = child(config, 'callee')\n const define = importedAs(program, 'defineConfig') ?? 'defineConfig'\n if (callee.type !== 'Identifier' || callee['name'] !== define) return undefined\n config = unwrap(children(config, 'arguments')[0])\n }\n if (config?.type !== 'ObjectExpression') return undefined\n // A guard on the offsets: they must frame the literal in `source` itself.\n if (source[config.start] !== '{' || source[config.end - 1] !== '}') return undefined\n return {\n program,\n config,\n envName: importedAs(program, 'env'),\n envBound: bindsEnv(program),\n namedImport: configImports(program).find((d) =>\n children(d, 'specifiers').some((s) => s.type === 'ImportSpecifier'),\n ),\n }\n}\n\nfunction isEnvRef(value: unknown): value is { env: string; default?: string } {\n if (typeof value !== 'object' || value === null) return false\n const keys = Object.keys(value)\n return (\n typeof (value as { env?: unknown }).env === 'string' &&\n keys.every((k) => k === 'env' || k === 'default')\n )\n}\n\n/** The value a literal node holds, `env('X')` as `{ env: 'X' }`; undefined for anything that is not a literal. */\nfunction evaluate(node: Node, envName: string | undefined): unknown {\n const at = unwrap(node)!\n switch (at.type) {\n case 'StringLiteral':\n case 'NumericLiteral':\n case 'BooleanLiteral':\n return at['value']\n case 'TemplateLiteral': {\n const quasis = children(at, 'quasis')\n return children(at, 'expressions').length === 0\n ? (quasis[0]?.['value'] as { cooked: string }).cooked\n : undefined\n }\n case 'ObjectExpression': {\n const out: Record<string, unknown> = {}\n for (const prop of children(at, 'properties')) {\n const key =\n prop.type === 'ObjectProperty' && !prop['computed']\n ? nameOf(child(prop, 'key'))\n : undefined\n const value = key === undefined ? undefined : evaluate(child(prop, 'value'), envName)\n if (key === undefined || value === undefined) return undefined\n out[key] = value\n }\n return out\n }\n case 'CallExpression': {\n const callee = child(at, 'callee')\n const args = children(at, 'arguments')\n if (callee.type !== 'Identifier' || callee['name'] !== (envName ?? 'env')) return undefined\n if (args.length < 1 || args.length > 2 || args.some((a) => a.type !== 'StringLiteral'))\n return undefined\n return {\n env: args[0]!['value'],\n ...(args[1] !== undefined && { default: args[1]['value'] }),\n }\n }\n default:\n return undefined\n }\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return a === b\n const ka = Object.keys(a).sort()\n const kb = Object.keys(b).sort()\n return (\n ka.length === kb.length &&\n ka.every(\n (k, i) =>\n k === kb[i] &&\n sameValue((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]),\n )\n )\n}\n\nfunction isScaffoldDefault(value: unknown): boolean {\n if (typeof value === 'string') return SCAFFOLD_DEFAULTS.includes(value)\n const provider = (value as { provider?: unknown } | null)?.provider\n return typeof provider === 'string' && SCAFFOLD_DEFAULTS.includes(provider)\n}\n\ninterface Style {\n quote: string\n unit: string\n envName: string\n}\n\nfunction styleOf(source: string, mod: ConfigModule): Style {\n const firstString = /(['\"])(?:(?!\\1)[^\\\\\\r\\n]|\\\\.)*\\1/.exec(source.slice(mod.config.start))\n const indented = /\\n([ \\t]+)\\S/.exec(source.slice(mod.config.start))\n return {\n quote: firstString?.[1] ?? \"'\",\n unit: indented?.[1] ?? ' ',\n envName: mod.envName ?? 'env',\n }\n}\n\nfunction quoted(text: string, style: Style): string {\n const q = style.quote\n const body = text\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(new RegExp(q, 'g'), `\\\\${q}`)\n .replace(/\\r/g, '\\\\r')\n .replace(/\\n/g, '\\\\n')\n return `${q}${body}${q}`\n}\n\nfunction renderKey(key: string, style: Style): string {\n return /^[A-Za-z_$][\\w$]*$/.test(key) ? key : quoted(key, style)\n}\n\n/** `value` as source text, an object over several lines starting at `indent`. */\nfunction render(value: RecipeValue, indent: string, style: Style): string {\n if (typeof value === 'string') return quoted(value, style)\n if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n if (isEnvRef(value)) {\n const fallback = value.default === undefined ? '' : `, ${quoted(value.default, style)}`\n return `${style.envName}(${quoted(value.env, style)}${fallback})`\n }\n const entries = Object.entries(value)\n if (entries.length === 0) return '{}'\n const inner = indent + style.unit\n const lines = entries.map(\n ([k, v]) => `${inner}${renderKey(k, style)}: ${render(v, inner, style)},`,\n )\n return `{\\n${lines.join('\\n')}\\n${indent}}`\n}\n\nfunction writesEnv(value: RecipeValue): boolean {\n if (isEnvRef(value)) return true\n return typeof value === 'object' && Object.values(value).some(writesEnv)\n}\n\n/** The whitespace that starts the line `offset` is on. */\nfunction indentAt(source: string, offset: number): string {\n const lineStart = source.lastIndexOf('\\n', offset - 1) + 1\n return /^[ \\t]*/.exec(source.slice(lineStart))![0]\n}\n\n/** An edit at offsets of the LF copy, its text LF too. */\ntype Splice = { at: number; remove: number; text: string }\n\n/**\n * `source` with `edits` made. Their offsets are mapped from the LF copy back to `source`, and a line an edit adds ends\n * as the line it lands in does, so a CRLF or mixed file keeps its own endings and every byte outside the edits.\n */\nfunction spliced(source: string, edits: Splice[]): string {\n // The LF copy's offset of every `\\n` that a `\\r` stands before in `source`.\n const crlf: number[] = []\n for (const m of source.matchAll(/\\r\\n/g)) crlf.push(m.index - crlf.length)\n const at = (lf: number): number => lf + crlf.filter((p) => p < lf).length\n const lastBreak = /\\r?\\n(?![\\s\\S]*\\n)/.exec(source)?.[0] ?? '\\n'\n return edits\n .map((e) => {\n const start = at(e.at)\n const end = at(e.at + e.remove)\n const eol = /\\r?\\n/.exec(source.slice(end))?.[0] ?? lastBreak\n return { start, end, text: e.text.replace(/\\n/g, eol) }\n })\n .sort((a, b) => b.start - a.start)\n .reduce((s, e) => s.slice(0, e.start) + e.text + s.slice(e.end), source)\n}\n\n/** The edits that add `key: value` as the last property of `object`, in the layout the object already has. */\nfunction addProperty(\n source: string,\n object: Node,\n key: string,\n value: RecipeValue,\n style: Style,\n): Splice[] {\n const props = children(object, 'properties')\n const close = object.end - 1\n const last = props.at(-1)\n if (last === undefined) {\n const indent = indentAt(source, object.start)\n const inside = source.slice(object.start + 1, close)\n const text = `${indent}${style.unit}${renderKey(key, style)}: ${render(value, indent + style.unit, style)},`\n // An empty `{}` (or one holding only whitespace) is rewritten; anything else in it, a comment, stays above.\n return inside.trim() === ''\n ? [\n {\n at: object.start + 1,\n remove: inside.length,\n text: `\\n${text}\\n${indent}`,\n },\n ]\n : [{ at: close, remove: 0, text: `\\n${text}\\n${indent}` }]\n }\n const after = /^[ \\t]*,/.exec(source.slice(last.end, close))\n const comma = after === null ? undefined : last.end + after[0].length\n const lineEnd = source.slice(last.end, close).indexOf('\\n')\n const property = (indent: string): string =>\n `${renderKey(key, style)}: ${render(value, indent, style)}`\n if (lineEnd === -1) {\n // `{ a: 1 }` on one line: the property joins it there.\n return comma === undefined\n ? [{ at: last.end, remove: 0, text: `, ${property(indentAt(source, last.start))}` }]\n : [{ at: comma, remove: 0, text: ` ${property(indentAt(source, last.start))},` }]\n }\n const indent = indentAt(source, last.start)\n const edits: Splice[] = [\n {\n at: last.end + lineEnd,\n remove: 0,\n text: `\\n${indent}${property(indent)}${comma === undefined ? '' : ','}`,\n },\n ]\n if (comma === undefined) edits.push({ at: last.end, remove: 0, text: ',' })\n return edits\n}\n\nfunction findProperty(object: Node, key: string): Node | undefined {\n return children(object, 'properties').findLast(\n (p) => p.type === 'ObjectProperty' && !p['computed'] && nameOf(child(p, 'key')) === key,\n )\n}\n\nfunction editByHand(recipe: Recipe, why: string): Error {\n const wanted = recipe.set.map(({ path, value }) => `${path} = ${JSON.stringify(value)}`)\n return new Error(\n `nymbal.config.ts ${why}, so the ${recipe.name} recipe cannot edit it: edit by hand and set ${wanted.join('; ')}`,\n )\n}\n\ntype Step = { source: string; wrote: boolean } | { conflict: Conflict }\n\n/** One `set` entry applied to `source`. */\nfunction setPath(\n source: string,\n recipe: Recipe,\n path: string,\n value: RecipeValue,\n force: boolean,\n): Step {\n const lf = lfCopy(source)\n const mod = locate(lf)\n if (mod === undefined)\n throw editByHand(recipe, 'does not export a defineConfig({...}) object literal')\n const style = styleOf(lf, mod)\n const keys = path.split('.')\n let object = mod.config\n for (const [i, key] of keys.entries()) {\n const prop = findProperty(object, key)\n if (prop === undefined) {\n const nested = keys.slice(i + 1).reduceRight<RecipeValue>((v, k) => ({ [k]: v }), value)\n return {\n source: spliced(source, addProperty(lf, object, key, nested, style)),\n wrote: true,\n }\n }\n const held = child(prop, 'value')\n if (i === keys.length - 1) {\n const current = evaluate(held, mod.envName)\n if (current !== undefined && sameValue(current, value)) return { source, wrote: false }\n if (!force && !isScaffoldDefault(current)) {\n return {\n conflict: { path, current: current ?? lf.slice(held.start, held.end), wanted: value },\n }\n }\n const text = render(value, indentAt(lf, prop.start), style)\n return {\n source: spliced(source, [{ at: held.start, remove: held.end - held.start, text }]),\n wrote: true,\n }\n }\n const inner = unwrap(held)\n if (inner?.type !== 'ObjectExpression') {\n throw editByHand(\n recipe,\n `holds ${keys.slice(0, i + 1).join('.')} as something other than an object literal`,\n )\n }\n object = inner\n }\n return { source, wrote: false }\n}\n\n/** `source` importing `env` from @nymbalhq/config, by adding it to an import that names its imports, or a new one. */\nfunction importEnv(source: string, recipe: Recipe): string {\n const lf = lfCopy(source)\n const mod = locate(lf)!\n if (mod.envName !== undefined) return source\n if (mod.envBound)\n throw editByHand(recipe, 'binds `env` to something other than the env of @nymbalhq/config')\n const style = styleOf(lf, mod)\n if (mod.namedImport !== undefined) {\n const last = children(mod.namedImport, 'specifiers')\n .filter((s) => s.type === 'ImportSpecifier')\n .at(-1)!\n return spliced(source, [{ at: last.end, remove: 0, text: ', env' }])\n }\n const imports = children(mod.program, 'body').filter((n) => n.type === 'ImportDeclaration')\n const line = `import { env } from ${quoted(CONFIG_MODULE, style)}\\n`\n const lastImport = imports.at(-1)\n const lineEnd = lastImport === undefined ? -1 : lf.indexOf('\\n', lastImport.end)\n const edit: Splice =\n lastImport === undefined\n ? { at: 0, remove: 0, text: line }\n : lineEnd === -1\n ? { at: lf.length, remove: 0, text: `\\n${line}` }\n : { at: lineEnd + 1, remove: 0, text: line }\n return spliced(source, [edit])\n}\n\n/**\n * `source` (a `nymbal.config.ts`) with every `set` path of the recipe holding the recipe's value, through the AST of\n * the `defineConfig({...})` literal (or a plain object default export). Everything outside the edited properties is\n * kept byte for byte, and a path already holding the value is left alone, so applying it twice equals applying it\n * once. A path holding another value that is not the scaffold's default is a conflict unless `force`. A config that\n * is not such a literal throws \"edit by hand\".\n */\nexport function applyRecipeToConfig(\n source: string,\n recipe: Recipe,\n opts: { force: boolean },\n): AppliedRecipe {\n if (locate(lfCopy(source)) === undefined) {\n throw editByHand(recipe, 'does not export a defineConfig({...}) object literal')\n }\n let current = source\n const changed: string[] = []\n let envWritten = false\n for (const { path, value } of recipe.set) {\n const step = setPath(current, recipe, path, value, opts.force)\n if ('conflict' in step) return step\n if (!step.wrote) continue\n current = step.source\n changed.push(path)\n envWritten ||= writesEnv(value)\n }\n if (envWritten) current = importEnv(current, recipe)\n return { source: current, changed }\n}\n\nexport type EnvCall = { name: string; defaulted: boolean }\n\n/**\n * Every variable an `env('NAME')` call names in the config, `env` imported from @nymbalhq/config, and whether every\n * call naming it has a default. A load needs the others set; a defaulted one runs on its default unless `.env` sets it.\n */\nexport function envCalls(source: string): EnvCall[] {\n const lf = lfCopy(source)\n const mod = locate(lf)\n const envName = mod === undefined ? importedAs(parse(lf), 'env') : mod.envName\n if (envName === undefined) return []\n const defaulted = new Map<string, boolean>()\n const visit = (node: unknown): void => {\n if (Array.isArray(node)) return node.forEach(visit)\n if (typeof node !== 'object' || node === null || typeof (node as Node).type !== 'string') return\n const n = node as Node\n if (n.type === 'CallExpression') {\n const callee = child(n, 'callee')\n const args = children(n, 'arguments')\n const first = args[0]\n if (\n callee.type === 'Identifier' &&\n callee['name'] === envName &&\n first?.type === 'StringLiteral'\n ) {\n const name = first['value'] as string\n defaulted.set(name, (defaulted.get(name) ?? true) && args.length > 1)\n }\n }\n for (const [key, value] of Object.entries(n)) {\n if (key !== 'loc' && key !== 'comments' && key !== 'extra' && key !== 'original') visit(value)\n }\n }\n visit(mod?.program ?? parse(lf))\n return [...defaulted].map(([name, all]) => ({ name, defaulted: all }))\n}\n","import type { Recipe } from '@nymbalhq/types'\n\nconst escapeRegExp = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\/]/g, '\\\\$&')\n\n/** `NAME=` or `# NAME=`: a variable the file already lists, set or commented out. */\nfunction declares(lines: string[], name: string): boolean {\n const re = new RegExp(`^(#\\\\s*)?${escapeRegExp(name)}=`)\n return lines.some((line) => re.test(line.trim()))\n}\n\n/** The recipe's variables `example` does not list, each once. */\nexport function missingEnv(example: string, recipe: Recipe): Recipe['env'] {\n const lines = example.split(/\\r?\\n/)\n return recipe.env.filter(\n (v, i) => !declares(lines, v.name) && recipe.env.findIndex((w) => w.name === v.name) === i,\n )\n}\n\n/**\n * `example` (a `.env.example`) with every variable of the recipe it does not list yet appended under a\n * `# <recipe> (nymbal add <recipe>)` header, each with its comment above it; an optional one is commented out.\n * No line is removed or moved, and a file that lists them all is returned as it is.\n */\nexport function appendRecipeEnv(example: string, recipe: Recipe): string {\n const eol = example.includes('\\r\\n') ? '\\r\\n' : '\\n'\n const missing = missingEnv(example, recipe)\n if (missing.length === 0) return example\n\n const block = [`# ${recipe.name} (nymbal add ${recipe.name})`]\n for (const v of missing) {\n if (v.comment !== '') block.push(`# ${v.comment}`)\n block.push(`${v.required ? '' : '# '}${v.name}=${v.example}`)\n }\n let head = example\n if (head !== '' && !head.endsWith('\\n')) head += eol\n const last = head.split(/\\r?\\n/).at(-2)\n const gap = last === undefined || last.trim() === '' ? '' : eol\n return `${head}${gap}${block.join(eol)}${eol}`\n}\n","import { existsSync } from 'node:fs'\nimport { defineCommand } from 'citty'\nimport type { LoadedConfig } from '@nymbalhq/config'\nimport { createLogger, diagnose, type DiagnosisReport } from '@nymbalhq/platform'\nimport { errorText, HEALTH_CHECK_TIMEOUT_MS } from '@nymbalhq/types'\nimport { loadProject } from '../utils/project.js'\nimport { resolveMigrations } from './migrate.js'\nimport { formatDoctorReport } from './doctor-report.js'\n\nfunction timeoutOf(flag: string | undefined): number {\n if (flag === undefined || flag.trim() === '') return HEALTH_CHECK_TIMEOUT_MS\n const ms = Number(flag)\n if (!Number.isInteger(ms) || ms < 1) {\n throw new Error(`--timeout must be a whole number of milliseconds, got \"${flag}\"`)\n }\n return ms\n}\n\n/**\n * The migrations `nymbal migrate` applies here, when it can find them; else diagnose reads those of the platform this\n * CLI runs, which are the ones its kernel expects.\n */\nfunction migrationsOf(projectRoot: string): { migrationsRoot?: string } {\n const root = resolveMigrations(projectRoot)\n return existsSync(root) ? { migrationsRoot: root } : {}\n}\n\nexport const doctorCommand = defineCommand({\n meta: {\n name: 'doctor',\n description:\n 'Check the project without changing it: config, packages, command store, migrations, slots and primitives',\n },\n args: {\n json: { type: 'boolean', description: 'Print the checks as one JSON document', default: false },\n timeout: {\n type: 'string',\n description: `How long each check may take, in ms (default ${HEALTH_CHECK_TIMEOUT_MS})`,\n },\n },\n async run({ args }) {\n const timeoutMs = timeoutOf(args.timeout)\n let loaded: LoadedConfig | { error: unknown }\n try {\n loaded = await loadProject()\n } catch (error) {\n loaded = { error }\n }\n const report: DiagnosisReport =\n 'error' in loaded\n ? // Nothing else can be checked without a config, so it is the only line.\n { checks: [{ name: 'config', status: 'down', detail: errorText(loaded.error) }] }\n : await diagnose(loaded.config, {\n ...(loaded.adapters !== undefined && { adapters: loaded.adapters }),\n // The report carries every failure; a log line would only repeat one, and break `--json`.\n logger: createLogger({ level: 'silent', pretty: false }),\n timeoutMs,\n ...migrationsOf(loaded.projectRoot),\n })\n const text = formatDoctorReport(report, {\n json: args.json,\n config: 'error' in loaded ? undefined : loaded.config,\n env: process.env,\n })\n const down = report.checks.some((check) => check.status === 'down')\n // A pipe on macOS is written asynchronously: exiting before the write lands would cut the report short.\n process.stdout.write(`${text}\\n`, () => process.exit(down ? 1 : 0))\n },\n})\n","import pc from 'picocolors'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport { scrub as scrubSettings, type DiagnosisReport } from '@nymbalhq/platform'\nimport { connectionSecrets, displayUrl, SECRET_MIN_LENGTH } from '@nymbalhq/types'\n\nexport interface FormatDoctorOptions {\n json: boolean\n /** The config the report was made from: its secret values are removed from every detail. */\n config?: NymbalConfig | undefined\n /** The environment it was made from, `.env` included: likewise. */\n env?: NodeJS.ProcessEnv\n}\n\ntype Status = DiagnosisReport['checks'][number]['status']\n\nconst TEXT_STATUS: Record<Status, 'ok' | 'warn' | 'down'> = {\n ok: 'ok',\n healthy: 'ok',\n degraded: 'warn',\n down: 'down',\n}\n\nconst JSON_STATUS: Record<Status, 'ok' | 'degraded' | 'down'> = {\n ok: 'ok',\n healthy: 'ok',\n degraded: 'degraded',\n down: 'down',\n}\n\nconst COLOUR = { ok: pc.green, warn: pc.yellow, down: pc.red }\n\n/** Config keys whose values are secrets: `secretKey`, `webhookSecret`, `jwtSecret`, SMTP's `pass`, an `apiKey`. */\nconst SECRET_KEY =\n /secret|passw(?:or)?d|^pass$|token|api[-_]?key|private[-_]?key|credential|access[-_]?key/i\n/** Environment variables whose values are secrets: `STRIPE_SECRET_KEY`, `SMTP_PASS`, `AWS_SECRET_ACCESS_KEY`. */\nconst SECRET_ENV =\n /SECRET|PASSWORD|PASSWD|(?:^|_)PASS(?:$|_)|TOKEN|API_KEY|PRIVATE_KEY|CREDENTIAL|ACCESS_KEY/i\nconst URL_IN_TEXT = /\\b[a-z][a-z0-9+.-]*:\\/\\/[^\\s'\"`<>]+/gi\nconst TRAILING_PUNCTUATION = /[.,;:)\\]}]+$/\n\nfunction addSecret(into: Set<string>, value: string): void {\n if (value.length >= SECRET_MIN_LENGTH) into.add(value)\n}\n\nfunction collectFromConfig(value: unknown, key: string, into: Set<string>, seen: WeakSet<object>) {\n if (typeof value === 'string') {\n if (SECRET_KEY.test(key)) addSecret(into, value)\n if (value.includes('://'))\n for (const s of connectionSecrets(value, { user: false })) addSecret(into, s)\n return\n }\n if (value === null || typeof value !== 'object' || seen.has(value)) return\n seen.add(value)\n for (const [k, v] of Object.entries(value)) collectFromConfig(v, k, into, seen)\n}\n\n/** Every value of `config` and `env` that must not be printed, longest first. */\nfunction secretsOf(config: NymbalConfig | undefined, env: NodeJS.ProcessEnv): string[] {\n const found = new Set<string>()\n collectFromConfig(config, '', found, new WeakSet())\n for (const [name, value] of Object.entries(env)) {\n if (value === undefined) continue\n if (SECRET_ENV.test(name)) addSecret(found, value)\n if (value.includes('://'))\n for (const s of connectionSecrets(value, { user: false })) addSecret(found, s)\n }\n return [...found].sort((a, b) => b.length - a.length)\n}\n\n/**\n * A detail as it may be printed: on one line, every URL as `scheme://host:port/db`, and no secret value, whether the\n * config and env hold it or diagnose decrypted it from Settings.\n */\nfunction scrub(detail: string, secrets: readonly string[]): string {\n let text = scrubSettings(detail).replace(URL_IN_TEXT, (match) => {\n const trailing = TRAILING_PUNCTUATION.exec(match)?.[0] ?? ''\n return displayUrl(match.slice(0, match.length - trailing.length)) + trailing\n })\n for (const secret of secrets) text = text.split(secret).join('***')\n return text.replace(/\\s*\\n\\s*(?:•\\s*)?/g, ' ').trim()\n}\n\n/**\n * Doctor's output: one line per check (`<ok|warn|down> <name> <detail>`) and a count, or with `json` one document,\n * `{ checks: [{ name, status, detail }] }`, whose status is `ok`, `degraded` or `down`. Neither prints a secret.\n */\nexport function formatDoctorReport(report: DiagnosisReport, options: FormatDoctorOptions): string {\n const secrets = secretsOf(options.config, options.env ?? {})\n const checks = report.checks.map((check) => ({\n name: check.name,\n status: check.status,\n detail: scrub(check.detail, secrets),\n }))\n if (options.json) {\n return JSON.stringify(\n {\n checks: checks.map((c) => ({\n name: c.name,\n status: JSON_STATUS[c.status],\n detail: c.detail,\n })),\n },\n null,\n 2,\n )\n }\n const width = Math.max(...checks.map((c) => c.name.length), 0)\n const lines = checks.map((c) => {\n const status = TEXT_STATUS[c.status]\n return `${COLOUR[status](status.padEnd(4))} ${c.name.padEnd(width)} ${c.detail}`.trimEnd()\n })\n const count = (s: 'ok' | 'warn' | 'down') =>\n checks.filter((c) => TEXT_STATUS[c.status] === s).length\n return [...lines, '', `${count('down')} down, ${count('warn')} warn, ${count('ok')} ok`].join(\n '\\n',\n )\n}\n","import { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport {\n createCommandStore,\n createSettingsRepository,\n decrypt,\n encrypt,\n isMissingSettingsTable,\n keyProblem,\n readSecretsKey,\n SECRETS_KEY_ENV,\n SECRETS_KEY_OLD_ENV,\n settingAad,\n type SettingRow,\n} from '@nymbalhq/platform'\nimport { loadProject } from '../utils/project.js'\n\n/** Rotation's refusal: exit 2, and nothing written. */\nclass RotationRefused extends Error {}\n\nfunction refuse(message: string): void {\n process.stderr.write(`${pc.red(`✗ ${message}`)}\\n`)\n process.exitCode = 2\n}\n\n/**\n * Every encrypted row decrypted under OLD and encrypted again under NEW, in one transaction. A row that is not OLD's,\n * or does not decrypt under it, refuses the rotation before anything is written. Values never reach the output.\n */\nexport async function rotateSecrets(env: NodeJS.ProcessEnv = process.env): Promise<number> {\n const oldKey = readSecretsKey(env, SECRETS_KEY_OLD_ENV)\n if (!oldKey.ok) throw new RotationRefused(keyProblem(oldKey.reason, SECRETS_KEY_OLD_ENV))\n const newKey = readSecretsKey(env, SECRETS_KEY_ENV)\n if (!newKey.ok) throw new RotationRefused(keyProblem(newKey.reason, SECRETS_KEY_ENV))\n const { config } = await loadProject()\n const store = createCommandStore(config)\n try {\n const repo = createSettingsRepository(store)\n return await store.transaction(async (tx) => {\n const rows = await repo.list(tx)\n const rotated: SettingRow[] = []\n for (const row of rows) {\n if (row.ciphertext === null) continue\n const field = `${row.slot}.${row.path}`\n if (row.keyId !== oldKey.id) {\n throw new RotationRefused(\n `${field} is under key ${row.keyId ?? '(none)'}, not ${SECRETS_KEY_OLD_ENV} (key ${oldKey.id}); nothing was rotated`,\n )\n }\n let value: string\n try {\n value = decrypt(oldKey.key, settingAad(row.slot, row.path), row)\n } catch {\n throw new RotationRefused(\n `${field} does not decrypt under ${SECRETS_KEY_OLD_ENV}; nothing was rotated`,\n )\n }\n const sealed = encrypt(newKey.key, settingAad(row.slot, row.path), value)\n rotated.push({ ...row, ...sealed, keyId: newKey.id, updatedAt: new Date() })\n }\n for (const row of rotated) await repo.put(tx, row)\n return rotated.length\n })\n } finally {\n await store.close()\n }\n}\n\n/** Deletes rows, every one or those of a slot or path, without the key: the recovery for a lost one. */\nexport async function clearSecrets(filter: { slot?: string; path?: string }): Promise<number> {\n const { config } = await loadProject()\n const store = createCommandStore(config)\n try {\n const repo = createSettingsRepository(store)\n return await store.transaction((tx) => repo.clear(tx, filter))\n } catch (error) {\n if (isMissingSettingsTable(error)) return 0\n throw error\n } finally {\n await store.close()\n }\n}\n\nconst rotateCommand = defineCommand({\n meta: {\n name: 'rotate',\n description: `Re-encrypt every saved secret from ${SECRETS_KEY_OLD_ENV} to ${SECRETS_KEY_ENV}, all or none`,\n },\n async run() {\n try {\n const count = await rotateSecrets()\n process.stdout.write(\n `${pc.green(`✓ rotated ${count} secret${count === 1 ? '' : 's'} to ${SECRETS_KEY_ENV}`)}\\n`,\n )\n } catch (error) {\n // Any failure leaves every row as it was (one transaction), and rotation answers 2 for all of them.\n refuse(error instanceof Error ? error.message : String(error))\n }\n },\n})\n\nconst clearCommand = defineCommand({\n meta: {\n name: 'clear',\n description: 'Delete saved settings (all, or one slot or path); needs no key',\n },\n args: {\n slot: { type: 'string', description: 'Only this slot' },\n path: { type: 'string', description: 'Only this path' },\n },\n async run({ args }) {\n const count = await clearSecrets({\n ...(args.slot !== undefined && { slot: args.slot }),\n ...(args.path !== undefined && { path: args.path }),\n })\n process.stdout.write(\n `${pc.green(`✓ cleared ${count} setting${count === 1 ? '' : 's'}`)}; restart the store to apply\\n`,\n )\n },\n})\n\nexport const secretsCommand = defineCommand({\n meta: { name: 'secrets', description: \"Manage the values saved in the admin's Settings\" },\n subCommands: { rotate: rotateCommand, clear: clearCommand },\n})\n","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { defineCommand } from 'citty'\nimport {\n createCommandStore,\n createEventLogRepository,\n sqliteFile,\n type CommandStore,\n type EventLogRepository,\n type LoggedEvent,\n} from '@nymbalhq/platform'\nimport { errorText, isValidCorrelationId } from '@nymbalhq/types'\nimport { loadProject } from '../utils/project.js'\n\nconst POLL_MS = 500\nconst TAIL_PAGE = 1000\n\n/** A bad flag or a missing store, said in the user's terms. */\nclass EventsError extends Error {}\n\n/** One line per event: `<seq> <timestamp> <type> <correlationId> <id>`, or its envelope as JSON. */\nfunction formatEvent(row: LoggedEvent, opts: { json: boolean; payload: boolean }): string {\n const { event } = row\n if (!opts.json) {\n // Events from before inbound ids were validated may carry any string: quoted, it cannot break the line.\n const correlationId = isValidCorrelationId(event.correlationId)\n ? event.correlationId\n : JSON.stringify(event.correlationId)\n return `${row.seq} ${event.timestamp} ${event.type} ${correlationId} ${event.id}`\n }\n // Payloads hold customer data: printed only when asked for.\n const { payload, ...envelope } = event\n return JSON.stringify({\n ...envelope,\n ...(opts.payload && { payload }),\n seq: row.seq,\n deliveredAt: row.deliveredAt,\n })\n}\n\nfunction timeFlag(name: string, value: string | undefined): Date | undefined {\n if (value === undefined) return undefined\n const at = new Date(value)\n if (value.trim() === '' || Number.isNaN(at.getTime())) {\n throw new EventsError(`--${name} must be an ISO 8601 time, got \"${value}\"`)\n }\n return at\n}\n\nfunction countFlag(name: string, value: string | undefined, min: number): number | undefined {\n if (value === undefined) return undefined\n const n = Number(value)\n if (value.trim() === '' || !Number.isInteger(n) || n < min) {\n throw new EventsError(`--${name} must be a whole number of at least ${min}, got \"${value}\"`)\n }\n return n\n}\n\nfunction typesFlag(value: string | undefined): { types?: string[] } {\n if (value === undefined) return {}\n if (value.trim() === '') throw new EventsError('--type must not be empty')\n return { types: [value] }\n}\n\n/** The project's command store, opened read-only as `nymbal doctor` opens it: these commands never write. */\nasync function openLog(): Promise<{ store: CommandStore; eventLog: EventLogRepository }> {\n const { config } = await loadProject()\n if (config.infrastructure.commandStore === 'sqlite') {\n const path = sqliteFile()\n if (!existsSync(resolve(path))) {\n throw new EventsError(`no database at ${path}: run \\`nymbal migrate\\``)\n }\n }\n const store = createCommandStore(config, { readOnly: true })\n return { store, eventLog: createEventLogRepository(store) }\n}\n\n/** Runs `body`; any error it throws (a bad flag, no config, no store) is printed to stderr with exit code 2. */\nasync function guarded(body: () => Promise<void>): Promise<void> {\n try {\n await body()\n } catch (error) {\n process.stderr.write(`nymbal events: ${errorText(error)}\\n`)\n process.exitCode = 2\n }\n}\n\nfunction write(lines: string[]): Promise<void> {\n if (lines.length === 0) return Promise.resolve()\n return new Promise((done) => process.stdout.write(`${lines.join('\\n')}\\n`, () => done()))\n}\n\nconst outputArgs = {\n json: {\n type: 'boolean',\n description: 'One envelope per line, with seq and deliveredAt',\n default: false,\n },\n payload: {\n type: 'boolean',\n description: 'Include each event’s payload (it may hold customer data)',\n default: false,\n },\n} as const\n\nconst queryCommand = defineCommand({\n meta: { name: 'query', description: 'Print one correlation id’s events, in seq order' },\n args: {\n correlation: { type: 'string', description: 'The correlation id (required)' },\n type: {\n type: 'string',\n description: 'Only types matching this glob; * matches anything (order.*)',\n },\n since: { type: 'string', description: 'Only events appended at or after this ISO time' },\n until: { type: 'string', description: 'Only events appended before this ISO time' },\n limit: { type: 'string', description: 'At most this many events (default 1000)' },\n ...outputArgs,\n },\n run: ({ args }) =>\n guarded(async () => {\n const correlationId = args.correlation\n if (correlationId === undefined || correlationId === '') {\n throw new EventsError('--correlation <id> is required')\n }\n const since = timeFlag('since', args.since)\n const until = timeFlag('until', args.until)\n const filter = {\n ...typesFlag(args.type),\n ...(since !== undefined && { since }),\n ...(until !== undefined && { until }),\n limit: countFlag('limit', args.limit, 1) ?? 1000,\n }\n const { store, eventLog } = await openLog()\n try {\n const rows = await store.read((tx) =>\n eventLog.queryByCorrelation(tx, correlationId, filter),\n )\n await write(rows.map((row) => formatEvent(row, args)))\n } finally {\n await store.close()\n }\n }),\n})\n\nconst tailCommand = defineCommand({\n meta: {\n name: 'tail',\n description:\n 'Print events as they are appended, until interrupted. Exact for serially committed events; on Postgres an ' +\n 'event whose lower seq commits after a higher one has been printed is skipped.',\n },\n args: {\n type: {\n type: 'string',\n description: 'Only types matching this glob; * matches anything (order.*)',\n },\n from: {\n type: 'string',\n description: 'Print events above this seq (default: the current maximum)',\n },\n ...outputArgs,\n },\n run: ({ args }) =>\n guarded(async () => {\n const types = typesFlag(args.type)\n const from = countFlag('from', args.from, 0)\n const { store, eventLog } = await openLog()\n let stopped = false\n let wake: (() => void) | undefined\n const stop = () => {\n stopped = true\n wake?.()\n }\n process.once('SIGINT', stop)\n process.once('SIGTERM', stop)\n try {\n let cursor = from ?? (await store.read((tx) => eventLog.maxSeq(tx)))\n process.stderr.write(`tailing from seq ${cursor}\\n`)\n while (!stopped) {\n const after = cursor\n const rows = await store.read((tx) =>\n eventLog.listAfter(tx, after, { ...types, limit: TAIL_PAGE }),\n )\n await write(rows.map((row) => formatEvent(row, args)))\n if (rows.length > 0) cursor = rows[rows.length - 1]!.seq\n // A full page means more is waiting: read it now.\n if (rows.length === TAIL_PAGE) continue\n await new Promise<void>((done) => {\n const timer = setTimeout(done, POLL_MS)\n wake = () => {\n clearTimeout(timer)\n done()\n }\n })\n wake = undefined\n }\n } finally {\n process.off('SIGINT', stop)\n process.off('SIGTERM', stop)\n await store.close()\n }\n }),\n})\n\nexport const eventsCommand = defineCommand({\n meta: { name: 'events', description: 'Read the event log without changing it' },\n subCommands: { query: queryCommand, tail: tailCommand },\n})\n","import { createWriteStream, existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { once } from 'node:events'\nimport type { Writable } from 'node:stream'\nimport { defineCommand } from 'citty'\nimport {\n auditEntriesInOrder,\n createCommandStore,\n sqliteFile,\n type AuditFilter,\n} from '@nymbalhq/platform'\nimport { errorText } from '@nymbalhq/types'\nimport { loadProject } from '../utils/project.js'\n\n/** A bad flag or a missing store, said in the user's terms. */\nclass AuditError extends Error {}\n\nfunction timeFlag(name: string, value: string | undefined): Date | undefined {\n if (value === undefined) return undefined\n const at = new Date(value)\n if (value.trim() === '' || Number.isNaN(at.getTime())) {\n throw new AuditError(`--${name} must be an ISO 8601 time, got \"${value}\"`)\n }\n return at\n}\n\nasync function write(out: Writable, text: string): Promise<void> {\n if (!out.write(text)) await once(out, 'drain')\n}\n\nconst exportCommand = defineCommand({\n meta: {\n name: 'export',\n description:\n 'Print audit entries as NDJSON, oldest first: ids only, no event payloads or customer data',\n },\n args: {\n since: { type: 'string', description: 'Only entries at or after this ISO time' },\n until: { type: 'string', description: 'Only entries before this ISO time' },\n correlation: { type: 'string', description: 'Only the entries of this correlation id' },\n out: { type: 'string', description: 'Write the lines to this file instead of stdout' },\n },\n async run({ args }) {\n try {\n const since = timeFlag('since', args.since)\n const until = timeFlag('until', args.until)\n const filter: AuditFilter = {\n ...(since !== undefined && { since }),\n ...(until !== undefined && { until }),\n ...(args.correlation !== undefined && { correlation: args.correlation }),\n }\n const { config } = await loadProject()\n if (config.infrastructure.commandStore === 'sqlite') {\n const path = sqliteFile()\n if (!existsSync(resolve(path))) {\n throw new AuditError(`no database at ${path}: run \\`nymbal migrate\\``)\n }\n }\n // Opened read-only, as `nymbal doctor` and `nymbal events` open it: an export never writes the store.\n const store = createCommandStore(config, { readOnly: true })\n const out = args.out === undefined ? process.stdout : createWriteStream(args.out)\n try {\n for await (const entry of auditEntriesInOrder(store, filter)) {\n await write(out, `${JSON.stringify(entry)}\\n`)\n }\n } finally {\n await store.close()\n if (out !== process.stdout) {\n out.end()\n await once(out, 'finish')\n }\n }\n } catch (error) {\n process.stderr.write(`nymbal audit: ${errorText(error)}\\n`)\n process.exitCode = 2\n }\n },\n})\n\nexport const auditCommand = defineCommand({\n meta: { name: 'audit', description: 'Read the audit trail' },\n subCommands: { export: exportCommand },\n})\n","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { defineCommand } from 'citty'\nimport {\n createLogger,\n diffReadModel,\n openReadModels,\n READ_MODEL_NAMES,\n rebuild,\n sqliteFile,\n type ReadModelDiff,\n type ReadModelName,\n type RebuildReport,\n} from '@nymbalhq/platform'\nimport { errorText } from '@nymbalhq/types'\nimport { loadProject } from '../utils/project.js'\n\n/** A bad flag, a missing store or a refused model, said in the user's terms. */\nclass ReplayError extends Error {}\n\nfunction modelsOf(to: string | undefined): readonly ReadModelName[] {\n const choices = `${READ_MODEL_NAMES.join(', ')} or all`\n if (to === undefined || to === '') throw new ReplayError(`--to <model> is required: ${choices}`)\n if (to === 'all') return READ_MODEL_NAMES\n const name = READ_MODEL_NAMES.find((n) => n === to)\n if (name === undefined) throw new ReplayError(`--to must be ${choices}, got \"${to}\"`)\n return [name]\n}\n\nconst plural = (n: number, word: string) => `${n} ${word}${n === 1 ? '' : 's'}`\n\n/** One block per model: what was swapped in, with each collection's documents, and any catch-up event that failed. */\nexport function formatRebuildReport(report: RebuildReport): string {\n const lines: string[] = []\n for (const entry of report) {\n const caught = plural(entry.caughtUpEvents, 'event')\n lines.push(\n entry.failures.length === 0\n ? `${entry.model}: swapped in ${entry.ms} ms, ${caught} caught up`\n : `${entry.model}: swapped in ${entry.ms} ms, but ${plural(entry.failures.length, 'catch-up event')} failed ` +\n '(the model is swapped without them: fix the cause and replay it again)',\n )\n for (const c of entry.collections) lines.push(` ${c.name} ${c.documents}`)\n for (const f of entry.failures) {\n lines.push(` failed: seq ${f.seq} ${f.type} (${f.handler}): ${f.error}`)\n }\n if (entry.note !== undefined) lines.push(` note: ${entry.note}`)\n }\n return lines.join('\\n')\n}\n\n/** One block per model: per collection, the documents a rebuild would add, change and remove. */\nexport function formatDiff(diffs: ReadModelDiff[]): string {\n const lines: string[] = []\n for (const diff of diffs) {\n lines.push(`${diff.model} (dry run, nothing written):`)\n if (diff.skipped !== undefined) lines.push(` skipped: ${diff.skipped}`)\n for (const c of diff.collections) {\n lines.push(` ${c.name}: ${c.added} added, ${c.changed} changed, ${c.removed} removed`)\n }\n }\n return lines.join('\\n')\n}\n\nconst differs = (diffs: ReadModelDiff[]) =>\n diffs.some((d) => d.collections.some((c) => c.added + c.changed + c.removed > 0))\n\nfunction write(stream: NodeJS.WriteStream, text: string): Promise<void> {\n return new Promise((done) => stream.write(`${text}\\n`, () => done()))\n}\n\nexport const replayCommand = defineCommand({\n meta: {\n name: 'replay',\n description:\n 'Rebuild a derived read model from the command store and swap it in: catalogue, orders, customers, search or all',\n },\n args: {\n to: {\n type: 'string',\n description: 'The read model: catalogue, orders, customers, search or all',\n },\n 'dry-run': {\n type: 'boolean',\n description:\n 'Rebuild into memory and count what differs from the live read model; exits 1 if anything does',\n default: false,\n },\n },\n async run({ args }) {\n try {\n const names = modelsOf(args.to)\n const { config, adapters } = await loadProject()\n const shared = names.filter((n) => n !== 'search')\n if (config.infrastructure.documentStore === 'in-memory' && shared.length > 0) {\n throw new ReplayError(\n `the ${shared.join(', ')} read model${shared.length === 1 ? '' : 's'} live in the server's own process ` +\n '(documentStore: in-memory), out of reach of this one; a restart of the server rebuilds them. ' +\n 'With documentStore redis or postgres-jsonb the read models are shared, and replay rebuilds them in ' +\n 'place. --to search works here: the native index lives in the command store.',\n )\n }\n if (config.infrastructure.commandStore === 'sqlite' && !existsSync(resolve(sqliteFile()))) {\n throw new ReplayError(`no database at ${sqliteFile()}: run \\`nymbal migrate\\``)\n }\n const { deps, close } = await openReadModels(config, {\n // The report says what happened; log lines would repeat it.\n logger: createLogger({ level: 'silent', pretty: false }),\n ...(adapters !== undefined && { adapters }),\n })\n try {\n if (args['dry-run']) {\n const diffs: ReadModelDiff[] = []\n for (const name of names) diffs.push(await diffReadModel(name, deps))\n await write(process.stdout, formatDiff(diffs))\n process.exitCode = differs(diffs) ? 1 : 0\n return\n }\n const report = await rebuild(names, deps)\n await write(process.stdout, formatRebuildReport(report))\n process.exitCode = report.some((e) => e.failures.length > 0) ? 2 : 0\n } finally {\n await close()\n }\n } catch (error) {\n await write(process.stderr, `nymbal replay: ${errorText(error)}`)\n process.exitCode = 2\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport { createLogger, importProviderPackage } from '@nymbalhq/platform'\nimport {\n errorText,\n type DriftReport,\n type SecurityState,\n type ValidationResult,\n} from '@nymbalhq/types'\nimport { loadProject } from '../utils/project.js'\n\ntype Security = NymbalConfig['security']\n\ninterface EdgeRule {\n ref?: string\n expression: string\n action: string\n}\n\n/** `@nymbalhq/security-cloudflare`'s SecurityPlan, as far as the CLI prints it. */\ninterface SecurityPlan {\n phases: Array<{\n phase: string\n add: EdgeRule[]\n change: Array<{ ref: string; from: EdgeRule; to: EdgeRule }>\n remove: EdgeRule[]\n }>\n}\n\n/** The Cloudflare adapter's commands beside the SecurityAdapter it is. */\ninterface EdgeSecurityAdapter {\n validate(config: Security): Promise<ValidationResult>\n plan(config: Security): Promise<SecurityPlan>\n apply(config: Security): Promise<SecurityPlan>\n drift(config: Security): Promise<DriftReport>\n inspect(): Promise<SecurityState>\n}\n\ninterface EdgeModule {\n createAdapter(ctx: unknown): unknown\n hasSingleStar(key: string): boolean\n}\n\n/** 0 done or in sync, 1 drift (`security:drift` only), 2 a config, credential or API error. */\ntype ExitCode = 0 | 1 | 2\n\ninterface Outcome {\n code: ExitCode\n stdout: string[]\n stderr: string[]\n}\n\nconst failure = (...stderr: string[]): Outcome => ({ code: 2, stdout: [], stderr })\n\nconst isEmpty = (plan: SecurityPlan): boolean =>\n plan.phases.every((p) => p.add.length + p.change.length + p.remove.length === 0)\n\nfunction formatPlan(plan: SecurityPlan): string[] {\n const lines: string[] = []\n for (const { phase, add, change, remove } of plan.phases) {\n if (add.length + change.length + remove.length === 0) continue\n lines.push(\n `${phase}: ${add.length} to add, ${change.length} to change, ${remove.length} to remove`,\n )\n for (const rule of add) lines.push(` + ${rule.ref} ${rule.action} ${rule.expression}`)\n for (const { ref, to } of change) lines.push(` ~ ${ref} ${to.action} ${to.expression}`)\n for (const rule of remove) lines.push(` - ${rule.ref}`)\n }\n return lines\n}\n\nfunction invalid(result: ValidationResult): Outcome {\n return failure(\n 'The security config cannot go onto the zone:',\n ...result.errors.map((e) => ` ${e.code} ${e.message}`),\n )\n}\n\n/** What the edge does differently from the config as the origin reads it. */\nfunction edgeNotes(security: Security, mod: EdgeModule): string[] {\n const notes = Object.keys(security.rateLimit)\n .filter((key) => key.startsWith('/') && mod.hasSingleStar(key))\n .map(\n (key) =>\n `note: '${key}' matches one path segment per * in process, but any number at the edge (Cloudflare's * crosses /)`,\n )\n if (security.botProtection.mode !== 'off') {\n notes.push(\n 'note: botProtection is left as the zone has it: Bot Fight Mode is a zone setting, not a ruleset rule',\n )\n }\n return notes\n}\n\n/** Writes the outcome with every secret masked, then exits once both streams have flushed. */\nfunction finish(outcome: Outcome, secrets: readonly string[]): void {\n const masked = (lines: string[]): string =>\n lines\n .map((line) => secrets.reduce((text, secret) => text.split(secret).join('***'), line))\n .map((line) => `${line}\\n`)\n .join('')\n process.stderr.write(masked(outcome.stderr), () =>\n process.stdout.write(masked(outcome.stdout), () => process.exit(outcome.code)),\n )\n}\n\n/**\n * Loads the project, builds the Cloudflare adapter from `security.cloudflare`, and runs `body` on it. A store whose\n * adapter is not `cloudflare` has no edge, and any error is exit 2 with its message.\n */\nasync function runEdge(\n command: string,\n body: (adapter: EdgeSecurityAdapter, security: Security, mod: EdgeModule) => Promise<Outcome>,\n): Promise<void> {\n const secrets = [process.env['CLOUDFLARE_API_TOKEN']]\n let outcome: Outcome\n try {\n const { config } = await loadProject()\n const security = config.security\n secrets.push(security.cloudflare?.apiToken)\n if (security.adapter !== 'cloudflare') {\n outcome = failure(\n `security.adapter is '${security.adapter}', which has no edge rules for nymbal ${command}: ` +\n \"set security.adapter to 'cloudflare' (nymbal add cloudflare) to manage them on a Cloudflare zone\",\n )\n } else {\n const mod = (await importProviderPackage(\n 'security',\n 'cloudflare',\n process.env,\n )) as unknown as EdgeModule\n const adapter = (await mod.createAdapter({\n slot: 'security',\n config: security.cloudflare ?? {},\n logger: createLogger({ level: 'silent', pretty: false }),\n env: process.env,\n })) as EdgeSecurityAdapter\n outcome = await body(adapter, security, mod)\n }\n } catch (error) {\n outcome = failure(`nymbal ${command} failed: ${errorText(error)}`)\n }\n finish(\n outcome,\n secrets.filter((s): s is string => typeof s === 'string' && s !== ''),\n )\n}\n\nconst json = {\n type: 'boolean',\n description: 'Print the result as one JSON document',\n default: false,\n} as const\n\nexport const securityPlanCommand = defineCommand({\n meta: {\n name: 'security:plan',\n description: 'Show what security:apply would change on the Cloudflare zone',\n },\n args: { json },\n run: ({ args }) =>\n runEdge('security:plan', async (adapter, security, mod) => {\n const check = await adapter.validate(security)\n if (!check.valid) return invalid(check)\n const plan = await adapter.plan(security)\n const notes = edgeNotes(security, mod)\n if (args.json) return { code: 0, stdout: [JSON.stringify(plan, null, 2)], stderr: notes }\n const lines = isEmpty(plan)\n ? ['No changes: the zone holds every Nymbal rule.']\n : formatPlan(plan)\n return { code: 0, stdout: [...lines, ...notes], stderr: [] }\n }),\n})\n\nexport const securityApplyCommand = defineCommand({\n meta: {\n name: 'security:apply',\n description:\n \"Write the store's security rules to the Cloudflare zone, leaving the zone's own rules\",\n },\n run: () =>\n runEdge('security:apply', async (adapter, security) => {\n const check = await adapter.validate(security)\n if (!check.valid) return invalid(check)\n const done = await adapter.apply(security)\n const lines = isEmpty(done)\n ? ['Nothing to write: the zone already holds every Nymbal rule.']\n : ['Applied:', ...formatPlan(done)]\n return { code: 0, stdout: lines, stderr: [] }\n }),\n})\n\nexport const securityDriftCommand = defineCommand({\n meta: {\n name: 'security:drift',\n description: \"Report where the zone's Nymbal rules differ from the config (exit 1 on drift)\",\n },\n args: { json },\n run: ({ args }) =>\n runEdge('security:drift', async (adapter, security) => {\n const report = await adapter.drift(security)\n const code: ExitCode = report.drift ? 1 : 0\n if (args.json) return { code, stdout: [JSON.stringify(report, null, 2)], stderr: [] }\n if (!report.drift)\n return { code, stdout: ['In sync: the zone holds every Nymbal rule.'], stderr: [] }\n const lines = report.differences.map(\n (d) =>\n ` ${d.path} configured ${JSON.stringify(d.configured) ?? 'nothing'}, live ${JSON.stringify(d.actual) ?? 'nothing'}`,\n )\n return {\n code,\n stdout: [\n `Drift: ${report.differences.length} difference(s); security:apply restores them`,\n ...lines,\n ],\n stderr: [],\n }\n }),\n})\n\nexport const securityInspectCommand = defineCommand({\n meta: {\n name: 'security:inspect',\n description: 'List the Nymbal rules live on the Cloudflare zone',\n },\n run: () =>\n runEdge('security:inspect', async (adapter) => {\n const { rulesApplied } = await adapter.inspect()\n const lines =\n rulesApplied.length === 0 ? ['No Nymbal rules are live on the zone.'] : rulesApplied\n return { code: 0, stdout: lines, stderr: [] }\n }),\n})\n","import { defineCommand } from 'citty'\nimport { loadConfig } from '@nymbalhq/config'\nimport { run, runOrFail } from '../utils/spawn.js'\nimport { CertifyError, certifyPackage } from './test-contracts.js'\n\nexport const testCommand = defineCommand({\n meta: { name: 'test', description: 'Run unit + integration tests (vitest)' },\n async run() {\n await runOrFail('pnpm', ['vitest', 'run'])\n },\n})\n\nexport const testE2eCommand = defineCommand({\n meta: { name: 'test:e2e', description: 'Run Playwright E2E against the configured template' },\n async run() {\n const { config } = await loadConfig()\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep-invert', '@visual|@a11y',\n ])\n },\n})\n\nexport const testVisualCommand = defineCommand({\n meta: { name: 'test:visual', description: 'Run visual regression tests (Playwright toHaveScreenshot)' },\n args: {\n 'update-baselines': {\n type: 'boolean',\n description: 'Regenerate screenshot baselines',\n default: false,\n },\n },\n async run({ args }) {\n const { config } = await loadConfig()\n const isCI = !!process.env.CI\n const updateBaselines = args['update-baselines']\n\n if (updateBaselines && !isCI) {\n // Run in Docker for Linux-consistent baselines\n const dockerImage = 'mcr.microsoft.com/playwright:v1.50-jammy'\n const cwd = process.cwd()\n await runOrFail('docker', [\n 'run', '--rm', '-v', `${cwd}:${cwd}`, '-w', cwd,\n dockerImage, 'sh', '-c',\n `pnpm --filter @nymbalhq/e2e exec playwright test --project ${config.template} --grep \"@visual\" --update-snapshots`,\n ])\n } else {\n const pwArgs = [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep', '@visual',\n ]\n if (updateBaselines) pwArgs.push('--update-snapshots')\n await runOrFail('pnpm', pwArgs)\n }\n },\n})\n\nexport const testContractsCommand = defineCommand({\n meta: { name: 'test:contracts', description: 'Run adapter contract tests, or certify an adapter package' },\n args: {\n adapter: { type: 'string', description: 'Run only contracts for a specific adapter (e.g. payments, email)' },\n package: {\n type: 'string',\n description: \"Certify an installed adapter package against the published suite for its kind\",\n },\n slot: { type: 'string', description: 'With --package: the commerce slot whose config builds it' },\n },\n async run({ args }) {\n if (args.package) {\n const code = await certifyPackage({\n pkg: String(args.package),\n ...(args.slot !== undefined && { slot: String(args.slot) }),\n cwd: process.cwd(),\n }).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err)\n const line = err instanceof CertifyError ? message : `test:contracts: ${message}`\n process.stderr.write(`${line.split('\\n')[0]}\\n`)\n return 1\n })\n // Exits once the output is written: an adapter under test may hold a connection open after its suite.\n await Promise.all([\n new Promise((done) => process.stdout.write('', done)),\n new Promise((done) => process.stderr.write('', done)),\n ])\n process.exit(code)\n }\n const vArgs = [\n 'vitest', 'run',\n '--project', 'contracts-native',\n ]\n if (args.adapter) {\n // Pass the specific file path as additional argument\n vArgs.push(`tests/contracts/${String(args.adapter)}.test.ts`)\n }\n await runOrFail('pnpm', vArgs)\n },\n})\n\nexport const testPerformanceCommand = defineCommand({\n meta: { name: 'test:performance', description: 'Run Lighthouse CI against the configured template' },\n async run() {\n const { config } = await loadConfig()\n const port = config.template === 'nextjs' ? 3000 : 4321\n await runOrFail('pnpm', ['lhci', 'autorun'], {\n env: {\n ...process.env,\n NYMBAL_TEMPLATE: config.template,\n NYMBAL_TEMPLATE_PORT: String(port),\n },\n })\n },\n})\n\nexport const testAllCommand = defineCommand({\n meta: { name: 'test:all', description: 'Run unit, contract, e2e, visual, and performance tests' },\n async run() {\n const steps: Array<{ name: string; args: string[] }> = [\n { name: 'unit', args: ['vitest', 'run'] },\n { name: 'contracts', args: ['vitest', 'run', '--project', 'contracts-native'] },\n ]\n\n for (const step of steps) {\n const { done } = run('pnpm', step.args)\n const code = await done\n if (code !== 0) {\n // eslint-disable-next-line no-console\n console.error(`✗ ${step.name} failed`)\n process.exit(code)\n }\n }\n\n const { config } = await loadConfig()\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep-invert', '@visual|@a11y',\n ])\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep', '@visual',\n ])\n await runOrFail('pnpm', ['lhci', 'autorun'], {\n env: { ...process.env, NYMBAL_TEMPLATE: config.template },\n })\n },\n})\n","import { mkdirSync, realpathSync, writeFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { dirname, join, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { isDeepStrictEqual } from 'node:util'\nimport { findConfigFile, loadConfig } from '@nymbalhq/config'\nimport { isInstalled } from '../recipes/holders.js'\n\n/** A reason `test:contracts --package` cannot run, printed as its one line. */\nexport class CertifyError extends Error {}\n\n/** What a third-party adapter package may export beside `createAdapter`. */\ninterface ContractOptionsExport {\n /** The options `createAdapter` takes when no slot of the project names the package. */\n options?: unknown\n /** The options that build an adapter whose dependency cannot be reached: given, the downtime cases run. */\n unreachable?: unknown\n /** A primitive's kind (`documentStore`, `eventBus` or `media`); a commerce adapter says its own `kind`. */\n kind?: string\n}\n\ninterface AdapterModule {\n createAdapter?: unknown\n contractOptions?: ContractOptionsExport\n}\n\ninterface TaskLike {\n type: string\n mode?: string\n result?: { state?: string }\n tasks?: TaskLike[]\n}\n\ninterface VitestLike {\n state: { getFiles(): TaskLike[]; getUnhandledErrors(): unknown[] }\n close(): Promise<void>\n}\n\nconst firstLine = (text: string): string => text.split('\\n')[0]!.trim()\nconst messageOf = (err: unknown): string =>\n firstLine(err instanceof Error ? err.message : String(err))\n\n/** Where the project resolves `specifier`, as its own code would; a package it has not installed is the install line. */\nfunction resolveFrom(project: string, specifier: string, name: string, install: string): string {\n try {\n return createRequire(join(project, 'package.json')).resolve(specifier)\n } catch (err) {\n if ((err as { code?: unknown }).code === 'MODULE_NOT_FOUND') {\n throw new CertifyError(`${name} is not installed in ${project}: ${install}`)\n }\n throw new CertifyError(`${name} could not be resolved from ${project}: ${messageOf(err)}`)\n }\n}\n\n/** The `config` record of the project's commerce slot that names `pkg`, or undefined when none does. */\nasync function slotOptions(\n project: string,\n pkg: string,\n slot: string | undefined,\n): Promise<Record<string, unknown> | undefined> {\n if (findConfigFile(project) === null) return undefined\n let commerce: Record<string, unknown>\n try {\n commerce = (await loadConfig(project)).config.commerce as unknown as Record<string, unknown>\n } catch (err) {\n throw new CertifyError(`the project's config could not be loaded: ${messageOf(err)}`)\n }\n const naming = Object.entries(commerce).filter(([, block]) => {\n const b = block as { provider?: unknown; package?: unknown }\n return b.provider === 'custom' && b.package === pkg\n })\n const picked = slot === undefined ? naming : naming.filter(([name]) => name === slot)\n if (slot !== undefined && picked.length === 0) {\n throw new CertifyError(`no commerce slot '${slot}' with provider 'custom' names ${pkg}`)\n }\n if (picked.length > 1) {\n throw new CertifyError(\n `${pkg} is named by the ${picked.map(([name]) => name).join(', ')} slots: pick one with --slot`,\n )\n }\n const block = picked[0]?.[1] as { config?: Record<string, unknown> } | undefined\n return block === undefined ? undefined : (block.config ?? {})\n}\n\n/**\n * `value` with every own key whose value is `undefined` dropped, at any depth: an unset optional\n * (`apiKey: process.env.ACME_KEY`) is absent, as JSON leaves it. Anything but a plain object or array, and a cycle, is\n * kept as it is, for survivesJson to refuse.\n */\nfunction withoutUndefined(value: unknown, path: Set<object> = new Set()): unknown {\n if (value === null || typeof value !== 'object' || path.has(value)) return value\n const proto = Object.getPrototypeOf(value) as unknown\n if (!Array.isArray(value) && proto !== Object.prototype && proto !== null) return value\n path.add(value)\n const out = Array.isArray(value)\n ? value.map((item) => withoutUndefined(item, path))\n : Object.fromEntries(\n Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => [k, withoutUndefined(v, path)]),\n )\n path.delete(value)\n return out\n}\n\n/** Whether a JSON round-trip gives `value` back unchanged; a value JSON cannot write (a BigInt, a cycle) does not. */\nfunction survivesJson(value: unknown): boolean {\n try {\n return isDeepStrictEqual(JSON.parse(JSON.stringify(value)), value)\n } catch {\n return false\n }\n}\n\nasync function closeProbe(adapter: unknown): Promise<void> {\n const close = (adapter as { close?: unknown } | null)?.close\n if (typeof close === 'function') await (close as () => Promise<void>).call(adapter)\n}\n\nfunction countCases(files: TaskLike[]): { passed: number; failed: number } {\n let passed = 0\n let failed = 0\n const visit = (task: TaskLike) => {\n if (task.type === 'test') {\n if (task.result?.state === 'pass') passed += 1\n else if (task.mode !== 'skip' && task.mode !== 'todo') failed += 1\n }\n for (const child of task.tasks ?? []) visit(child)\n }\n for (const file of files) visit(file)\n return { passed, failed }\n}\n\n/**\n * Certifies `pkg`, an adapter package installed in the project: builds it from the config of the project's slot that\n * names it, and runs the published suite for its kind with the project's own vitest. Returns the exit code.\n */\nexport async function certifyPackage(input: {\n pkg: string\n slot?: string\n cwd: string\n}): Promise<number> {\n const { pkg, slot } = input\n const config = findConfigFile(input.cwd)\n const project = realpathSync(config === null ? resolve(input.cwd) : dirname(config))\n\n const vitestNode = resolveFrom(project, 'vitest/node', 'vitest', 'npm install --save-dev vitest')\n // The suites' vitest-free entry: the suites themselves import vitest, which throws outside a test run.\n const kindsEntry = resolveFrom(\n project,\n '@nymbalhq/contract-tests/kinds',\n '@nymbalhq/contract-tests',\n 'npm install --save-dev @nymbalhq/contract-tests',\n )\n if (!isInstalled(pkg, project)) {\n throw new CertifyError(`${pkg} is not installed in ${project}: npm install ${pkg}`)\n }\n\n const contracts = join(project, '.nymbal', 'contracts')\n const slug = pkg.replace(/[^a-z0-9]+/gi, '-').replace(/^-|-$/g, '')\n mkdirSync(contracts, { recursive: true })\n // Imported from inside the project, so Node resolves the package from the project's node_modules, as vitest will.\n const shim = join(contracts, `${slug}.adapter.mjs`)\n writeFileSync(shim, `export * from ${JSON.stringify(pkg)}\\n`)\n let mod: AdapterModule\n try {\n mod = (await import(pathToFileURL(shim).href)) as AdapterModule\n } catch (err) {\n throw new CertifyError(`${pkg} could not be loaded: ${messageOf(err)}`)\n }\n if (typeof mod.createAdapter !== 'function') {\n throw new CertifyError(`${pkg} exports no createAdapter(options) function to certify`)\n }\n const createAdapter = mod.createAdapter as (options: unknown) => unknown\n const extra = mod.contractOptions ?? {}\n const slotConfig = await slotOptions(project, pkg, slot)\n const fromSlot =\n slotConfig === undefined ? undefined : (withoutUndefined(slotConfig) as Record<string, unknown>)\n const options = fromSlot ?? extra.options ?? {}\n // The generated file carries the slot's record as JSON, so a record JSON changes would certify another adapter.\n if (fromSlot !== undefined && !survivesJson(fromSlot)) {\n throw new CertifyError(\n `the config of the slot naming ${pkg} holds a value JSON cannot carry (a function, Date, BigInt or cycle): certify it with plain data`,\n )\n }\n\n let kind: string | undefined\n try {\n const probe = await createAdapter(options)\n const own = (probe as { kind?: unknown } | null)?.kind\n kind = typeof own === 'string' ? own : extra.kind\n await closeProbe(probe)\n } catch (err) {\n throw new CertifyError(`createAdapter from ${pkg} threw: ${messageOf(err)}`)\n }\n if (kind === undefined) {\n throw new CertifyError(\n `${pkg}'s adapter has no kind: a primitive names its own in contractOptions.kind`,\n )\n }\n const { CONTRACT_KINDS } = (await import(pathToFileURL(kindsEntry).href)) as {\n CONTRACT_KINDS: readonly string[]\n }\n if (!CONTRACT_KINDS.includes(kind)) {\n throw new CertifyError(\n `no contract suite for kind '${kind}' (${pkg}); the kinds with one are ${CONTRACT_KINDS.join(', ')}`,\n )\n }\n\n const file = `${slug}.contract.test.mjs`\n writeFileSync(\n join(contracts, file),\n [\n `// Written by \\`nymbal test:contracts --package ${pkg}\\`, and again on every run.`,\n `import * as adapter from ${JSON.stringify(pkg)}`,\n `import { contractSuites } from '@nymbalhq/contract-tests'`,\n ``,\n fromSlot === undefined\n ? `const options = adapter.contractOptions?.options ?? {}`\n : `const options = ${JSON.stringify(fromSlot)}`,\n `const unreachable = adapter.contractOptions?.unreachable`,\n ``,\n `async function build(config) {`,\n ` const built = await adapter.createAdapter(config)`,\n ` if (typeof built?.initialize === 'function') await built.initialize(config)`,\n ` return built`,\n `}`,\n ``,\n `contractSuites[${JSON.stringify(kind)}](${JSON.stringify(pkg)}, () => build(options), {`,\n ` ...(unreachable !== undefined && { unreachable: () => build(unreachable) }),`,\n `})`,\n ``,\n ].join('\\n'),\n )\n\n const { startVitest } = (await import(pathToFileURL(vitestNode).href)) as {\n startVitest: (\n mode: 'test',\n filters: string[],\n options: Record<string, unknown>,\n vite: Record<string, unknown>,\n ) => Promise<VitestLike | undefined>\n }\n // No project config: a vitest.config of the store's own cannot hide or reshape the suite, and the cache stays here.\n const vitest = await startVitest(\n 'test',\n [],\n {\n config: false,\n root: contracts,\n include: [file],\n watch: false,\n testTimeout: 60_000,\n hookTimeout: 60_000,\n },\n { cacheDir: join(contracts, '.vite') },\n )\n if (vitest === undefined) throw new CertifyError(`vitest did not start for ${pkg}`)\n const files = vitest.state.getFiles()\n const { passed, failed } = countCases(files)\n // A file that failed outside its cases (collection, a hook) or an unhandled error certifies nothing either.\n const broken =\n files.some((f) => f.result?.state === 'fail') || vitest.state.getUnhandledErrors().length > 0\n await vitest.close()\n\n const total = passed + failed\n if (failed === 0 && total > 0 && !broken) {\n process.stdout.write(`certified ${pkg} (${kind}): ${passed} cases passed\\n`)\n return 0\n }\n process.stdout.write(`not certified ${pkg} (${kind}): ${failed} of ${total} cases failed\\n`)\n return 1\n}\n"],"mappings":"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","names":["defineCommand","resolve","defineCommand","dirname","child","resolve","resolve","err","existsSync","resolve","dirname","resolve","existsSync","existsSync","dirname","join","err","resolve","text","resolve","defineCommand","shutdown","defineCommand","defineCommand","defineCommand","runSeed","defineCommand","runSeed","defineCommand","createApp","join","defineCommand","join","createApp","defineCommand","pc","defineCommand","pc","err","existsSync","readFileSync","dirname","join","defineCommand","pc","findConfigFile","loadConfig","existsSync","createRequire","dirname","join","resolve","p","out","text","p","indent","pc","join","existsSync","readFileSync","loadConfig","i","j","findConfigFile","dirname","defineCommand","existsSync","defineCommand","createLogger","pc","displayUrl","text","flag","existsSync","defineCommand","createLogger","text","defineCommand","pc","createCommandStore","pc","createCommandStore","row","defineCommand","existsSync","resolve","defineCommand","createCommandStore","sqliteFile","errorText","row","sqliteFile","existsSync","resolve","createCommandStore","errorText","defineCommand","existsSync","resolve","defineCommand","createCommandStore","sqliteFile","errorText","timeFlag","write","out","text","defineCommand","sqliteFile","existsSync","resolve","createCommandStore","errorText","existsSync","resolve","defineCommand","createLogger","sqliteFile","errorText","write","text","defineCommand","existsSync","resolve","sqliteFile","createLogger","errorText","defineCommand","createLogger","errorText","p","add","text","createLogger","errorText","defineCommand","defineCommand","loadConfig","writeFileSync","createRequire","dirname","join","resolve","pathToFileURL","findConfigFile","loadConfig","text","err","createRequire","join","findConfigFile","loadConfig","block","out","child","resolve","dirname","writeFileSync","pathToFileURL","defineCommand","loadConfig","err","defineCommand"]}