@sequenceholdings/orm 0.1.0 → 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 +6208 -1693
  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 +6262 -1749
  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 +1730 -327
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +126 -56
  35. package/dist/index.d.ts +126 -56
  36. package/dist/index.js +1643 -324
  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,581 @@
1
+ import { CanonicalEnum, CanonicalDefinition, PolicyExpression } from './canonical.cjs';
2
+ import { ClaimKey, PredIr, RootIr, InputRefKind, TableMetaIr, CompiledOperation, CompiledArtifact, CmpOp, VariableIr, OrderIr, SelectionIr } from './ir.cjs';
3
+ import { DocumentNode, OperationDefinitionNode, FragmentDefinitionNode, GraphQLSchema, ValueNode, SelectionSetNode } from 'graphql';
4
+ export { P as PLATFORM_USER_TYPENAME, c as camelCase, e as enumTypeName, p as pascalCase } from './naming-DRyinU4u.cjs';
5
+ import 'zod';
6
+
7
+ type DiagnosticSeverity = 'error' | 'warning';
8
+ interface CompilerDiagnostic {
9
+ severity: DiagnosticSeverity;
10
+ /** Stable machine code, e.g. 'unknown-column', 'unsupported-variable-type'. */
11
+ code: string;
12
+ message: string;
13
+ /** Source document path, when the diagnostic is document-scoped. */
14
+ document?: string;
15
+ /** Operation name, when known. */
16
+ operation?: string;
17
+ /** Table name, for canonical/policy-scoped diagnostics. */
18
+ table?: string;
19
+ }
20
+ /**
21
+ * Thrown internally while compiling one operation; artifact assembly catches
22
+ * it and records a diagnostic, so one broken document never hides the rest.
23
+ */
24
+ declare class DocumentCompileError extends Error {
25
+ readonly code: string;
26
+ readonly candidates: readonly string[];
27
+ readonly name = "DocumentCompileError";
28
+ constructor(message: string, code: string, candidates?: readonly string[]);
29
+ }
30
+ /** Thrown by compileNamespace when any error-severity diagnostic was produced. */
31
+ declare class NamespaceCompileError extends Error {
32
+ readonly diagnostics: CompilerDiagnostic[];
33
+ readonly name = "NamespaceCompileError";
34
+ constructor(diagnostics: CompilerDiagnostic[]);
35
+ }
36
+
37
+ /**
38
+ * Inject pass — bake policies into the lowered IR so the artifact is
39
+ * self-contained (plan §4 invariant: execution needs only IR + claims +
40
+ * variables):
41
+ *
42
+ * - read policy AND-ed into every select/byPk/aggregate root `where`, every
43
+ * relation subtree `where`, every aggregate `where`, and — via relation
44
+ * subtrees — mutation `returning`;
45
+ * - document-authored relationship predicates (exists/aggPredicate) get the
46
+ * TARGET table's read policy injected too, so filtering through a link
47
+ * can't become an existence oracle on rows the caller can't read;
48
+ * - write policy AND-ed into update/delete row filters, and set as the
49
+ * insert check for inserts (claims + inserted-values only in v2.0 — an
50
+ * exists() write policy makes a table un-insertable, loudly);
51
+ * - `col = claim(k)` AND-conjuncts of the write policy become pinned columns
52
+ * merged into every inserted row (and excluded from insertable/settable).
53
+ */
54
+
55
+ interface PinnedColumn {
56
+ column: string;
57
+ claim: ClaimKey;
58
+ }
59
+ /**
60
+ * Pins come from `col = claim(k)` comparisons the write policy fixes for EVERY
61
+ * caller, so the server can fill the column and drop it from the insert input.
62
+ *
63
+ * - `and` contributes the UNION of its operands' pins: each conjunct must hold.
64
+ * - `or` contributes their INTERSECTION on (column, claim): a policy with
65
+ * variants is a permissive union (§4c), so only a pin present — and pinned
66
+ * to the same claim — in every arm is fixed regardless of which arm admits
67
+ * the caller. Pinning from one arm alone would silently narrow the others
68
+ * (a `deals-admin` variant that only constrains `org` would lose the ability
69
+ * to insert on another author's behalf).
70
+ * - everything else (not/exists/capability/role/const/dynamic) pins nothing.
71
+ *
72
+ * A column left unpinned is not unprotected: it stays in the insert input and
73
+ * the same policy is enforced as the insert check, so a forged value is
74
+ * rejected with POLICY_CHECK_FAILED. Pinning is about removing the column from
75
+ * the client's reach, not about whether the rule is enforced.
76
+ */
77
+ declare function collectPinnedColumns(writePolicy: PredIr): PinnedColumn[];
78
+ declare function injectPolicies({ roots, ctx }: {
79
+ roots: RootIr[];
80
+ ctx: CompileContext;
81
+ }): {
82
+ roots: RootIr[];
83
+ tableSet: string[];
84
+ };
85
+
86
+ /**
87
+ * Compiler-side naming — a thin adaptor over the CANONICAL naming authority,
88
+ * `src/sdl/naming.ts`. Every type/input/enum/scalar/root name the compiler
89
+ * resolves is derived from the same `tableNames`/`typeName` math the SDL
90
+ * generator emits (singularized PascalCase types, lowercase custom scalars),
91
+ * so the two surfaces can never skew. Pinned by
92
+ * `test/compiler/naming-parity.test.ts`.
93
+ */
94
+
95
+ /**
96
+ * Artifact/link key for the built-in platform-users entity (plan §4b). This
97
+ * is the LOGICAL key (`artifact.tables['platformUsers']`, link targets) — the
98
+ * SQL identity of the backing relation is `platform.users_directory` (see
99
+ * `platformUserMeta` in context.ts).
100
+ */
101
+ declare const PLATFORM_USER_TABLE = "platformUsers";
102
+
103
+ /** GraphQL object type name for a table: `deal_comments` → `DealComment`. */
104
+ declare function typeNameForTable(table: string): string;
105
+ /** Query-root field names for a table — the SDL generator's own root names. */
106
+ declare function queryRootNames(table: string): {
107
+ select: string;
108
+ byPk: string;
109
+ aggregate: string;
110
+ };
111
+ type MutationOp = 'insert' | 'insertOne' | 'update' | 'updateByPk' | 'delete' | 'deleteByPk';
112
+ declare function mutationRootNames(table: string): Record<MutationOp, string>;
113
+ /** Generated input type name for a table, e.g. ('deals', 'boolExp') → 'DealBoolExp'. */
114
+ declare function inputTypeName(table: string, kind: InputRefKind): string;
115
+ /**
116
+ * Map a GraphQL input/enum type name back to `{ input, table }` via the naming
117
+ * rules. Returns undefined when the name doesn't match a generated §4f type
118
+ * for any known table.
119
+ */
120
+ declare function classifyInputType(name: string, tableByTypename: ReadonlyMap<string, string>): {
121
+ input: InputRefKind;
122
+ table: string;
123
+ } | undefined;
124
+
125
+ /**
126
+ * Compile context — everything derived from the canonical definition that the
127
+ * restrict/lower/inject passes need: per-table runtime metadata (TableMetaIr),
128
+ * the root-field and input-type name indexes, and the compiled read/write
129
+ * policies with their pinned columns.
130
+ */
131
+
132
+ interface QueryRootInfo {
133
+ kind: 'select' | 'byPk' | 'aggregate';
134
+ table: string;
135
+ }
136
+ interface MutationRootInfo {
137
+ op: MutationOp;
138
+ table: string;
139
+ }
140
+ interface CompileContext {
141
+ namespace: string;
142
+ tables: Record<string, TableMetaIr>;
143
+ /** GraphQL object type name → table name. */
144
+ tableByTypename: Map<string, string>;
145
+ queryRoots: Map<string, QueryRootInfo>;
146
+ mutationRoots: Map<string, MutationRootInfo>;
147
+ /** GraphQL enum type name → canonical enum (SelectColumn enums are NOT here). */
148
+ enumsByTypeName: Map<string, CanonicalEnum>;
149
+ readPolicies: Map<string, PredIr>;
150
+ writePolicies: Map<string, PredIr>;
151
+ /** Per-table `col = claim(k)` write-policy pins (insert-merged, non-insertable). */
152
+ pins: Map<string, PinnedColumn[]>;
153
+ }
154
+ /**
155
+ * §4b curated platform-users view — synthesized, never consumer-defined.
156
+ *
157
+ * The SQL identity (`schema`."`table`" — what the executor's tableFrag
158
+ * renders) is the hand-migrated view `platform.users_directory` (atlas
159
+ * migration 0481_platform_users_view.sql), NOT the logical artifact key
160
+ * `platformUsers` that links/tableSets/policies use. Must match
161
+ * atlas/src/server/services/orm/platform-users.ts EXACTLY — import-sharing is
162
+ * impossible across the package boundary, so the two are pinned by tests on
163
+ * both sides (test/compiler/compile-namespace.test.ts §4b and atlas
164
+ * platform-users.test.ts).
165
+ */
166
+ declare function platformUserMeta(): TableMetaIr;
167
+ interface BuildContextResult {
168
+ ctx: CompileContext;
169
+ diagnostics: CompilerDiagnostic[];
170
+ }
171
+ declare function buildCompileContext(rawCanonical: CanonicalDefinition): BuildContextResult;
172
+
173
+ /**
174
+ * Parse pass — build the GraphQLSchema from SDL text and parse + validate the
175
+ * consumer's documents against it with graphql-js's spec rules. Validation
176
+ * failures become diagnostics (never thrown mid-pipeline) so every document
177
+ * reports at once.
178
+ */
179
+
180
+ interface SourceDocument {
181
+ path: string;
182
+ contents: string;
183
+ }
184
+ interface ParsedDocument {
185
+ path: string;
186
+ document: DocumentNode;
187
+ operations: OperationDefinitionNode[];
188
+ /** Fragments are document-scoped — bios colocates them via TS interpolation. */
189
+ fragments: Map<string, FragmentDefinitionNode>;
190
+ }
191
+ declare function parseSdl(sdl: string): GraphQLSchema;
192
+ interface ParseDocumentsResult {
193
+ documents: ParsedDocument[];
194
+ diagnostics: CompilerDiagnostic[];
195
+ }
196
+ declare function parseDocuments({ schema, documents, }: {
197
+ schema: GraphQLSchema;
198
+ documents: SourceDocument[];
199
+ }): ParseDocumentsResult;
200
+
201
+ /** Content hash of the canonical definition — the schema identity ops compile against. */
202
+ declare function computeSchemaHash(canonical: CanonicalDefinition): string;
203
+ interface ClientManifestOperation {
204
+ opHash: string;
205
+ kind: 'query' | 'mutation' | 'action';
206
+ requires: CompiledOperation['requires'];
207
+ }
208
+ /** What codegen/the client transport needs: name → hash mapping + set identity. */
209
+ interface ClientManifest {
210
+ namespace: string;
211
+ schemaHash: string;
212
+ opsHash: string;
213
+ operations: Record<string, ClientManifestOperation>;
214
+ }
215
+ interface CompileNamespaceInput {
216
+ canonical: CanonicalDefinition;
217
+ /** Generated SDL text (src/sdl once it lands; test-local SDL until then). */
218
+ sdl: string;
219
+ documents: SourceDocument[];
220
+ }
221
+ type CompileNamespaceResult = {
222
+ ok: true;
223
+ artifact: CompiledArtifact;
224
+ manifest: ClientManifest;
225
+ diagnostics: CompilerDiagnostic[];
226
+ } | {
227
+ ok: false;
228
+ diagnostics: CompilerDiagnostic[];
229
+ };
230
+ declare function compileNamespace({ canonical, sdl, documents }: CompileNamespaceInput): CompileNamespaceResult;
231
+ /** compileNamespace that throws on errors — for callers that want the v1-style hard failure. */
232
+ declare function compileNamespaceOrThrow(input: CompileNamespaceInput): {
233
+ artifact: CompiledArtifact;
234
+ manifest: ClientManifest;
235
+ diagnostics: CompilerDiagnostic[];
236
+ };
237
+ /** Per-table `col = claim(k)` write-policy pins — exposed for SDL generation options. */
238
+ declare function computePinnedColumnsByTable(canonical: CanonicalDefinition): Record<string, PinnedColumn[]>;
239
+
240
+ /**
241
+ * §4f dynamic-input validators — PURE, data-only functions the data plane
242
+ * imports to check client-supplied values for dynamic slots (BoolExp /
243
+ * OrderBy / SelectColumn / InsertInput / SetInput / AppendInput / OnConflict)
244
+ * against the artifact's per-table whitelist metadata (TableMetaIr).
245
+ *
246
+ * No drizzle imports, no IO. Each validator returns a normalized tree or
247
+ * typed issues; the executor's runtime lowering step consumes the normalized
248
+ * form and ANDs the result with the baked policy predicate — the policy is
249
+ * non-negotiable regardless of what the client sends.
250
+ */
251
+
252
+ interface DynamicInputIssue {
253
+ code: 'invalid-shape' | 'unknown-column' | 'unknown-link' | 'unknown-operator' | 'invalid-value' | 'column-not-allowed' | 'nested-insert' | 'unknown-constraint' | 'too-deep' | 'too-many-nodes' | 'too-many-rows';
254
+ path: string;
255
+ message: string;
256
+ }
257
+ type DynamicInputResult<T> = {
258
+ ok: true;
259
+ value: T;
260
+ } | {
261
+ ok: false;
262
+ issues: DynamicInputIssue[];
263
+ };
264
+ type NormalizedBoolExp = {
265
+ kind: 'and' | 'or';
266
+ operands: NormalizedBoolExp[];
267
+ } | {
268
+ kind: 'not';
269
+ operand: NormalizedBoolExp;
270
+ } | {
271
+ kind: 'cmp';
272
+ op: CmpOp;
273
+ column: string;
274
+ value: unknown;
275
+ } | {
276
+ kind: 'exists';
277
+ link: string;
278
+ target: string;
279
+ where: NormalizedBoolExp;
280
+ };
281
+ interface NormalizedOrderBy {
282
+ column: string;
283
+ link?: string;
284
+ direction: 'asc' | 'desc';
285
+ nulls?: 'first' | 'last';
286
+ }
287
+ type NormalizedRow = Record<string, unknown>;
288
+ interface NormalizedOnConflict {
289
+ constraint: string;
290
+ updateColumns: string[];
291
+ }
292
+ interface BoolExpInput {
293
+ table: TableMetaIr;
294
+ /** Artifact tables record — relationship predicates resolve targets here. */
295
+ tables: Record<string, TableMetaIr>;
296
+ value: unknown;
297
+ maxDepth?: number;
298
+ maxNodes?: number;
299
+ }
300
+ declare function validateBoolExpInput({ table, tables, value, maxDepth, maxNodes }: BoolExpInput): DynamicInputResult<NormalizedBoolExp>;
301
+ declare function validateOrderByInput({ table, tables, value, }: {
302
+ table: TableMetaIr;
303
+ tables: Record<string, TableMetaIr>;
304
+ value: unknown;
305
+ }): DynamicInputResult<NormalizedOrderBy[]>;
306
+ declare function validateSelectColumns({ table, value }: {
307
+ table: TableMetaIr;
308
+ value: unknown;
309
+ }): DynamicInputResult<string[]>;
310
+ declare function validateInsertInput({ table, value, list, maxRows, }: {
311
+ table: TableMetaIr;
312
+ value: unknown;
313
+ /** true for `$objects: [FooInsertInput!]`, false for `$object: FooInsertInput`. */
314
+ list: boolean;
315
+ maxRows?: number;
316
+ }): DynamicInputResult<NormalizedRow[]>;
317
+ declare function validateSetInput({ table, value }: {
318
+ table: TableMetaIr;
319
+ value: unknown;
320
+ }): DynamicInputResult<NormalizedRow>;
321
+ /** _append targets jsonb columns; values are arbitrary JSON (no scalar check). */
322
+ declare function validateAppendInput({ table, value }: {
323
+ table: TableMetaIr;
324
+ value: unknown;
325
+ }): DynamicInputResult<NormalizedRow>;
326
+ declare function validateOnConflictInput({ table, value, }: {
327
+ table: TableMetaIr;
328
+ value: unknown;
329
+ }): DynamicInputResult<NormalizedOnConflict>;
330
+
331
+ /**
332
+ * Flatten pass — inline every fragment spread (and inline fragment) so the
333
+ * lowering pass sees one plain selection tree. The bios corpus uses flat,
334
+ * TS-interpolated fragments only; nested spreads still work here, but cycles
335
+ * and directives-on-spreads are rejected.
336
+ */
337
+
338
+ declare function flattenOperation({ operation, fragments, }: {
339
+ operation: OperationDefinitionNode;
340
+ fragments: ReadonlyMap<string, FragmentDefinitionNode>;
341
+ }): OperationDefinitionNode;
342
+
343
+ /** Bump on any change to lowering semantics — invalidates every op hash. */
344
+ declare const COMPILER_MAJOR = 1;
345
+ /** Canonical print of one flattened operation (fragments already inlined). */
346
+ declare function canonicalOperationText(definition: OperationDefinitionNode): string;
347
+ declare function computeOpHash({ definition, schemaHash, }: {
348
+ definition: OperationDefinitionNode;
349
+ schemaHash: string;
350
+ }): string;
351
+ /** Order-independent set hash over the sorted op hashes. */
352
+ declare function computeOpsHash(opHashes: readonly string[]): string;
353
+
354
+ /**
355
+ * Restrict pass — the grammar gate that keeps operations inside the v2.0
356
+ * envelope BEFORE lowering:
357
+ *
358
+ * - operations must be named (the op name keys the registry + manifest);
359
+ * - no subscriptions (post-v1);
360
+ * - every variable must be a scalar, a scalar list, a declared enum, OR one
361
+ * of the §4f generated input types (BoolExp/OrderBy/SelectColumn/
362
+ * InsertInput/SetInput/AppendInput/OnConflict) — mapped back to
363
+ * `{ inputRef kind, table }` via the naming rules. Anything else gets a
364
+ * targeted error naming what IS allowed.
365
+ * - a declared default is validated here and persisted into the IR, so the
366
+ * executor can apply it. A default the IR cannot carry faithfully is a
367
+ * compile error rather than a value that silently becomes NULL.
368
+ */
369
+
370
+ interface RestrictedOperation {
371
+ name: string;
372
+ kind: 'query' | 'mutation';
373
+ requires: CompiledOperation['requires'];
374
+ variables: VariableIr[];
375
+ definition: OperationDefinitionNode;
376
+ }
377
+ declare function restrictOperation({ operation, ctx, }: {
378
+ operation: OperationDefinitionNode;
379
+ ctx: CompileContext;
380
+ }): RestrictedOperation;
381
+
382
+ /**
383
+ * Lower pass — flattened GraphQL selection trees → IR. Document-authored
384
+ * argument literals lower to PredIr/OrderIr (variables allowed in leaf
385
+ * positions as ValueIr variables); whole-variable arguments become §4f
386
+ * dynamic slots keyed by the variable name. Policies are NOT injected here —
387
+ * see inject.ts (this pass emits document-only `where` shapes).
388
+ */
389
+
390
+ declare const DEFAULT_LIMIT = 100;
391
+ declare const MAX_LIMIT = 1000;
392
+ declare class OperationLowerer {
393
+ private readonly ctx;
394
+ private readonly variables;
395
+ constructor(ctx: CompileContext, restricted: RestrictedOperation);
396
+ private meta;
397
+ private column;
398
+ private link;
399
+ private fieldCandidates;
400
+ /** Validate that a whole-variable argument is the declared §4f slot for this table. */
401
+ private slot;
402
+ private lowerValue;
403
+ lowerBoolExp(node: ValueNode, table: string): PredIr;
404
+ private lowerComparison;
405
+ /** Hasura aggregation predicate: `{ count: { predicate: { _gt: 2 }, filter: {…} } }`. */
406
+ private lowerAggPredicate;
407
+ lowerOrderBy(node: ValueNode, table: string): OrderIr[];
408
+ private lowerDirection;
409
+ lowerDistinctOn(node: ValueNode, table: string): string[] | {
410
+ slot: string;
411
+ };
412
+ private lowerLimit;
413
+ private lowerOffset;
414
+ lowerSelection(selectionSet: SelectionSetNode, table: string): SelectionIr;
415
+ /** The `{ aggregate { count sum {…} avg {…} } nodes {…} }` block shared by roots and relations. */
416
+ private lowerAggregateSelection;
417
+ lowerRoots(operation: OperationDefinitionNode, kind: 'query' | 'mutation'): RootIr[];
418
+ private parseRootDirectives;
419
+ private lowerQueryRoot;
420
+ /** byPk-style pk arguments: one argument per primary-key column, exactly. */
421
+ private lowerPkArgs;
422
+ private lowerMutationRoot;
423
+ private lowerMutationResponse;
424
+ private lowerInsertObjects;
425
+ private lowerInsertRow;
426
+ private lowerOnConflictArg;
427
+ private lowerWriteValues;
428
+ private lowerColumnEntries;
429
+ private lowerPkColumnsArg;
430
+ }
431
+ declare function lowerOperation({ restricted, ctx }: {
432
+ restricted: RestrictedOperation;
433
+ ctx: CompileContext;
434
+ }): RootIr[];
435
+
436
+ declare const CONST_TRUE: PredIr;
437
+ /**
438
+ * AND predicates together, dropping `const(true)` operands so a policy-less
439
+ * table (or an absent document where) doesn't wrap everything in dead nodes.
440
+ */
441
+ declare function andPred(...preds: Array<PredIr | undefined>): PredIr;
442
+ declare function walkPred(pred: PredIr, visit: (node: PredIr) => void): void;
443
+ declare function predContainsExists(pred: PredIr): boolean;
444
+ /** Structural containment: does `haystack` carry `needle` as a subtree? */
445
+ declare function predContains(haystack: PredIr, needle: PredIr): boolean;
446
+
447
+ declare const POLICY_COMPARE_OPS: readonly ["=", "!=", "<", "<=", ">", ">="];
448
+ type PolicyCompareOp = (typeof POLICY_COMPARE_OPS)[number];
449
+ type PolicyOperand =
450
+ /** A column reference, or a dotted to-one path ending in a column (`a.b.c`). */
451
+ {
452
+ kind: 'path';
453
+ segments: readonly string[];
454
+ }
455
+ /** `claim('sub')` / `claim('org')` — the only claim() keys in CLAIMS_CONTRACT. */
456
+ | {
457
+ kind: 'claim';
458
+ key: ClaimKey;
459
+ } | {
460
+ kind: 'literal';
461
+ value: string | number | boolean | null;
462
+ };
463
+ type PolicyNode = {
464
+ kind: 'and';
465
+ operands: readonly PolicyNode[];
466
+ } | {
467
+ kind: 'or';
468
+ operands: readonly PolicyNode[];
469
+ } | {
470
+ kind: 'not';
471
+ operand: PolicyNode;
472
+ } | {
473
+ kind: 'compare';
474
+ op: PolicyCompareOp;
475
+ left: PolicyOperand;
476
+ right: PolicyOperand;
477
+ }
478
+ /** Boolean claims leaves — pre-resolved against the caller's claims at runtime. */
479
+ | {
480
+ kind: 'capability';
481
+ key: string;
482
+ } | {
483
+ kind: 'role';
484
+ key: string;
485
+ }
486
+ /** `exists(<link-path>, <pred>)` — the inner predicate runs against the final target. */
487
+ | {
488
+ kind: 'exists';
489
+ path: readonly string[];
490
+ where: PolicyNode;
491
+ };
492
+ interface ParsedPolicy {
493
+ readonly source: string;
494
+ readonly ast: PolicyNode;
495
+ }
496
+ declare function walkPolicy(node: PolicyNode, visit: (node: PolicyNode) => void): void;
497
+
498
+ /** Parse-time failure — bad token stream, malformed call, invalid claim key. */
499
+ declare class PolicyParseError extends Error {
500
+ readonly position: number;
501
+ readonly name = "PolicyParseError";
502
+ constructor(message: string, position: number);
503
+ }
504
+ type PolicyCompileErrorCode = 'unknown-table' | 'unknown-column' | 'unknown-link' | 'not-to-one' | 'link-depth-exceeded' | 'unsupported-comparison' | 'invalid-null-comparison' | 'when-not-claims-only';
505
+ /**
506
+ * Compile-time failure — the parsed policy references something the table
507
+ * doesn't declare, or uses a shape the v2.0 IR cannot represent. Carries
508
+ * `candidates` so the error can name what IS available.
509
+ */
510
+ declare class PolicyCompileError extends Error {
511
+ readonly code: PolicyCompileErrorCode;
512
+ readonly candidates: readonly string[];
513
+ readonly name = "PolicyCompileError";
514
+ constructor(message: string, code: PolicyCompileErrorCode, candidates?: readonly string[]);
515
+ }
516
+
517
+ declare function parsePolicy(source: string): ParsedPolicy;
518
+
519
+ /**
520
+ * Policy DSL v2 → PredIr compiler. Resolves column/link references against a
521
+ * table resolver (TableMetaIr satisfies the shapes structurally), normalizes
522
+ * everything to LOGICAL column names, and enforces the v2.0 representability
523
+ * rules the frozen IR imposes:
524
+ *
525
+ * - dotted to-one paths (`deal.org = claim('org')`) lower to nested
526
+ * `exists(link, …)` with the comparison innermost;
527
+ * - total link-traversal depth (dotted hops + exists nesting) ≤ 3;
528
+ * - a comparison must reference exactly ONE column side (column↔column and
529
+ * claims↔literal comparisons have no PredIr shape in v2.0);
530
+ * - `col = null` / `col != null` normalize to the isNull operator;
531
+ * - variant `when` guards are claims-only: capability()/role() under
532
+ * and/or/not. (claim() comparisons in `when` are not representable in the
533
+ * v2.0 IR — a targeted error says so.)
534
+ */
535
+
536
+ declare const POLICY_MAX_LINK_DEPTH = 3;
537
+ interface PolicyColumnInfo {
538
+ readonly name: string;
539
+ readonly columnName: string;
540
+ }
541
+ interface PolicyLinkInfo {
542
+ readonly name: string;
543
+ readonly kind: 'toOne' | 'toMany' | 'toPlatformUser';
544
+ readonly target: string;
545
+ }
546
+ interface PolicyTableInfo {
547
+ readonly columns: readonly PolicyColumnInfo[];
548
+ readonly links: readonly PolicyLinkInfo[];
549
+ }
550
+ /** `{ tables }` keyed by table name — TableMetaIr's record is assignable. */
551
+ interface PolicyResolver {
552
+ readonly tables: Record<string, PolicyTableInfo>;
553
+ }
554
+ interface CompilePredicateInput {
555
+ /** DSL source text, or an already-parsed policy. */
556
+ expression: string | ParsedPolicy;
557
+ table: string;
558
+ resolver: PolicyResolver;
559
+ maxLinkDepth?: number;
560
+ }
561
+ declare function compilePredicateV2({ expression, table, resolver, maxLinkDepth }: CompilePredicateInput): PredIr;
562
+ /** Variant `when` guards may only test claims: capability()/role() under and/or/not. */
563
+ declare function assertClaimsOnlyWhen(parsed: ParsedPolicy): void;
564
+ interface CompilePolicyInput {
565
+ expression: PolicyExpression;
566
+ table: string;
567
+ resolver: PolicyResolver;
568
+ maxLinkDepth?: number;
569
+ }
570
+ /**
571
+ * Policy expression (string or `{default, variants}`) → one PredIr under §4c
572
+ * permissive-union semantics:
573
+ *
574
+ * OR(default, …variants.map(v => AND(when, v.allow ? const(true) : policy)))
575
+ *
576
+ * Granting a role/capability only ever widens access; `allow: true`
577
+ * short-circuits its branch to the guard alone.
578
+ */
579
+ declare function compilePolicy({ expression, table, resolver, maxLinkDepth }: CompilePolicyInput): PredIr;
580
+
581
+ export { type BuildContextResult, COMPILER_MAJOR, CONST_TRUE, type ClientManifest, type ClientManifestOperation, type CompileContext, type CompileNamespaceInput, type CompileNamespaceResult, type CompilePolicyInput, type CompilePredicateInput, type CompilerDiagnostic, DEFAULT_LIMIT, type DiagnosticSeverity, DocumentCompileError, type DynamicInputIssue, type DynamicInputResult, MAX_LIMIT, type MutationOp, type MutationRootInfo, NamespaceCompileError, type NormalizedBoolExp, type NormalizedOnConflict, type NormalizedOrderBy, type NormalizedRow, OperationLowerer, PLATFORM_USER_TABLE, POLICY_COMPARE_OPS, POLICY_MAX_LINK_DEPTH, type ParseDocumentsResult, type ParsedDocument, type ParsedPolicy, type PinnedColumn, type PolicyColumnInfo, type PolicyCompareOp, PolicyCompileError, type PolicyCompileErrorCode, type PolicyLinkInfo, type PolicyNode, type PolicyOperand, PolicyParseError, type PolicyResolver, type PolicyTableInfo, type QueryRootInfo, type RestrictedOperation, type SourceDocument, andPred, assertClaimsOnlyWhen, buildCompileContext, canonicalOperationText, classifyInputType, collectPinnedColumns, compileNamespace, compileNamespaceOrThrow, compilePolicy, compilePredicateV2, computeOpHash, computeOpsHash, computePinnedColumnsByTable, computeSchemaHash, flattenOperation, injectPolicies, inputTypeName, lowerOperation, mutationRootNames, parseDocuments, parsePolicy, parseSdl, platformUserMeta, predContains, predContainsExists, queryRootNames, restrictOperation, typeNameForTable, validateAppendInput, validateBoolExpInput, validateInsertInput, validateOnConflictInput, validateOrderByInput, validateSelectColumns, validateSetInput, walkPolicy, walkPred };