@sequenceholdings/orm 2.3.0 → 2.5.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 (59) hide show
  1. package/dist/authoring.cjs +53 -7
  2. package/dist/authoring.cjs.map +1 -1
  3. package/dist/authoring.d.cts +11 -7
  4. package/dist/authoring.d.ts +11 -7
  5. package/dist/authoring.js +53 -7
  6. package/dist/authoring.js.map +1 -1
  7. package/dist/canonical.cjs +48 -2
  8. package/dist/canonical.cjs.map +1 -1
  9. package/dist/canonical.d.cts +72 -72
  10. package/dist/canonical.d.ts +72 -72
  11. package/dist/canonical.js +48 -2
  12. package/dist/canonical.js.map +1 -1
  13. package/dist/cli.cjs +337 -86
  14. package/dist/cli.cjs.map +1 -1
  15. package/dist/cli.js +337 -86
  16. package/dist/cli.js.map +1 -1
  17. package/dist/client.cjs +1 -1
  18. package/dist/client.cjs.map +1 -1
  19. package/dist/client.d.cts +1 -1
  20. package/dist/client.d.ts +1 -1
  21. package/dist/client.js +1 -1
  22. package/dist/client.js.map +1 -1
  23. package/dist/compiler.cjs +493 -52
  24. package/dist/compiler.cjs.map +1 -1
  25. package/dist/compiler.d.cts +22 -7
  26. package/dist/compiler.d.ts +22 -7
  27. package/dist/compiler.js +493 -53
  28. package/dist/compiler.js.map +1 -1
  29. package/dist/{constants-C6EG6Wq7.d.cts → constants-Dou1RkTo.d.cts} +7 -2
  30. package/dist/{constants-C6EG6Wq7.d.ts → constants-Dou1RkTo.d.ts} +7 -2
  31. package/dist/dynamic-input.d.cts +1 -1
  32. package/dist/dynamic-input.d.ts +1 -1
  33. package/dist/index.cjs +329 -130
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +66 -58
  36. package/dist/index.d.ts +66 -58
  37. package/dist/index.js +329 -131
  38. package/dist/index.js.map +1 -1
  39. package/dist/ir.cjs +50 -3
  40. package/dist/ir.cjs.map +1 -1
  41. package/dist/ir.d.cts +71 -71
  42. package/dist/ir.d.ts +71 -71
  43. package/dist/ir.js +50 -3
  44. package/dist/ir.js.map +1 -1
  45. package/dist/predicate-v2.cjs +145 -22
  46. package/dist/predicate-v2.cjs.map +1 -1
  47. package/dist/predicate-v2.d.cts +41 -4
  48. package/dist/predicate-v2.d.ts +41 -4
  49. package/dist/predicate-v2.js +145 -22
  50. package/dist/predicate-v2.js.map +1 -1
  51. package/dist/sdl.cjs +53 -3
  52. package/dist/sdl.cjs.map +1 -1
  53. package/dist/sdl.d.cts +3 -1
  54. package/dist/sdl.d.ts +3 -1
  55. package/dist/sdl.js +53 -3
  56. package/dist/sdl.js.map +1 -1
  57. package/package.json +1 -1
  58. package/dist/{definition-DjfC7Lll.d.cts → definition-B99BsOAO.d.cts} +4 -4
  59. package/dist/{definition-DjfC7Lll.d.ts → definition-B99BsOAO.d.ts} +4 -4
package/dist/sdl.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { B as BUCKETABLE_COLUMN_TYPES, C as CELL_TYPENAMES, a as CUSTOM_SCALARS, D as DATE_BUCKET_ENUM, N as NUMERICISH_COLUMN_TYPES, O as ORDER_BY_ENUM, b as ORDER_BY_ENUM_VALUES, P as PLATFORM_USER_TYPENAME, T as TableNames, V as VARIABLE_SCALAR_NAMES, c as camelCase, d as cellsTypename, e as columnTypeForScalar, f as comparisonExpName, g as enumTypeName, h as fieldName, i as graphqlScalarFor, p as pascalCase, t as tableNames, j as typeName } from './naming-CU9ThP_E.cjs';
2
2
  import { CanonicalDefinition, CanonicalRelation, CanonicalColumn } from './canonical.cjs';
3
3
  import { z } from 'zod';
4
- import './constants-C6EG6Wq7.cjs';
4
+ import './constants-Dou1RkTo.cjs';
5
5
  import './policy-1iZbGnZZ.cjs';
6
6
 
7
7
  /**
@@ -37,6 +37,8 @@ interface GenerateSdlOptions {
37
37
  * released CLI; operations always compile against the default shape.
38
38
  */
39
39
  stringOnlyPatternOperators?: boolean;
40
+ /** Reproduce earlier SDL for the server's compatibility check only. */
41
+ omitReadBudgetDirective?: boolean;
40
42
  }
41
43
  declare function generateSdl(canonical: CanonicalDefinition, options?: GenerateSdlOptions): string;
42
44
  /** Columns a resolved-table mutation may write: authored data columns, never the view's system columns. */
package/dist/sdl.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { B as BUCKETABLE_COLUMN_TYPES, C as CELL_TYPENAMES, a as CUSTOM_SCALARS, D as DATE_BUCKET_ENUM, N as NUMERICISH_COLUMN_TYPES, O as ORDER_BY_ENUM, b as ORDER_BY_ENUM_VALUES, P as PLATFORM_USER_TYPENAME, T as TableNames, V as VARIABLE_SCALAR_NAMES, c as camelCase, d as cellsTypename, e as columnTypeForScalar, f as comparisonExpName, g as enumTypeName, h as fieldName, i as graphqlScalarFor, p as pascalCase, t as tableNames, j as typeName } from './naming-CPfx7EfF.js';
2
2
  import { CanonicalDefinition, CanonicalRelation, CanonicalColumn } from './canonical.js';
3
3
  import { z } from 'zod';
4
- import './constants-C6EG6Wq7.js';
4
+ import './constants-Dou1RkTo.js';
5
5
  import './policy-1iZbGnZZ.js';
6
6
 
7
7
  /**
@@ -37,6 +37,8 @@ interface GenerateSdlOptions {
37
37
  * released CLI; operations always compile against the default shape.
38
38
  */
39
39
  stringOnlyPatternOperators?: boolean;
40
+ /** Reproduce earlier SDL for the server's compatibility check only. */
41
+ omitReadBudgetDirective?: boolean;
40
42
  }
41
43
  declare function generateSdl(canonical: CanonicalDefinition, options?: GenerateSdlOptions): string;
42
44
  /** Columns a resolved-table mutation may write: authored data columns, never the view's system columns. */
package/dist/sdl.js CHANGED
@@ -202,8 +202,10 @@ function compileCheckExpression(source, columns) {
202
202
  }
203
203
 
204
204
  // src/constants.ts
205
+ var NAMESPACE_PATTERN = /^(?!(?:events|native_sources)$)[a-z][a-z0-9_]{0,40}$/;
205
206
  var COLUMN_IDENTIFIER_PATTERN = /^_?[a-z][a-z0-9_]*$/;
206
207
  var MAX_IDENTIFIER_LENGTH = 63;
208
+ var MAX_PERSISTED_READ_ROWS = 50001;
207
209
  var QUALIFIED_TABLE_PATTERN = /^[a-z][a-z0-9_]{0,62}\.[a-z][a-z0-9_]{0,62}$/;
208
210
  var CELL_PARTS = ["at", "by", "rev", "source", "conflicts"];
209
211
  var CELL_PART_SUFFIX = {
@@ -356,6 +358,7 @@ function validateResolvedView({ view, tables, views = [] }) {
356
358
  function validateSource({ scope, source, table }) {
357
359
  const { fail } = scope;
358
360
  if (source.kind === "etl" && table.source === void 0) fail(`etl source '${source.name}' must reference a synced table`);
361
+ if (source.kind === "etl" && table.primaryKey?.length === 0) fail(`etl source '${source.name}' cannot use an unkeyed synced table for resolved row identity`);
359
362
  if (source.kind !== "etl" && (table.internal !== true || table.cellMetadata !== true)) {
360
363
  fail(`${source.kind} source '${source.name}' must reference an internal table with cell metadata`);
361
364
  }
@@ -647,7 +650,7 @@ var canonicalTableSchema = z.object({
647
650
  /** Synced/reflected read-only tables (`source: schema.table`) — v1 semantics. */
648
651
  source: z.string().regex(QUALIFIED_TABLE_PATTERN).optional(),
649
652
  columns: z.array(canonicalColumnSchema).default([]),
650
- primaryKey: z.array(columnIdentifier).min(1).max(8).optional(),
653
+ primaryKey: z.array(columnIdentifier).max(8).optional(),
651
654
  links: z.array(canonicalLinkSchema).default([]),
652
655
  indexes: z.array(canonicalIndexSchema).default([]),
653
656
  /** Omitted by old definitions, preserving their existing content hashes. */
@@ -683,6 +686,29 @@ var canonicalTableSchema = z.object({
683
686
  * data plane. Omitted otherwise.
684
687
  */
685
688
  materializes: identifier2.optional()
689
+ }).superRefine((table, ctx) => {
690
+ if (table.primaryKey?.length !== 0) return;
691
+ const fail = (message, path = ["primaryKey"]) => ctx.addIssue({ code: "custom", path, message: `unkeyed table '${table.table}' ${message}` });
692
+ if (table.source === void 0 || table.columns.length === 0) {
693
+ fail("requires a typed synced source");
694
+ }
695
+ if ([table.policies.write, table.policies.insert, table.policies.update].some((policy) => policy !== void 0)) {
696
+ fail("is read-only and cannot declare write policies", ["policies"]);
697
+ }
698
+ const ownedCollections = [table.indexes, table.actions, table.checks, table.foreignKeys, table.cowMutations];
699
+ const ownedMetadata = [table.cellMetadata, table.internal, table.materializes, table.renamedFrom];
700
+ if (ownedCollections.some((items) => items !== void 0 && items.length > 0) || ownedMetadata.some((value) => value !== void 0)) {
701
+ fail("cannot declare owned storage, constraints or identity operations");
702
+ }
703
+ for (const [index, column] of table.columns.entries()) {
704
+ const ownedColumnMetadata = [column.default, column.defaultFn, column.onUpdateFn, column.renamedFrom, column.cast, column.cell];
705
+ if (column.unique || ownedColumnMetadata.some((value) => value !== void 0)) {
706
+ fail("cannot declare column uniqueness, mutation defaults or migration metadata", ["columns", index]);
707
+ }
708
+ }
709
+ for (const [index, link] of table.links.entries()) {
710
+ if (link.enforce || link.kind === "toMany") fail("cannot provide an identity for this link", ["links", index]);
711
+ }
686
712
  });
687
713
  var MAX_VIEW_QUERY = 1e5;
688
714
  var MAX_RESOLVED_VIEW_QUERY = 5e6;
@@ -739,6 +765,26 @@ var canonicalViewSchema = z.object({
739
765
  }
740
766
  }
741
767
  });
768
+ function validateUnkeyedLinkIdentities({ definition, ctx }) {
769
+ const tables = new Map(definition.tables.map((table) => [table.table, table]));
770
+ const relations = [
771
+ ...definition.tables.map((table, index) => ({ kind: "tables", index, links: table.links })),
772
+ ...(definition.views ?? []).map((view, index) => ({ kind: "views", index, links: view.links }))
773
+ ];
774
+ for (const relation of relations) {
775
+ for (const [linkIndex, link] of relation.links.entries()) {
776
+ if (link.kind !== "toOne" || link.namespace !== void 0 && link.namespace !== definition.namespace) continue;
777
+ const target = link.target === void 0 ? void 0 : tables.get(link.target);
778
+ if (target?.source !== void 0 && target.primaryKey?.length === 0) {
779
+ ctx.addIssue({
780
+ code: "custom",
781
+ path: [relation.kind, relation.index, "links", linkIndex],
782
+ message: `link '${link.name}' cannot use unkeyed table '${target.table}' as a to-one identity`
783
+ });
784
+ }
785
+ }
786
+ }
787
+ }
742
788
  var CELL_PART_TYPES = {
743
789
  at: "timestamptz",
744
790
  by: "text",
@@ -802,7 +848,7 @@ var exportGateSchema = z.union([z.literal(true), z.object({ capability: z.string
802
848
  var relationExportSchema = z.object({ read: exportGateSchema, write: exportGateSchema.optional() }).strict();
803
849
  var localDefinitionSchema = z.object({
804
850
  definition_format: z.literal(CANONICAL_FORMAT),
805
- namespace: identifier2.max(41),
851
+ namespace: identifier2.max(41).regex(NAMESPACE_PATTERN, "invalid or reserved ORM namespace"),
806
852
  description: z.string().max(2e3).optional(),
807
853
  enums: z.array(canonicalEnumSchema).default([]),
808
854
  tables: z.array(canonicalTableSchema).min(0).max(500),
@@ -836,6 +882,7 @@ var localDefinitionSchema = z.object({
836
882
  }
837
883
  }
838
884
  const fkTables = new Map(definition.tables.map((table) => [table.table, table]));
885
+ validateUnkeyedLinkIdentities({ definition, ctx });
839
886
  const relations = /* @__PURE__ */ new Set([...fkTables.keys(), ...(definition.views ?? []).map((view) => view.view)]);
840
887
  for (const name of Object.keys(definition.exports ?? {})) {
841
888
  if (!relations.has(name)) ctx.addIssue({ code: "custom", path: ["exports", name], message: `export '${name}' is not a local object` });
@@ -1264,7 +1311,7 @@ var limitIrSchema = z.object({
1264
1311
  variable: z.string().optional(),
1265
1312
  value: z.number().int().positive().optional(),
1266
1313
  default: z.number().int().positive(),
1267
- max: z.number().int().positive()
1314
+ max: z.number().int().positive().max(MAX_PERSISTED_READ_ROWS)
1268
1315
  });
1269
1316
  var selectionIrSchema = z.lazy(
1270
1317
  () => z.object({
@@ -1790,6 +1837,9 @@ function generateSdl(canonical, options = {}) {
1790
1837
  blocks.push(
1791
1838
  '"""Gates an operation behind a platform capability or custom role \u2014 checked by the data plane before execution."""\ndirective @requires(capability: String, role: String) on QUERY | MUTATION'
1792
1839
  );
1840
+ if (!options.omitReadBudgetDirective) blocks.push(
1841
+ '"""Sets a document-authored ceiling of 1\u201350001 rows for one flat select root. Runtime variables cannot raise it."""\ndirective @readBudget(maxRows: Int!) on QUERY'
1842
+ );
1793
1843
  blocks.push("directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT");
1794
1844
  blocks.push(
1795
1845
  '"""Abort the entire mutation unless this root affects exactly the document-authored number of rows. Mutation roots only; cannot be conditional."""\ndirective @assertAffectedRows(exactly: Int!) on FIELD'