@sequenceholdings/orm 2.8.1 → 2.8.3
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 +11 -6
- package/dist/authoring.d.cts +1 -1
- package/dist/authoring.d.ts +1 -1
- package/dist/canonical.d.cts +71 -71
- package/dist/canonical.d.ts +71 -71
- package/dist/cli.cjs +38 -54
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +42 -58
- package/dist/cli.js.map +1 -1
- package/dist/client.cjs +66 -70
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +32 -17
- package/dist/client.d.ts +32 -17
- package/dist/client.js +66 -71
- package/dist/client.js.map +1 -1
- package/dist/compiler.cjs.map +1 -1
- package/dist/compiler.d.cts +1 -1
- package/dist/compiler.d.ts +1 -1
- package/dist/compiler.js.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -57
- package/dist/index.d.ts +57 -57
- package/dist/index.js.map +1 -1
- package/dist/ir.cjs.map +1 -1
- package/dist/ir.d.cts +72 -72
- package/dist/ir.d.ts +72 -72
- package/dist/ir.js.map +1 -1
- package/dist/predicate-v2.cjs.map +1 -1
- package/dist/predicate-v2.js.map +1 -1
- package/dist/sdl.cjs +5 -17
- package/dist/sdl.cjs.map +1 -1
- package/dist/sdl.d.cts +9 -10
- package/dist/sdl.d.ts +9 -10
- package/dist/sdl.js +5 -17
- package/dist/sdl.js.map +1 -1
- package/package.json +2 -1
- package/dist/{definition-B99BsOAO.d.cts → definition-DjfC7Lll.d.cts} +4 -4
- package/dist/{definition-B99BsOAO.d.ts → definition-DjfC7Lll.d.ts} +4 -4
package/dist/client.d.cts
CHANGED
|
@@ -86,7 +86,10 @@ declare class TableQuery<Row extends Record<string, unknown>, Result = Row> {
|
|
|
86
86
|
private filter;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
type OperationSelection = 'name';
|
|
90
|
+
|
|
89
91
|
/** Runtime SQL inputs are values, never interpolated into the submitted SQL. */
|
|
92
|
+
declare const BUILTIN_SQL_READ_NAME = "BuiltinSqlRead";
|
|
90
93
|
declare const BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
|
|
91
94
|
type SqlQueryParameter = {
|
|
92
95
|
type: 'text' | 'uuid' | 'date' | 'timestamptz' | 'numeric' | 'bigint';
|
|
@@ -115,9 +118,19 @@ interface SqlQueryResult {
|
|
|
115
118
|
truncated: boolean;
|
|
116
119
|
}
|
|
117
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Persisted-operation client for the v2 data plane. The wire carries only
|
|
123
|
+
* `{ op: <name>, variables, idempotencyKey?, expectedSourceGeneration? }`. Runtime SQL contracts accept SQL in variables;
|
|
124
|
+
* GraphQL and fixed SQL operations keep their documents server-side. This runtime
|
|
125
|
+
* is deliberately free of node builtins and third-
|
|
126
|
+
* party deps (no @apollo/client import): Apollo integration happens through a
|
|
127
|
+
* fetch-compatible shim (`createOrmFetch`) handed to `HttpLink({ fetch })`.
|
|
128
|
+
*/
|
|
129
|
+
|
|
118
130
|
/** One entry of `operations.manifest.json` (generated by `orm generate`). */
|
|
119
131
|
interface ManifestOperation {
|
|
120
|
-
|
|
132
|
+
/** Legacy manifests only; requests use the operation name. */
|
|
133
|
+
readonly hash?: string;
|
|
121
134
|
readonly kind: 'query' | 'mutation';
|
|
122
135
|
readonly requires: {
|
|
123
136
|
readonly capability?: string;
|
|
@@ -125,7 +138,8 @@ interface ManifestOperation {
|
|
|
125
138
|
} | null;
|
|
126
139
|
}
|
|
127
140
|
interface OperationsManifest {
|
|
128
|
-
|
|
141
|
+
/** Legacy manifest metadata; absent from newly generated clients. */
|
|
142
|
+
readonly schemaHash?: string;
|
|
129
143
|
readonly opsHash?: string;
|
|
130
144
|
readonly operations: Readonly<Record<string, ManifestOperation>>;
|
|
131
145
|
}
|
|
@@ -134,6 +148,8 @@ interface OperationExecutorConfig {
|
|
|
134
148
|
baseUrl: string;
|
|
135
149
|
namespace: string;
|
|
136
150
|
manifest?: OperationsManifest;
|
|
151
|
+
/** Optional compatibility setting; only stable name selection is supported. */
|
|
152
|
+
operationSelection?: OperationSelection;
|
|
137
153
|
/** App-user / session bearer → `Authorization: Bearer`. */
|
|
138
154
|
getToken?: () => Promise<string | null> | string | null;
|
|
139
155
|
/** Delegated, attenuated function token → the `ORM_DATA_TOKEN_HEADER`. */
|
|
@@ -147,7 +163,7 @@ interface OperationExecutionOptions {
|
|
|
147
163
|
expectedSourceGeneration?: string;
|
|
148
164
|
}
|
|
149
165
|
interface OperationExecutor {
|
|
150
|
-
/** Execute a
|
|
166
|
+
/** Execute a registered operation by its stable name. */
|
|
151
167
|
execute<TData = Record<string, unknown>>(op: string, variables?: Record<string, unknown>, options?: OperationExecutionOptions): Promise<TData>;
|
|
152
168
|
}
|
|
153
169
|
/** Additive factory result; existing host wrappers implementing OperationExecutor remain valid. */
|
|
@@ -178,13 +194,19 @@ interface TypedReadReceiptOperationExecutor extends TypedOperationExecutor {
|
|
|
178
194
|
}
|
|
179
195
|
type TypedReadReceiptSqlOperationExecutor = TypedReadReceiptOperationExecutor & ReadReceiptSqlOperationExecutor;
|
|
180
196
|
/** Generated handle identifies the registered contract; optional types are phantom. */
|
|
181
|
-
|
|
197
|
+
type OperationReference<TVariables extends Record<string, unknown>, TData> = {
|
|
182
198
|
readonly namespace: string;
|
|
183
|
-
readonly hash: string;
|
|
184
199
|
readonly variables?: TVariables;
|
|
185
200
|
readonly result?: TData;
|
|
186
|
-
|
|
187
|
-
|
|
201
|
+
readonly kind?: 'query' | 'mutation';
|
|
202
|
+
} & ({
|
|
203
|
+
readonly name: string;
|
|
204
|
+
readonly hash?: string;
|
|
205
|
+
} | {
|
|
206
|
+
readonly hash: string;
|
|
207
|
+
readonly name?: string;
|
|
208
|
+
});
|
|
209
|
+
declare function createOperationExecutor({ baseUrl, namespace, manifest, operationSelection, getToken, getDataToken, fetchImpl, }: OperationExecutorConfig): TypedReadReceiptSqlOperationExecutor;
|
|
188
210
|
/**
|
|
189
211
|
* Configure the process-wide executor the generated `db<Name>` server
|
|
190
212
|
* functions call through. Call once at startup (server-side); browser apps
|
|
@@ -200,7 +222,7 @@ declare function executeOperation<TData = Record<string, unknown>>({ op, variabl
|
|
|
200
222
|
/**
|
|
201
223
|
* A fetch-compatible function for `new HttpLink({ uri: '/unused', fetch: createOrmFetch(...) })`.
|
|
202
224
|
* Intercepts Apollo's GraphQL POST, swaps the body for the persisted-op
|
|
203
|
-
* envelope (`{ op: <
|
|
225
|
+
* envelope (`{ op: <name>, variables }`) resolved via the manifest's
|
|
204
226
|
* operationName, rewrites the URL to the data plane, and attaches auth.
|
|
205
227
|
* The GraphQL-spec response body passes through untouched, so InMemoryCache
|
|
206
228
|
* and error links behave exactly as they do against a GraphQL server.
|
|
@@ -213,6 +235,7 @@ interface OperationTransportRequest {
|
|
|
213
235
|
variables: Record<string, unknown>;
|
|
214
236
|
idempotencyKey?: string;
|
|
215
237
|
expectedSourceGeneration?: string;
|
|
238
|
+
expectedKind?: 'query' | 'mutation';
|
|
216
239
|
}
|
|
217
240
|
interface OperationTransportResponse {
|
|
218
241
|
ok: boolean;
|
|
@@ -220,14 +243,6 @@ interface OperationTransportResponse {
|
|
|
220
243
|
body: unknown;
|
|
221
244
|
}
|
|
222
245
|
type OperationTransport = (request: OperationTransportRequest) => Promise<OperationTransportResponse>;
|
|
223
|
-
/**
|
|
224
|
-
* How a string selector reaches the server. `hash` (the default) resolves the
|
|
225
|
-
* name through the manifest and sends the hash, pinning the exact contract the
|
|
226
|
-
* caller was generated against. `name` sends the name itself, resolved by the
|
|
227
|
-
* server against the namespace's active version when the request runs, so the
|
|
228
|
-
* caller survives the rehash every schema change causes and needs no manifest.
|
|
229
|
-
*/
|
|
230
|
-
type OperationSelection = 'hash' | 'name';
|
|
231
246
|
/**
|
|
232
247
|
* Execute generated operations through a host-owned authenticated transport.
|
|
233
248
|
* No credential handling, retries, or global configuration. The manifest is
|
|
@@ -338,4 +353,4 @@ declare function createServiceOrmClient<Tables extends Record<string, Record<str
|
|
|
338
353
|
transport?: OrmTransport;
|
|
339
354
|
}): OrmClient<Tables, Actions>;
|
|
340
355
|
|
|
341
|
-
export { BUILTIN_SQL_READ_HASH, type FilterValue, type ManifestOperation, type OperationErrorEntry, type OperationExecutionOptions, type OperationExecutor, type OperationExecutorConfig, type OperationReadReceipt, type OperationReference, type OperationSelection, type OperationTransport, type OperationTransportRequest, type OperationTransportResponse, type OperationsManifest, type OrmActionShape, type OrmActions, type OrmClient, OrmClientError, OrmOperationError, type OrmTransport, type QueryParam, type ReadReceiptOperationExecutor, type ReadReceiptSqlOperationExecutor, type ReadResponse, type SqlOperationExecutor, type SqlQueryParameter, type SqlQueryResult, type SqlQueryVariables, TableQuery, type TypedOperationExecutor, type TypedReadReceiptOperationExecutor, type TypedReadReceiptSqlOperationExecutor, type TypedSqlOperationExecutor, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
|
356
|
+
export { BUILTIN_SQL_READ_HASH, BUILTIN_SQL_READ_NAME, type FilterValue, type ManifestOperation, type OperationErrorEntry, type OperationExecutionOptions, type OperationExecutor, type OperationExecutorConfig, type OperationReadReceipt, type OperationReference, type OperationSelection, type OperationTransport, type OperationTransportRequest, type OperationTransportResponse, type OperationsManifest, type OrmActionShape, type OrmActions, type OrmClient, OrmClientError, OrmOperationError, type OrmTransport, type QueryParam, type ReadReceiptOperationExecutor, type ReadReceiptSqlOperationExecutor, type ReadResponse, type SqlOperationExecutor, type SqlQueryParameter, type SqlQueryResult, type SqlQueryVariables, TableQuery, type TypedOperationExecutor, type TypedReadReceiptOperationExecutor, type TypedReadReceiptSqlOperationExecutor, type TypedSqlOperationExecutor, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
package/dist/client.d.ts
CHANGED
|
@@ -86,7 +86,10 @@ declare class TableQuery<Row extends Record<string, unknown>, Result = Row> {
|
|
|
86
86
|
private filter;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
type OperationSelection = 'name';
|
|
90
|
+
|
|
89
91
|
/** Runtime SQL inputs are values, never interpolated into the submitted SQL. */
|
|
92
|
+
declare const BUILTIN_SQL_READ_NAME = "BuiltinSqlRead";
|
|
90
93
|
declare const BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
|
|
91
94
|
type SqlQueryParameter = {
|
|
92
95
|
type: 'text' | 'uuid' | 'date' | 'timestamptz' | 'numeric' | 'bigint';
|
|
@@ -115,9 +118,19 @@ interface SqlQueryResult {
|
|
|
115
118
|
truncated: boolean;
|
|
116
119
|
}
|
|
117
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Persisted-operation client for the v2 data plane. The wire carries only
|
|
123
|
+
* `{ op: <name>, variables, idempotencyKey?, expectedSourceGeneration? }`. Runtime SQL contracts accept SQL in variables;
|
|
124
|
+
* GraphQL and fixed SQL operations keep their documents server-side. This runtime
|
|
125
|
+
* is deliberately free of node builtins and third-
|
|
126
|
+
* party deps (no @apollo/client import): Apollo integration happens through a
|
|
127
|
+
* fetch-compatible shim (`createOrmFetch`) handed to `HttpLink({ fetch })`.
|
|
128
|
+
*/
|
|
129
|
+
|
|
118
130
|
/** One entry of `operations.manifest.json` (generated by `orm generate`). */
|
|
119
131
|
interface ManifestOperation {
|
|
120
|
-
|
|
132
|
+
/** Legacy manifests only; requests use the operation name. */
|
|
133
|
+
readonly hash?: string;
|
|
121
134
|
readonly kind: 'query' | 'mutation';
|
|
122
135
|
readonly requires: {
|
|
123
136
|
readonly capability?: string;
|
|
@@ -125,7 +138,8 @@ interface ManifestOperation {
|
|
|
125
138
|
} | null;
|
|
126
139
|
}
|
|
127
140
|
interface OperationsManifest {
|
|
128
|
-
|
|
141
|
+
/** Legacy manifest metadata; absent from newly generated clients. */
|
|
142
|
+
readonly schemaHash?: string;
|
|
129
143
|
readonly opsHash?: string;
|
|
130
144
|
readonly operations: Readonly<Record<string, ManifestOperation>>;
|
|
131
145
|
}
|
|
@@ -134,6 +148,8 @@ interface OperationExecutorConfig {
|
|
|
134
148
|
baseUrl: string;
|
|
135
149
|
namespace: string;
|
|
136
150
|
manifest?: OperationsManifest;
|
|
151
|
+
/** Optional compatibility setting; only stable name selection is supported. */
|
|
152
|
+
operationSelection?: OperationSelection;
|
|
137
153
|
/** App-user / session bearer → `Authorization: Bearer`. */
|
|
138
154
|
getToken?: () => Promise<string | null> | string | null;
|
|
139
155
|
/** Delegated, attenuated function token → the `ORM_DATA_TOKEN_HEADER`. */
|
|
@@ -147,7 +163,7 @@ interface OperationExecutionOptions {
|
|
|
147
163
|
expectedSourceGeneration?: string;
|
|
148
164
|
}
|
|
149
165
|
interface OperationExecutor {
|
|
150
|
-
/** Execute a
|
|
166
|
+
/** Execute a registered operation by its stable name. */
|
|
151
167
|
execute<TData = Record<string, unknown>>(op: string, variables?: Record<string, unknown>, options?: OperationExecutionOptions): Promise<TData>;
|
|
152
168
|
}
|
|
153
169
|
/** Additive factory result; existing host wrappers implementing OperationExecutor remain valid. */
|
|
@@ -178,13 +194,19 @@ interface TypedReadReceiptOperationExecutor extends TypedOperationExecutor {
|
|
|
178
194
|
}
|
|
179
195
|
type TypedReadReceiptSqlOperationExecutor = TypedReadReceiptOperationExecutor & ReadReceiptSqlOperationExecutor;
|
|
180
196
|
/** Generated handle identifies the registered contract; optional types are phantom. */
|
|
181
|
-
|
|
197
|
+
type OperationReference<TVariables extends Record<string, unknown>, TData> = {
|
|
182
198
|
readonly namespace: string;
|
|
183
|
-
readonly hash: string;
|
|
184
199
|
readonly variables?: TVariables;
|
|
185
200
|
readonly result?: TData;
|
|
186
|
-
|
|
187
|
-
|
|
201
|
+
readonly kind?: 'query' | 'mutation';
|
|
202
|
+
} & ({
|
|
203
|
+
readonly name: string;
|
|
204
|
+
readonly hash?: string;
|
|
205
|
+
} | {
|
|
206
|
+
readonly hash: string;
|
|
207
|
+
readonly name?: string;
|
|
208
|
+
});
|
|
209
|
+
declare function createOperationExecutor({ baseUrl, namespace, manifest, operationSelection, getToken, getDataToken, fetchImpl, }: OperationExecutorConfig): TypedReadReceiptSqlOperationExecutor;
|
|
188
210
|
/**
|
|
189
211
|
* Configure the process-wide executor the generated `db<Name>` server
|
|
190
212
|
* functions call through. Call once at startup (server-side); browser apps
|
|
@@ -200,7 +222,7 @@ declare function executeOperation<TData = Record<string, unknown>>({ op, variabl
|
|
|
200
222
|
/**
|
|
201
223
|
* A fetch-compatible function for `new HttpLink({ uri: '/unused', fetch: createOrmFetch(...) })`.
|
|
202
224
|
* Intercepts Apollo's GraphQL POST, swaps the body for the persisted-op
|
|
203
|
-
* envelope (`{ op: <
|
|
225
|
+
* envelope (`{ op: <name>, variables }`) resolved via the manifest's
|
|
204
226
|
* operationName, rewrites the URL to the data plane, and attaches auth.
|
|
205
227
|
* The GraphQL-spec response body passes through untouched, so InMemoryCache
|
|
206
228
|
* and error links behave exactly as they do against a GraphQL server.
|
|
@@ -213,6 +235,7 @@ interface OperationTransportRequest {
|
|
|
213
235
|
variables: Record<string, unknown>;
|
|
214
236
|
idempotencyKey?: string;
|
|
215
237
|
expectedSourceGeneration?: string;
|
|
238
|
+
expectedKind?: 'query' | 'mutation';
|
|
216
239
|
}
|
|
217
240
|
interface OperationTransportResponse {
|
|
218
241
|
ok: boolean;
|
|
@@ -220,14 +243,6 @@ interface OperationTransportResponse {
|
|
|
220
243
|
body: unknown;
|
|
221
244
|
}
|
|
222
245
|
type OperationTransport = (request: OperationTransportRequest) => Promise<OperationTransportResponse>;
|
|
223
|
-
/**
|
|
224
|
-
* How a string selector reaches the server. `hash` (the default) resolves the
|
|
225
|
-
* name through the manifest and sends the hash, pinning the exact contract the
|
|
226
|
-
* caller was generated against. `name` sends the name itself, resolved by the
|
|
227
|
-
* server against the namespace's active version when the request runs, so the
|
|
228
|
-
* caller survives the rehash every schema change causes and needs no manifest.
|
|
229
|
-
*/
|
|
230
|
-
type OperationSelection = 'hash' | 'name';
|
|
231
246
|
/**
|
|
232
247
|
* Execute generated operations through a host-owned authenticated transport.
|
|
233
248
|
* No credential handling, retries, or global configuration. The manifest is
|
|
@@ -338,4 +353,4 @@ declare function createServiceOrmClient<Tables extends Record<string, Record<str
|
|
|
338
353
|
transport?: OrmTransport;
|
|
339
354
|
}): OrmClient<Tables, Actions>;
|
|
340
355
|
|
|
341
|
-
export { BUILTIN_SQL_READ_HASH, type FilterValue, type ManifestOperation, type OperationErrorEntry, type OperationExecutionOptions, type OperationExecutor, type OperationExecutorConfig, type OperationReadReceipt, type OperationReference, type OperationSelection, type OperationTransport, type OperationTransportRequest, type OperationTransportResponse, type OperationsManifest, type OrmActionShape, type OrmActions, type OrmClient, OrmClientError, OrmOperationError, type OrmTransport, type QueryParam, type ReadReceiptOperationExecutor, type ReadReceiptSqlOperationExecutor, type ReadResponse, type SqlOperationExecutor, type SqlQueryParameter, type SqlQueryResult, type SqlQueryVariables, TableQuery, type TypedOperationExecutor, type TypedReadReceiptOperationExecutor, type TypedReadReceiptSqlOperationExecutor, type TypedSqlOperationExecutor, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
|
356
|
+
export { BUILTIN_SQL_READ_HASH, BUILTIN_SQL_READ_NAME, type FilterValue, type ManifestOperation, type OperationErrorEntry, type OperationExecutionOptions, type OperationExecutor, type OperationExecutorConfig, type OperationReadReceipt, type OperationReference, type OperationSelection, type OperationTransport, type OperationTransportRequest, type OperationTransportResponse, type OperationsManifest, type OrmActionShape, type OrmActions, type OrmClient, OrmClientError, OrmOperationError, type OrmTransport, type QueryParam, type ReadReceiptOperationExecutor, type ReadReceiptSqlOperationExecutor, type ReadResponse, type SqlOperationExecutor, type SqlQueryParameter, type SqlQueryResult, type SqlQueryVariables, TableQuery, type TypedOperationExecutor, type TypedReadReceiptOperationExecutor, type TypedReadReceiptSqlOperationExecutor, type TypedSqlOperationExecutor, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
package/dist/client.js
CHANGED
|
@@ -159,6 +159,51 @@ var TableQuery = class _TableQuery {
|
|
|
159
159
|
}
|
|
160
160
|
};
|
|
161
161
|
|
|
162
|
+
// src/client/sql.ts
|
|
163
|
+
var BUILTIN_SQL_READ_NAME = "BuiltinSqlRead";
|
|
164
|
+
var BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
|
|
165
|
+
|
|
166
|
+
// src/client/operation-selection.ts
|
|
167
|
+
var NAME = /^[_A-Za-z][_0-9A-Za-z]{0,254}$/;
|
|
168
|
+
function selectorForReference(op) {
|
|
169
|
+
if (typeof op === "string") return op;
|
|
170
|
+
if (op.name) return op.name;
|
|
171
|
+
if (op.hash?.startsWith("sha256:")) return op.hash;
|
|
172
|
+
throw new OrmClientError("unknown operation reference \u2014 regenerate the client");
|
|
173
|
+
}
|
|
174
|
+
function manifestEntry({ selector, operations }) {
|
|
175
|
+
if (selector.startsWith("sha256:")) return [...operations].find(([, entry2]) => entry2.hash === selector);
|
|
176
|
+
const entry = operations.get(selector);
|
|
177
|
+
return entry ? [selector, entry] : void 0;
|
|
178
|
+
}
|
|
179
|
+
function referenceKind(op) {
|
|
180
|
+
return typeof op === "string" ? void 0 : op.kind;
|
|
181
|
+
}
|
|
182
|
+
function assertKnownName({ name, known, operations, selector }) {
|
|
183
|
+
if (!NAME.test(name) || !known || ["__proto__", "constructor", "prototype"].includes(name)) {
|
|
184
|
+
throw new OrmClientError(`unknown operation "${selector}" \u2014 not in the manifest (${operations.size} known); regenerate the typed operation reference`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function assertReferenceKind({ op, kind }) {
|
|
188
|
+
const declared = referenceKind(op);
|
|
189
|
+
if (declared && kind !== declared) throw new OrmClientError("operation kind differs from the typed reference");
|
|
190
|
+
}
|
|
191
|
+
function selectOperationTarget({ op, operations, selection = "name", readReceipt = false }) {
|
|
192
|
+
if (selection !== "name") throw new OrmClientError("ORM calls use operation names; hash selection is no longer supported");
|
|
193
|
+
const selector = selectorForReference(op);
|
|
194
|
+
if (selector === BUILTIN_SQL_READ_HASH || selector === BUILTIN_SQL_READ_NAME) {
|
|
195
|
+
return { op: `query:${BUILTIN_SQL_READ_NAME}`, expectedKind: "query" };
|
|
196
|
+
}
|
|
197
|
+
const match = manifestEntry({ selector, operations });
|
|
198
|
+
const name = match?.[0] ?? selector;
|
|
199
|
+
const kind = match?.[1].kind ?? referenceKind(op);
|
|
200
|
+
assertKnownName({ name, known: operations.size === 0 || match !== void 0, operations, selector });
|
|
201
|
+
assertReferenceKind({ op, kind });
|
|
202
|
+
if (readReceipt && kind !== "query") throw new OrmClientError("read receipts require a registered query or the built-in SQL read");
|
|
203
|
+
const guarded = kind ? `${kind}:${name}` : name;
|
|
204
|
+
return { op: guarded, ...kind ? { expectedKind: kind } : {} };
|
|
205
|
+
}
|
|
206
|
+
|
|
162
207
|
// src/client/response.ts
|
|
163
208
|
function isRecord(value) {
|
|
164
209
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -206,9 +251,6 @@ function readOperationResponseWithReceipt({
|
|
|
206
251
|
return { data, sourceGeneration };
|
|
207
252
|
}
|
|
208
253
|
|
|
209
|
-
// src/client/sql.ts
|
|
210
|
-
var BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
|
|
211
|
-
|
|
212
254
|
// src/client/operations.ts
|
|
213
255
|
function validateIdempotencyKey(key) {
|
|
214
256
|
if (key !== void 0 && !/^[A-Za-z0-9._:-]{1,128}$/.test(key)) {
|
|
@@ -221,38 +263,11 @@ function validateExpectedSourceGeneration(value) {
|
|
|
221
263
|
}
|
|
222
264
|
}
|
|
223
265
|
var dataPlanePath = (namespace) => `/_data/v2/${namespace}`;
|
|
224
|
-
function resolveOpHash(manifest, op) {
|
|
225
|
-
if (op.startsWith("sha256:")) return op;
|
|
226
|
-
const entry = manifest.operations[op];
|
|
227
|
-
if (!entry) {
|
|
228
|
-
const known = Object.keys(manifest.operations).sort();
|
|
229
|
-
throw new OrmClientError(
|
|
230
|
-
`unknown operation "${op}" \u2014 not in the manifest (${known.length} known). Re-run \`seq-studio orm generate\` after editing graphql documents.`
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
return entry.hash;
|
|
234
|
-
}
|
|
235
|
-
function createReadReceiptOperationResolver({ operations }) {
|
|
236
|
-
const hashesByName = /* @__PURE__ */ new Map();
|
|
237
|
-
const readHashes = /* @__PURE__ */ new Set([BUILTIN_SQL_READ_HASH]);
|
|
238
|
-
const mutationHashes = /* @__PURE__ */ new Set();
|
|
239
|
-
for (const [name, entry] of operations) {
|
|
240
|
-
hashesByName.set(name, entry.hash);
|
|
241
|
-
if (entry.kind === "query" && /^sha256:[a-f0-9]{64}$/.test(entry.hash)) readHashes.add(entry.hash);
|
|
242
|
-
if (entry.kind === "mutation") mutationHashes.add(entry.hash);
|
|
243
|
-
}
|
|
244
|
-
return ({ selector, hashOnly = false }) => {
|
|
245
|
-
const hash = selector.startsWith("sha256:") ? selector : hashOnly ? void 0 : hashesByName.get(selector);
|
|
246
|
-
if (!hash || !readHashes.has(hash) || mutationHashes.has(hash)) {
|
|
247
|
-
throw new OrmClientError("read receipts require a registered query or the built-in SQL read");
|
|
248
|
-
}
|
|
249
|
-
return hash;
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
266
|
function createOperationExecutor({
|
|
253
267
|
baseUrl,
|
|
254
268
|
namespace,
|
|
255
|
-
manifest = {
|
|
269
|
+
manifest = { operations: {} },
|
|
270
|
+
operationSelection = "name",
|
|
256
271
|
getToken,
|
|
257
272
|
getDataToken,
|
|
258
273
|
fetchImpl = globalThis.fetch
|
|
@@ -262,12 +277,12 @@ function createOperationExecutor({
|
|
|
262
277
|
throw new OrmClientError("provide exactly one of getToken (bearer) or getDataToken (delegated)");
|
|
263
278
|
}
|
|
264
279
|
const root = baseUrl.replace(/\/+$/, "");
|
|
265
|
-
const
|
|
280
|
+
const operations = new Map(Object.entries(manifest.operations).map(([name, entry]) => [name, { ...entry }]));
|
|
266
281
|
async function request({ op, variables, options, requireReadReceipt = false }) {
|
|
267
282
|
validateIdempotencyKey(options.idempotencyKey);
|
|
268
283
|
validateExpectedSourceGeneration(options.expectedSourceGeneration);
|
|
269
284
|
if (typeof op !== "string" && op.namespace !== namespace) throw new OrmClientError("operation belongs to a different namespace");
|
|
270
|
-
const
|
|
285
|
+
const target = selectOperationTarget({ op, operations, selection: operationSelection, readReceipt: requireReadReceipt });
|
|
271
286
|
const token = await (getDataToken ?? getToken)();
|
|
272
287
|
if (!token) throw new OrmClientError("not authenticated \u2014 no token available");
|
|
273
288
|
const auth = getDataToken ? { [ORM_DATA_TOKEN_HEADER]: token } : { Authorization: `Bearer ${token}` };
|
|
@@ -275,7 +290,7 @@ function createOperationExecutor({
|
|
|
275
290
|
method: "POST",
|
|
276
291
|
headers: { ...auth, "Content-Type": "application/json" },
|
|
277
292
|
body: JSON.stringify({
|
|
278
|
-
|
|
293
|
+
...target,
|
|
279
294
|
variables,
|
|
280
295
|
idempotencyKey: options.idempotencyKey,
|
|
281
296
|
expectedSourceGeneration: options.expectedSourceGeneration
|
|
@@ -340,7 +355,7 @@ function createOrmFetch({
|
|
|
340
355
|
"createOrmFetch requires named operations (Apollo sends operationName for named documents)"
|
|
341
356
|
);
|
|
342
357
|
}
|
|
343
|
-
const
|
|
358
|
+
const target = selectOperationTarget({ op: name, operations: new Map(Object.entries(manifest.operations)) });
|
|
344
359
|
const idempotencyKey = new Headers(init?.headers).get("Idempotency-Key") ?? void 0;
|
|
345
360
|
validateIdempotencyKey(idempotencyKey);
|
|
346
361
|
const token = await (getDataToken ?? getToken)();
|
|
@@ -349,7 +364,7 @@ function createOrmFetch({
|
|
|
349
364
|
return fetchImpl(url, {
|
|
350
365
|
method: "POST",
|
|
351
366
|
headers: { ...auth, "Content-Type": "application/json" },
|
|
352
|
-
body: JSON.stringify({
|
|
367
|
+
body: JSON.stringify({ ...target, variables: parsed.variables ?? {}, idempotencyKey }),
|
|
353
368
|
...init?.signal ? { signal: init.signal } : {}
|
|
354
369
|
});
|
|
355
370
|
};
|
|
@@ -357,57 +372,37 @@ function createOrmFetch({
|
|
|
357
372
|
|
|
358
373
|
// src/client/transport-executor.ts
|
|
359
374
|
var operationHash = /^sha256:[a-f0-9]{64}$/;
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
if (response.status !== 404 || !isRecord(response.body) || !Array.isArray(response.body.errors)) return false;
|
|
363
|
-
const first = response.body.errors[0];
|
|
364
|
-
const extensions = isRecord(first) && isRecord(first.extensions) ? first.extensions : void 0;
|
|
365
|
-
return extensions?.code === "NOT_FOUND" && !(isRecord(extensions.details) && extensions.details.cause === "unknown_operation") && isRecord(first) && typeof first.message === "string" && first.message.startsWith("operation not found");
|
|
366
|
-
}
|
|
367
|
-
function readManifestHashes(manifest) {
|
|
368
|
-
if (!isRecord(manifest) || typeof manifest.schemaHash !== "string" || !manifest.schemaHash || !isRecord(manifest.operations)) {
|
|
375
|
+
function readManifestOperations(manifest) {
|
|
376
|
+
if (!isRecord(manifest) || !isRecord(manifest.operations)) {
|
|
369
377
|
throw new OrmClientError("invalid operations manifest \u2014 use operations.manifest.json from seq-studio orm generate");
|
|
370
378
|
}
|
|
371
|
-
const
|
|
379
|
+
const operations = /* @__PURE__ */ new Map();
|
|
372
380
|
for (const [name, entry] of Object.entries(manifest.operations)) {
|
|
373
|
-
if (!/^[_A-Za-z][_0-9A-Za-z]*$/.test(name) || !isRecord(entry) || typeof entry.hash !== "string" || !operationHash.test(entry.hash) || entry.kind !== "query" && entry.kind !== "mutation") {
|
|
381
|
+
if (!/^[_A-Za-z][_0-9A-Za-z]*$/.test(name) || !isRecord(entry) || entry.hash !== void 0 && (typeof entry.hash !== "string" || !operationHash.test(entry.hash)) || entry.kind !== "query" && entry.kind !== "mutation") {
|
|
374
382
|
throw new OrmClientError(`invalid operations manifest entry "${name}" \u2014 regenerate the manifest`);
|
|
375
383
|
}
|
|
376
|
-
|
|
384
|
+
operations.set(name, { ...typeof entry.hash === "string" ? { hash: entry.hash } : {}, kind: entry.kind });
|
|
377
385
|
}
|
|
378
|
-
return
|
|
386
|
+
return operations;
|
|
379
387
|
}
|
|
380
|
-
function createOperationExecutorWithTransport({ namespace, manifest, transport, operationSelection = "
|
|
381
|
-
if (operationSelection !== "
|
|
388
|
+
function createOperationExecutorWithTransport({ namespace, manifest, transport, operationSelection = "name" }) {
|
|
389
|
+
if (operationSelection !== "name") throw new OrmClientError("ORM calls use operation names; hash selection is no longer supported");
|
|
382
390
|
if (typeof namespace !== "string" || !NAMESPACE_PATTERN.test(namespace)) throw new OrmClientError("invalid ORM namespace \u2014 expected a lowercase identifier of at most 41 characters");
|
|
383
|
-
const
|
|
384
|
-
const knownHashes = new Set([...hashes.values()].map((entry) => entry.hash));
|
|
385
|
-
const resolveReceiptOperation = createReadReceiptOperationResolver({ operations: hashes });
|
|
386
|
-
function selectTarget({ op, requireReadReceipt }) {
|
|
387
|
-
const selector = typeof op === "string" ? op : op.hash;
|
|
388
|
-
if (operationSelection === "name" && !requireReadReceipt && typeof op === "string" && operationName.test(op)) {
|
|
389
|
-
return { target: op, byName: true };
|
|
390
|
-
}
|
|
391
|
-
const hash = requireReadReceipt ? resolveReceiptOperation({ selector, hashOnly: typeof op !== "string" }) : selector === BUILTIN_SQL_READ_HASH ? selector : hashes.get(selector)?.hash ?? (knownHashes.has(selector) ? selector : void 0);
|
|
392
|
-
if (!hash) throw new OrmClientError(`unknown operation "${String(op)}" \u2014 not in the manifest (${hashes.size} known). Re-run seq-studio orm generate.`);
|
|
393
|
-
return { target: hash, byName: false };
|
|
394
|
-
}
|
|
391
|
+
const operations = manifest === void 0 ? /* @__PURE__ */ new Map() : readManifestOperations(manifest);
|
|
395
392
|
async function request({ op, variables, options, requireReadReceipt = false }) {
|
|
396
393
|
validateIdempotencyKey(options.idempotencyKey);
|
|
397
394
|
validateExpectedSourceGeneration(options.expectedSourceGeneration);
|
|
398
395
|
if (typeof op !== "string" && op.namespace !== namespace) throw new OrmClientError("operation belongs to a different namespace");
|
|
399
|
-
const
|
|
396
|
+
const target = selectOperationTarget({ op, operations, selection: operationSelection, readReceipt: requireReadReceipt });
|
|
400
397
|
if (!isRecord(variables)) throw new OrmClientError("operation variables must be an object");
|
|
401
|
-
const send = (
|
|
398
|
+
const send = () => transport({
|
|
402
399
|
namespace,
|
|
403
|
-
|
|
400
|
+
...target,
|
|
404
401
|
variables,
|
|
405
402
|
...options.idempotencyKey === void 0 ? {} : { idempotencyKey: options.idempotencyKey },
|
|
406
403
|
...options.expectedSourceGeneration === void 0 ? {} : { expectedSourceGeneration: options.expectedSourceGeneration }
|
|
407
404
|
});
|
|
408
|
-
|
|
409
|
-
const fallback = byName && typeof op === "string" ? hashes.get(op)?.hash : void 0;
|
|
410
|
-
if (fallback && response && refusedAsUnknownSelector(response)) response = await send(fallback);
|
|
405
|
+
const response = await send();
|
|
411
406
|
if (!response || typeof response.ok !== "boolean" || !Number.isInteger(response.status) || response.status < 100 || response.status > 599 || response.ok !== (response.status >= 200 && response.status < 300)) {
|
|
412
407
|
throw new OrmOperationError("malformed transport response", null, null);
|
|
413
408
|
}
|
|
@@ -493,6 +488,6 @@ function requireOption(value, name) {
|
|
|
493
488
|
return value;
|
|
494
489
|
}
|
|
495
490
|
|
|
496
|
-
export { BUILTIN_SQL_READ_HASH, NAMESPACE_PATTERN, ORM_DATA_TOKEN_HEADER, ORM_SERVICE_DATA_TOKEN_HEADER, OrmClientError, OrmOperationError, TableQuery, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
|
491
|
+
export { BUILTIN_SQL_READ_HASH, BUILTIN_SQL_READ_NAME, NAMESPACE_PATTERN, ORM_DATA_TOKEN_HEADER, ORM_SERVICE_DATA_TOKEN_HEADER, OrmClientError, OrmOperationError, TableQuery, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
|
497
492
|
//# sourceMappingURL=client.js.map
|
|
498
493
|
//# sourceMappingURL=client.js.map
|