@sequenceholdings/orm 2.6.2 → 2.7.1

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.
package/dist/index.cjs CHANGED
@@ -423,6 +423,7 @@ function defineSyncedTable(name2, columnsOrConfig, maybeConfig) {
423
423
  if (config.primaryKey !== void 0) tableConfig.primaryKey = config.primaryKey;
424
424
  if (config.links !== void 0) tableConfig.links = config.links;
425
425
  if (config.policies !== void 0) tableConfig.policies = { read: config.policies.read };
426
+ if (config.internal === true) tableConfig.internal = true;
426
427
  const table = {
427
428
  kind: TABLE_BRAND,
428
429
  tableName: name2,
@@ -2889,6 +2890,11 @@ function serializeNamespace(input) {
2889
2890
  enumsByName.set(ref.name, ref);
2890
2891
  }
2891
2892
  const canonicalTables = tables.map((table) => buildCanonicalTable({ table, relationsByName, enumsByName }));
2893
+ for (const table of tables) {
2894
+ if (table.source !== void 0 && table.config.internal === true && config.exports && Object.hasOwn(config.exports, table.tableName)) {
2895
+ throw new OrmDefinitionError(`internal synced source "${table.tableName}" cannot be exported; export a permitted managed view instead`, table.file);
2896
+ }
2897
+ }
2892
2898
  const canonicalEnums = [...enumsByName.values()].map((ref) => ({
2893
2899
  name: ref.name,
2894
2900
  values: [...ref.values]
@@ -3222,6 +3228,9 @@ function buildCanonicalLink({
3222
3228
  if (!relationsByName.has(targetName)) {
3223
3229
  return fail3(`targets ${relationKind(target)} "${targetName}" which is not part of this namespace`);
3224
3230
  }
3231
+ if (isSeqTable(target) && target.source !== void 0 && target.config.internal === true) {
3232
+ return fail3(`targets internal synced source "${targetName}"; expose a permitted managed view instead`);
3233
+ }
3225
3234
  if (link.enforce && (!isSeqTable(relation) || !isSeqTable(target))) {
3226
3235
  return fail3("cannot enforce a PostgreSQL foreign key involving a view");
3227
3236
  }
@@ -4220,6 +4229,8 @@ function compilePredIrToSql(pred, options = {}) {
4220
4229
  return `(NOT ${compilePredIrToSql(pred.operand, options)})`;
4221
4230
  case "cmp":
4222
4231
  return compileCmp(pred.op, pred.column, pred.value, options);
4232
+ case "servicePrincipal":
4233
+ return `coalesce(${claimExpression("servicePrincipal")} = 'true', false)`;
4223
4234
  case "capability":
4224
4235
  return `(${options.statementClaimChecks ? "SELECT " : ""}${capabilityExpression(pred.key, pred.namespace ?? options.namespace)})`;
4225
4236
  case "role":
@@ -4447,6 +4458,39 @@ function resolveValidatesTarget(definition, entry) {
4447
4458
  }
4448
4459
  return { schema: ormSchemaName(definition.namespace), table: entry.table, key };
4449
4460
  }
4461
+
4462
+ // src/compiler/static-policy-sql.ts
4463
+ function compileStaticPolicySql({ table, predicate, tables, namespace, alias, rootRelation, statementClaimChecks, onRead }) {
4464
+ let sequence = 0;
4465
+ const aliases = new Set([alias, rootRelation].filter((value) => value !== void 0));
4466
+ const column = (meta, qualifier, name2) => {
4467
+ const found = meta.columns.find((c) => c.name === name2 || c.columnName === name2);
4468
+ if (!found) throw new OrmDefinitionError("Static policy relationship column is unavailable");
4469
+ return `${quoteIdentifier(qualifier)}.${quoteIdentifier(found.columnName)}`;
4470
+ };
4471
+ const render = (meta, pred, qualifier, outerRelation) => compilePredIrToSql(pred, {
4472
+ alias: qualifier,
4473
+ namespace: meta.namespace ?? namespace,
4474
+ statementClaimChecks,
4475
+ columnNames: Object.fromEntries(meta.columns.map((c) => [c.name, c.columnName])),
4476
+ columnTypes: Object.fromEntries(meta.columns.map((c) => [c.name, c.type])),
4477
+ exists: (node) => {
4478
+ const link = meta.links.find((candidate) => candidate.name === node.link);
4479
+ const target = link?.target ? tables[link.target] : void 0;
4480
+ const parent = qualifier ?? outerRelation;
4481
+ if (!link || !target || !parent) throw new OrmDefinitionError("Static policy relationship metadata is unavailable");
4482
+ onRead?.(target);
4483
+ let child;
4484
+ do {
4485
+ child = `policy_${++sequence}`;
4486
+ } while (aliases.has(child));
4487
+ aliases.add(child);
4488
+ const join4 = link.kind === "toMany" ? `${column(target, child, link.on)} = ${column(meta, parent, link.references)}` : `${column(meta, parent, link.on)} = ${column(target, child, link.references)}`;
4489
+ return `EXISTS (SELECT 1 FROM ${quoteIdentifier(target.schema)}.${quoteIdentifier(target.table)} AS ${quoteIdentifier(child)} WHERE ${join4} AND (${render(target, node.where, child)}))`;
4490
+ }
4491
+ });
4492
+ return render(table, predicate, alias, rootRelation);
4493
+ }
4450
4494
  var linkSchema = zod.z.strictObject({
4451
4495
  to: tableReferenceSchema,
4452
4496
  on: identifierSchema,
@@ -4796,6 +4840,7 @@ function syncedViewStatements({
4796
4840
  definition,
4797
4841
  backings,
4798
4842
  readPolicyIrByTable,
4843
+ policyTables,
4799
4844
  columnNamesByTable,
4800
4845
  columnTypesByTable,
4801
4846
  executionOwnerRole = SYNCED_VIEW_EXECUTION_OWNER_ROLE,
@@ -4842,7 +4887,15 @@ function syncedViewStatements({
4842
4887
  });
4843
4888
  const readPolicyIr = readPolicyIrByTable?.get(table.table);
4844
4889
  const readPolicy = table.policies?.read;
4845
- const policyClause = readPolicyIr ? ` WHERE ${compilePredIrToSql(readPolicyIr, {
4890
+ const policyTable = policyTables?.[table.table];
4891
+ const policyClause = readPolicyIr ? ` WHERE ${policyTable && policyTables ? compileStaticPolicySql({
4892
+ table: policyTable,
4893
+ predicate: readPolicyIr,
4894
+ tables: policyTables,
4895
+ namespace: definition.namespace,
4896
+ rootRelation: physical2.table,
4897
+ statementClaimChecks
4898
+ }) : compilePredIrToSql(readPolicyIr, {
4846
4899
  namespace: definition.namespace,
4847
4900
  statementClaimChecks,
4848
4901
  columnTypes,
@@ -6427,6 +6480,15 @@ function correctIntrospectionQuery(query) {
6427
6480
  if (!drizzleOrm.is(query, drizzleOrm.SQL)) return query;
6428
6481
  const compiled = new pgCore.PgDialect().sqlToQuery(query);
6429
6482
  let text4 = compiled.sql;
6483
+ if (text4.includes("JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name)")) {
6484
+ text4 = text4.replace(/;\s*$/, "") + ` ORDER BY tc.constraint_name,
6485
+ (SELECT key_usage.ordinal_position FROM information_schema.key_column_usage AS key_usage
6486
+ WHERE key_usage.constraint_schema = tc.constraint_schema
6487
+ AND key_usage.constraint_name = tc.constraint_name
6488
+ AND key_usage.table_schema = tc.table_schema
6489
+ AND key_usage.table_name = tc.table_name
6490
+ AND key_usage.column_name = c.column_name)`;
6491
+ }
6430
6492
  const indexJoin = "pg_constraint con ON con.conindid = idx.indexrelid";
6431
6493
  if (text4.includes("AS generated_by_constraint") && text4.includes(indexJoin)) {
6432
6494
  text4 = text4.replace(indexJoin, `${indexJoin} AND con.contype IN ('p', 'u', 'x')`);
@@ -6659,14 +6721,21 @@ function renderOrmMigrationExport(exported) {
6659
6721
  var BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
6660
6722
 
6661
6723
  // src/ir/index.ts
6662
- var IR_VERSION = 5;
6724
+ var IR_VERSION = 6;
6663
6725
  var LEGACY_IR_VERSION = 1;
6664
6726
  var GUARDED_IR_VERSION = 2;
6665
6727
  var COMPOSED_IR_VERSION = 3;
6666
6728
  var SQL_IR_VERSION = 4;
6667
6729
  var RUNTIME_SQL_IR_VERSION = 5;
6668
- var irVersionSchema = zod.z.union([zod.z.literal(LEGACY_IR_VERSION), zod.z.literal(GUARDED_IR_VERSION), zod.z.literal(COMPOSED_IR_VERSION), zod.z.literal(SQL_IR_VERSION), zod.z.literal(RUNTIME_SQL_IR_VERSION)]);
6730
+ var SERVICE_PRINCIPAL_IR_VERSION = 6;
6731
+ var irVersionSchema = zod.z.union([zod.z.literal(LEGACY_IR_VERSION), zod.z.literal(GUARDED_IR_VERSION), zod.z.literal(COMPOSED_IR_VERSION), zod.z.literal(SQL_IR_VERSION), zod.z.literal(RUNTIME_SQL_IR_VERSION), zod.z.literal(SERVICE_PRINCIPAL_IR_VERSION)]);
6669
6732
  var operationVersionSchema = zod.z.object({ irVersion: irVersionSchema });
6733
+ function usesServicePrincipal(value) {
6734
+ if (value === null || typeof value !== "object") return false;
6735
+ if (Array.isArray(value)) return value.some(usesServicePrincipal);
6736
+ const row = value;
6737
+ return row.kind === "servicePrincipal" || Object.values(row).some(usesServicePrincipal);
6738
+ }
6670
6739
  function requiredArtifactIrVersion(operations) {
6671
6740
  let required = LEGACY_IR_VERSION;
6672
6741
  for (const operation of operations) {
@@ -6726,6 +6795,7 @@ var predIrSchema = zod.z.lazy(
6726
6795
  zod.z.object({ kind: zod.z.literal("capability"), key: zod.z.string(), namespace: zod.z.string().optional() }),
6727
6796
  zod.z.object({ kind: zod.z.literal("role"), key: zod.z.string(), namespace: zod.z.string().optional() }),
6728
6797
  zod.z.object({ kind: zod.z.literal("dynamicFilter"), slot: zod.z.string() }),
6798
+ zod.z.object({ kind: zod.z.literal("servicePrincipal") }).strict(),
6729
6799
  zod.z.object({ kind: zod.z.literal("const"), value: zod.z.boolean() })
6730
6800
  ])
6731
6801
  );
@@ -6951,7 +7021,7 @@ var variableIrSchema = zod.z.object({
6951
7021
  /** Absent = no default declared; see {@link variableDefaultIrSchema}. */
6952
7022
  defaultValue: variableDefaultIrSchema.optional()
6953
7023
  });
6954
- var sqlColumnSchema = zod.z.object({ name: zod.z.string(), type: zod.z.enum(["text", "boolean", "integer", "bigint", "numeric", "double", "uuid", "date", "timestamptz"]), nullable: zod.z.boolean() });
7024
+ var sqlColumnSchema = zod.z.object({ name: zod.z.string(), type: zod.z.enum(["text", "boolean", "integer", "bigint", "numeric", "double", "uuid", "date", "timestamptz", "jsonb"]), nullable: zod.z.boolean() });
6955
7025
  var compiledOperationSchema = zod.z.object({
6956
7026
  language: zod.z.literal("sql").optional(),
6957
7027
  /** Server-compiled object catalog and permission ceiling, never caller SQL. */
@@ -6989,6 +7059,9 @@ var compiledOperationSchema = zod.z.object({
6989
7059
  tableSet: zod.z.array(zod.z.string()).min(1),
6990
7060
  roots: zod.z.array(rootIrSchema)
6991
7061
  }).superRefine((operation, ctx) => {
7062
+ if (operation.irVersion < SERVICE_PRINCIPAL_IR_VERSION && usesServicePrincipal(operation.roots)) {
7063
+ ctx.addIssue({ code: "custom", message: "servicePrincipal() requires IR v6" });
7064
+ }
6992
7065
  if (operation.language === "sql") {
6993
7066
  const validPlan = operation.sqlQuery ? !operation.sql && operation.irVersion === RUNTIME_SQL_IR_VERSION : !!operation.sql && operation.irVersion === SQL_IR_VERSION;
6994
7067
  const builtin = operation.name === "BuiltinSqlRead" && operation.opHash === BUILTIN_SQL_READ_HASH && operation.requires === null;
@@ -7121,6 +7194,9 @@ var compiledArtifactSchema = zod.z.object({
7121
7194
  tables: zod.z.record(zod.z.string(), tableMetaIrSchema),
7122
7195
  operations: zod.z.record(zod.z.string(), compiledOperationSchema)
7123
7196
  }).superRefine((artifact, ctx) => {
7197
+ if (artifact.irVersion < SERVICE_PRINCIPAL_IR_VERSION && usesServicePrincipal(artifact)) {
7198
+ ctx.addIssue({ code: "custom", message: "servicePrincipal() requires IR v6" });
7199
+ }
7124
7200
  if (Object.keys(artifact.dependencies ?? {}).length > 0 && artifact.irVersion < COMPOSED_IR_VERSION) {
7125
7201
  ctx.addIssue({ code: "custom", path: ["irVersion"], message: "cross-namespace dependencies require IR v3" });
7126
7202
  }
@@ -8445,6 +8521,7 @@ exports.RESERVED_TABLE_NAMES = RESERVED_TABLE_NAMES;
8445
8521
  exports.ROLES_CLAIM_KEY = ROLES_CLAIM_KEY;
8446
8522
  exports.RUNTIME_SQL_IR_VERSION = RUNTIME_SQL_IR_VERSION;
8447
8523
  exports.SCHEMA_DIR = SCHEMA_DIR;
8524
+ exports.SERVICE_PRINCIPAL_IR_VERSION = SERVICE_PRINCIPAL_IR_VERSION;
8448
8525
  exports.SQL_IR_VERSION = SQL_IR_VERSION;
8449
8526
  exports.STATEMENT_KINDS = STATEMENT_KINDS;
8450
8527
  exports.SYNCED_CONTRACT_HASH_DOMAIN = SYNCED_CONTRACT_HASH_DOMAIN;
@@ -8619,6 +8696,7 @@ exports.toMany = toMany;
8619
8696
  exports.toOne = toOne;
8620
8697
  exports.toPlatformUser = toPlatformUser;
8621
8698
  exports.typesInterfaceName = typesInterfaceName;
8699
+ exports.usesServicePrincipal = usesServicePrincipal;
8622
8700
  exports.validateNamespaceCatalog = validateNamespaceCatalog;
8623
8701
  exports.validateViewCatalogStatement = validateViewCatalogStatement;
8624
8702
  exports.valueIrSchema = valueIrSchema;