@sequenceholdings/orm 2.5.0 → 2.6.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/README.md +23 -0
- package/dist/cli.cjs +23 -11
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +23 -11
- package/dist/cli.js.map +1 -1
- package/dist/client.cjs +10 -5
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +37 -30
- package/dist/client.d.ts +37 -30
- package/dist/client.js +10 -6
- package/dist/client.js.map +1 -1
- package/dist/compiler.cjs +127 -9
- package/dist/compiler.cjs.map +1 -1
- package/dist/compiler.d.cts +25 -2
- package/dist/compiler.d.ts +25 -2
- package/dist/compiler.js +125 -10
- package/dist/compiler.js.map +1 -1
- package/dist/index.cjs +260 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -3
- package/dist/index.d.ts +25 -3
- package/dist/index.js +260 -139
- package/dist/index.js.map +1 -1
- package/dist/ir.cjs +5 -1
- package/dist/ir.cjs.map +1 -1
- package/dist/ir.js +5 -1
- package/dist/ir.js.map +1 -1
- package/dist/predicate-v2.cjs +5 -1
- package/dist/predicate-v2.cjs.map +1 -1
- package/dist/predicate-v2.js +5 -1
- package/dist/predicate-v2.js.map +1 -1
- package/dist/sdl.cjs +7 -1
- package/dist/sdl.cjs.map +1 -1
- package/dist/sdl.js +7 -1
- package/dist/sdl.js.map +1 -1
- package/package.json +1 -1
- package/templates/orm-namespace/package.json +2 -0
- package/templates/orm-namespace/schema/tables.ts +7 -3
package/README.md
CHANGED
|
@@ -131,6 +131,29 @@ Execute uses the `/_data/v2` endpoint by default. Set
|
|
|
131
131
|
`SEQUENCE_ORM_ATLAS_EXECUTE_V2=1` to opt into Atlas's `/api/data/v2` endpoint.
|
|
132
132
|
This client rollout switch does not bypass server feature flags or authorization.
|
|
133
133
|
|
|
134
|
+
## Default read-only SQL (planned 2.6.0)
|
|
135
|
+
|
|
136
|
+
With the matching SDK and Atlas rollout, every active v2 namespace supports
|
|
137
|
+
runtime-supplied SQL without an authored operation or Function:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
const orm = createArtifactOrmExecutor({ namespace: 'lending' })
|
|
141
|
+
const result = await orm.sql({
|
|
142
|
+
sql: `SELECT l.id, c.name FROM lending.loans l
|
|
143
|
+
JOIN party.customers c ON c.id = l."customerId"
|
|
144
|
+
WHERE c.type = :type`,
|
|
145
|
+
parameters: { type: { type: 'text', value: 'retail' } },
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Functions use `createFunctionOrmExecutor({ request, baseUrl, namespace })` and
|
|
150
|
+
the same `sql()` method. Namespace access, object policies, foreign exports,
|
|
151
|
+
delegated table scopes and optional consumer contracts still apply. Queries are
|
|
152
|
+
read-only, restricted to supported SELECT syntax, and capped at 1,000 rows / 8 MiB.
|
|
153
|
+
Separate protected execution targets cannot be joined. Existing registered
|
|
154
|
+
operations remain supported; supply a manifest when executing them by name.
|
|
155
|
+
Source versions alone do not prove package publication or server availability.
|
|
156
|
+
|
|
134
157
|
## Public exports
|
|
135
158
|
|
|
136
159
|
- `@sequenceholdings/orm/authoring` — namespace, table, policy, and view DSL
|
package/dist/cli.cjs
CHANGED
|
@@ -1458,6 +1458,9 @@ function normalizeCanonical(definition) {
|
|
|
1458
1458
|
return normalized;
|
|
1459
1459
|
}
|
|
1460
1460
|
|
|
1461
|
+
// src/client/sql.ts
|
|
1462
|
+
var BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
|
|
1463
|
+
|
|
1461
1464
|
// src/ir/index.ts
|
|
1462
1465
|
var IR_VERSION = 5;
|
|
1463
1466
|
var LEGACY_IR_VERSION = 1;
|
|
@@ -1791,7 +1794,8 @@ var compiledOperationSchema = zod.z.object({
|
|
|
1791
1794
|
}).superRefine((operation, ctx) => {
|
|
1792
1795
|
if (operation.language === "sql") {
|
|
1793
1796
|
const validPlan = operation.sqlQuery ? !operation.sql && operation.irVersion === RUNTIME_SQL_IR_VERSION : !!operation.sql && operation.irVersion === SQL_IR_VERSION;
|
|
1794
|
-
|
|
1797
|
+
const builtin = operation.name === "BuiltinSqlRead" && operation.opHash === BUILTIN_SQL_READ_HASH && operation.requires === null;
|
|
1798
|
+
if (!validPlan || operation.kind !== "query" || operation.roots.length !== 0 || !builtin && !operation.requires?.capability) {
|
|
1795
1799
|
ctx.addIssue({ code: "custom", message: "SQL operations require a query-only v4 plan or v5 runtime contract, capability, and no GraphQL roots" });
|
|
1796
1800
|
}
|
|
1797
1801
|
} else if (operation.sql || operation.sqlQuery || operation.roots.length === 0) {
|
|
@@ -5173,9 +5177,9 @@ function compilePredIrToSql(pred, options = {}) {
|
|
|
5173
5177
|
case "cmp":
|
|
5174
5178
|
return compileCmp(pred.op, pred.column, pred.value, options);
|
|
5175
5179
|
case "capability":
|
|
5176
|
-
return `(${capabilityExpression(pred.key, pred.namespace ?? options.namespace)})`;
|
|
5180
|
+
return `(${options.statementClaimChecks ? "SELECT " : ""}${capabilityExpression(pred.key, pred.namespace ?? options.namespace)})`;
|
|
5177
5181
|
case "role":
|
|
5178
|
-
return `(${roleExpression(pred.key, pred.namespace ?? options.namespace)})`;
|
|
5182
|
+
return `(${options.statementClaimChecks ? "SELECT " : ""}${roleExpression(pred.key, pred.namespace ?? options.namespace)})`;
|
|
5179
5183
|
case "exists":
|
|
5180
5184
|
if (options.exists) return options.exists(pred);
|
|
5181
5185
|
throw new OrmDefinitionError("synced view read policy cannot use 'exists' without a relationship resolver");
|
|
@@ -5283,7 +5287,8 @@ function createSqlCatalog({ canonical, publishedObjects, executionTarget }) {
|
|
|
5283
5287
|
const { ctx, diagnostics } = buildCompileContext(canonical);
|
|
5284
5288
|
if (diagnostics.some((d) => d.severity === "error")) throw new Error(diagnostics.map((d) => d.message).join("; "));
|
|
5285
5289
|
const identity = sqlHash(`ontology-sql-v1\0${computeSchemaHash(canonical)}\0${executionTarget}`);
|
|
5286
|
-
const
|
|
5290
|
+
const logicalNames = new Map(Object.entries(ctx.tables).map(([key, meta]) => [meta, key]));
|
|
5291
|
+
const refOf = (meta) => `${meta.namespace ?? canonical.namespace}/${logicalNames.get(meta)}`;
|
|
5287
5292
|
const definitions = [canonical, ...canonical.imports ?? []];
|
|
5288
5293
|
const internal = new Set(definitions.flatMap((owner) => [
|
|
5289
5294
|
...owner.tables.filter((t2) => t2.internal).map((t2) => `${owner.namespace}/${t2.table}`),
|
|
@@ -5359,15 +5364,22 @@ function only(node, keys) {
|
|
|
5359
5364
|
var parser;
|
|
5360
5365
|
var SQL_TYPES = ["text", "boolean", "integer", "bigint", "numeric", "double", "uuid", "date", "timestamptz"];
|
|
5361
5366
|
var pgType = (type) => type === "double" ? "double precision" : SQL_TYPES.some((t2) => t2 === type) ? type : fail3("unsupported SQL type");
|
|
5362
|
-
async function
|
|
5363
|
-
if (
|
|
5367
|
+
async function parseSelect(sql4) {
|
|
5368
|
+
if (Buffer.byteLength(sql4) > 65536) fail3("SQL limit exceeded");
|
|
5364
5369
|
parser ??= new pgParser.PgParser({ version: 17 });
|
|
5365
5370
|
const parsed = await parser.parse(sql4);
|
|
5366
5371
|
if (parsed.error || !parsed.tree) fail3("invalid SQL");
|
|
5367
5372
|
const statements = list(obj(parsed.tree).stmts);
|
|
5368
5373
|
if (statements.length !== 1) fail3("one SQL SELECT is required");
|
|
5374
|
+
const statement = obj(obj(statements[0]).stmt);
|
|
5375
|
+
if (!statement.SelectStmt) fail3("one SQL SELECT is required");
|
|
5376
|
+
return statement;
|
|
5377
|
+
}
|
|
5378
|
+
async function compileOntologySql({ catalog, sql: sql4, parameterTypes = [], maxRows = 1e3 }) {
|
|
5379
|
+
if (!Number.isInteger(maxRows) || maxRows < 1 || maxRows > 1e4 || Buffer.byteLength(sql4) > 65536) fail3("SQL limit exceeded");
|
|
5380
|
+
const statement = await parseSelect(sql4);
|
|
5369
5381
|
const emitter = new SqlEmitter({ catalog, parameterTypes });
|
|
5370
|
-
const result = emitter.select(
|
|
5382
|
+
const result = emitter.select(statement, { relations: [], ctes: /* @__PURE__ */ new Map() });
|
|
5371
5383
|
if (emitter.used.size !== parameterTypes.length) fail3("SQL parameters must be used exactly as declared");
|
|
5372
5384
|
if (!emitter.read.size) fail3("SQL operation must read an ontology object");
|
|
5373
5385
|
return {
|
|
@@ -7786,19 +7798,19 @@ function compileComparison(op, left, right, columnTypes) {
|
|
|
7786
7798
|
}
|
|
7787
7799
|
return `${compileOperand(left, right, columnTypes)} ${SQL_COMPARE_OPS[op]} ${compileOperand(right, left, columnTypes)}`;
|
|
7788
7800
|
}
|
|
7789
|
-
function compilePredicate(predicate, columnTypes) {
|
|
7801
|
+
function compilePredicate(predicate, columnTypes, options = {}) {
|
|
7790
7802
|
switch (predicate.kind) {
|
|
7791
7803
|
case "and":
|
|
7792
7804
|
case "or": {
|
|
7793
|
-
const joined = predicate.operands.map((operand) => compilePredicate(operand, columnTypes)).join(` ${predicate.kind.toUpperCase()} `);
|
|
7805
|
+
const joined = predicate.operands.map((operand) => compilePredicate(operand, columnTypes, options)).join(` ${predicate.kind.toUpperCase()} `);
|
|
7794
7806
|
return `(${joined})`;
|
|
7795
7807
|
}
|
|
7796
7808
|
case "not":
|
|
7797
|
-
return `(NOT ${compilePredicate(predicate.operand, columnTypes)})`;
|
|
7809
|
+
return `(NOT ${compilePredicate(predicate.operand, columnTypes, options)})`;
|
|
7798
7810
|
case "compare":
|
|
7799
7811
|
return `(${compileComparison(predicate.op, predicate.left, predicate.right, columnTypes)})`;
|
|
7800
7812
|
case "capability":
|
|
7801
|
-
return `(${capabilityExpression(predicate.key)})`;
|
|
7813
|
+
return `(${options.statementClaimChecks ? "SELECT " : ""}${capabilityExpression(predicate.key)})`;
|
|
7802
7814
|
}
|
|
7803
7815
|
}
|
|
7804
7816
|
|