@prisma-idb/family-idb 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/bin/prisma-idb.d.mts +1 -0
  4. package/dist/bin/prisma-idb.mjs +13 -0
  5. package/dist/bin/prisma-idb.mjs.map +1 -0
  6. package/dist/chain-order-CaHXo5jz.mjs +44 -0
  7. package/dist/chain-order-CaHXo5jz.mjs.map +1 -0
  8. package/dist/cli-Dlaym_DD.mjs +342 -0
  9. package/dist/cli-Dlaym_DD.mjs.map +1 -0
  10. package/dist/contract-space-codegen--gfuyap2.mjs +128 -0
  11. package/dist/contract-space-codegen--gfuyap2.mjs.map +1 -0
  12. package/dist/exports/cli.d.mts +26 -0
  13. package/dist/exports/cli.d.mts.map +1 -0
  14. package/dist/exports/cli.mjs +2 -0
  15. package/dist/exports/config-types.d.mts +38 -0
  16. package/dist/exports/config-types.d.mts.map +1 -0
  17. package/dist/exports/config-types.mjs +66 -0
  18. package/dist/exports/config-types.mjs.map +1 -0
  19. package/dist/exports/contract-psl.d.mts +59 -0
  20. package/dist/exports/contract-psl.d.mts.map +1 -0
  21. package/dist/exports/contract-psl.mjs +97 -0
  22. package/dist/exports/contract-psl.mjs.map +1 -0
  23. package/dist/exports/contract-ts.d.mts +98 -0
  24. package/dist/exports/contract-ts.d.mts.map +1 -0
  25. package/dist/exports/contract-ts.mjs +275 -0
  26. package/dist/exports/contract-ts.mjs.map +1 -0
  27. package/dist/exports/control.d.mts +107 -0
  28. package/dist/exports/control.d.mts.map +1 -0
  29. package/dist/exports/control.mjs +573 -0
  30. package/dist/exports/control.mjs.map +1 -0
  31. package/dist/exports/pack.d.mts +10 -0
  32. package/dist/exports/pack.d.mts.map +1 -0
  33. package/dist/exports/pack.mjs +11 -0
  34. package/dist/exports/pack.mjs.map +1 -0
  35. package/dist/migration-plan-BWhd8BdV.mjs +330 -0
  36. package/dist/migration-plan-BWhd8BdV.mjs.map +1 -0
  37. package/dist/preflight-4jDCNvS0.mjs +119 -0
  38. package/dist/preflight-4jDCNvS0.mjs.map +1 -0
  39. package/dist/psl-interpreter-C0suaXu2.d.mts +45 -0
  40. package/dist/psl-interpreter-C0suaXu2.d.mts.map +1 -0
  41. package/dist/psl-interpreter-C6Q4okuO.mjs +809 -0
  42. package/dist/psl-interpreter-C6Q4okuO.mjs.map +1 -0
  43. package/dist/validate-BLnItEKs.mjs +48 -0
  44. package/dist/validate-BLnItEKs.mjs.map +1 -0
  45. package/package.json +64 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight-4jDCNvS0.mjs","names":[],"sources":["../src/core/preflight.ts"],"sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { IDBFactory } from \"fake-indexeddb\";\nimport type { MigrationMetadata } from \"@prisma/orm-toolchain/migration-tools/metadata\";\nimport { computeMigrationHash } from \"@prisma/orm-toolchain/migration-tools/hash\";\nimport { chainOrderByMetadata, type ChainablePackage } from \"./chain-order\";\nimport { applyOneDdlOp, isIdbDdlOp, type IdbDdlOp } from \"@prisma-idb/target-idb/migration\";\nimport { join } from \"pathe\";\n\nexport interface PreflightOptions {\n readonly migrationsDir: string;\n /** Output sinks. Default to `process.stdout`/`process.stderr`. */\n readonly out?: (line: string) => void;\n readonly err?: (line: string) => void;\n}\n\n/**\n * Walk every migration package under `<migrationsDir>/app/` in chain order,\n * applying each package's `ops.json` against a fresh `fake-indexeddb`\n * instance inside an `upgradeneeded` callback. Reports per-step status to\n * stdout and the final outcome via exit code.\n *\n * **Why this exists**: a dedicated preflight command avoids three failure modes\n * of inlining this into `db update`: (a) `fake-indexeddb` disagrees with real\n * browsers on some edge cases and is not a reliable production oracle; (b) it\n * would substitute a runtime check for proper test coverage; (c) it would ship\n * a test-only package on a production path. Running it in CI gives the gate\n * without the workflow tax on every author.\n *\n * **Scope vs runtime**: this command catches \"the chain doesn't apply\n * cleanly\" — a structural issue. It does NOT catch \"the chain produces\n * the wrong schema\" (that's `verifySchema` against the head's contract,\n * resolvable via `migrations/snapshots/<hash>/contract.json` since Phase\n * 8.9 — still deferred to a follow-up).\n *\n * Exit codes: 0 on full chain success; 1 on any failure.\n */\nexport async function runPreflight(opts: PreflightOptions): Promise<number> {\n const out = opts.out ?? ((line: string) => process.stdout.write(line));\n const err = opts.err ?? ((line: string) => process.stderr.write(line));\n const migrationsDir = opts.migrationsDir;\n const appDir = join(migrationsDir, \"app\");\n\n const packages = await loadPackages(appDir);\n if (packages.length === 0) {\n out(\"No migration packages found. Nothing to preflight.\\n\");\n return 0;\n }\n\n out(`Preflighting ${packages.length} migration(s) against fake-indexeddb…\\n`);\n\n const factory = new IDBFactory();\n const dbName = \"__preflight__\";\n\n let currentVersion = 0;\n for (const pkg of packages) {\n out(` ${pkg.dirName} … `);\n try {\n currentVersion += 1;\n await applyPackage({ factory, dbName, targetVersion: currentVersion, ops: pkg.ops });\n out(\"ok\\n\");\n } catch (applyErr) {\n out(\"FAILED\\n\");\n err(` ${applyErr instanceof Error ? applyErr.message : String(applyErr)}\\n`);\n err(\"\\nPreflight failed.\\n\");\n return 1;\n }\n }\n\n out(\"\\nPreflight passed: every migration in the chain applies cleanly.\\n\");\n return 0;\n}\n\ninterface LoadedPackage extends ChainablePackage {\n readonly metadata: MigrationMetadata;\n readonly ops: readonly IdbDdlOp[];\n}\n\nasync function loadPackages(appDir: string): Promise<LoadedPackage[]> {\n let dirs: string[];\n try {\n dirs = (await readdir(appDir, { withFileTypes: true })).filter((d) => d.isDirectory()).map((d) => d.name);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw err;\n }\n\n // Load all packages unordered, then derive chain order by walking\n // metadata.from/to edges. Directory name sort is unreliable when\n // timestamp formats mix between hand-authored baselines and CLI-emitted\n // additions (e.g. T120000 vs T0337).\n const unordered = new Map<string, LoadedPackage>();\n for (const dirName of dirs) {\n const metaRaw = await readFile(join(appDir, dirName, \"migration.json\"), \"utf-8\");\n const opsRaw = await readFile(join(appDir, dirName, \"ops.json\"), \"utf-8\");\n const metadata = JSON.parse(metaRaw) as MigrationMetadata;\n const opsParsed = JSON.parse(opsRaw) as unknown[];\n const ops: IdbDdlOp[] = [];\n for (const op of opsParsed) {\n if (!isIdbDdlOp(op as never)) {\n throw new Error(`Non-IDB op found in ${dirName}/ops.json: ${JSON.stringify(op)}`);\n }\n ops.push(op as IdbDdlOp);\n }\n const computedHash = computeMigrationHash(metadata, ops as unknown as Parameters<typeof computeMigrationHash>[1]);\n if (computedHash !== metadata.migrationHash) {\n throw new Error(\n `Migration hash mismatch in ${dirName}: stored migrationHash ${metadata.migrationHash} ` +\n `does not match computed hash ${computedHash}`\n );\n }\n unordered.set(dirName, { dirName, metadata, ops });\n }\n\n return chainOrderByMetadata(unordered);\n}\n\nfunction applyPackage(input: {\n readonly factory: IDBFactory;\n readonly dbName: string;\n readonly targetVersion: number;\n readonly ops: readonly IdbDdlOp[];\n}): Promise<void> {\n return new Promise((resolve, reject) => {\n const req = input.factory.open(input.dbName, input.targetVersion);\n req.onupgradeneeded = (event) => {\n const target = event.target as IDBOpenDBRequest;\n const db = target.result;\n const tx = target.transaction;\n if (tx === null) {\n reject(new Error(\"upgradeneeded fired with null version-change transaction\"));\n return;\n }\n try {\n for (const op of input.ops) {\n applyOneDdlOp(db, tx, op);\n }\n } catch (err) {\n reject(err);\n }\n };\n req.onsuccess = () => {\n req.result.close();\n resolve();\n };\n req.onerror = () => reject(req.error ?? new Error(\"preflight open request failed\"));\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,eAAsB,aAAa,MAAyC;CAC1E,MAAM,MAAM,KAAK,SAAS,SAAiB,QAAQ,OAAO,MAAM,IAAI;CACpE,MAAM,MAAM,KAAK,SAAS,SAAiB,QAAQ,OAAO,MAAM,IAAI;CACpE,MAAM,gBAAgB,KAAK;CAG3B,MAAM,WAAW,MAAM,aAFR,KAAK,eAAe,KAEM,CAAC;CAC1C,IAAI,SAAS,WAAW,GAAG;EACzB,IAAI,sDAAsD;EAC1D,OAAO;CACT;CAEA,IAAI,gBAAgB,SAAS,OAAO,wCAAwC;CAE5E,MAAM,UAAU,IAAI,WAAW;CAC/B,MAAM,SAAS;CAEf,IAAI,iBAAiB;CACrB,KAAK,MAAM,OAAO,UAAU;EAC1B,IAAI,KAAK,IAAI,QAAQ,IAAI;EACzB,IAAI;GACF,kBAAkB;GAClB,MAAM,aAAa;IAAE;IAAS;IAAQ,eAAe;IAAgB,KAAK,IAAI;GAAI,CAAC;GACnF,IAAI,MAAM;EACZ,SAAS,UAAU;GACjB,IAAI,UAAU;GACd,IAAI,OAAO,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ,EAAE,GAAG;GAC9E,IAAI,uBAAuB;GAC3B,OAAO;EACT;CACF;CAEA,IAAI,qEAAqE;CACzE,OAAO;AACT;AAOA,eAAe,aAAa,QAA0C;CACpE,IAAI;CACJ,IAAI;EACF,QAAQ,MAAM,QAAQ,QAAQ,EAAE,eAAe,KAAK,CAAC,EAAA,CAAG,QAAQ,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;CAC1G,SAAS,KAAK;EACZ,IAAK,IAA8B,SAAS,UAAU,OAAO,CAAC;EAC9D,MAAM;CACR;CAMA,MAAM,4BAAY,IAAI,IAA2B;CACjD,KAAK,MAAM,WAAW,MAAM;EAC1B,MAAM,UAAU,MAAM,SAAS,KAAK,QAAQ,SAAS,gBAAgB,GAAG,OAAO;EAC/E,MAAM,SAAS,MAAM,SAAS,KAAK,QAAQ,SAAS,UAAU,GAAG,OAAO;EACxE,MAAM,WAAW,KAAK,MAAM,OAAO;EACnC,MAAM,YAAY,KAAK,MAAM,MAAM;EACnC,MAAM,MAAkB,CAAC;EACzB,KAAK,MAAM,MAAM,WAAW;GAC1B,IAAI,CAAC,WAAW,EAAW,GACzB,MAAM,IAAI,MAAM,uBAAuB,QAAQ,aAAa,KAAK,UAAU,EAAE,GAAG;GAElF,IAAI,KAAK,EAAc;EACzB;EACA,MAAM,eAAe,qBAAqB,UAAU,GAA4D;EAChH,IAAI,iBAAiB,SAAS,eAC5B,MAAM,IAAI,MACR,8BAA8B,QAAQ,yBAAyB,SAAS,cAAc,gCACpD,cACpC;EAEF,UAAU,IAAI,SAAS;GAAE;GAAS;GAAU;EAAI,CAAC;CACnD;CAEA,OAAO,qBAAqB,SAAS;AACvC;AAEA,SAAS,aAAa,OAKJ;CAChB,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,MAAM,MAAM,QAAQ,KAAK,MAAM,QAAQ,MAAM,aAAa;EAChE,IAAI,mBAAmB,UAAU;GAC/B,MAAM,SAAS,MAAM;GACrB,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;GAClB,IAAI,OAAO,MAAM;IACf,uBAAO,IAAI,MAAM,0DAA0D,CAAC;IAC5E;GACF;GACA,IAAI;IACF,KAAK,MAAM,MAAM,MAAM,KACrB,cAAc,IAAI,IAAI,EAAE;GAE5B,SAAS,KAAK;IACZ,OAAO,GAAG;GACZ;EACF;EACA,IAAI,kBAAkB;GACpB,IAAI,OAAO,MAAM;GACjB,QAAQ;EACV;EACA,IAAI,gBAAgB,OAAO,IAAI,yBAAS,IAAI,MAAM,+BAA+B,CAAC;CACpF,CAAC;AACH"}
@@ -0,0 +1,45 @@
1
+ import { Contract } from "@prisma/orm-framework/contract/types";
2
+ import { Result } from "@prisma/orm-framework/utils/result";
3
+ import { SymbolTable } from "@prisma/orm-framework/psl-parser";
4
+ import { ContractSourceDiagnostics } from "@prisma/orm-framework/config/config-types";
5
+ import { IdbStorage } from "@prisma-idb/target-idb/pack";
6
+ //#region src/core/psl-interpreter.d.ts
7
+ /**
8
+ * `"full"` interprets the schema as-is (today's behavior, unchanged — this is
9
+ * the server-facing shape). `"client"` additionally strips anything marked
10
+ * `@idb.exclude`/`@@idb.exclude`, producing the projected client contract.
11
+ *
12
+ * A surviving model's relation (any cardinality, required or optional) to an
13
+ * excluded model is dropped (with a warning), keeping the underlying FK
14
+ * scalar field — the model itself is never excluded as a result (ADR 013;
15
+ * see its §"Why we don't cascade on requiredness"). Field-level excludes
16
+ * that entangle with a relation (excluding an FK column, or the relation
17
+ * field itself) remain unsupported and are reported as diagnostics — a
18
+ * different, still out-of-scope case ADR 013 doesn't cover.
19
+ */
20
+ type ContractProjection = "full" | "client";
21
+ /**
22
+ * Interprets a PSL symbol table (`buildSymbolTable` from `@prisma/orm-toolchain`)
23
+ * and produces an IDB `Contract`.
24
+ *
25
+ * This is the IDB equivalent of `interpretPslDocumentToSqlContract` from the
26
+ * SQL family. It handles IDB-specific constraints:
27
+ *
28
+ * - No namespace blocks (IDB has a single implicit `__unbound__` namespace)
29
+ * - No compound primary keys (IDB `keyPath` must be a single field)
30
+ * - Relations are FK-side (`@relation`) + backrelation list fields
31
+ * - Indexes map directly to `IDBObjectStore.createIndex()` calls
32
+ *
33
+ * `options.projection: "client"` additionally strips models/fields marked
34
+ * `@@idb.exclude`/`@idb.exclude`, producing the projected client contract
35
+ * (ADR 012). Call this twice — once per projection — to emit both the full
36
+ * and client `Contract`s from the same schema.
37
+ */
38
+ interface InterpretPslOptions {
39
+ /** @default "full" */
40
+ readonly projection?: ContractProjection;
41
+ }
42
+ declare function interpretPslDocumentToIdbContract(table: SymbolTable, sourceId: string, options?: InterpretPslOptions): Result<Contract<IdbStorage>, ContractSourceDiagnostics>;
43
+ //#endregion
44
+ export { InterpretPslOptions as n, interpretPslDocumentToIdbContract as r, ContractProjection as t };
45
+ //# sourceMappingURL=psl-interpreter-C0suaXu2.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"psl-interpreter-C0suaXu2.d.mts","names":[],"sources":["../src/core/psl-interpreter.ts"],"mappings":";;;;;;;;;;;;;;;;;;;KAmLY;;;;;;;;;;;;;;;;;;UAksBK;;WAEN,aAAa;;iBAGR,kCACd,OAAO,aACP,kBACA,UAAU,sBACT,OAAO,SAAS,aAAa"}