@sequenceholdings/orm 0.1.1 → 0.1.2

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 (63) hide show
  1. package/README.md +1 -1
  2. package/dist/authoring.cjs +794 -0
  3. package/dist/authoring.cjs.map +1 -0
  4. package/dist/authoring.d.cts +274 -0
  5. package/dist/authoring.d.ts +274 -0
  6. package/dist/authoring.js +763 -0
  7. package/dist/authoring.js.map +1 -0
  8. package/dist/canonical.cjs +146 -0
  9. package/dist/canonical.cjs.map +1 -0
  10. package/dist/canonical.d.cts +369 -0
  11. package/dist/canonical.d.ts +369 -0
  12. package/dist/canonical.js +131 -0
  13. package/dist/canonical.js.map +1 -0
  14. package/dist/cli.cjs +6172 -1683
  15. package/dist/cli.cjs.map +1 -1
  16. package/dist/cli.d.cts +8 -1
  17. package/dist/cli.d.ts +8 -1
  18. package/dist/cli.js +6172 -1685
  19. package/dist/cli.js.map +1 -1
  20. package/dist/client.cjs +120 -0
  21. package/dist/client.cjs.map +1 -1
  22. package/dist/client.d.cts +74 -2
  23. package/dist/client.d.ts +74 -2
  24. package/dist/client.js +116 -1
  25. package/dist/client.js.map +1 -1
  26. package/dist/compiler.cjs +3001 -0
  27. package/dist/compiler.cjs.map +1 -0
  28. package/dist/compiler.d.cts +581 -0
  29. package/dist/compiler.d.ts +581 -0
  30. package/dist/compiler.js +2947 -0
  31. package/dist/compiler.js.map +1 -0
  32. package/dist/index.cjs +1705 -326
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +117 -56
  35. package/dist/index.d.ts +117 -56
  36. package/dist/index.js +1619 -323
  37. package/dist/index.js.map +1 -1
  38. package/dist/ir.cjs +407 -0
  39. package/dist/ir.cjs.map +1 -0
  40. package/dist/ir.d.cts +1179 -0
  41. package/dist/ir.d.ts +1179 -0
  42. package/dist/ir.js +388 -0
  43. package/dist/ir.js.map +1 -0
  44. package/dist/naming-CTvWSRTf.d.ts +79 -0
  45. package/dist/naming-DRyinU4u.d.cts +79 -0
  46. package/dist/sdl.cjs +833 -0
  47. package/dist/sdl.cjs.map +1 -0
  48. package/dist/sdl.d.cts +96 -0
  49. package/dist/sdl.d.ts +96 -0
  50. package/dist/sdl.js +809 -0
  51. package/dist/sdl.js.map +1 -0
  52. package/package.json +36 -3
  53. package/src/codegen-gql/apollo-hooks.cjs +98 -0
  54. package/src/codegen-gql/server-fns.cjs +101 -0
  55. package/templates/README.md +13 -0
  56. package/templates/orm-namespace/CLAUDE.md +81 -0
  57. package/templates/orm-namespace/codegen.ts +22 -0
  58. package/templates/orm-namespace/gitignore +5 -0
  59. package/templates/orm-namespace/graphql/example/queries.ts +56 -0
  60. package/templates/orm-namespace/package.json +24 -0
  61. package/templates/orm-namespace/schema/tables.ts +71 -0
  62. package/templates/orm-namespace/sequence.config.ts +32 -0
  63. package/templates/orm-namespace/tsconfig.json +15 -0
@@ -0,0 +1,369 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Canonical namespace definition v2 — the data-only JSON a consumer's
5
+ * TypeScript schema serializes to. This is v2's equivalent of the v1 YAML
6
+ * `NamespaceDefinition`: the CLI's jiti loader produces it, the content hash
7
+ * is computed over it, the server re-validates it (consumer TS never runs
8
+ * server-side), and the SDL generator / GraphQL compiler / migration engine
9
+ * all consume it.
10
+ *
11
+ * FROZEN CONTRACT (week 1): downstream tracks build against these shapes.
12
+ * Additive evolution only; `definition_format` discriminates on the wire.
13
+ */
14
+
15
+ declare const CANONICAL_FORMAT: 2;
16
+ /** Identifier grammar shared with v1 (`^[a-z][a-z0-9_]*$`, ≤63 bytes). */
17
+ declare const IDENTIFIER_RE: RegExp;
18
+ /** The 10 v1 column types, unchanged in v2. */
19
+ declare const COLUMN_TYPES: readonly ["uuid", "text", "integer", "bigint", "numeric", "double", "boolean", "timestamptz", "date", "jsonb"];
20
+ type ColumnType = (typeof COLUMN_TYPES)[number];
21
+ /** Enum columns reference a namespace-level `defineEnum` by name. */
22
+ declare const canonicalEnumSchema: z.ZodObject<{
23
+ name: z.ZodString;
24
+ values: z.ZodArray<z.ZodString>;
25
+ }, z.core.$strip>;
26
+ type CanonicalEnum = z.infer<typeof canonicalEnumSchema>;
27
+ declare const canonicalColumnSchema: z.ZodObject<{
28
+ name: z.ZodString;
29
+ columnName: z.ZodString;
30
+ type: z.ZodUnion<readonly [z.ZodEnum<{
31
+ bigint: "bigint";
32
+ boolean: "boolean";
33
+ uuid: "uuid";
34
+ text: "text";
35
+ integer: "integer";
36
+ numeric: "numeric";
37
+ double: "double";
38
+ timestamptz: "timestamptz";
39
+ date: "date";
40
+ jsonb: "jsonb";
41
+ }>, z.ZodObject<{
42
+ enum: z.ZodString;
43
+ }, z.core.$strip>]>;
44
+ nullable: z.ZodDefault<z.ZodBoolean>;
45
+ unique: z.ZodDefault<z.ZodBoolean>;
46
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
47
+ defaultFn: z.ZodOptional<z.ZodEnum<{
48
+ "gen_random_uuid()": "gen_random_uuid()";
49
+ "now()": "now()";
50
+ }>>;
51
+ description: z.ZodOptional<z.ZodString>;
52
+ renamedFrom: z.ZodOptional<z.ZodString>;
53
+ cast: z.ZodOptional<z.ZodString>;
54
+ deprecated: z.ZodDefault<z.ZodBoolean>;
55
+ }, z.core.$strip>;
56
+ type CanonicalColumn = z.infer<typeof canonicalColumnSchema>;
57
+ declare const canonicalLinkSchema: z.ZodObject<{
58
+ name: z.ZodString;
59
+ kind: z.ZodEnum<{
60
+ toOne: "toOne";
61
+ toMany: "toMany";
62
+ toPlatformUser: "toPlatformUser";
63
+ }>;
64
+ target: z.ZodOptional<z.ZodString>;
65
+ on: z.ZodString;
66
+ references: z.ZodOptional<z.ZodString>;
67
+ enforce: z.ZodDefault<z.ZodBoolean>;
68
+ description: z.ZodOptional<z.ZodString>;
69
+ }, z.core.$strip>;
70
+ type CanonicalLink = z.infer<typeof canonicalLinkSchema>;
71
+ declare const canonicalIndexSchema: z.ZodObject<{
72
+ columns: z.ZodArray<z.ZodString>;
73
+ unique: z.ZodDefault<z.ZodBoolean>;
74
+ name: z.ZodOptional<z.ZodString>;
75
+ }, z.core.$strip>;
76
+ /**
77
+ * Policy expressions stay DSL SOURCE STRINGS in the canonical form — parsing
78
+ * and claim-key validation happen in both CLI and server via the shared
79
+ * predicate parser. Variants follow §4c permissive-union semantics.
80
+ */
81
+ declare const policyVariantSchema: z.ZodObject<{
82
+ when: z.ZodString;
83
+ allow: z.ZodOptional<z.ZodLiteral<true>>;
84
+ policy: z.ZodOptional<z.ZodString>;
85
+ }, z.core.$strip>;
86
+ declare const policyExpressionSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
87
+ default: z.ZodString;
88
+ variants: z.ZodDefault<z.ZodArray<z.ZodObject<{
89
+ when: z.ZodString;
90
+ allow: z.ZodOptional<z.ZodLiteral<true>>;
91
+ policy: z.ZodOptional<z.ZodString>;
92
+ }, z.core.$strip>>>;
93
+ }, z.core.$strip>]>;
94
+ type PolicyExpression = z.infer<typeof policyExpressionSchema>;
95
+ declare const canonicalPoliciesSchema: z.ZodObject<{
96
+ read: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
97
+ default: z.ZodString;
98
+ variants: z.ZodDefault<z.ZodArray<z.ZodObject<{
99
+ when: z.ZodString;
100
+ allow: z.ZodOptional<z.ZodLiteral<true>>;
101
+ policy: z.ZodOptional<z.ZodString>;
102
+ }, z.core.$strip>>>;
103
+ }, z.core.$strip>]>>;
104
+ write: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
105
+ default: z.ZodString;
106
+ variants: z.ZodDefault<z.ZodArray<z.ZodObject<{
107
+ when: z.ZodString;
108
+ allow: z.ZodOptional<z.ZodLiteral<true>>;
109
+ policy: z.ZodOptional<z.ZodString>;
110
+ }, z.core.$strip>>>;
111
+ }, z.core.$strip>]>>;
112
+ }, z.core.$strip>;
113
+ /** Actions carry over from v1 as compiled named-SQL ops (plan: resolved OQ-1). */
114
+ declare const canonicalActionSchema: z.ZodObject<{
115
+ name: z.ZodString;
116
+ requires: z.ZodOptional<z.ZodString>;
117
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
118
+ type: z.ZodEnum<{
119
+ bigint: "bigint";
120
+ boolean: "boolean";
121
+ uuid: "uuid";
122
+ text: "text";
123
+ integer: "integer";
124
+ numeric: "numeric";
125
+ double: "double";
126
+ timestamptz: "timestamptz";
127
+ date: "date";
128
+ jsonb: "jsonb";
129
+ }>;
130
+ nullable: z.ZodDefault<z.ZodBoolean>;
131
+ }, z.core.$strip>>>;
132
+ executes: z.ZodString;
133
+ returns: z.ZodDefault<z.ZodEnum<{
134
+ rows: "rows";
135
+ rowsAffected: "rowsAffected";
136
+ scalar: "scalar";
137
+ }>>;
138
+ audit: z.ZodOptional<z.ZodObject<{
139
+ action: z.ZodString;
140
+ resource: z.ZodString;
141
+ }, z.core.$strip>>;
142
+ }, z.core.$strip>;
143
+ declare const canonicalTableSchema: z.ZodObject<{
144
+ table: z.ZodString;
145
+ description: z.ZodOptional<z.ZodString>;
146
+ renamedFrom: z.ZodOptional<z.ZodString>;
147
+ source: z.ZodOptional<z.ZodString>;
148
+ columns: z.ZodDefault<z.ZodArray<z.ZodObject<{
149
+ name: z.ZodString;
150
+ columnName: z.ZodString;
151
+ type: z.ZodUnion<readonly [z.ZodEnum<{
152
+ bigint: "bigint";
153
+ boolean: "boolean";
154
+ uuid: "uuid";
155
+ text: "text";
156
+ integer: "integer";
157
+ numeric: "numeric";
158
+ double: "double";
159
+ timestamptz: "timestamptz";
160
+ date: "date";
161
+ jsonb: "jsonb";
162
+ }>, z.ZodObject<{
163
+ enum: z.ZodString;
164
+ }, z.core.$strip>]>;
165
+ nullable: z.ZodDefault<z.ZodBoolean>;
166
+ unique: z.ZodDefault<z.ZodBoolean>;
167
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
168
+ defaultFn: z.ZodOptional<z.ZodEnum<{
169
+ "gen_random_uuid()": "gen_random_uuid()";
170
+ "now()": "now()";
171
+ }>>;
172
+ description: z.ZodOptional<z.ZodString>;
173
+ renamedFrom: z.ZodOptional<z.ZodString>;
174
+ cast: z.ZodOptional<z.ZodString>;
175
+ deprecated: z.ZodDefault<z.ZodBoolean>;
176
+ }, z.core.$strip>>>;
177
+ primaryKey: z.ZodOptional<z.ZodArray<z.ZodString>>;
178
+ links: z.ZodDefault<z.ZodArray<z.ZodObject<{
179
+ name: z.ZodString;
180
+ kind: z.ZodEnum<{
181
+ toOne: "toOne";
182
+ toMany: "toMany";
183
+ toPlatformUser: "toPlatformUser";
184
+ }>;
185
+ target: z.ZodOptional<z.ZodString>;
186
+ on: z.ZodString;
187
+ references: z.ZodOptional<z.ZodString>;
188
+ enforce: z.ZodDefault<z.ZodBoolean>;
189
+ description: z.ZodOptional<z.ZodString>;
190
+ }, z.core.$strip>>>;
191
+ indexes: z.ZodDefault<z.ZodArray<z.ZodObject<{
192
+ columns: z.ZodArray<z.ZodString>;
193
+ unique: z.ZodDefault<z.ZodBoolean>;
194
+ name: z.ZodOptional<z.ZodString>;
195
+ }, z.core.$strip>>>;
196
+ policies: z.ZodDefault<z.ZodObject<{
197
+ read: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
198
+ default: z.ZodString;
199
+ variants: z.ZodDefault<z.ZodArray<z.ZodObject<{
200
+ when: z.ZodString;
201
+ allow: z.ZodOptional<z.ZodLiteral<true>>;
202
+ policy: z.ZodOptional<z.ZodString>;
203
+ }, z.core.$strip>>>;
204
+ }, z.core.$strip>]>>;
205
+ write: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
206
+ default: z.ZodString;
207
+ variants: z.ZodDefault<z.ZodArray<z.ZodObject<{
208
+ when: z.ZodString;
209
+ allow: z.ZodOptional<z.ZodLiteral<true>>;
210
+ policy: z.ZodOptional<z.ZodString>;
211
+ }, z.core.$strip>>>;
212
+ }, z.core.$strip>]>>;
213
+ }, z.core.$strip>>;
214
+ actions: z.ZodDefault<z.ZodArray<z.ZodObject<{
215
+ name: z.ZodString;
216
+ requires: z.ZodOptional<z.ZodString>;
217
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
218
+ type: z.ZodEnum<{
219
+ bigint: "bigint";
220
+ boolean: "boolean";
221
+ uuid: "uuid";
222
+ text: "text";
223
+ integer: "integer";
224
+ numeric: "numeric";
225
+ double: "double";
226
+ timestamptz: "timestamptz";
227
+ date: "date";
228
+ jsonb: "jsonb";
229
+ }>;
230
+ nullable: z.ZodDefault<z.ZodBoolean>;
231
+ }, z.core.$strip>>>;
232
+ executes: z.ZodString;
233
+ returns: z.ZodDefault<z.ZodEnum<{
234
+ rows: "rows";
235
+ rowsAffected: "rowsAffected";
236
+ scalar: "scalar";
237
+ }>>;
238
+ audit: z.ZodOptional<z.ZodObject<{
239
+ action: z.ZodString;
240
+ resource: z.ZodString;
241
+ }, z.core.$strip>>;
242
+ }, z.core.$strip>>>;
243
+ }, z.core.$strip>;
244
+ type CanonicalTable = z.infer<typeof canonicalTableSchema>;
245
+ declare const canonicalDefinitionSchema: z.ZodObject<{
246
+ definition_format: z.ZodLiteral<2>;
247
+ namespace: z.ZodString;
248
+ description: z.ZodOptional<z.ZodString>;
249
+ enums: z.ZodDefault<z.ZodArray<z.ZodObject<{
250
+ name: z.ZodString;
251
+ values: z.ZodArray<z.ZodString>;
252
+ }, z.core.$strip>>>;
253
+ tables: z.ZodArray<z.ZodObject<{
254
+ table: z.ZodString;
255
+ description: z.ZodOptional<z.ZodString>;
256
+ renamedFrom: z.ZodOptional<z.ZodString>;
257
+ source: z.ZodOptional<z.ZodString>;
258
+ columns: z.ZodDefault<z.ZodArray<z.ZodObject<{
259
+ name: z.ZodString;
260
+ columnName: z.ZodString;
261
+ type: z.ZodUnion<readonly [z.ZodEnum<{
262
+ bigint: "bigint";
263
+ boolean: "boolean";
264
+ uuid: "uuid";
265
+ text: "text";
266
+ integer: "integer";
267
+ numeric: "numeric";
268
+ double: "double";
269
+ timestamptz: "timestamptz";
270
+ date: "date";
271
+ jsonb: "jsonb";
272
+ }>, z.ZodObject<{
273
+ enum: z.ZodString;
274
+ }, z.core.$strip>]>;
275
+ nullable: z.ZodDefault<z.ZodBoolean>;
276
+ unique: z.ZodDefault<z.ZodBoolean>;
277
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
278
+ defaultFn: z.ZodOptional<z.ZodEnum<{
279
+ "gen_random_uuid()": "gen_random_uuid()";
280
+ "now()": "now()";
281
+ }>>;
282
+ description: z.ZodOptional<z.ZodString>;
283
+ renamedFrom: z.ZodOptional<z.ZodString>;
284
+ cast: z.ZodOptional<z.ZodString>;
285
+ deprecated: z.ZodDefault<z.ZodBoolean>;
286
+ }, z.core.$strip>>>;
287
+ primaryKey: z.ZodOptional<z.ZodArray<z.ZodString>>;
288
+ links: z.ZodDefault<z.ZodArray<z.ZodObject<{
289
+ name: z.ZodString;
290
+ kind: z.ZodEnum<{
291
+ toOne: "toOne";
292
+ toMany: "toMany";
293
+ toPlatformUser: "toPlatformUser";
294
+ }>;
295
+ target: z.ZodOptional<z.ZodString>;
296
+ on: z.ZodString;
297
+ references: z.ZodOptional<z.ZodString>;
298
+ enforce: z.ZodDefault<z.ZodBoolean>;
299
+ description: z.ZodOptional<z.ZodString>;
300
+ }, z.core.$strip>>>;
301
+ indexes: z.ZodDefault<z.ZodArray<z.ZodObject<{
302
+ columns: z.ZodArray<z.ZodString>;
303
+ unique: z.ZodDefault<z.ZodBoolean>;
304
+ name: z.ZodOptional<z.ZodString>;
305
+ }, z.core.$strip>>>;
306
+ policies: z.ZodDefault<z.ZodObject<{
307
+ read: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
308
+ default: z.ZodString;
309
+ variants: z.ZodDefault<z.ZodArray<z.ZodObject<{
310
+ when: z.ZodString;
311
+ allow: z.ZodOptional<z.ZodLiteral<true>>;
312
+ policy: z.ZodOptional<z.ZodString>;
313
+ }, z.core.$strip>>>;
314
+ }, z.core.$strip>]>>;
315
+ write: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
316
+ default: z.ZodString;
317
+ variants: z.ZodDefault<z.ZodArray<z.ZodObject<{
318
+ when: z.ZodString;
319
+ allow: z.ZodOptional<z.ZodLiteral<true>>;
320
+ policy: z.ZodOptional<z.ZodString>;
321
+ }, z.core.$strip>>>;
322
+ }, z.core.$strip>]>>;
323
+ }, z.core.$strip>>;
324
+ actions: z.ZodDefault<z.ZodArray<z.ZodObject<{
325
+ name: z.ZodString;
326
+ requires: z.ZodOptional<z.ZodString>;
327
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
328
+ type: z.ZodEnum<{
329
+ bigint: "bigint";
330
+ boolean: "boolean";
331
+ uuid: "uuid";
332
+ text: "text";
333
+ integer: "integer";
334
+ numeric: "numeric";
335
+ double: "double";
336
+ timestamptz: "timestamptz";
337
+ date: "date";
338
+ jsonb: "jsonb";
339
+ }>;
340
+ nullable: z.ZodDefault<z.ZodBoolean>;
341
+ }, z.core.$strip>>>;
342
+ executes: z.ZodString;
343
+ returns: z.ZodDefault<z.ZodEnum<{
344
+ rows: "rows";
345
+ rowsAffected: "rowsAffected";
346
+ scalar: "scalar";
347
+ }>>;
348
+ audit: z.ZodOptional<z.ZodObject<{
349
+ action: z.ZodString;
350
+ resource: z.ZodString;
351
+ }, z.core.$strip>>;
352
+ }, z.core.$strip>>>;
353
+ }, z.core.$strip>>;
354
+ capabilities: z.ZodDefault<z.ZodObject<{
355
+ roles: z.ZodOptional<z.ZodUnknown>;
356
+ uses: z.ZodDefault<z.ZodArray<z.ZodString>>;
357
+ }, z.core.$strip>>;
358
+ }, z.core.$strip>;
359
+ type CanonicalDefinition = z.infer<typeof canonicalDefinitionSchema>;
360
+ /**
361
+ * Deterministic serialization discipline: tables sorted by name, columns in
362
+ * declaration order (order is meaningful for DDL), links/indexes/actions
363
+ * sorted by name, object keys emitted in schema order. `serializeNamespace`
364
+ * (authoring layer) and the server-side re-validation both normalize through
365
+ * this function before hashing so CLI and server hash identical bytes.
366
+ */
367
+ declare function normalizeCanonical(definition: CanonicalDefinition): CanonicalDefinition;
368
+
369
+ export { CANONICAL_FORMAT, COLUMN_TYPES, type CanonicalColumn, type CanonicalDefinition, type CanonicalEnum, type CanonicalLink, type CanonicalTable, type ColumnType, IDENTIFIER_RE, type PolicyExpression, canonicalActionSchema, canonicalColumnSchema, canonicalDefinitionSchema, canonicalEnumSchema, canonicalIndexSchema, canonicalLinkSchema, canonicalPoliciesSchema, canonicalTableSchema, normalizeCanonical, policyExpressionSchema, policyVariantSchema };
@@ -0,0 +1,131 @@
1
+ import { z } from 'zod';
2
+
3
+ // src/canonical/v2.ts
4
+ var CANONICAL_FORMAT = 2;
5
+ var IDENTIFIER_RE = /^[a-z][a-z0-9_]*$/;
6
+ var identifier = z.string().min(1).max(63).regex(IDENTIFIER_RE);
7
+ var COLUMN_TYPES = [
8
+ "uuid",
9
+ "text",
10
+ "integer",
11
+ "bigint",
12
+ "numeric",
13
+ "double",
14
+ "boolean",
15
+ "timestamptz",
16
+ "date",
17
+ "jsonb"
18
+ ];
19
+ var columnTypeSchema = z.enum(COLUMN_TYPES);
20
+ var canonicalEnumSchema = z.object({
21
+ name: identifier,
22
+ values: z.array(z.string().min(1).max(63)).min(1).max(100)
23
+ });
24
+ var canonicalColumnSchema = z.object({
25
+ /** Property name in TS (camelCase); columnName is the Postgres name. */
26
+ name: z.string().min(1).max(63),
27
+ columnName: identifier,
28
+ type: z.union([columnTypeSchema, z.object({ enum: identifier })]),
29
+ nullable: z.boolean().default(true),
30
+ unique: z.boolean().default(false),
31
+ /** Literal default, or one of the allowlisted SQL functions. */
32
+ default: z.union([z.string(), z.number(), z.boolean(), z.null()]).optional(),
33
+ defaultFn: z.enum(["gen_random_uuid()", "now()"]).optional(),
34
+ description: z.string().max(500).optional(),
35
+ /** Migration hints — same semantics as v1. */
36
+ renamedFrom: identifier.optional(),
37
+ cast: z.string().max(200).optional(),
38
+ deprecated: z.boolean().default(false)
39
+ });
40
+ var canonicalLinkSchema = z.object({
41
+ name: z.string().min(1).max(63),
42
+ kind: z.enum(["toOne", "toMany", "toPlatformUser"]),
43
+ /** Target table name (namespace-local). Absent for toPlatformUser. */
44
+ target: identifier.optional(),
45
+ /** FK column on the owning side (toOne/toPlatformUser: on this table; toMany: on the target). */
46
+ on: identifier,
47
+ /** Referenced column on the target (default: target's PK / platform user `sub`). */
48
+ references: identifier.optional(),
49
+ /** enforce: true emits a real FK constraint (same-namespace toOne only). */
50
+ enforce: z.boolean().default(false),
51
+ description: z.string().max(500).optional()
52
+ });
53
+ var canonicalIndexSchema = z.object({
54
+ columns: z.array(identifier).min(1),
55
+ unique: z.boolean().default(false),
56
+ name: identifier.optional()
57
+ });
58
+ var policyVariantSchema = z.object({
59
+ /** Claims-only guard (capability()/role()/claim() comparisons — no columns). */
60
+ when: z.string().min(1).max(1e3),
61
+ /** Exactly one of: allow-all bypass, or a row predicate. */
62
+ allow: z.literal(true).optional(),
63
+ policy: z.string().min(1).max(2e3).optional()
64
+ }).refine((v) => v.allow === true !== (typeof v.policy === "string"), {
65
+ message: "A variant declares exactly one of allow: true or policy"
66
+ });
67
+ var policyExpressionSchema = z.union([
68
+ z.string().min(1).max(2e3),
69
+ z.object({
70
+ default: z.string().min(1).max(2e3),
71
+ variants: z.array(policyVariantSchema).max(10).default([])
72
+ })
73
+ ]);
74
+ var canonicalPoliciesSchema = z.object({
75
+ read: policyExpressionSchema.optional(),
76
+ write: policyExpressionSchema.optional()
77
+ });
78
+ var canonicalActionSchema = z.object({
79
+ name: identifier,
80
+ requires: z.string().max(1e3).optional(),
81
+ params: z.record(z.string(), z.object({
82
+ type: columnTypeSchema,
83
+ nullable: z.boolean().default(false)
84
+ })).default({}),
85
+ executes: z.string().min(1).max(1e4),
86
+ returns: z.enum(["rows", "rowsAffected", "scalar"]).default("rowsAffected"),
87
+ audit: z.object({ action: z.string(), resource: z.string() }).optional()
88
+ });
89
+ var canonicalTableSchema = z.object({
90
+ table: identifier,
91
+ description: z.string().max(2e3).optional(),
92
+ /** Table-level rename hint (new in v2). */
93
+ renamedFrom: identifier.optional(),
94
+ /** Synced/reflected read-only tables (`source: gold.*`) — v1 semantics. */
95
+ source: z.string().regex(/^gold\.[a-z][a-z0-9_]*$/).optional(),
96
+ columns: z.array(canonicalColumnSchema).default([]),
97
+ primaryKey: z.array(identifier).min(1).max(8).optional(),
98
+ links: z.array(canonicalLinkSchema).default([]),
99
+ indexes: z.array(canonicalIndexSchema).default([]),
100
+ policies: canonicalPoliciesSchema.default({}),
101
+ actions: z.array(canonicalActionSchema).default([])
102
+ });
103
+ var canonicalDefinitionSchema = z.object({
104
+ definition_format: z.literal(CANONICAL_FORMAT),
105
+ namespace: identifier.max(41),
106
+ description: z.string().max(2e3).optional(),
107
+ enums: z.array(canonicalEnumSchema).default([]),
108
+ tables: z.array(canonicalTableSchema).min(0).max(500),
109
+ /** Verbatim custom-roles grammar (@sequenceholdings/custom-roles-manifest). */
110
+ capabilities: z.object({
111
+ roles: z.unknown().optional(),
112
+ uses: z.array(z.string()).default([])
113
+ }).default({ uses: [] })
114
+ });
115
+ function normalizeCanonical(definition) {
116
+ const sortByName = (items) => [...items].sort((a, b) => a.name.localeCompare(b.name));
117
+ return {
118
+ ...definition,
119
+ enums: sortByName(definition.enums),
120
+ tables: [...definition.tables].sort((a, b) => a.table.localeCompare(b.table)).map((t) => ({
121
+ ...t,
122
+ links: sortByName(t.links),
123
+ indexes: [...t.indexes].sort((a, b) => (a.name ?? a.columns.join("_")).localeCompare(b.name ?? b.columns.join("_"))),
124
+ actions: sortByName(t.actions)
125
+ }))
126
+ };
127
+ }
128
+
129
+ export { CANONICAL_FORMAT, COLUMN_TYPES, IDENTIFIER_RE, canonicalActionSchema, canonicalColumnSchema, canonicalDefinitionSchema, canonicalEnumSchema, canonicalIndexSchema, canonicalLinkSchema, canonicalPoliciesSchema, canonicalTableSchema, normalizeCanonical, policyExpressionSchema, policyVariantSchema };
130
+ //# sourceMappingURL=canonical.js.map
131
+ //# sourceMappingURL=canonical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/canonical/v2.ts"],"names":[],"mappings":"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","file":"canonical.js","sourcesContent":["/**\n * Canonical namespace definition v2 — the data-only JSON a consumer's\n * TypeScript schema serializes to. This is v2's equivalent of the v1 YAML\n * `NamespaceDefinition`: the CLI's jiti loader produces it, the content hash\n * is computed over it, the server re-validates it (consumer TS never runs\n * server-side), and the SDL generator / GraphQL compiler / migration engine\n * all consume it.\n *\n * FROZEN CONTRACT (week 1): downstream tracks build against these shapes.\n * Additive evolution only; `definition_format` discriminates on the wire.\n */\nimport { z } from 'zod'\n\nexport const CANONICAL_FORMAT = 2 as const\n\n/** Identifier grammar shared with v1 (`^[a-z][a-z0-9_]*$`, ≤63 bytes). */\nexport const IDENTIFIER_RE = /^[a-z][a-z0-9_]*$/\nconst identifier = z.string().min(1).max(63).regex(IDENTIFIER_RE)\n\n/** The 10 v1 column types, unchanged in v2. */\nexport const COLUMN_TYPES = [\n 'uuid', 'text', 'integer', 'bigint', 'numeric', 'double',\n 'boolean', 'timestamptz', 'date', 'jsonb',\n] as const\nexport type ColumnType = (typeof COLUMN_TYPES)[number]\n\nconst columnTypeSchema = z.enum(COLUMN_TYPES)\n\n/** Enum columns reference a namespace-level `defineEnum` by name. */\nexport const canonicalEnumSchema = z.object({\n name: identifier,\n values: z.array(z.string().min(1).max(63)).min(1).max(100),\n})\nexport type CanonicalEnum = z.infer<typeof canonicalEnumSchema>\n\nexport const canonicalColumnSchema = z.object({\n /** Property name in TS (camelCase); columnName is the Postgres name. */\n name: z.string().min(1).max(63),\n columnName: identifier,\n type: z.union([columnTypeSchema, z.object({ enum: identifier })]),\n nullable: z.boolean().default(true),\n unique: z.boolean().default(false),\n /** Literal default, or one of the allowlisted SQL functions. */\n default: z.union([z.string(), z.number(), z.boolean(), z.null()]).optional(),\n defaultFn: z.enum(['gen_random_uuid()', 'now()']).optional(),\n description: z.string().max(500).optional(),\n /** Migration hints — same semantics as v1. */\n renamedFrom: identifier.optional(),\n cast: z.string().max(200).optional(),\n deprecated: z.boolean().default(false),\n})\nexport type CanonicalColumn = z.infer<typeof canonicalColumnSchema>\n\nexport const canonicalLinkSchema = z.object({\n name: z.string().min(1).max(63),\n kind: z.enum(['toOne', 'toMany', 'toPlatformUser']),\n /** Target table name (namespace-local). Absent for toPlatformUser. */\n target: identifier.optional(),\n /** FK column on the owning side (toOne/toPlatformUser: on this table; toMany: on the target). */\n on: identifier,\n /** Referenced column on the target (default: target's PK / platform user `sub`). */\n references: identifier.optional(),\n /** enforce: true emits a real FK constraint (same-namespace toOne only). */\n enforce: z.boolean().default(false),\n description: z.string().max(500).optional(),\n})\nexport type CanonicalLink = z.infer<typeof canonicalLinkSchema>\n\nexport const canonicalIndexSchema = z.object({\n columns: z.array(identifier).min(1),\n unique: z.boolean().default(false),\n name: identifier.optional(),\n})\n\n/**\n * Policy expressions stay DSL SOURCE STRINGS in the canonical form — parsing\n * and claim-key validation happen in both CLI and server via the shared\n * predicate parser. Variants follow §4c permissive-union semantics.\n */\nexport const policyVariantSchema = z.object({\n /** Claims-only guard (capability()/role()/claim() comparisons — no columns). */\n when: z.string().min(1).max(1000),\n /** Exactly one of: allow-all bypass, or a row predicate. */\n allow: z.literal(true).optional(),\n policy: z.string().min(1).max(2000).optional(),\n}).refine((v) => (v.allow === true) !== (typeof v.policy === 'string'), {\n message: 'A variant declares exactly one of allow: true or policy',\n})\n\nexport const policyExpressionSchema = z.union([\n z.string().min(1).max(2000),\n z.object({\n default: z.string().min(1).max(2000),\n variants: z.array(policyVariantSchema).max(10).default([]),\n }),\n])\nexport type PolicyExpression = z.infer<typeof policyExpressionSchema>\n\nexport const canonicalPoliciesSchema = z.object({\n read: policyExpressionSchema.optional(),\n write: policyExpressionSchema.optional(),\n})\n\n/** Actions carry over from v1 as compiled named-SQL ops (plan: resolved OQ-1). */\nexport const canonicalActionSchema = z.object({\n name: identifier,\n requires: z.string().max(1000).optional(),\n params: z.record(z.string(), z.object({\n type: columnTypeSchema,\n nullable: z.boolean().default(false),\n })).default({}),\n executes: z.string().min(1).max(10_000),\n returns: z.enum(['rows', 'rowsAffected', 'scalar']).default('rowsAffected'),\n audit: z.object({ action: z.string(), resource: z.string() }).optional(),\n})\n\nexport const canonicalTableSchema = z.object({\n table: identifier,\n description: z.string().max(2000).optional(),\n /** Table-level rename hint (new in v2). */\n renamedFrom: identifier.optional(),\n /** Synced/reflected read-only tables (`source: gold.*`) — v1 semantics. */\n source: z.string().regex(/^gold\\.[a-z][a-z0-9_]*$/).optional(),\n columns: z.array(canonicalColumnSchema).default([]),\n primaryKey: z.array(identifier).min(1).max(8).optional(),\n links: z.array(canonicalLinkSchema).default([]),\n indexes: z.array(canonicalIndexSchema).default([]),\n policies: canonicalPoliciesSchema.default({}),\n actions: z.array(canonicalActionSchema).default([]),\n})\nexport type CanonicalTable = z.infer<typeof canonicalTableSchema>\n\nexport const canonicalDefinitionSchema = z.object({\n definition_format: z.literal(CANONICAL_FORMAT),\n namespace: identifier.max(41),\n description: z.string().max(2000).optional(),\n enums: z.array(canonicalEnumSchema).default([]),\n tables: z.array(canonicalTableSchema).min(0).max(500),\n /** Verbatim custom-roles grammar (@sequenceholdings/custom-roles-manifest). */\n capabilities: z.object({\n roles: z.unknown().optional(),\n uses: z.array(z.string()).default([]),\n }).default({ uses: [] }),\n})\nexport type CanonicalDefinition = z.infer<typeof canonicalDefinitionSchema>\n\n/**\n * Deterministic serialization discipline: tables sorted by name, columns in\n * declaration order (order is meaningful for DDL), links/indexes/actions\n * sorted by name, object keys emitted in schema order. `serializeNamespace`\n * (authoring layer) and the server-side re-validation both normalize through\n * this function before hashing so CLI and server hash identical bytes.\n */\nexport function normalizeCanonical(definition: CanonicalDefinition): CanonicalDefinition {\n const sortByName = <T extends { name: string }>(items: T[]): T[] =>\n [...items].sort((a, b) => a.name.localeCompare(b.name))\n return {\n ...definition,\n enums: sortByName(definition.enums),\n tables: [...definition.tables]\n .sort((a, b) => a.table.localeCompare(b.table))\n .map((t) => ({\n ...t,\n links: sortByName(t.links),\n indexes: [...t.indexes].sort((a, b) =>\n (a.name ?? a.columns.join('_')).localeCompare(b.name ?? b.columns.join('_'))),\n actions: sortByName(t.actions),\n })),\n }\n}\n"]}