@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/README.md +75 -1
- package/dist/authoring.cjs +9 -0
- package/dist/authoring.cjs.map +1 -1
- package/dist/authoring.d.cts +6 -0
- package/dist/authoring.d.ts +6 -0
- package/dist/authoring.js +9 -0
- package/dist/authoring.js.map +1 -1
- package/dist/cli.cjs +89 -29
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +89 -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 +82 -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 +81 -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/README.md
CHANGED
|
@@ -131,6 +131,37 @@ 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
|
+
## Internal synced dependencies
|
|
135
|
+
|
|
136
|
+
Use `internal: true` on a typed, keyed `defineSyncedTable` when its rows are
|
|
137
|
+
inputs to a managed view and must not be queried directly. The reflected source
|
|
138
|
+
and its read policy remain available inside the view. Internal sources are
|
|
139
|
+
excluded from GraphQL roots and links, default SQL, and registered SQL object
|
|
140
|
+
ceilings. A missing persisted operation alone does not make a source private.
|
|
141
|
+
Authoring rejects declared links targeting an internal synced source and
|
|
142
|
+
rejects exporting it. This also prevents dynamic predicates from reaching it
|
|
143
|
+
through hidden intermediate relations or cross-namespace links.
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
const privacy = defineSyncedTable("privacy", {
|
|
147
|
+
uid: t.text().primaryKey(),
|
|
148
|
+
restricted: t.boolean().notNull(),
|
|
149
|
+
}, { source: "gold.customer_privacy", internal: true, policies: { read: "true" } });
|
|
150
|
+
if (privacy.config.internal !== true) {
|
|
151
|
+
throw new Error("Upgrade the ORM SDK: internal synced dependencies are required.");
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Publish only the permitted projection through `defineView`, with its own read
|
|
156
|
+
policy. Declaring `internal` does not grant access to the source or change row
|
|
157
|
+
policies. The existing unkeyed-source restrictions remain in force.
|
|
158
|
+
|
|
159
|
+
This authoring addition needs a released SDK containing the option. The existing
|
|
160
|
+
Atlas internal-object exclusion remains the runtime boundary; do not replace
|
|
161
|
+
the declaration with casts or edits to generated canonical JSON. ORM releases
|
|
162
|
+
use the separate [Studio CLI chain release workflow](https://github.com/sequenceholdings/studio/blob/main/.changeset/README.md#studio-cli-chain-releases);
|
|
163
|
+
chain packages do not use Changesets.
|
|
164
|
+
|
|
134
165
|
## Default read-only SQL (introduced in 2.6.0)
|
|
135
166
|
|
|
136
167
|
With the matching SDK and Atlas rollout, every active v2 namespace supports
|
|
@@ -191,7 +222,42 @@ matching acknowledgement. Existing calls without that option are unchanged.
|
|
|
191
222
|
- `@sequenceholdings/orm/client` — persisted-operation client utilities
|
|
192
223
|
- `@sequenceholdings/orm/drizzle` — supported Drizzle helpers for views
|
|
193
224
|
- `@sequenceholdings/orm/codegen` — GraphQL Code Generator preset used by a
|
|
194
|
-
scaffolded namespace
|
|
225
|
+
scaffolded namespace. Custom scalars (`bigint`, `date`, `jsonb`, `numeric`,
|
|
226
|
+
`timestamptz`, `uuid`) and any other unmapped scalar are emitted as
|
|
227
|
+
TypeScript `unknown`, not `any`, so `generated/client.ts` and
|
|
228
|
+
`generated/server.ts` pass native `@typescript-eslint/no-explicit-any`.
|
|
229
|
+
|
|
230
|
+
### Regenerating clients after upgrading
|
|
231
|
+
|
|
232
|
+
Existing scaffolds that already committed generated clients need a regenerate.
|
|
233
|
+
`any` on those scalars fails native lint; the files are checked, not ignored.
|
|
234
|
+
|
|
235
|
+
1. Install the `@sequenceholdings/orm` release that contains this preset.
|
|
236
|
+
2. Run `seq-studio orm generate .` in the namespace directory.
|
|
237
|
+
3. Commit the rewritten `generated/client.ts` and `generated/server.ts`.
|
|
238
|
+
4. Narrow call sites that treated those scalars as `any`. `unknown` has to be
|
|
239
|
+
checked before it is used.
|
|
240
|
+
|
|
241
|
+
To keep a concrete type, set `config.scalars` on the `./generated/` output in
|
|
242
|
+
`codegen.ts`. A consumer entry replaces the preset default for that scalar
|
|
243
|
+
only. Lossless `numeric` and `bigint` transport should use `string`:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
generates: {
|
|
247
|
+
'./generated/': {
|
|
248
|
+
preset,
|
|
249
|
+
config: { scalars: { numeric: 'string', bigint: 'string' } },
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Then run `seq-studio orm generate .` again. Mapping a scalar to `any`, or
|
|
255
|
+
eslint-ignoring `generated/client.ts` and `generated/server.ts`, fails the
|
|
256
|
+
purpose of the check: an authored file that uses `any` must still fail.
|
|
257
|
+
|
|
258
|
+
A scaffold that cannot regenerate should replace each custom scalar's `any`
|
|
259
|
+
with `unknown` (or `string` for lossless numeric/bigint) in the `Scalars` map
|
|
260
|
+
and in every inlined field of both generated files.
|
|
195
261
|
|
|
196
262
|
The `@sequenceholdings/orm/client` entry point contains the persisted-operation
|
|
197
263
|
executor and error types without importing compiler, migration, Node builtins,
|
|
@@ -208,3 +274,11 @@ For a function invocation with no human caller (a Lattice step), use
|
|
|
208
274
|
service account. The host adapters supply authentication; they do not grant namespace access or
|
|
209
275
|
register operations. Do not extract CLI credentials or invent a browser token
|
|
210
276
|
provider to wire a generated client.
|
|
277
|
+
|
|
278
|
+
### Verified service policies (planned 2.7.0)
|
|
279
|
+
|
|
280
|
+
`servicePrincipal()` is a zero-argument Boolean row-policy predicate. Combine it with a private capability, for example `servicePrincipal() and capability('ticket-delivery')`. A role or a `service-account|` subject string does not establish this predicate. The executing runtime derives it afresh from verified service authentication or an attached service delegation; user, dev, console run-as, impersonated and external-borrower requests cannot satisfy it. It is not accepted through `claim()`, request variables or serialized data-token claims.
|
|
281
|
+
|
|
282
|
+
Affected namespaces require IR v6, including namespaces that only declare a write policy and have no operations. `orm apply` first checks the authenticated target's `/api/orm/runtime-capabilities` response; a missing or older endpoint blocks registration. The compiler and executor also reject an incompatible IR version. Publish the matching ORM and deploy its runtime before activating these policies. Service identity does not grant namespace access, operation capability, declared data scope or row access by itself.
|
|
283
|
+
|
|
284
|
+
ORM 2.7.0 and downstream Artifact Studio 0.10.0, Managed Functions 0.4.4, Pipeline Spec 0.2.6 and Studio CLI 0.6.6 remain prepared for the separate chain-release workflow and awaiting publication. Their workspace dependencies are pinned to this ORM version when packed; no candidate build constitutes registry evidence.
|
package/dist/authoring.cjs
CHANGED
|
@@ -387,6 +387,7 @@ function defineSyncedTable(name2, columnsOrConfig, maybeConfig) {
|
|
|
387
387
|
if (config.primaryKey !== void 0) tableConfig.primaryKey = config.primaryKey;
|
|
388
388
|
if (config.links !== void 0) tableConfig.links = config.links;
|
|
389
389
|
if (config.policies !== void 0) tableConfig.policies = { read: config.policies.read };
|
|
390
|
+
if (config.internal === true) tableConfig.internal = true;
|
|
390
391
|
const table = {
|
|
391
392
|
kind: TABLE_BRAND,
|
|
392
393
|
tableName: name2,
|
|
@@ -2748,6 +2749,11 @@ function serializeNamespace(input) {
|
|
|
2748
2749
|
enumsByName.set(ref.name, ref);
|
|
2749
2750
|
}
|
|
2750
2751
|
const canonicalTables = tables.map((table) => buildCanonicalTable({ table, relationsByName, enumsByName }));
|
|
2752
|
+
for (const table of tables) {
|
|
2753
|
+
if (table.source !== void 0 && table.config.internal === true && config.exports && Object.hasOwn(config.exports, table.tableName)) {
|
|
2754
|
+
throw new OrmDefinitionError(`internal synced source "${table.tableName}" cannot be exported; export a permitted managed view instead`, table.file);
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2751
2757
|
const canonicalEnums = [...enumsByName.values()].map((ref) => ({
|
|
2752
2758
|
name: ref.name,
|
|
2753
2759
|
values: [...ref.values]
|
|
@@ -3081,6 +3087,9 @@ function buildCanonicalLink({
|
|
|
3081
3087
|
if (!relationsByName.has(targetName)) {
|
|
3082
3088
|
return fail(`targets ${relationKind(target)} "${targetName}" which is not part of this namespace`);
|
|
3083
3089
|
}
|
|
3090
|
+
if (isSeqTable(target) && target.source !== void 0 && target.config.internal === true) {
|
|
3091
|
+
return fail(`targets internal synced source "${targetName}"; expose a permitted managed view instead`);
|
|
3092
|
+
}
|
|
3084
3093
|
if (link.enforce && (!isSeqTable(relation) || !isSeqTable(target))) {
|
|
3085
3094
|
return fail("cannot enforce a PostgreSQL foreign key involving a view");
|
|
3086
3095
|
}
|