@prisma-next/sql-runtime 0.5.0-dev.7 → 0.5.0-dev.70

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 (48) hide show
  1. package/README.md +31 -22
  2. package/dist/exports-CXtbKm5q.mjs +1516 -0
  3. package/dist/exports-CXtbKm5q.mjs.map +1 -0
  4. package/dist/{index-yb51L_1h.d.mts → index-C4Dz0JKE.d.mts} +116 -45
  5. package/dist/index-C4Dz0JKE.d.mts.map +1 -0
  6. package/dist/index.d.mts +2 -2
  7. package/dist/index.mjs +2 -3
  8. package/dist/test/utils.d.mts +38 -33
  9. package/dist/test/utils.d.mts.map +1 -1
  10. package/dist/test/utils.mjs +107 -56
  11. package/dist/test/utils.mjs.map +1 -1
  12. package/package.json +18 -19
  13. package/src/codecs/alias-resolver.ts +34 -0
  14. package/src/codecs/decoding.ts +263 -176
  15. package/src/codecs/encoding.ts +151 -38
  16. package/src/codecs/validation.ts +4 -4
  17. package/src/content-hash.ts +44 -0
  18. package/src/exports/index.ts +13 -7
  19. package/src/fingerprint.ts +22 -0
  20. package/src/guardrails/raw.ts +165 -0
  21. package/src/lower-sql-plan.ts +3 -3
  22. package/src/marker.ts +75 -0
  23. package/src/middleware/before-compile-chain.ts +1 -0
  24. package/src/middleware/budgets.ts +36 -120
  25. package/src/middleware/lints.ts +3 -3
  26. package/src/middleware/sql-middleware.ts +6 -5
  27. package/src/runtime-spi.ts +44 -0
  28. package/src/sql-context.ts +315 -105
  29. package/src/sql-family-adapter.ts +3 -2
  30. package/src/sql-marker.ts +89 -51
  31. package/src/sql-runtime.ts +305 -144
  32. package/dist/exports-BQZSVXXt.mjs +0 -981
  33. package/dist/exports-BQZSVXXt.mjs.map +0 -1
  34. package/dist/index-yb51L_1h.d.mts.map +0 -1
  35. package/src/codecs/json-schema-validation.ts +0 -61
  36. package/test/async-iterable-result.test.ts +0 -141
  37. package/test/before-compile-chain.test.ts +0 -223
  38. package/test/budgets.test.ts +0 -431
  39. package/test/context.types.test-d.ts +0 -68
  40. package/test/execution-stack.test.ts +0 -161
  41. package/test/json-schema-validation.test.ts +0 -571
  42. package/test/lints.test.ts +0 -160
  43. package/test/mutation-default-generators.test.ts +0 -254
  44. package/test/parameterized-types.test.ts +0 -529
  45. package/test/sql-context.test.ts +0 -384
  46. package/test/sql-family-adapter.test.ts +0 -103
  47. package/test/sql-runtime.test.ts +0 -792
  48. package/test/utils.ts +0 -297
package/src/sql-marker.ts CHANGED
@@ -1,4 +1,7 @@
1
- import type { MarkerStatement } from '@prisma-next/runtime-executor';
1
+ import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
2
+ import type { MarkerStatement } from '@prisma-next/sql-relational-core/ast';
3
+
4
+ export { APP_SPACE_ID };
2
5
 
3
6
  export interface SqlStatement {
4
7
  readonly sql: string;
@@ -6,12 +9,30 @@ export interface SqlStatement {
6
9
  }
7
10
 
8
11
  export interface WriteMarkerInput {
12
+ /**
13
+ * Logical space identifier for this marker row. Required at every
14
+ * call site so the type system surfaces every place that needs to
15
+ * thread the value (rather than letting an `?? APP_SPACE_ID`
16
+ * fall-through silently collapse multi-space markers onto the
17
+ * `'app'` row). App-plan callers pass {@link APP_SPACE_ID}
18
+ * (`'app'`); per-extension callers pass the extension's space id.
19
+ */
20
+ readonly space: string;
9
21
  readonly storageHash: string;
10
22
  readonly profileHash: string;
11
23
  readonly contractJson?: unknown;
12
24
  readonly canonicalVersion?: number;
13
25
  readonly appTag?: string;
14
26
  readonly meta?: Record<string, unknown>;
27
+ /**
28
+ * Applied-invariants set on the marker.
29
+ *
30
+ * - `undefined` → existing column left untouched. Sign and
31
+ * verify-database paths use this; they don't accumulate invariants.
32
+ * - explicit value (including `[]`) → column overwritten with
33
+ * exactly that value.
34
+ */
35
+ readonly invariants?: readonly string[];
15
36
  }
16
37
 
17
38
  export const ensureSchemaStatement: SqlStatement = {
@@ -19,21 +40,33 @@ export const ensureSchemaStatement: SqlStatement = {
19
40
  params: [],
20
41
  };
21
42
 
43
+ /**
44
+ * Schema for `prisma_contract.marker`. The `space text` primary key
45
+ * supports one row per loaded contract space (`'app'`,
46
+ * `'<extension-id>'`, …); brand-new databases create this shape
47
+ * directly. Pre-1.0 single-row markers (no `space` column) are not
48
+ * auto-migrated — the target-specific migration runner detects the
49
+ * legacy shape at boot and surfaces a structured `LEGACY_MARKER_SHAPE`
50
+ * failure pointing the operator at re-running `dbInit`.
51
+ *
52
+ * @see specs/framework-mechanism.spec.md § 2.
53
+ */
22
54
  export const ensureTableStatement: SqlStatement = {
23
55
  sql: `create table if not exists prisma_contract.marker (
24
- id smallint primary key default 1,
56
+ space text not null primary key default '${APP_SPACE_ID}',
25
57
  core_hash text not null,
26
58
  profile_hash text not null,
27
59
  contract_json jsonb,
28
60
  canonical_version int,
29
61
  updated_at timestamptz not null default now(),
30
62
  app_tag text,
31
- meta jsonb not null default '{}'
63
+ meta jsonb not null default '{}',
64
+ invariants text[] not null default '{}'
32
65
  )`,
33
66
  params: [],
34
67
  };
35
68
 
36
- export function readContractMarker(): MarkerStatement {
69
+ export function readContractMarker(space: string): MarkerStatement {
37
70
  return {
38
71
  sql: `select
39
72
  core_hash,
@@ -42,10 +75,11 @@ export function readContractMarker(): MarkerStatement {
42
75
  canonical_version,
43
76
  updated_at,
44
77
  app_tag,
45
- meta
78
+ meta,
79
+ invariants
46
80
  from prisma_contract.marker
47
- where id = $1`,
48
- params: [1],
81
+ where space = $1`,
82
+ params: [space],
49
83
  };
50
84
  }
51
85
 
@@ -54,52 +88,56 @@ export interface WriteContractMarkerStatements {
54
88
  readonly update: SqlStatement;
55
89
  }
56
90
 
57
- export function writeContractMarker(input: WriteMarkerInput): WriteContractMarkerStatements {
58
- const baseParams: readonly unknown[] = [
59
- 1,
60
- input.storageHash,
61
- input.profileHash,
62
- input.contractJson ?? null,
63
- input.canonicalVersion ?? null,
64
- input.appTag ?? null,
65
- JSON.stringify(input.meta ?? {}),
91
+ /**
92
+ * Variable columns that participate in INSERT/UPDATE alongside the
93
+ * always-on `space = $1` and `updated_at = now()`. Each column declares
94
+ * its name, optional cast type, and parameter value; the placeholder
95
+ * (`$N`) is computed positionally below — adding or reordering a
96
+ * column doesn't desync indices. `invariants` only appears when the
97
+ * caller supplies it — see `WriteMarkerInput.invariants`.
98
+ */
99
+ function markerColumns(
100
+ input: WriteMarkerInput,
101
+ ): ReadonlyArray<{ readonly name: string; readonly type?: string; readonly param: unknown }> {
102
+ return [
103
+ { name: 'core_hash', param: input.storageHash },
104
+ { name: 'profile_hash', param: input.profileHash },
105
+ { name: 'contract_json', type: 'jsonb', param: input.contractJson ?? null },
106
+ { name: 'canonical_version', param: input.canonicalVersion ?? null },
107
+ { name: 'app_tag', param: input.appTag ?? null },
108
+ { name: 'meta', type: 'jsonb', param: JSON.stringify(input.meta ?? {}) },
109
+ ...(input.invariants !== undefined
110
+ ? [{ name: 'invariants' as const, type: 'text[]' as const, param: input.invariants }]
111
+ : []),
66
112
  ];
113
+ }
67
114
 
68
- const insert: SqlStatement = {
69
- sql: `insert into prisma_contract.marker (
70
- id,
71
- core_hash,
72
- profile_hash,
73
- contract_json,
74
- canonical_version,
75
- updated_at,
76
- app_tag,
77
- meta
78
- ) values (
79
- $1,
80
- $2,
81
- $3,
82
- $4::jsonb,
83
- $5,
84
- now(),
85
- $6,
86
- $7::jsonb
87
- )`,
88
- params: baseParams,
89
- };
115
+ export function writeContractMarker(input: WriteMarkerInput): WriteContractMarkerStatements {
116
+ const cols = markerColumns(input);
117
+ // $1 is reserved for `space`; subsequent positions follow the order of cols.
118
+ const placed = cols.map((c, i) => ({
119
+ name: c.name,
120
+ expr: c.type ? `$${i + 2}::${c.type}` : `$${i + 2}`,
121
+ param: c.param,
122
+ }));
123
+ const params: readonly unknown[] = [input.space, ...placed.map((c) => c.param)];
90
124
 
91
- const update: SqlStatement = {
92
- sql: `update prisma_contract.marker set
93
- core_hash = $2,
94
- profile_hash = $3,
95
- contract_json = $4::jsonb,
96
- canonical_version = $5,
97
- updated_at = now(),
98
- app_tag = $6,
99
- meta = $7::jsonb
100
- where id = $1`,
101
- params: baseParams,
102
- };
125
+ // `updated_at = now()` is a SQL literal with no parameter slot, so it
126
+ // sits outside `placed` and is appended directly to each statement.
127
+ const insertColumns = ['space', ...placed.map((c) => c.name), 'updated_at'].join(', ');
128
+ const insertValues = ['$1', ...placed.map((c) => c.expr), 'now()'].join(', ');
129
+ const setClauses = [...placed.map((c) => `${c.name} = ${c.expr}`), 'updated_at = now()'].join(
130
+ ', ',
131
+ );
103
132
 
104
- return { insert, update };
133
+ return {
134
+ insert: {
135
+ sql: `insert into prisma_contract.marker (${insertColumns}) values (${insertValues})`,
136
+ params,
137
+ },
138
+ update: {
139
+ sql: `update prisma_contract.marker set ${setClauses} where space = $1`,
140
+ params,
141
+ },
142
+ };
105
143
  }