@sequenceholdings/orm 2.4.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 +237 -20
  14. package/dist/cli.cjs.map +1 -1
  15. package/dist/cli.js +237 -20
  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 +386 -14
  24. package/dist/compiler.cjs.map +1 -1
  25. package/dist/compiler.d.cts +16 -3
  26. package/dist/compiler.d.ts +16 -3
  27. package/dist/compiler.js +386 -15
  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 +50 -3
  46. package/dist/predicate-v2.cjs.map +1 -1
  47. package/dist/predicate-v2.d.cts +1 -1
  48. package/dist/predicate-v2.d.ts +1 -1
  49. package/dist/predicate-v2.js +50 -3
  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
@@ -31,9 +31,11 @@ var PolicyCompileError = class extends Error {
31
31
  };
32
32
 
33
33
  // src/constants.ts
34
+ var NAMESPACE_PATTERN = /^(?!(?:events|native_sources)$)[a-z][a-z0-9_]{0,40}$/;
34
35
  var COLUMN_IDENTIFIER_PATTERN = /^_?[a-z][a-z0-9_]*$/;
35
36
  var MAX_IDENTIFIER_LENGTH = 63;
36
37
  var CAPABILITY_KEY_PATTERN = /^(?:org\/|app\/[a-z][a-z0-9-]{0,63}\/)?[a-z0-9-]{1,64}$/;
38
+ var MAX_PERSISTED_READ_ROWS = 50001;
37
39
  var QUALIFIED_TABLE_PATTERN = /^[a-z][a-z0-9_]{0,62}\.[a-z][a-z0-9_]{0,62}$/;
38
40
  var CELL_PARTS = ["at", "by", "rev", "source", "conflicts"];
39
41
  var CELL_PART_SUFFIX = {
@@ -383,6 +385,7 @@ function validateResolvedView({ view, tables, views = [] }) {
383
385
  function validateSource({ scope, source, table }) {
384
386
  const { fail } = scope;
385
387
  if (source.kind === "etl" && table.source === void 0) fail(`etl source '${source.name}' must reference a synced table`);
388
+ if (source.kind === "etl" && table.primaryKey?.length === 0) fail(`etl source '${source.name}' cannot use an unkeyed synced table for resolved row identity`);
386
389
  if (source.kind !== "etl" && (table.internal !== true || table.cellMetadata !== true)) {
387
390
  fail(`${source.kind} source '${source.name}' must reference an internal table with cell metadata`);
388
391
  }
@@ -674,7 +677,7 @@ var canonicalTableSchema = zod.z.object({
674
677
  /** Synced/reflected read-only tables (`source: schema.table`) — v1 semantics. */
675
678
  source: zod.z.string().regex(QUALIFIED_TABLE_PATTERN).optional(),
676
679
  columns: zod.z.array(canonicalColumnSchema).default([]),
677
- primaryKey: zod.z.array(columnIdentifier).min(1).max(8).optional(),
680
+ primaryKey: zod.z.array(columnIdentifier).max(8).optional(),
678
681
  links: zod.z.array(canonicalLinkSchema).default([]),
679
682
  indexes: zod.z.array(canonicalIndexSchema).default([]),
680
683
  /** Omitted by old definitions, preserving their existing content hashes. */
@@ -710,6 +713,29 @@ var canonicalTableSchema = zod.z.object({
710
713
  * data plane. Omitted otherwise.
711
714
  */
712
715
  materializes: identifier2.optional()
716
+ }).superRefine((table, ctx) => {
717
+ if (table.primaryKey?.length !== 0) return;
718
+ const fail = (message, path = ["primaryKey"]) => ctx.addIssue({ code: "custom", path, message: `unkeyed table '${table.table}' ${message}` });
719
+ if (table.source === void 0 || table.columns.length === 0) {
720
+ fail("requires a typed synced source");
721
+ }
722
+ if ([table.policies.write, table.policies.insert, table.policies.update].some((policy) => policy !== void 0)) {
723
+ fail("is read-only and cannot declare write policies", ["policies"]);
724
+ }
725
+ const ownedCollections = [table.indexes, table.actions, table.checks, table.foreignKeys, table.cowMutations];
726
+ const ownedMetadata = [table.cellMetadata, table.internal, table.materializes, table.renamedFrom];
727
+ if (ownedCollections.some((items) => items !== void 0 && items.length > 0) || ownedMetadata.some((value) => value !== void 0)) {
728
+ fail("cannot declare owned storage, constraints or identity operations");
729
+ }
730
+ for (const [index, column] of table.columns.entries()) {
731
+ const ownedColumnMetadata = [column.default, column.defaultFn, column.onUpdateFn, column.renamedFrom, column.cast, column.cell];
732
+ if (column.unique || ownedColumnMetadata.some((value) => value !== void 0)) {
733
+ fail("cannot declare column uniqueness, mutation defaults or migration metadata", ["columns", index]);
734
+ }
735
+ }
736
+ for (const [index, link] of table.links.entries()) {
737
+ if (link.enforce || link.kind === "toMany") fail("cannot provide an identity for this link", ["links", index]);
738
+ }
713
739
  });
714
740
  var MAX_VIEW_QUERY = 1e5;
715
741
  var MAX_RESOLVED_VIEW_QUERY = 5e6;
@@ -766,6 +792,26 @@ var canonicalViewSchema = zod.z.object({
766
792
  }
767
793
  }
768
794
  });
795
+ function validateUnkeyedLinkIdentities({ definition, ctx }) {
796
+ const tables = new Map(definition.tables.map((table) => [table.table, table]));
797
+ const relations = [
798
+ ...definition.tables.map((table, index) => ({ kind: "tables", index, links: table.links })),
799
+ ...(definition.views ?? []).map((view, index) => ({ kind: "views", index, links: view.links }))
800
+ ];
801
+ for (const relation of relations) {
802
+ for (const [linkIndex, link] of relation.links.entries()) {
803
+ if (link.kind !== "toOne" || link.namespace !== void 0 && link.namespace !== definition.namespace) continue;
804
+ const target = link.target === void 0 ? void 0 : tables.get(link.target);
805
+ if (target?.source !== void 0 && target.primaryKey?.length === 0) {
806
+ ctx.addIssue({
807
+ code: "custom",
808
+ path: [relation.kind, relation.index, "links", linkIndex],
809
+ message: `link '${link.name}' cannot use unkeyed table '${target.table}' as a to-one identity`
810
+ });
811
+ }
812
+ }
813
+ }
814
+ }
769
815
  var CELL_PART_TYPES = {
770
816
  at: "timestamptz",
771
817
  by: "text",
@@ -829,7 +875,7 @@ var exportGateSchema = zod.z.union([zod.z.literal(true), zod.z.object({ capabili
829
875
  var relationExportSchema = zod.z.object({ read: exportGateSchema, write: exportGateSchema.optional() }).strict();
830
876
  var localDefinitionSchema = zod.z.object({
831
877
  definition_format: zod.z.literal(CANONICAL_FORMAT),
832
- namespace: identifier2.max(41),
878
+ namespace: identifier2.max(41).regex(NAMESPACE_PATTERN, "invalid or reserved ORM namespace"),
833
879
  description: zod.z.string().max(2e3).optional(),
834
880
  enums: zod.z.array(canonicalEnumSchema).default([]),
835
881
  tables: zod.z.array(canonicalTableSchema).min(0).max(500),
@@ -863,6 +909,7 @@ var localDefinitionSchema = zod.z.object({
863
909
  }
864
910
  }
865
911
  const fkTables = new Map(definition.tables.map((table) => [table.table, table]));
912
+ validateUnkeyedLinkIdentities({ definition, ctx });
866
913
  const relations = /* @__PURE__ */ new Set([...fkTables.keys(), ...(definition.views ?? []).map((view) => view.view)]);
867
914
  for (const name of Object.keys(definition.exports ?? {})) {
868
915
  if (!relations.has(name)) ctx.addIssue({ code: "custom", path: ["exports", name], message: `export '${name}' is not a local object` });
@@ -1126,7 +1173,7 @@ var limitIrSchema = zod.z.object({
1126
1173
  variable: zod.z.string().optional(),
1127
1174
  value: zod.z.number().int().positive().optional(),
1128
1175
  default: zod.z.number().int().positive(),
1129
- max: zod.z.number().int().positive()
1176
+ max: zod.z.number().int().positive().max(MAX_PERSISTED_READ_ROWS)
1130
1177
  });
1131
1178
  var selectionIrSchema = zod.z.lazy(
1132
1179
  () => zod.z.object({