@sequenceholdings/orm 2.6.2 → 2.7.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.
- package/README.md +44 -1
- package/dist/cli.cjs +81 -29
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +81 -29
- package/dist/cli.js.map +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +4 -1
- package/dist/client.d.ts +4 -1
- package/dist/client.js.map +1 -1
- package/dist/compiler.cjs +68 -29
- package/dist/compiler.cjs.map +1 -1
- package/dist/compiler.js +68 -29
- package/dist/compiler.js.map +1 -1
- package/dist/index.cjs +73 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +72 -5
- package/dist/index.js.map +1 -1
- package/dist/ir.cjs +19 -3
- package/dist/ir.cjs.map +1 -1
- package/dist/ir.d.cts +13 -6
- package/dist/ir.d.ts +13 -6
- package/dist/ir.js +18 -4
- package/dist/ir.js.map +1 -1
- package/dist/predicate-v2.cjs +24 -2
- package/dist/predicate-v2.cjs.map +1 -1
- package/dist/predicate-v2.d.cts +4 -0
- package/dist/predicate-v2.d.ts +4 -0
- package/dist/predicate-v2.js +24 -2
- package/dist/predicate-v2.js.map +1 -1
- package/dist/sdl.cjs +16 -2
- package/dist/sdl.cjs.map +1 -1
- package/dist/sdl.js +16 -2
- package/dist/sdl.js.map +1 -1
- package/package.json +1 -1
- package/src/codegen-gql/preset.cjs +45 -8
- package/templates/orm-namespace/codegen.ts +5 -0
package/dist/compiler.js
CHANGED
|
@@ -1312,14 +1312,21 @@ function normalizeCanonical(definition) {
|
|
|
1312
1312
|
var BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
|
|
1313
1313
|
|
|
1314
1314
|
// src/ir/index.ts
|
|
1315
|
-
var IR_VERSION =
|
|
1315
|
+
var IR_VERSION = 6;
|
|
1316
1316
|
var LEGACY_IR_VERSION = 1;
|
|
1317
1317
|
var GUARDED_IR_VERSION = 2;
|
|
1318
1318
|
var COMPOSED_IR_VERSION = 3;
|
|
1319
1319
|
var SQL_IR_VERSION = 4;
|
|
1320
1320
|
var RUNTIME_SQL_IR_VERSION = 5;
|
|
1321
|
-
var
|
|
1321
|
+
var SERVICE_PRINCIPAL_IR_VERSION = 6;
|
|
1322
|
+
var irVersionSchema = z.union([z.literal(LEGACY_IR_VERSION), z.literal(GUARDED_IR_VERSION), z.literal(COMPOSED_IR_VERSION), z.literal(SQL_IR_VERSION), z.literal(RUNTIME_SQL_IR_VERSION), z.literal(SERVICE_PRINCIPAL_IR_VERSION)]);
|
|
1322
1323
|
var operationVersionSchema = z.object({ irVersion: irVersionSchema });
|
|
1324
|
+
function usesServicePrincipal(value) {
|
|
1325
|
+
if (value === null || typeof value !== "object") return false;
|
|
1326
|
+
if (Array.isArray(value)) return value.some(usesServicePrincipal);
|
|
1327
|
+
const row = value;
|
|
1328
|
+
return row.kind === "servicePrincipal" || Object.values(row).some(usesServicePrincipal);
|
|
1329
|
+
}
|
|
1323
1330
|
function requiredArtifactIrVersion(operations) {
|
|
1324
1331
|
let required = LEGACY_IR_VERSION;
|
|
1325
1332
|
for (const operation of operations) {
|
|
@@ -1379,6 +1386,7 @@ var predIrSchema = z.lazy(
|
|
|
1379
1386
|
z.object({ kind: z.literal("capability"), key: z.string(), namespace: z.string().optional() }),
|
|
1380
1387
|
z.object({ kind: z.literal("role"), key: z.string(), namespace: z.string().optional() }),
|
|
1381
1388
|
z.object({ kind: z.literal("dynamicFilter"), slot: z.string() }),
|
|
1389
|
+
z.object({ kind: z.literal("servicePrincipal") }).strict(),
|
|
1382
1390
|
z.object({ kind: z.literal("const"), value: z.boolean() })
|
|
1383
1391
|
])
|
|
1384
1392
|
);
|
|
@@ -1604,7 +1612,7 @@ var variableIrSchema = z.object({
|
|
|
1604
1612
|
/** Absent = no default declared; see {@link variableDefaultIrSchema}. */
|
|
1605
1613
|
defaultValue: variableDefaultIrSchema.optional()
|
|
1606
1614
|
});
|
|
1607
|
-
var sqlColumnSchema = z.object({ name: z.string(), type: z.enum(["text", "boolean", "integer", "bigint", "numeric", "double", "uuid", "date", "timestamptz"]), nullable: z.boolean() });
|
|
1615
|
+
var sqlColumnSchema = z.object({ name: z.string(), type: z.enum(["text", "boolean", "integer", "bigint", "numeric", "double", "uuid", "date", "timestamptz", "jsonb"]), nullable: z.boolean() });
|
|
1608
1616
|
var compiledOperationSchema = z.object({
|
|
1609
1617
|
language: z.literal("sql").optional(),
|
|
1610
1618
|
/** Server-compiled object catalog and permission ceiling, never caller SQL. */
|
|
@@ -1642,6 +1650,9 @@ var compiledOperationSchema = z.object({
|
|
|
1642
1650
|
tableSet: z.array(z.string()).min(1),
|
|
1643
1651
|
roots: z.array(rootIrSchema)
|
|
1644
1652
|
}).superRefine((operation, ctx) => {
|
|
1653
|
+
if (operation.irVersion < SERVICE_PRINCIPAL_IR_VERSION && usesServicePrincipal(operation.roots)) {
|
|
1654
|
+
ctx.addIssue({ code: "custom", message: "servicePrincipal() requires IR v6" });
|
|
1655
|
+
}
|
|
1645
1656
|
if (operation.language === "sql") {
|
|
1646
1657
|
const validPlan = operation.sqlQuery ? !operation.sql && operation.irVersion === RUNTIME_SQL_IR_VERSION : !!operation.sql && operation.irVersion === SQL_IR_VERSION;
|
|
1647
1658
|
const builtin = operation.name === "BuiltinSqlRead" && operation.opHash === BUILTIN_SQL_READ_HASH && operation.requires === null;
|
|
@@ -1774,6 +1785,9 @@ var compiledArtifactSchema = z.object({
|
|
|
1774
1785
|
tables: z.record(z.string(), tableMetaIrSchema),
|
|
1775
1786
|
operations: z.record(z.string(), compiledOperationSchema)
|
|
1776
1787
|
}).superRefine((artifact, ctx) => {
|
|
1788
|
+
if (artifact.irVersion < SERVICE_PRINCIPAL_IR_VERSION && usesServicePrincipal(artifact)) {
|
|
1789
|
+
ctx.addIssue({ code: "custom", message: "servicePrincipal() requires IR v6" });
|
|
1790
|
+
}
|
|
1777
1791
|
if (Object.keys(artifact.dependencies ?? {}).length > 0 && artifact.irVersion < COMPOSED_IR_VERSION) {
|
|
1778
1792
|
ctx.addIssue({ code: "custom", path: ["irVersion"], message: "cross-namespace dependencies require IR v3" });
|
|
1779
1793
|
}
|
|
@@ -2064,6 +2078,12 @@ var Parser2 = class {
|
|
|
2064
2078
|
}
|
|
2065
2079
|
return node;
|
|
2066
2080
|
}
|
|
2081
|
+
if (this.peekKeyword("servicePrincipal") && this.tokens[this.index + 1]?.kind === "lparen") {
|
|
2082
|
+
this.advance();
|
|
2083
|
+
this.expect("lparen", "'(' after servicePrincipal");
|
|
2084
|
+
this.expect("rparen", "')' closing servicePrincipal()");
|
|
2085
|
+
return { kind: "servicePrincipal" };
|
|
2086
|
+
}
|
|
2067
2087
|
if (this.peekKeyword("exists")) return this.parseExists();
|
|
2068
2088
|
if (this.peekKeyword("visible") && this.tokens[this.index + 1]?.kind === "lparen") return this.parseVisible();
|
|
2069
2089
|
return this.parseComparison();
|
|
@@ -2276,6 +2296,8 @@ var PolicyCompiler = class _PolicyCompiler {
|
|
|
2276
2296
|
return { kind: "capability", key: node.key };
|
|
2277
2297
|
case "role":
|
|
2278
2298
|
return { kind: "role", key: node.key };
|
|
2299
|
+
case "servicePrincipal":
|
|
2300
|
+
return { kind: "servicePrincipal" };
|
|
2279
2301
|
case "exists":
|
|
2280
2302
|
return this.compileExists(node.path, node.where, table, depth);
|
|
2281
2303
|
case "visible":
|
|
@@ -2971,7 +2993,10 @@ function platformUserMeta() {
|
|
|
2971
2993
|
{ name: "role", columnName: "role", type: "text", nullable: true },
|
|
2972
2994
|
{ name: "managerId", columnName: "manager_id", type: "text", nullable: true },
|
|
2973
2995
|
// NOT NULL DEFAULT true on chat.users, so non-null through the view.
|
|
2974
|
-
{ name: "accountEnabled", columnName: "account_enabled", type: "boolean", nullable: false }
|
|
2996
|
+
{ name: "accountEnabled", columnName: "account_enabled", type: "boolean", nullable: false },
|
|
2997
|
+
{ name: "canonicalSub", columnName: "canonical_sub", type: "text", nullable: false },
|
|
2998
|
+
{ name: "normalizedEmail", columnName: "normalized_email", type: "text", nullable: true },
|
|
2999
|
+
{ name: "emailDomain", columnName: "email_domain", type: "text", nullable: true }
|
|
2975
3000
|
];
|
|
2976
3001
|
return {
|
|
2977
3002
|
table: "users_directory",
|
|
@@ -4958,7 +4983,7 @@ function compileNamespace({ canonical, sdl, documents }) {
|
|
|
4958
4983
|
}
|
|
4959
4984
|
}
|
|
4960
4985
|
operations[restricted.name] = {
|
|
4961
|
-
irVersion: canonical.imports?.length ? COMPOSED_IR_VERSION : roots.some((root) => root.kind === "mutation" && root.assertAffectedRows !== void 0) ? GUARDED_IR_VERSION : LEGACY_IR_VERSION,
|
|
4986
|
+
irVersion: usesServicePrincipal(roots) ? SERVICE_PRINCIPAL_IR_VERSION : canonical.imports?.length ? COMPOSED_IR_VERSION : roots.some((root) => root.kind === "mutation" && root.assertAffectedRows !== void 0) ? GUARDED_IR_VERSION : LEGACY_IR_VERSION,
|
|
4962
4987
|
name: restricted.name,
|
|
4963
4988
|
opHash: computeOpHash({ definition: flattened, schemaHash }),
|
|
4964
4989
|
kind: restricted.kind,
|
|
@@ -4985,7 +5010,7 @@ function compileNamespace({ canonical, sdl, documents }) {
|
|
|
4985
5010
|
}
|
|
4986
5011
|
if (diagnostics.some((d) => d.severity === "error")) return { ok: false, diagnostics };
|
|
4987
5012
|
const artifact = {
|
|
4988
|
-
irVersion: canonical.imports?.length ? COMPOSED_IR_VERSION : requiredArtifactIrVersion(Object.values(operations)),
|
|
5013
|
+
irVersion: usesServicePrincipal([...ctx.readPolicies.values(), ...ctx.writePolicies.values(), ...ctx.insertPolicies.values(), ...ctx.updatePolicies.values(), ...Object.values(operations)]) ? SERVICE_PRINCIPAL_IR_VERSION : canonical.imports?.length ? COMPOSED_IR_VERSION : requiredArtifactIrVersion(Object.values(operations)),
|
|
4989
5014
|
namespace: ctx.namespace,
|
|
4990
5015
|
schemaHash,
|
|
4991
5016
|
ownSchemaHash: computeSchemaHash(localContract(canonical)),
|
|
@@ -5422,6 +5447,8 @@ function compilePredIrToSql(pred, options = {}) {
|
|
|
5422
5447
|
return `(NOT ${compilePredIrToSql(pred.operand, options)})`;
|
|
5423
5448
|
case "cmp":
|
|
5424
5449
|
return compileCmp(pred.op, pred.column, pred.value, options);
|
|
5450
|
+
case "servicePrincipal":
|
|
5451
|
+
return `coalesce(${claimExpression("servicePrincipal")} = 'true', false)`;
|
|
5425
5452
|
case "capability":
|
|
5426
5453
|
return `(${options.statementClaimChecks ? "SELECT " : ""}${capabilityExpression(pred.key, pred.namespace ?? options.namespace)})`;
|
|
5427
5454
|
case "role":
|
|
@@ -5524,6 +5551,39 @@ function compileArrayValue(value, columnType, _options) {
|
|
|
5524
5551
|
return columnType ? `${array}::${sqlTypeName(columnType)}[]` : array;
|
|
5525
5552
|
}
|
|
5526
5553
|
|
|
5554
|
+
// src/compiler/static-policy-sql.ts
|
|
5555
|
+
function compileStaticPolicySql({ table, predicate, tables, namespace, alias, rootRelation, statementClaimChecks, onRead }) {
|
|
5556
|
+
let sequence = 0;
|
|
5557
|
+
const aliases = new Set([alias, rootRelation].filter((value) => value !== void 0));
|
|
5558
|
+
const column = (meta, qualifier, name2) => {
|
|
5559
|
+
const found = meta.columns.find((c) => c.name === name2 || c.columnName === name2);
|
|
5560
|
+
if (!found) throw new OrmDefinitionError("Static policy relationship column is unavailable");
|
|
5561
|
+
return `${quoteIdentifier(qualifier)}.${quoteIdentifier(found.columnName)}`;
|
|
5562
|
+
};
|
|
5563
|
+
const render = (meta, pred, qualifier, outerRelation) => compilePredIrToSql(pred, {
|
|
5564
|
+
alias: qualifier,
|
|
5565
|
+
namespace: meta.namespace ?? namespace,
|
|
5566
|
+
statementClaimChecks,
|
|
5567
|
+
columnNames: Object.fromEntries(meta.columns.map((c) => [c.name, c.columnName])),
|
|
5568
|
+
columnTypes: Object.fromEntries(meta.columns.map((c) => [c.name, c.type])),
|
|
5569
|
+
exists: (node) => {
|
|
5570
|
+
const link = meta.links.find((candidate) => candidate.name === node.link);
|
|
5571
|
+
const target = link?.target ? tables[link.target] : void 0;
|
|
5572
|
+
const parent = qualifier ?? outerRelation;
|
|
5573
|
+
if (!link || !target || !parent) throw new OrmDefinitionError("Static policy relationship metadata is unavailable");
|
|
5574
|
+
onRead?.(target);
|
|
5575
|
+
let child;
|
|
5576
|
+
do {
|
|
5577
|
+
child = `policy_${++sequence}`;
|
|
5578
|
+
} while (aliases.has(child));
|
|
5579
|
+
aliases.add(child);
|
|
5580
|
+
const join = link.kind === "toMany" ? `${column(target, child, link.on)} = ${column(meta, parent, link.references)}` : `${column(meta, parent, link.on)} = ${column(target, child, link.references)}`;
|
|
5581
|
+
return `EXISTS (SELECT 1 FROM ${quoteIdentifier(target.schema)}.${quoteIdentifier(target.table)} AS ${quoteIdentifier(child)} WHERE ${join} AND (${render(target, node.where, child)}))`;
|
|
5582
|
+
}
|
|
5583
|
+
});
|
|
5584
|
+
return render(table, predicate, alias, rootRelation);
|
|
5585
|
+
}
|
|
5586
|
+
|
|
5527
5587
|
// src/sql/catalog.ts
|
|
5528
5588
|
function sqlHash(value) {
|
|
5529
5589
|
return `sha256:${createHash("sha256").update(value).digest("hex")}`;
|
|
@@ -5544,27 +5604,6 @@ function createSqlCatalog({ canonical, publishedObjects, executionTarget }) {
|
|
|
5544
5604
|
const meta = Object.values(ctx.tables).find((table) => refOf(table) === ref);
|
|
5545
5605
|
if (!meta || internal.has(ref) || meta.namespace !== canonical.namespace && !meta.exportRead) throw new Error(`SQL object not published: ${ref}`);
|
|
5546
5606
|
const reads = /* @__PURE__ */ new Set([ref]);
|
|
5547
|
-
let sequence = 0;
|
|
5548
|
-
const predicate = (table, pred, alias) => compilePredIrToSql(pred, {
|
|
5549
|
-
alias,
|
|
5550
|
-
namespace: table.namespace ?? canonical.namespace,
|
|
5551
|
-
columnNames: Object.fromEntries(table.columns.map((c) => [c.name, c.columnName])),
|
|
5552
|
-
columnTypes: Object.fromEntries(table.columns.map((c) => [c.name, c.type])),
|
|
5553
|
-
exists: (node) => {
|
|
5554
|
-
const link = table.links.find((candidate) => candidate.name === node.link);
|
|
5555
|
-
const target = link?.target ? ctx.tables[link.target] : void 0;
|
|
5556
|
-
if (!link || !target) throw new Error("SQL policy link is unavailable");
|
|
5557
|
-
reads.add(refOf(target));
|
|
5558
|
-
const child = `p${++sequence}`;
|
|
5559
|
-
const col = (t, a, name2) => {
|
|
5560
|
-
const c = t.columns.find((c2) => c2.name === name2 || c2.columnName === name2);
|
|
5561
|
-
if (!c) throw new Error("SQL policy column is unavailable");
|
|
5562
|
-
return `${quoteIdentifier(a)}.${quoteIdentifier(c.columnName)}`;
|
|
5563
|
-
};
|
|
5564
|
-
const join = link.kind === "toMany" ? `${col(target, child, link.on)} = ${col(table, alias, link.references)}` : `${col(table, alias, link.on)} = ${col(target, child, link.references)}`;
|
|
5565
|
-
return `EXISTS (SELECT 1 FROM ${quoteIdentifier(target.schema)}.${quoteIdentifier(target.table)} AS ${quoteIdentifier(child)} WHERE ${join} AND (${predicate(target, node.where, child)}))`;
|
|
5566
|
-
}
|
|
5567
|
-
});
|
|
5568
5607
|
const columns = meta.columns.filter((c) => meta.filterable.includes(c.name)).map((c) => ({
|
|
5569
5608
|
name: c.name,
|
|
5570
5609
|
type: typeof c.type === "string" ? c.type : "text",
|
|
@@ -5575,7 +5614,7 @@ function createSqlCatalog({ canonical, publishedObjects, executionTarget }) {
|
|
|
5575
5614
|
return `${quoteIdentifier("p0")}.${quoteIdentifier(physical.columnName)}${typeof physical.type === "object" ? "::text" : ""} AS ${quoteIdentifier(c.name)}`;
|
|
5576
5615
|
}).join(", ");
|
|
5577
5616
|
const policy = ctx.readPolicies.get(meta.table) ?? { kind: "const", value: true };
|
|
5578
|
-
const scan = `SELECT ${projection} FROM ${quoteIdentifier(meta.schema)}.${quoteIdentifier(meta.table)} AS ${quoteIdentifier("p0")} WHERE ${
|
|
5617
|
+
const scan = `SELECT ${projection} FROM ${quoteIdentifier(meta.schema)}.${quoteIdentifier(meta.table)} AS ${quoteIdentifier("p0")} WHERE ${compileStaticPolicySql({ table: meta, predicate: policy, tables: ctx.tables, namespace: canonical.namespace, alias: "p0", onRead: (target) => reads.add(refOf(target)) })}`;
|
|
5579
5618
|
return { ref, table: meta.table, columns, scan, read: [...reads].sort() };
|
|
5580
5619
|
});
|
|
5581
5620
|
return { identity, objects };
|
|
@@ -6368,7 +6407,7 @@ function compileDatasetPreviews(input) {
|
|
|
6368
6407
|
}
|
|
6369
6408
|
const hash = createHash("sha256").update("sequence-orm-dataset-preview-v1\0").update(stableJson({ schemaHash, roots, tableSet })).digest("hex");
|
|
6370
6409
|
operations[relation.table] = compiledOperationSchema.parse({
|
|
6371
|
-
irVersion: canonical.imports?.length ? COMPOSED_IR_VERSION : LEGACY_IR_VERSION,
|
|
6410
|
+
irVersion: usesServicePrincipal(roots) ? SERVICE_PRINCIPAL_IR_VERSION : canonical.imports?.length ? COMPOSED_IR_VERSION : LEGACY_IR_VERSION,
|
|
6372
6411
|
name: `DatasetPreview_${relation.table}`,
|
|
6373
6412
|
opHash: `sha256:${hash}`,
|
|
6374
6413
|
kind: "query",
|