@noy-db/cli 0.2.0-pre.8 → 0.3.0-pre.1
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/README.md +1 -1
- package/package.json +11 -18
- package/dist/bin/noydb.cjs +0 -964
- package/dist/bin/noydb.cjs.map +0 -1
- package/dist/index.cjs +0 -941
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -97
package/dist/bin/noydb.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/inspect.ts","../../src/commands/verify.ts","../../src/commands/config.ts","../../src/commands/monitor.ts","../../src/commands/describe.ts","../../src/bin/noydb.ts"],"sourcesContent":["/**\n * `noydb inspect <file.noydb>` — print the unencrypted header.\n *\n * This command is the security-sensitive one in the CLI: it must\n * never prompt for a passphrase and never decrypt anything. It reads\n * exactly the unencrypted header bytes (magic + flags + header\n * length prefix + JSON header) and returns structured metadata.\n *\n * What the header reveals:\n * - `formatVersion` — container format version\n * - `handle` — ULID identifier\n * - `bodyBytes` — compressed body size\n * - `bodySha256` — body integrity hash\n *\n * What it does **not** reveal: record counts, collection names,\n * ciphertext, keyring, timestamps inside records. Those live past\n * the decryption boundary.\n *\n * @module\n */\nimport { readNoydbBundleHeader } from '@noy-db/hub'\nimport { readFile } from 'node:fs/promises'\n\nexport interface InspectResult {\n formatVersion: number\n handle: string\n bodyBytes: number\n bodySha256: string\n}\n\nexport async function inspect(filePath: string): Promise<InspectResult> {\n const bytes = await readFile(filePath)\n const header = readNoydbBundleHeader(new Uint8Array(bytes))\n return {\n formatVersion: header.formatVersion,\n handle: header.handle,\n bodyBytes: header.bodyBytes,\n bodySha256: header.bodySha256,\n }\n}\n\nexport async function runInspect(argv: readonly string[]): Promise<number> {\n const file = argv[0]\n if (!file) {\n process.stderr.write('usage: noydb inspect <file.noydb>\\n')\n return 2\n }\n try {\n const info = await inspect(file)\n process.stdout.write(JSON.stringify(info, null, 2) + '\\n')\n return 0\n } catch (err) {\n process.stderr.write(`inspect failed: ${(err as Error).message}\\n`)\n return 1\n }\n}\n","/**\n * `noydb verify <file.noydb>` — integrity check.\n *\n * Validates the three integrity properties of a bundle that can be\n * verified **without the passphrase**:\n *\n * 1. Magic prefix + format version match what this CLI supports.\n * 2. Header parses as JSON with the minimum-disclosure key set.\n * 3. Compressed body SHA-256 matches `header.bodySha256`.\n *\n * Ledger-head verification (which does need the passphrase) is not\n * covered here — that's a future enhancement when an `open` subcommand\n * lands. For now, `verify` answers \"was this file transmitted intact?\"\n * without involving keys.\n *\n * @module\n */\nimport { readNoydbBundle, readNoydbBundleHeader } from '@noy-db/hub'\nimport { readFile } from 'node:fs/promises'\n\nexport interface VerifyReport {\n ok: boolean\n file: string\n handle: string\n bodyBytes: number\n checks: { magic: boolean; header: boolean; bodyHash: boolean }\n error?: string\n}\n\nexport async function verify(filePath: string): Promise<VerifyReport> {\n const bytes = new Uint8Array(await readFile(filePath))\n const checks = { magic: false, header: false, bodyHash: false }\n\n let handle = ''\n let bodyBytes = 0\n\n try {\n const header = readNoydbBundleHeader(bytes)\n checks.magic = true\n checks.header = true\n handle = header.handle\n bodyBytes = header.bodyBytes\n\n // readNoydbBundle() verifies bodySha256 internally — if it doesn't\n // throw, the body hash matched.\n await readNoydbBundle(bytes)\n checks.bodyHash = true\n\n return { ok: true, file: filePath, handle, bodyBytes, checks }\n } catch (err) {\n return {\n ok: false, file: filePath, handle, bodyBytes, checks,\n error: (err as Error).message,\n }\n }\n}\n\nexport async function runVerify(argv: readonly string[]): Promise<number> {\n const file = argv[0]\n if (!file) {\n process.stderr.write('usage: noydb verify <file.noydb>\\n')\n return 2\n }\n const report = await verify(file)\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n')\n return report.ok ? 0 : 1\n}\n","/**\n * `noydb config validate` and `noydb config scaffold`.\n *\n * **validate** — sanity-check a `NoydbOptions` value at runtime. The\n * input file is expected to default-export a `NoydbOptions` object\n * (or a factory returning one). We dynamically import it and check:\n *\n * - `store` is present and exposes the 6-method `NoydbStore` shape.\n * - Sync targets have role ∈ {sync-peer, backup, archive} and a store.\n * - `archive` targets don't carry a pull policy (archive is push-only).\n * - `syncPolicy` pairs with at least one sync target.\n * - `blob` routes (if present) sit on a bundle-capable store.\n *\n * **scaffold** — emit a working skeleton for one of the topology\n * profiles from `docs/guides/topology-matrix.md`. Output goes to stdout\n * (pipe to a file yourself) and is a ready-to-edit `.ts` + `.env`\n * pair, concatenated so the consumer can split them.\n *\n * @module\n */\nimport { pathToFileURL } from 'node:url'\nimport { resolve } from 'node:path'\n\nexport interface ValidationIssue {\n severity: 'warn' | 'error'\n code: string\n path: string\n message: string\n}\n\nexport interface ValidationReport {\n ok: boolean\n issues: ValidationIssue[]\n}\n\n/**\n * Validate a NoydbOptions-shaped object (not a file path — this is\n * the programmatic API). Conservative: if a check can't be made\n * confidently, it's skipped rather than warned, to avoid nagging.\n */\n/** Coerces arbitrary values to a human-readable string without triggering\n * `[object Object]` — used by the config validator to report bad field types. */\nfunction safeStringify(v: unknown): string {\n if (typeof v === 'string') return v\n if (typeof v === 'number' || typeof v === 'boolean' || v === null || v === undefined) {\n return String(v)\n }\n try { return JSON.stringify(v) } catch { return '<unserializable>' }\n}\n\nexport function validateOptions(opts: unknown): ValidationReport {\n const issues: ValidationIssue[] = []\n\n if (!isRecord(opts)) {\n issues.push({ severity: 'error', code: 'not-object', path: '<root>',\n message: 'NoydbOptions must be an object' })\n return { ok: false, issues }\n }\n\n // Required: store\n if (!opts.store) {\n issues.push({ severity: 'error', code: 'missing-store', path: 'store',\n message: '`store` is required' })\n } else if (!isStoreShape(opts.store)) {\n issues.push({ severity: 'error', code: 'bad-store-shape', path: 'store',\n message: '`store` does not expose the 6-method NoydbStore contract' })\n }\n\n // sync — accept single store, SyncTarget, or SyncTarget[]\n if (opts.sync !== undefined) {\n const targets = normalizeSync(opts.sync)\n targets.forEach((t, i) => validateTarget(t, `sync[${i}]`, issues))\n }\n\n // syncPolicy requires at least one sync target\n if (opts.syncPolicy !== undefined && opts.sync === undefined) {\n issues.push({ severity: 'warn', code: 'policy-without-sync', path: 'syncPolicy',\n message: '`syncPolicy` has no effect without a `sync` target' })\n }\n\n // user is recommended\n if (typeof opts.user !== 'string' || !opts.user) {\n issues.push({ severity: 'warn', code: 'missing-user', path: 'user',\n message: '`user` identifier is recommended — audit entries default to \"anonymous\" without it' })\n }\n\n // passphrase-or-encryption check\n if (opts.secret === undefined && opts.passphrase === undefined && opts.encrypt !== false) {\n issues.push({ severity: 'warn', code: 'no-secret', path: 'secret',\n message: '`secret` / `passphrase` missing and `encrypt` not explicitly false — vault open will fail' })\n }\n\n const hasError = issues.some((i) => i.severity === 'error')\n return { ok: !hasError, issues }\n}\n\n/** Dynamically import a JS/MJS/CJS config file and pull the NoydbOptions\n * out of it. Accepts a default export that is either the options\n * object or a zero-arg function (sync or async) returning the options.\n *\n * **TypeScript note.** Node cannot `import()` a bare `.ts` file without\n * a loader. If the adopter's config is TypeScript, they should either\n * compile it first (`tsc foo.ts`) or run the CLI under a TS-capable\n * runtime (e.g. `tsx $(which noydb) config validate foo.ts`). The\n * function throws a human-readable error for `.ts` input rather than\n * propagating Node's cryptic `Unknown file extension` message. */\nexport async function loadOptionsFromFile(filePath: string): Promise<unknown> {\n const abs = resolve(filePath)\n if (abs.endsWith('.ts') || abs.endsWith('.mts') || abs.endsWith('.cts')) {\n throw new Error(\n `TypeScript config files are not directly loadable — Node has no native .ts loader.\\n` +\n ` Options:\\n` +\n ` (a) compile first: tsc ${filePath} && noydb config validate ${filePath.replace(/\\.[mc]?ts$/, '.js')}\\n` +\n ` (b) run via tsx: npx tsx $(which noydb) config validate ${filePath}\\n` +\n ` (c) rename to .mjs/.js if your config has no TS-only syntax`,\n )\n }\n const mod = await import(pathToFileURL(abs).href) as { default?: unknown }\n const value = mod.default ?? mod\n if (typeof value === 'function') {\n return await (value as () => Promise<unknown>)()\n }\n return value\n}\n\nexport async function runConfigValidate(argv: readonly string[]): Promise<number> {\n const file = argv[0]\n if (!file) {\n process.stderr.write('usage: noydb config validate <file.ts|js>\\n')\n return 2\n }\n let opts: unknown\n try {\n opts = await loadOptionsFromFile(file)\n } catch (err) {\n process.stderr.write(`failed to load ${file}: ${(err as Error).message}\\n`)\n return 1\n }\n\n const report = validateOptions(opts)\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n')\n return report.ok ? 0 : 1\n}\n\n// ── Scaffold ────────────────────────────────────────────────────────────\n\n/** Profiles match `docs/guides/topology-matrix.md` § View 3. */\nexport type Profile = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J'\n\nexport interface ScaffoldResult {\n profile: Profile\n code: string\n env: string\n notes: string\n}\n\nexport function scaffold(profile: Profile): ScaffoldResult {\n switch (profile) {\n case 'A': return {\n profile, notes: 'Local-only single-user. No cloud.',\n code: [\n `import { createNoydb } from '@noy-db/hub'`,\n `import { jsonFile } from '@noy-db/to-file'`,\n ``,\n `export default {`,\n ` store: jsonFile({ dir: process.env.NOYDB_DATA_DIR ?? './data' }),`,\n ` user: process.env.NOYDB_USER ?? 'owner',`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=owner\\nNOYDB_SECRET=\\nNOYDB_DATA_DIR=./data\\n`,\n }\n case 'B': return {\n profile, notes: 'Offline-first + cloud mirror. Local authoritative, sync opportunistically.',\n code: [\n `import { createNoydb, INDEXED_STORE_POLICY } from '@noy-db/hub'`,\n `import { browserIdbStore } from '@noy-db/to-browser-idb'`,\n `import { awsDynamoStore } from '@noy-db/to-aws-dynamo'`,\n ``,\n `export default {`,\n ` store: browserIdbStore({ prefix: process.env.NOYDB_APP ?? 'myapp' }),`,\n ` sync: [{`,\n ` store: awsDynamoStore({`,\n ` table: process.env.NOYDB_DYNAMO_TABLE!,`,\n ` region: process.env.AWS_REGION ?? 'us-east-1',`,\n ` }),`,\n ` role: 'sync-peer',`,\n ` label: 'dynamo-live',`,\n ` }],`,\n ` syncPolicy: INDEXED_STORE_POLICY,`,\n ` user: process.env.NOYDB_USER ?? 'owner',`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=owner\\nNOYDB_SECRET=\\nNOYDB_APP=myapp\\nNOYDB_DYNAMO_TABLE=myapp-live\\nAWS_REGION=us-east-1\\n`,\n }\n case 'C': return {\n profile, notes: 'Records + blobs split (routeStore). Dynamo for records, S3 for blobs.',\n code: [\n `import { createNoydb, routeStore } from '@noy-db/hub'`,\n `import { awsDynamoStore } from '@noy-db/to-aws-dynamo'`,\n `import { awsS3Store } from '@noy-db/to-aws-s3'`,\n ``,\n `export default {`,\n ` store: routeStore({`,\n ` default: awsDynamoStore({`,\n ` table: process.env.NOYDB_DYNAMO_TABLE!,`,\n ` region: process.env.AWS_REGION ?? 'us-east-1',`,\n ` }),`,\n ` blobs: awsS3Store({`,\n ` bucket: process.env.NOYDB_S3_BUCKET!,`,\n ` region: process.env.AWS_REGION ?? 'us-east-1',`,\n ` }),`,\n ` }),`,\n ` user: process.env.NOYDB_USER ?? 'owner',`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=owner\\nNOYDB_SECRET=\\nNOYDB_DYNAMO_TABLE=myapp-records\\nNOYDB_S3_BUCKET=myapp-blobs\\nAWS_REGION=us-east-1\\n`,\n }\n case 'G': return {\n profile, notes: 'Middleware-hardened production: retry + breaker + cache + metrics.',\n code: [\n `import { createNoydb, wrapStore, withRetry, withCircuitBreaker, withCache, withHealthCheck, withMetrics } from '@noy-db/hub'`,\n `import { awsDynamoStore } from '@noy-db/to-aws-dynamo'`,\n ``,\n `export default {`,\n ` store: wrapStore(`,\n ` awsDynamoStore({ table: process.env.NOYDB_DYNAMO_TABLE! }),`,\n ` withRetry({ maxRetries: 3 }),`,\n ` withCircuitBreaker({ failureThreshold: 5, resetTimeoutMs: 30_000 }),`,\n ` withCache({ ttlMs: 60_000 }),`,\n ` withHealthCheck(),`,\n ` withMetrics({ onOperation: op => console.log(op) }),`,\n ` ),`,\n ` user: process.env.NOYDB_USER ?? 'owner',`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=owner\\nNOYDB_SECRET=\\nNOYDB_DYNAMO_TABLE=myapp-prod\\n`,\n }\n case 'D': return {\n profile, notes: 'Hot + cold tiered. Records age out to archive after N days.',\n code: [\n `import { createNoydb, routeStore } from '@noy-db/hub'`,\n `import { awsDynamoStore } from '@noy-db/to-aws-dynamo'`,\n `import { awsS3Store } from '@noy-db/to-aws-s3'`,\n ``,\n `export default {`,\n ` store: routeStore({`,\n ` default: awsDynamoStore({ table: process.env.NOYDB_DYNAMO_TABLE! }),`,\n ` age: {`,\n ` cold: awsS3Store({ bucket: process.env.NOYDB_S3_COLD! }),`,\n ` coldAfterDays: Number(process.env.NOYDB_COLD_AFTER_DAYS ?? '90'),`,\n ` },`,\n ` }),`,\n ` user: process.env.NOYDB_USER ?? 'owner',`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=owner\\nNOYDB_SECRET=\\nNOYDB_DYNAMO_TABLE=myapp-hot\\nNOYDB_S3_COLD=myapp-archive\\nNOYDB_COLD_AFTER_DAYS=90\\n`,\n }\n case 'E': return {\n profile, notes: 'Multi-peer team sync. Primary + peer + backup + archive.',\n code: [\n `import { createNoydb } from '@noy-db/hub'`,\n `import { browserIdbStore } from '@noy-db/to-browser-idb'`,\n `import { awsDynamoStore } from '@noy-db/to-aws-dynamo'`,\n `import { awsS3Store } from '@noy-db/to-aws-s3'`,\n ``,\n `export default {`,\n ` store: browserIdbStore({ prefix: process.env.NOYDB_APP ?? 'team' }),`,\n ` sync: [`,\n ` { store: awsDynamoStore({ table: process.env.NOYDB_DYNAMO_TABLE! }), role: 'sync-peer', label: 'team-hot' },`,\n ` { store: awsS3Store({ bucket: process.env.NOYDB_S3_BACKUP! }), role: 'backup', label: 'team-backup' },`,\n ` { store: awsS3Store({ bucket: process.env.NOYDB_S3_ARCHIVE! }), role: 'archive', label: 'team-archive' },`,\n ` ],`,\n ` user: process.env.NOYDB_USER ?? 'member',`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=member\\nNOYDB_SECRET=\\nNOYDB_APP=team\\nNOYDB_DYNAMO_TABLE=team-hot\\nNOYDB_S3_BACKUP=team-backup\\nNOYDB_S3_ARCHIVE=team-archive\\n`,\n }\n case 'F': return {\n profile, notes: 'CRDT collaboration — Yjs-backed shared records over the encrypted envelope.',\n code: [\n `import { createNoydb } from '@noy-db/hub'`,\n `import { browserIdbStore } from '@noy-db/to-browser-idb'`,\n `import { awsDynamoStore } from '@noy-db/to-aws-dynamo'`,\n `// import { yjsCollection } from '@noy-db/in-yjs' // use inside your app`,\n ``,\n `export default {`,\n ` store: browserIdbStore({ prefix: 'collab' }),`,\n ` sync: [{ store: awsDynamoStore({ table: process.env.NOYDB_DYNAMO_TABLE! }), role: 'sync-peer' }],`,\n ` user: process.env.NOYDB_USER!,`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ``,\n `// After createNoydb(), replace normal collections with yjsCollection() for CRDT fields.`,\n ].join('\\n'),\n env: `NOYDB_USER=\\nNOYDB_SECRET=\\nNOYDB_DYNAMO_TABLE=collab-live\\n`,\n }\n case 'H': return {\n profile, notes: 'USB-portable — everything on a single file store, no cloud.',\n code: [\n `import { createNoydb } from '@noy-db/hub'`,\n `import { jsonFile } from '@noy-db/to-file'`,\n ``,\n `export default {`,\n ` store: jsonFile({ dir: process.env.NOYDB_DATA_DIR ?? '/Volumes/MY_USB/data' }),`,\n ` user: process.env.NOYDB_USER!,`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=\\nNOYDB_SECRET=\\nNOYDB_DATA_DIR=/Volumes/MY_USB/data\\n`,\n }\n case 'I': return {\n profile, notes: 'Multi-tenant geographic sharding — per-vault primary per region.',\n code: [\n `import { createNoydb } from '@noy-db/hub'`,\n `import { awsDynamoStore } from '@noy-db/to-aws-dynamo'`,\n ``,\n `// Pick the nearest region at init time based on tenant config.`,\n `const region = process.env.NOYDB_REGION ?? 'ap-southeast-1'`,\n `const table = \\`myapp-\\${region}\\``,\n ``,\n `export default {`,\n ` store: awsDynamoStore({ table, region }),`,\n ` user: process.env.NOYDB_USER!,`,\n ` secret: process.env.NOYDB_SECRET,`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=\\nNOYDB_SECRET=\\nNOYDB_REGION=ap-southeast-1\\n`,\n }\n case 'J': return {\n profile, notes: 'Authentication bridge (passphrase-less unlock via OIDC or WebAuthn).',\n code: [\n `import { createNoydb } from '@noy-db/hub'`,\n `import { browserIdbStore } from '@noy-db/to-browser-idb'`,\n `// import { unlockWebAuthn } from '@noy-db/on-webauthn' // in the browser`,\n `// import { keyConnector } from '@noy-db/on-oidc' // in a server app`,\n ``,\n `export default {`,\n ` store: browserIdbStore({ prefix: process.env.NOYDB_APP ?? 'app' }),`,\n ` user: process.env.NOYDB_USER!,`,\n ` // secret supplied by the unlock method at openVault() time, not here.`,\n `}`,\n ].join('\\n'),\n env: `NOYDB_USER=\\nNOYDB_APP=app\\n`,\n }\n }\n}\n\nexport async function runConfigScaffold(argv: readonly string[]): Promise<number> {\n const profileArg = argv.find((a) => a.startsWith('--profile='))\n const profile = (profileArg?.split('=')[1] ?? 'A') as Profile\n if (!/^[A-J]$/.test(profile)) {\n process.stderr.write(`unknown profile: ${profile}. Valid: A-J (see docs/guides/topology-matrix.md)\\n`)\n return 2\n }\n const out = scaffold(profile)\n process.stdout.write(`// ── noydb config (profile ${out.profile}) ───────────────────\\n`)\n process.stdout.write(`// ${out.notes}\\n\\n`)\n process.stdout.write(out.code + '\\n\\n')\n if (out.env) {\n process.stdout.write(`// ── .env template ───────────────────────────────────────\\n`)\n process.stdout.write(out.env)\n }\n return 0\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\nfunction isStoreShape(v: unknown): boolean {\n if (!isRecord(v)) return false\n return ['get', 'put', 'delete', 'list', 'loadAll', 'saveAll']\n .every((m) => typeof v[m] === 'function')\n}\n\nfunction normalizeSync(v: unknown): unknown[] {\n if (Array.isArray(v)) return v\n return [v]\n}\n\nfunction validateTarget(t: unknown, path: string, issues: ValidationIssue[]): void {\n if (!isRecord(t)) {\n issues.push({ severity: 'error', code: 'bad-target', path,\n message: 'sync target must be an object with { store, role }' })\n return\n }\n if (t['role'] === undefined) {\n // Bare store is allowed — core wraps it as { store, role: 'sync-peer' }\n if (!isStoreShape(t)) {\n issues.push({ severity: 'error', code: 'bad-store-shape', path,\n message: 'sync target store does not expose the 6-method contract' })\n }\n return\n }\n const validRoles = ['sync-peer', 'backup', 'archive']\n if (!validRoles.includes(safeStringify(t['role']))) {\n issues.push({ severity: 'error', code: 'bad-role', path: `${path}.role`,\n message: `role must be one of ${validRoles.join(', ')}; got ${safeStringify(t['role'])}` })\n }\n if (!t['store'] || !isStoreShape(t['store'])) {\n issues.push({ severity: 'error', code: 'bad-store-shape', path: `${path}.store`,\n message: 'sync target store does not expose the 6-method contract' })\n }\n if (t['role'] === 'archive' && isRecord(t['policy']) && isRecord(t['policy']['pull'])) {\n issues.push({ severity: 'error', code: 'archive-pull-configured', path: `${path}.policy.pull`,\n message: 'archive targets are push-only — pull policy is invalid' })\n }\n}\n","/**\n * `noydb monitor <config.ts>` — live text dashboard of store metrics.\n *\n * Loads a `NoydbOptions` from a config file, wraps the primary store\n * in `@noy-db/to-meter`, creates a `Noydb` instance, and prints a\n * refreshing snapshot to stdout at a configurable interval. Ctrl-C\n * to stop.\n *\n * This is the scope of issue — CLI-first. A web dashboard\n * is deferred: the meter handle already exposes everything a dashboard\n * needs via `snapshot()` + `subscribe()`.\n *\n * @module\n */\nimport { toMeter } from '@noy-db/to-meter'\nimport type { MeterSnapshot } from '@noy-db/to-meter'\nimport { loadOptionsFromFile } from './config.js'\n\nexport interface MonitorOptions {\n intervalMs: number\n iterations?: number // undefined → run forever\n}\n\nexport async function runMonitor(argv: readonly string[]): Promise<number> {\n const file = argv[0]\n if (!file) {\n process.stderr.write('usage: noydb monitor <config.ts> [--interval=ms]\\n')\n return 2\n }\n\n const intervalArg = argv.find((a) => a.startsWith('--interval='))\n const intervalMs = intervalArg ? parseInt(intervalArg.split('=')[1] ?? '5000', 10) : 5_000\n\n let opts: Record<string, unknown>\n try {\n const loaded = await loadOptionsFromFile(file)\n if (typeof loaded !== 'object' || loaded === null) {\n process.stderr.write(`config file must export a NoydbOptions-shaped object\\n`)\n return 1\n }\n opts = loaded as Record<string, unknown>\n } catch (err) {\n process.stderr.write(`failed to load ${file}: ${(err as Error).message}\\n`)\n return 1\n }\n\n const innerStore = opts['store']\n if (!innerStore || typeof innerStore !== 'object') {\n process.stderr.write('config has no `store` — nothing to monitor\\n')\n return 1\n }\n\n const { store: metered, meter } = toMeter(innerStore as never, {\n degradedMs: 500,\n onDegraded: (e) => process.stderr.write(`DEGRADED: ${e.reason}\\n`),\n onRestored: (e) => process.stderr.write(`RESTORED: ${e.reason}\\n`),\n })\n\n // Replace the store in the options object so the Noydb instance\n // goes through the meter.\n const liveOpts = { ...opts, store: metered } as Record<string, unknown>\n\n // Dynamically import hub so the CLI doesn't need to bundle it at\n // build time. Adopter's installed @noy-db/hub version wins.\n const hub = await import('@noy-db/hub') as { createNoydb: (o: unknown) => Promise<unknown> }\n await hub.createNoydb(liveOpts)\n\n process.stdout.write(`monitoring ${file} — interval ${intervalMs}ms — Ctrl-C to stop\\n\\n`)\n\n const stop = installSigintHandler(meter)\n\n return new Promise<number>((resolveP) => {\n const timer = setInterval(() => {\n if (stop.signalled) {\n clearInterval(timer)\n meter.close()\n resolveP(0)\n return\n }\n const snap = meter.snapshot()\n process.stdout.write(formatSnapshot(snap) + '\\n')\n }, intervalMs)\n })\n}\n\nfunction installSigintHandler(meter: { close(): void }): { signalled: boolean } {\n const state = { signalled: false }\n const handler = () => { state.signalled = true; meter.close() }\n process.on('SIGINT', handler)\n process.on('SIGTERM', handler)\n return state\n}\n\nexport function formatSnapshot(snap: MeterSnapshot): string {\n const lines: string[] = []\n const ts = new Date(snap.collectedAt).toISOString().slice(11, 19)\n lines.push(`[${ts}] status=${snap.status} calls=${snap.totalCalls} casConflicts=${snap.casConflicts} windowMs=${snap.windowMs}`)\n for (const m of ['get', 'put', 'delete', 'list', 'loadAll', 'saveAll'] as const) {\n const s = snap.byMethod[m]\n if (s.count === 0) continue\n lines.push(` ${m.padEnd(7)} count=${s.count} errors=${s.errors} p50=${s.p50}ms p99=${s.p99}ms max=${s.max}ms avg=${s.avg}ms`)\n }\n return lines.join('\\n')\n}\n","/**\n * `noydb describe <file.noydb>` — emit a human-readable YAML/JSON\n * description of a bundle's structure (collections, fields, indexes,\n * FKs, MVs, overlays, derivations) with optional counters.\n *\n * Loads the bundle into an in-memory store, unlocks it with the\n * supplied passphrase + user, calls `vault.dumpSchema()`, then emits.\n *\n * See `docs/superpowers/specs/2026-05-22-schema-dump-design.md`.\n *\n * @module\n */\n\nimport { readFile, writeFile, mkdir } from 'node:fs/promises'\nimport { dirname, basename, join } from 'node:path'\nimport { createHash } from 'node:crypto'\nimport { stringify as yamlStringify } from 'yaml'\nimport type {\n EncryptedEnvelope,\n NoydbStore,\n VaultSnapshot,\n VaultSchemaSnapshot,\n} from '@noy-db/hub'\nimport {\n createNoydb,\n readNoydbBundle,\n ConflictError,\n loadPersistedSchema,\n SCHEMAS_COLLECTION,\n} from '@noy-db/hub'\n\nconst VERSION = '0.1.0'\n\nexport type DescribeFormat = 'yaml' | 'json'\nexport type SchemasMode = 'none' | 'full' | 'sidecar'\n\nexport interface DescribeOptions {\n readonly bundlePath: string\n readonly user: string\n readonly passphrase: string\n readonly format: DescribeFormat\n readonly withStats: boolean\n readonly schemas: SchemasMode\n readonly outPath?: string\n readonly sampleSize: number\n}\n\ninterface SnapshotWithProvenance extends VaultSchemaSnapshot {\n _provenance: {\n generatedBy: string\n source: string\n sourceSha256: string\n emittedAt: string\n }\n}\n\n/** In-memory adapter — used only for the temporary vault that hosts the loaded bundle. */\nfunction memoryStore(): NoydbStore {\n const data = new Map<string, Map<string, Map<string, EncryptedEnvelope>>>()\n const getColl = (v: string, c: string) => {\n let vm = data.get(v); if (!vm) { vm = new Map(); data.set(v, vm) }\n let cm = vm.get(c); if (!cm) { cm = new Map(); vm.set(c, cm) }\n return cm\n }\n return {\n async get(v, c, id) { return data.get(v)?.get(c)?.get(id) ?? null },\n async put(v, c, id, env, ev) {\n const coll = getColl(v, c); const ex = coll.get(id)\n if (ev !== undefined && ex && ex._v !== ev) throw new ConflictError(ex._v)\n coll.set(id, env)\n },\n async delete(v, c, id) { data.get(v)?.get(c)?.delete(id) },\n async list(v, c) { return [...(data.get(v)?.get(c)?.keys() ?? [])] },\n async loadAll(v) {\n const vm = data.get(v); const snap: VaultSnapshot = {}\n if (vm) for (const [cn, cm] of vm) {\n if (cn.startsWith('_')) continue\n const r: Record<string, EncryptedEnvelope> = {}\n for (const [id, e] of cm) r[id] = e\n snap[cn] = r\n }\n return snap\n },\n async saveAll(v, snap) {\n for (const [cn, recs] of Object.entries(snap)) {\n const coll = getColl(v, cn)\n for (const [id, env] of Object.entries(recs)) coll.set(id, env)\n }\n },\n }\n}\n\ninterface BackupShape {\n _compartment?: string\n}\n\n/** Run the full describe pipeline and return the emitted string. */\nexport async function describeBundle(opts: DescribeOptions): Promise<string> {\n const bytes = await readFile(opts.bundlePath)\n const sourceSha256 = createHash('sha256').update(bytes).digest('hex')\n\n const { dumpJson } = await readNoydbBundle(new Uint8Array(bytes))\n const backup = JSON.parse(dumpJson) as BackupShape\n const compartmentName = backup._compartment ?? 'vault'\n\n // Build a fresh in-memory Noydb to host the loaded bundle. The\n // `user` + `secret` must match a keyring in the bundle.\n const db = await createNoydb({\n store: memoryStore(),\n user: opts.user,\n secret: opts.passphrase,\n })\n const vault = await db.openVault(compartmentName)\n await vault.load(dumpJson)\n\n // Touch each collection so its config (refs, validator if registered\n // in-process) is in the cache. For a fresh bundle load, there's no\n // app code registering schemas, so collections without persisted\n // _schemas envelopes will show `source: 'unknown'`.\n const collectionNames = await vault.collections()\n for (const name of collectionNames) {\n if (!name.startsWith('_')) vault.collection(name)\n }\n\n const snapshot = await vault.dumpSchema({\n withStats: opts.withStats,\n sampleSize: opts.sampleSize,\n })\n\n // Optionally inline the persisted JSON Schemas under each collection.\n const enriched = opts.schemas === 'full'\n ? await enrichWithFullSchemas(snapshot, vault, collectionNames)\n : snapshot\n\n // Attach provenance at the top. Build the object in key-order\n // we want emitted: _noydb_snapshot first, _provenance second, then\n // every snapshot field (without _noydb_snapshot which we already set).\n const { _noydb_snapshot: _ignore, ...rest } = enriched\n void _ignore\n const withProvenance: SnapshotWithProvenance = {\n _noydb_snapshot: 1,\n _provenance: {\n generatedBy: `noydb describe v${VERSION}`,\n source: basename(opts.bundlePath),\n sourceSha256,\n emittedAt: enriched.emittedAt,\n },\n vault: rest.vault,\n emittedAt: rest.emittedAt,\n subsystems: rest.subsystems,\n collections: rest.collections,\n materializedViews: rest.materializedViews,\n overlayViews: rest.overlayViews,\n derivations: rest.derivations,\n ...(rest.internal !== undefined ? { internal: rest.internal } : {}),\n ...(rest.aclRoles !== undefined ? { aclRoles: rest.aclRoles } : {}),\n }\n\n // Sidecar emission — write each collection's JSON Schema to a\n // separate file next to the main output.\n if (opts.schemas === 'sidecar' && opts.outPath) {\n await writeSidecarSchemas(opts.outPath, vault, collectionNames)\n }\n\n const emitted = emit(withProvenance, opts.format)\n if (opts.outPath) {\n await mkdir(dirname(opts.outPath), { recursive: true })\n await writeFile(opts.outPath, emitted)\n }\n return emitted\n}\n\nasync function enrichWithFullSchemas(\n snapshot: VaultSchemaSnapshot,\n vault: { _introspectState(): { adapter: NoydbStore; name: string; getDEK: (n: string) => Promise<CryptoKey> } },\n collectionNames: readonly string[],\n): Promise<VaultSchemaSnapshot> {\n const state = vault._introspectState()\n const collections: Record<string, unknown> = {}\n for (const name of Object.keys(snapshot.collections)) {\n const base = snapshot.collections[name]\n if (!base) continue\n if (!collectionNames.includes(name)) {\n collections[name] = base\n continue\n }\n try {\n const dek = await state.getDEK(name)\n const persisted = await loadPersistedSchema(state.adapter, state.name, name, dek)\n if (persisted?.jsonSchema) {\n collections[name] = { ...base, jsonSchema: persisted.jsonSchema }\n } else {\n collections[name] = base\n }\n } catch {\n collections[name] = base\n }\n }\n return { ...snapshot, collections: collections as VaultSchemaSnapshot['collections'] }\n}\n\nasync function writeSidecarSchemas(\n outPath: string,\n vault: { _introspectState(): { adapter: NoydbStore; name: string; getDEK: (n: string) => Promise<CryptoKey> } },\n collectionNames: readonly string[],\n): Promise<void> {\n const state = vault._introspectState()\n const sidecarDir = `${outPath}.schemas`\n await mkdir(sidecarDir, { recursive: true })\n for (const name of collectionNames) {\n if (name.startsWith('_')) continue\n try {\n const dek = await state.getDEK(name)\n const persisted = await loadPersistedSchema(state.adapter, state.name, name, dek)\n if (persisted?.jsonSchema) {\n await writeFile(\n join(sidecarDir, `${name}.schema.json`),\n JSON.stringify(persisted.jsonSchema, null, 2),\n )\n }\n } catch {\n // Skip collections we can't decrypt.\n }\n }\n}\n\nfunction emit(snapshot: SnapshotWithProvenance, format: DescribeFormat): string {\n if (format === 'json') {\n return JSON.stringify(snapshot, null, 2) + '\\n'\n }\n // YAML — strict scalars; no anchors / refs for predictable output.\n return yamlStringify(snapshot, {\n aliasDuplicateObjects: false,\n indent: 2,\n lineWidth: 0, // never wrap; preserves long strings\n })\n}\n\n// ─── CLI dispatch ────────────────────────────────────────────\n\ninterface ParsedArgs {\n bundlePath: string\n user?: string\n passphrase?: string\n format: DescribeFormat\n withStats: boolean\n schemas: SchemasMode\n outPath?: string\n sampleSize: number\n}\n\nfunction parseArgs(argv: readonly string[]): ParsedArgs | { error: string } {\n const out: ParsedArgs = {\n bundlePath: '',\n format: 'yaml',\n withStats: false,\n schemas: 'none',\n sampleSize: 50,\n }\n let i = 0\n while (i < argv.length) {\n const arg = argv[i]\n if (arg === '--format') {\n const v = argv[++i]\n if (v !== 'yaml' && v !== 'json') return { error: `--format must be yaml or json (got: ${v ?? '<none>'})` }\n out.format = v\n } else if (arg === '--with-stats') {\n out.withStats = true\n } else if (arg === '--schemas') {\n const v = argv[++i]\n if (v !== 'none' && v !== 'full' && v !== 'sidecar') {\n return { error: `--schemas must be none|full|sidecar (got: ${v ?? '<none>'})` }\n }\n out.schemas = v\n } else if (arg === '-o' || arg === '--out') {\n const v = argv[++i]\n if (v === undefined) return { error: '-o requires a value' }\n out.outPath = v\n } else if (arg === '--passphrase') {\n const v = argv[++i]\n if (v === undefined) return { error: '--passphrase requires a value' }\n out.passphrase = v\n } else if (arg === '--user') {\n const v = argv[++i]\n if (v === undefined) return { error: '--user requires a value' }\n out.user = v\n } else if (arg === '--sample') {\n const n = parseInt(argv[++i] ?? '', 10)\n if (Number.isNaN(n) || n < 0) return { error: `--sample must be a non-negative integer` }\n out.sampleSize = n\n } else if (arg === '-h' || arg === '--help') {\n return { error: 'help' }\n } else if (arg?.startsWith('-')) {\n return { error: `unknown option: ${arg}` }\n } else if (!out.bundlePath) {\n out.bundlePath = arg ?? ''\n } else {\n return { error: `unexpected positional arg: ${arg}` }\n }\n i++\n }\n if (!out.bundlePath) return { error: 'missing bundle path' }\n return out\n}\n\nfunction usage(): string {\n return [\n 'usage: noydb describe <bundle-path> [options]',\n '',\n ' --format <yaml|json> output format (default: yaml)',\n ' --with-stats include records / bytes / oldest / newest per collection',\n ' --schemas <mode> JSON Schema body inclusion (default: none)',\n ' - none: summary only',\n ' - full: inline complete JSON Schema per collection',\n ' - sidecar: write `<out>.schemas/<col>.schema.json` siblings',\n ' -o, --out <file> write to file instead of stdout',\n ' --user <userId> keyring user identifier (required)',\n ' --passphrase <p> decryption passphrase (or via NOYDB_PASSPHRASE env)',\n ' --sample <n> max records sampled when no persisted/live schema (default: 50)',\n '',\n 'Exit codes: 0 ok, 1 internal error, 2 usage error, 3 auth failure',\n ].join('\\n')\n}\n\nexport async function runDescribe(argv: readonly string[]): Promise<number> {\n const parsed = parseArgs(argv)\n if ('error' in parsed) {\n if (parsed.error === 'help') {\n process.stdout.write(usage() + '\\n')\n return 0\n }\n process.stderr.write(`describe: ${parsed.error}\\n\\n${usage()}\\n`)\n return 2\n }\n const passphrase = parsed.passphrase ?? process.env.NOYDB_PASSPHRASE\n if (!passphrase) {\n process.stderr.write('describe: passphrase required — pass --passphrase or set NOYDB_PASSPHRASE env\\n')\n return 3\n }\n if (parsed.passphrase) {\n process.stderr.write(\n '[noy-db] warning: --passphrase appears in shell history; consider NOYDB_PASSPHRASE env instead\\n',\n )\n }\n if (!parsed.user) {\n process.stderr.write('describe: --user <userId> is required to unlock the bundle\\n')\n return 2\n }\n\n try {\n const out = await describeBundle({\n bundlePath: parsed.bundlePath,\n user: parsed.user,\n passphrase,\n format: parsed.format,\n withStats: parsed.withStats,\n schemas: parsed.schemas,\n ...(parsed.outPath !== undefined ? { outPath: parsed.outPath } : {}),\n sampleSize: parsed.sampleSize,\n })\n if (!parsed.outPath) process.stdout.write(out)\n return 0\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n if (/decrypt|tamper|wrong key|invalid/i.test(msg)) {\n process.stderr.write(`describe: decryption failed — check --user and --passphrase\\n ${msg}\\n`)\n return 3\n }\n process.stderr.write(`describe: ${msg}\\n`)\n return 1\n }\n}\n\n// Re-export for tests\nexport { loadPersistedSchema, SCHEMAS_COLLECTION }\n","#!/usr/bin/env node\n/**\n * `noydb` — command dispatcher.\n *\n * Routes argv to the appropriate subcommand. Kept minimal by design\n * (no commander/yargs dep) — scope is small enough for flat\n * if/else routing. Revisit if/when the CLI grows past ~5 commands.\n *\n * noydb inspect <file.noydb>\n * noydb verify <file.noydb>\n * noydb describe <file.noydb>\n * noydb config validate <file.ts>\n * noydb config scaffold [--profile=<A-J>]\n * noydb monitor <config.ts> [--interval=ms]\n * noydb --help\n * noydb --version\n *\n * @module\n */\nimport { runInspect } from '../commands/inspect.js'\nimport { runVerify } from '../commands/verify.js'\nimport { runConfigValidate, runConfigScaffold } from '../commands/config.js'\nimport { runMonitor } from '../commands/monitor.js'\nimport { runDescribe } from '../commands/describe.js'\n\nconst VERSION = '0.1.0'\n\nfunction usage(): string {\n return [\n 'noydb — command-line tools for @noy-db',\n '',\n 'Usage:',\n ' noydb inspect <file.noydb> Print bundle header (no passphrase)',\n ' noydb verify <file.noydb> Verify bundle integrity (no passphrase)',\n ' noydb describe <file.noydb> [options] Emit YAML/JSON audit of a bundle',\n ' noydb config validate <file.js|mjs> Sanity-check a NoydbOptions file',\n ' noydb config scaffold [--profile=<A-J>] Emit a topology-profile skeleton',\n ' noydb monitor <file.js|mjs> [--interval=ms] Live dashboard of store metrics',\n '',\n 'TypeScript configs: run under a TS-capable runtime, e.g. `npx tsx $(which noydb) config validate foo.ts`.',\n ' noydb --version Print CLI version',\n ' noydb --help Show this message',\n '',\n 'Profiles for `config scaffold` map to docs/guides/topology-matrix.md § View 3.',\n ].join('\\n')\n}\n\nasync function main(argv: readonly string[]): Promise<number> {\n const [cmd, ...rest] = argv\n\n if (!cmd || cmd === '--help' || cmd === '-h' || cmd === 'help') {\n process.stdout.write(usage() + '\\n')\n return 0\n }\n if (cmd === '--version' || cmd === '-v') {\n process.stdout.write(VERSION + '\\n')\n return 0\n }\n\n switch (cmd) {\n case 'inspect': return runInspect(rest)\n case 'verify': return runVerify(rest)\n case 'describe': return runDescribe(rest)\n case 'monitor': return runMonitor(rest)\n case 'config': {\n const [sub, ...subRest] = rest\n if (sub === 'validate') return runConfigValidate(subRest)\n if (sub === 'scaffold') return runConfigScaffold(subRest)\n process.stderr.write(`unknown config subcommand: ${sub ?? '(none)'}\\n`)\n return 2\n }\n default:\n process.stderr.write(`unknown command: ${cmd}\\n\\n${usage()}\\n`)\n return 2\n }\n}\n\nmain(process.argv.slice(2))\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(`fatal: ${(err as Error).message}\\n`)\n process.exit(1)\n })\n"],"mappings":"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","names":["import_hub","import_promises","import_promises","import_node_path","import_hub","yamlStringify","VERSION","usage"]}
|