@sequenceholdings/orm 2.1.0 → 2.2.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 +40 -1
- package/dist/authoring.cjs +1619 -121
- package/dist/authoring.cjs.map +1 -1
- package/dist/authoring.d.cts +252 -8
- package/dist/authoring.d.ts +252 -8
- package/dist/authoring.js +1607 -123
- package/dist/authoring.js.map +1 -1
- package/dist/canonical.cjs +713 -41
- package/dist/canonical.cjs.map +1 -1
- package/dist/canonical.d.cts +1520 -51
- package/dist/canonical.d.ts +1520 -51
- package/dist/canonical.js +693 -42
- package/dist/canonical.js.map +1 -1
- package/dist/cli.cjs +7103 -3901
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +7104 -3902
- package/dist/cli.js.map +1 -1
- package/dist/client.cjs +122 -40
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +85 -25
- package/dist/client.d.ts +85 -25
- package/dist/client.js +119 -41
- package/dist/client.js.map +1 -1
- package/dist/compiler.cjs +2464 -450
- package/dist/compiler.cjs.map +1 -1
- package/dist/compiler.d.cts +79 -4
- package/dist/compiler.d.ts +79 -4
- package/dist/compiler.js +2457 -451
- package/dist/compiler.js.map +1 -1
- package/dist/constants-C6EG6Wq7.d.cts +99 -0
- package/dist/constants-C6EG6Wq7.d.ts +99 -0
- package/dist/definition-DjfC7Lll.d.cts +91 -0
- package/dist/definition-DjfC7Lll.d.ts +91 -0
- package/dist/dynamic-input.cjs +2 -1
- package/dist/dynamic-input.cjs.map +1 -1
- package/dist/dynamic-input.d.cts +9 -1
- package/dist/dynamic-input.d.ts +9 -1
- package/dist/dynamic-input.js +2 -1
- package/dist/dynamic-input.js.map +1 -1
- package/dist/index.cjs +2656 -418
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +693 -116
- package/dist/index.d.ts +693 -116
- package/dist/index.js +2622 -420
- package/dist/index.js.map +1 -1
- package/dist/ir.cjs +811 -48
- package/dist/ir.cjs.map +1 -1
- package/dist/ir.d.cts +670 -27
- package/dist/ir.d.ts +670 -27
- package/dist/ir.js +802 -49
- package/dist/ir.js.map +1 -1
- package/dist/{naming-DCn94LJ4.d.ts → naming-CPfx7EfF.d.ts} +14 -1
- package/dist/{naming-DPglwzkB.d.cts → naming-CU9ThP_E.d.cts} +14 -1
- package/dist/policy-1iZbGnZZ.d.cts +24 -0
- package/dist/policy-1iZbGnZZ.d.ts +24 -0
- package/dist/predicate-v2.cjs +804 -51
- package/dist/predicate-v2.cjs.map +1 -1
- package/dist/predicate-v2.d.cts +2 -1
- package/dist/predicate-v2.d.ts +2 -1
- package/dist/predicate-v2.js +804 -51
- package/dist/predicate-v2.js.map +1 -1
- package/dist/sdl.cjs +1014 -75
- package/dist/sdl.cjs.map +1 -1
- package/dist/sdl.d.cts +14 -3
- package/dist/sdl.d.ts +14 -3
- package/dist/sdl.js +1012 -76
- package/dist/sdl.js.map +1 -1
- package/package.json +13 -7
- package/src/codegen-gql/server-fns.cjs +2 -2
- package/templates/orm-namespace/AGENTS.md +10 -0
- package/templates/orm-namespace/CLAUDE.md +1 -82
- package/templates/orm-namespace/codegen.preset.d.cts +7 -0
- package/templates/orm-namespace/codegen.ts +2 -1
- package/templates/orm-namespace/graphql/example/queries.ts +4 -3
- package/templates/orm-namespace/package.json +2 -1
- package/templates/orm-namespace/schema/tables.ts +3 -2
- package/templates/orm-namespace/sequence.config.ts +7 -11
package/dist/client.d.cts
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
|
+
export { N as NAMESPACE_PATTERN, O as ORM_DATA_TOKEN_HEADER, d as ORM_SERVICE_DATA_TOKEN_HEADER } from './constants-C6EG6Wq7.cjs';
|
|
2
|
+
|
|
1
3
|
declare class OrmClientError extends Error {
|
|
2
4
|
readonly status: number | null;
|
|
3
5
|
readonly name: string;
|
|
4
6
|
constructor(message: string, status?: number | null);
|
|
5
7
|
}
|
|
8
|
+
interface OperationErrorEntry {
|
|
9
|
+
readonly message: string;
|
|
10
|
+
readonly extensions?: {
|
|
11
|
+
readonly code?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
declare class OrmOperationError extends OrmClientError {
|
|
15
|
+
readonly code: string | null;
|
|
16
|
+
readonly errors: readonly OperationErrorEntry[];
|
|
17
|
+
readonly name = "OrmOperationError";
|
|
18
|
+
constructor(message: string, status: number | null, code: string | null, errors?: readonly OperationErrorEntry[]);
|
|
19
|
+
}
|
|
20
|
+
|
|
6
21
|
interface OrmTransport {
|
|
7
22
|
get(path: string, params: URLSearchParams): Promise<unknown>;
|
|
8
23
|
post(path: string, body: unknown): Promise<unknown>;
|
|
@@ -71,14 +86,6 @@ declare class TableQuery<Row extends Record<string, unknown>, Result = Row> {
|
|
|
71
86
|
private filter;
|
|
72
87
|
}
|
|
73
88
|
|
|
74
|
-
/**
|
|
75
|
-
* Persisted-operation client for the v2 data plane. The wire carries only
|
|
76
|
-
* `{ op: <hash>, variables }` — never GraphQL text, never SQL. Like the rest
|
|
77
|
-
* of `./client`, this module is deliberately free of node builtins and third-
|
|
78
|
-
* party deps (no @apollo/client import): Apollo integration happens through a
|
|
79
|
-
* fetch-compatible shim (`createOrmFetch`) handed to `HttpLink({ fetch })`.
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
89
|
/** One entry of `operations.manifest.json` (generated by `orm generate`). */
|
|
83
90
|
interface ManifestOperation {
|
|
84
91
|
readonly hash: string;
|
|
@@ -93,19 +100,6 @@ interface OperationsManifest {
|
|
|
93
100
|
readonly opsHash?: string;
|
|
94
101
|
readonly operations: Readonly<Record<string, ManifestOperation>>;
|
|
95
102
|
}
|
|
96
|
-
/** GraphQL-spec error envelope the data plane returns. */
|
|
97
|
-
interface OperationErrorEntry {
|
|
98
|
-
readonly message: string;
|
|
99
|
-
readonly extensions?: {
|
|
100
|
-
readonly code?: string;
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
declare class OrmOperationError extends OrmClientError {
|
|
104
|
-
readonly code: string | null;
|
|
105
|
-
readonly errors: readonly OperationErrorEntry[];
|
|
106
|
-
readonly name = "OrmOperationError";
|
|
107
|
-
constructor(message: string, status: number | null, code: string | null, errors?: readonly OperationErrorEntry[]);
|
|
108
|
-
}
|
|
109
103
|
interface OperationExecutorConfig {
|
|
110
104
|
/** Deployment host root, e.g. `https://atlas.seqholdings.com`. */
|
|
111
105
|
baseUrl: string;
|
|
@@ -117,11 +111,27 @@ interface OperationExecutorConfig {
|
|
|
117
111
|
getDataToken?: () => Promise<string | null> | string | null;
|
|
118
112
|
fetchImpl?: typeof globalThis.fetch;
|
|
119
113
|
}
|
|
114
|
+
interface OperationExecutionOptions {
|
|
115
|
+
/** Reuse only when retrying the same logical mutation. */
|
|
116
|
+
idempotencyKey?: string;
|
|
117
|
+
}
|
|
120
118
|
interface OperationExecutor {
|
|
121
119
|
/** Execute a manifest operation by name (or a raw `sha256:` hash). */
|
|
122
|
-
execute<TData = Record<string, unknown>>(op: string, variables?: Record<string, unknown
|
|
120
|
+
execute<TData = Record<string, unknown>>(op: string, variables?: Record<string, unknown>, options?: OperationExecutionOptions): Promise<TData>;
|
|
121
|
+
}
|
|
122
|
+
/** Additive factory result; existing host wrappers implementing OperationExecutor remain valid. */
|
|
123
|
+
interface TypedOperationExecutor extends OperationExecutor {
|
|
124
|
+
execute<TVariables extends Record<string, unknown>, TData>(op: OperationReference<TVariables, TData>, variables: TVariables, options?: OperationExecutionOptions): Promise<TData>;
|
|
125
|
+
execute<TData = Record<string, unknown>>(op: string, variables?: Record<string, unknown>, options?: OperationExecutionOptions): Promise<TData>;
|
|
126
|
+
}
|
|
127
|
+
/** Generated handle identifies the registered contract; optional types are phantom. */
|
|
128
|
+
interface OperationReference<TVariables extends Record<string, unknown>, TData> {
|
|
129
|
+
readonly namespace: string;
|
|
130
|
+
readonly hash: string;
|
|
131
|
+
readonly variables?: TVariables;
|
|
132
|
+
readonly result?: TData;
|
|
123
133
|
}
|
|
124
|
-
declare function createOperationExecutor({ baseUrl, namespace, manifest, getToken, getDataToken, fetchImpl, }: OperationExecutorConfig):
|
|
134
|
+
declare function createOperationExecutor({ baseUrl, namespace, manifest, getToken, getDataToken, fetchImpl, }: OperationExecutorConfig): TypedOperationExecutor;
|
|
125
135
|
/**
|
|
126
136
|
* Configure the process-wide executor the generated `db<Name>` server
|
|
127
137
|
* functions call through. Call once at startup (server-side); browser apps
|
|
@@ -129,9 +139,10 @@ declare function createOperationExecutor({ baseUrl, namespace, manifest, getToke
|
|
|
129
139
|
*/
|
|
130
140
|
declare function configureOrmOperations(config: OperationExecutorConfig): OperationExecutor;
|
|
131
141
|
/** Used by generated code: `executeOperation({ op: 'getOpenDeals', variables })`. */
|
|
132
|
-
declare function executeOperation<TData = Record<string, unknown>>({ op, variables, }: {
|
|
142
|
+
declare function executeOperation<TData = Record<string, unknown>>({ op, variables, idempotencyKey, }: {
|
|
133
143
|
op: string;
|
|
134
144
|
variables?: Record<string, unknown>;
|
|
145
|
+
idempotencyKey?: string;
|
|
135
146
|
}): Promise<TData>;
|
|
136
147
|
/**
|
|
137
148
|
* A fetch-compatible function for `new HttpLink({ uri: '/unused', fetch: createOrmFetch(...) })`.
|
|
@@ -143,6 +154,55 @@ declare function executeOperation<TData = Record<string, unknown>>({ op, variabl
|
|
|
143
154
|
*/
|
|
144
155
|
declare function createOrmFetch({ baseUrl, namespace, manifest, getToken, getDataToken, fetchImpl, }: OperationExecutorConfig): typeof globalThis.fetch;
|
|
145
156
|
|
|
157
|
+
/** Runtime SQL inputs are values, never interpolated into the submitted SQL. */
|
|
158
|
+
type SqlQueryParameter = {
|
|
159
|
+
type: 'text' | 'uuid' | 'date' | 'timestamptz' | 'numeric' | 'bigint';
|
|
160
|
+
value: string | null;
|
|
161
|
+
} | {
|
|
162
|
+
type: 'integer' | 'double';
|
|
163
|
+
value: number | null;
|
|
164
|
+
} | {
|
|
165
|
+
type: 'boolean';
|
|
166
|
+
value: boolean | null;
|
|
167
|
+
};
|
|
168
|
+
type SqlQueryVariables = {
|
|
169
|
+
sql: string;
|
|
170
|
+
parameters?: Record<string, SqlQueryParameter>;
|
|
171
|
+
};
|
|
172
|
+
interface SqlQueryResult {
|
|
173
|
+
columns: Array<{
|
|
174
|
+
name: string;
|
|
175
|
+
type: string;
|
|
176
|
+
nullable: boolean;
|
|
177
|
+
}>;
|
|
178
|
+
rows: Array<Array<string | number | boolean | null>>;
|
|
179
|
+
truncated: boolean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
interface OperationTransportRequest {
|
|
183
|
+
namespace: string;
|
|
184
|
+
op: string;
|
|
185
|
+
variables: Record<string, unknown>;
|
|
186
|
+
idempotencyKey?: string;
|
|
187
|
+
}
|
|
188
|
+
interface OperationTransportResponse {
|
|
189
|
+
ok: boolean;
|
|
190
|
+
status: number;
|
|
191
|
+
body: unknown;
|
|
192
|
+
}
|
|
193
|
+
type OperationTransport = (request: OperationTransportRequest) => Promise<OperationTransportResponse>;
|
|
194
|
+
/**
|
|
195
|
+
* Execute generated operations through a host-owned authenticated transport.
|
|
196
|
+
* No credential handling, retries, or global configuration. The manifest is
|
|
197
|
+
* validated once and copied, so later caller mutation cannot alter the target.
|
|
198
|
+
*/
|
|
199
|
+
declare function createOperationExecutorWithTransport({ namespace, manifest, transport }: {
|
|
200
|
+
namespace: string;
|
|
201
|
+
/** Accept generated JSON imports directly; validate them at construction. */
|
|
202
|
+
manifest: unknown;
|
|
203
|
+
transport: OperationTransport;
|
|
204
|
+
}): TypedOperationExecutor;
|
|
205
|
+
|
|
146
206
|
/** Bindable scalar for `query()` placeholders ($1, $2, …). */
|
|
147
207
|
type QueryParam = string | number | boolean | null;
|
|
148
208
|
/** Shape of one action in the generated `<Ns>Actions` map — params in, result out. */
|
|
@@ -240,4 +300,4 @@ declare function createServiceOrmClient<Tables extends Record<string, Record<str
|
|
|
240
300
|
transport?: OrmTransport;
|
|
241
301
|
}): OrmClient<Tables, Actions>;
|
|
242
302
|
|
|
243
|
-
export { type FilterValue, type ManifestOperation, type OperationErrorEntry, type OperationExecutor, type OperationExecutorConfig, type OperationsManifest, type OrmActionShape, type OrmActions, type OrmClient, OrmClientError, OrmOperationError, type OrmTransport, type QueryParam, type ReadResponse, TableQuery, configureOrmOperations, createFetchTransport, createOperationExecutor, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
|
303
|
+
export { type FilterValue, type ManifestOperation, type OperationErrorEntry, type OperationExecutor, type OperationExecutorConfig, type OperationReference, type OperationTransport, type OperationTransportRequest, type OperationTransportResponse, type OperationsManifest, type OrmActionShape, type OrmActions, type OrmClient, OrmClientError, OrmOperationError, type OrmTransport, type QueryParam, type ReadResponse, type SqlQueryParameter, type SqlQueryResult, type SqlQueryVariables, TableQuery, type TypedOperationExecutor, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
|
+
export { N as NAMESPACE_PATTERN, O as ORM_DATA_TOKEN_HEADER, d as ORM_SERVICE_DATA_TOKEN_HEADER } from './constants-C6EG6Wq7.js';
|
|
2
|
+
|
|
1
3
|
declare class OrmClientError extends Error {
|
|
2
4
|
readonly status: number | null;
|
|
3
5
|
readonly name: string;
|
|
4
6
|
constructor(message: string, status?: number | null);
|
|
5
7
|
}
|
|
8
|
+
interface OperationErrorEntry {
|
|
9
|
+
readonly message: string;
|
|
10
|
+
readonly extensions?: {
|
|
11
|
+
readonly code?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
declare class OrmOperationError extends OrmClientError {
|
|
15
|
+
readonly code: string | null;
|
|
16
|
+
readonly errors: readonly OperationErrorEntry[];
|
|
17
|
+
readonly name = "OrmOperationError";
|
|
18
|
+
constructor(message: string, status: number | null, code: string | null, errors?: readonly OperationErrorEntry[]);
|
|
19
|
+
}
|
|
20
|
+
|
|
6
21
|
interface OrmTransport {
|
|
7
22
|
get(path: string, params: URLSearchParams): Promise<unknown>;
|
|
8
23
|
post(path: string, body: unknown): Promise<unknown>;
|
|
@@ -71,14 +86,6 @@ declare class TableQuery<Row extends Record<string, unknown>, Result = Row> {
|
|
|
71
86
|
private filter;
|
|
72
87
|
}
|
|
73
88
|
|
|
74
|
-
/**
|
|
75
|
-
* Persisted-operation client for the v2 data plane. The wire carries only
|
|
76
|
-
* `{ op: <hash>, variables }` — never GraphQL text, never SQL. Like the rest
|
|
77
|
-
* of `./client`, this module is deliberately free of node builtins and third-
|
|
78
|
-
* party deps (no @apollo/client import): Apollo integration happens through a
|
|
79
|
-
* fetch-compatible shim (`createOrmFetch`) handed to `HttpLink({ fetch })`.
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
89
|
/** One entry of `operations.manifest.json` (generated by `orm generate`). */
|
|
83
90
|
interface ManifestOperation {
|
|
84
91
|
readonly hash: string;
|
|
@@ -93,19 +100,6 @@ interface OperationsManifest {
|
|
|
93
100
|
readonly opsHash?: string;
|
|
94
101
|
readonly operations: Readonly<Record<string, ManifestOperation>>;
|
|
95
102
|
}
|
|
96
|
-
/** GraphQL-spec error envelope the data plane returns. */
|
|
97
|
-
interface OperationErrorEntry {
|
|
98
|
-
readonly message: string;
|
|
99
|
-
readonly extensions?: {
|
|
100
|
-
readonly code?: string;
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
declare class OrmOperationError extends OrmClientError {
|
|
104
|
-
readonly code: string | null;
|
|
105
|
-
readonly errors: readonly OperationErrorEntry[];
|
|
106
|
-
readonly name = "OrmOperationError";
|
|
107
|
-
constructor(message: string, status: number | null, code: string | null, errors?: readonly OperationErrorEntry[]);
|
|
108
|
-
}
|
|
109
103
|
interface OperationExecutorConfig {
|
|
110
104
|
/** Deployment host root, e.g. `https://atlas.seqholdings.com`. */
|
|
111
105
|
baseUrl: string;
|
|
@@ -117,11 +111,27 @@ interface OperationExecutorConfig {
|
|
|
117
111
|
getDataToken?: () => Promise<string | null> | string | null;
|
|
118
112
|
fetchImpl?: typeof globalThis.fetch;
|
|
119
113
|
}
|
|
114
|
+
interface OperationExecutionOptions {
|
|
115
|
+
/** Reuse only when retrying the same logical mutation. */
|
|
116
|
+
idempotencyKey?: string;
|
|
117
|
+
}
|
|
120
118
|
interface OperationExecutor {
|
|
121
119
|
/** Execute a manifest operation by name (or a raw `sha256:` hash). */
|
|
122
|
-
execute<TData = Record<string, unknown>>(op: string, variables?: Record<string, unknown
|
|
120
|
+
execute<TData = Record<string, unknown>>(op: string, variables?: Record<string, unknown>, options?: OperationExecutionOptions): Promise<TData>;
|
|
121
|
+
}
|
|
122
|
+
/** Additive factory result; existing host wrappers implementing OperationExecutor remain valid. */
|
|
123
|
+
interface TypedOperationExecutor extends OperationExecutor {
|
|
124
|
+
execute<TVariables extends Record<string, unknown>, TData>(op: OperationReference<TVariables, TData>, variables: TVariables, options?: OperationExecutionOptions): Promise<TData>;
|
|
125
|
+
execute<TData = Record<string, unknown>>(op: string, variables?: Record<string, unknown>, options?: OperationExecutionOptions): Promise<TData>;
|
|
126
|
+
}
|
|
127
|
+
/** Generated handle identifies the registered contract; optional types are phantom. */
|
|
128
|
+
interface OperationReference<TVariables extends Record<string, unknown>, TData> {
|
|
129
|
+
readonly namespace: string;
|
|
130
|
+
readonly hash: string;
|
|
131
|
+
readonly variables?: TVariables;
|
|
132
|
+
readonly result?: TData;
|
|
123
133
|
}
|
|
124
|
-
declare function createOperationExecutor({ baseUrl, namespace, manifest, getToken, getDataToken, fetchImpl, }: OperationExecutorConfig):
|
|
134
|
+
declare function createOperationExecutor({ baseUrl, namespace, manifest, getToken, getDataToken, fetchImpl, }: OperationExecutorConfig): TypedOperationExecutor;
|
|
125
135
|
/**
|
|
126
136
|
* Configure the process-wide executor the generated `db<Name>` server
|
|
127
137
|
* functions call through. Call once at startup (server-side); browser apps
|
|
@@ -129,9 +139,10 @@ declare function createOperationExecutor({ baseUrl, namespace, manifest, getToke
|
|
|
129
139
|
*/
|
|
130
140
|
declare function configureOrmOperations(config: OperationExecutorConfig): OperationExecutor;
|
|
131
141
|
/** Used by generated code: `executeOperation({ op: 'getOpenDeals', variables })`. */
|
|
132
|
-
declare function executeOperation<TData = Record<string, unknown>>({ op, variables, }: {
|
|
142
|
+
declare function executeOperation<TData = Record<string, unknown>>({ op, variables, idempotencyKey, }: {
|
|
133
143
|
op: string;
|
|
134
144
|
variables?: Record<string, unknown>;
|
|
145
|
+
idempotencyKey?: string;
|
|
135
146
|
}): Promise<TData>;
|
|
136
147
|
/**
|
|
137
148
|
* A fetch-compatible function for `new HttpLink({ uri: '/unused', fetch: createOrmFetch(...) })`.
|
|
@@ -143,6 +154,55 @@ declare function executeOperation<TData = Record<string, unknown>>({ op, variabl
|
|
|
143
154
|
*/
|
|
144
155
|
declare function createOrmFetch({ baseUrl, namespace, manifest, getToken, getDataToken, fetchImpl, }: OperationExecutorConfig): typeof globalThis.fetch;
|
|
145
156
|
|
|
157
|
+
/** Runtime SQL inputs are values, never interpolated into the submitted SQL. */
|
|
158
|
+
type SqlQueryParameter = {
|
|
159
|
+
type: 'text' | 'uuid' | 'date' | 'timestamptz' | 'numeric' | 'bigint';
|
|
160
|
+
value: string | null;
|
|
161
|
+
} | {
|
|
162
|
+
type: 'integer' | 'double';
|
|
163
|
+
value: number | null;
|
|
164
|
+
} | {
|
|
165
|
+
type: 'boolean';
|
|
166
|
+
value: boolean | null;
|
|
167
|
+
};
|
|
168
|
+
type SqlQueryVariables = {
|
|
169
|
+
sql: string;
|
|
170
|
+
parameters?: Record<string, SqlQueryParameter>;
|
|
171
|
+
};
|
|
172
|
+
interface SqlQueryResult {
|
|
173
|
+
columns: Array<{
|
|
174
|
+
name: string;
|
|
175
|
+
type: string;
|
|
176
|
+
nullable: boolean;
|
|
177
|
+
}>;
|
|
178
|
+
rows: Array<Array<string | number | boolean | null>>;
|
|
179
|
+
truncated: boolean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
interface OperationTransportRequest {
|
|
183
|
+
namespace: string;
|
|
184
|
+
op: string;
|
|
185
|
+
variables: Record<string, unknown>;
|
|
186
|
+
idempotencyKey?: string;
|
|
187
|
+
}
|
|
188
|
+
interface OperationTransportResponse {
|
|
189
|
+
ok: boolean;
|
|
190
|
+
status: number;
|
|
191
|
+
body: unknown;
|
|
192
|
+
}
|
|
193
|
+
type OperationTransport = (request: OperationTransportRequest) => Promise<OperationTransportResponse>;
|
|
194
|
+
/**
|
|
195
|
+
* Execute generated operations through a host-owned authenticated transport.
|
|
196
|
+
* No credential handling, retries, or global configuration. The manifest is
|
|
197
|
+
* validated once and copied, so later caller mutation cannot alter the target.
|
|
198
|
+
*/
|
|
199
|
+
declare function createOperationExecutorWithTransport({ namespace, manifest, transport }: {
|
|
200
|
+
namespace: string;
|
|
201
|
+
/** Accept generated JSON imports directly; validate them at construction. */
|
|
202
|
+
manifest: unknown;
|
|
203
|
+
transport: OperationTransport;
|
|
204
|
+
}): TypedOperationExecutor;
|
|
205
|
+
|
|
146
206
|
/** Bindable scalar for `query()` placeholders ($1, $2, …). */
|
|
147
207
|
type QueryParam = string | number | boolean | null;
|
|
148
208
|
/** Shape of one action in the generated `<Ns>Actions` map — params in, result out. */
|
|
@@ -240,4 +300,4 @@ declare function createServiceOrmClient<Tables extends Record<string, Record<str
|
|
|
240
300
|
transport?: OrmTransport;
|
|
241
301
|
}): OrmClient<Tables, Actions>;
|
|
242
302
|
|
|
243
|
-
export { type FilterValue, type ManifestOperation, type OperationErrorEntry, type OperationExecutor, type OperationExecutorConfig, type OperationsManifest, type OrmActionShape, type OrmActions, type OrmClient, OrmClientError, OrmOperationError, type OrmTransport, type QueryParam, type ReadResponse, TableQuery, configureOrmOperations, createFetchTransport, createOperationExecutor, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
|
303
|
+
export { type FilterValue, type ManifestOperation, type OperationErrorEntry, type OperationExecutor, type OperationExecutorConfig, type OperationReference, type OperationTransport, type OperationTransportRequest, type OperationTransportResponse, type OperationsManifest, type OrmActionShape, type OrmActions, type OrmClient, OrmClientError, OrmOperationError, type OrmTransport, type QueryParam, type ReadResponse, type SqlQueryParameter, type SqlQueryResult, type SqlQueryVariables, TableQuery, type TypedOperationExecutor, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
package/dist/client.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
+
var NAMESPACE_PATTERN = /^[a-z][a-z0-9_]{0,40}$/;
|
|
2
3
|
var ORM_DATA_TOKEN_HEADER = "x-sequence-data-token";
|
|
4
|
+
var ORM_SERVICE_DATA_TOKEN_HEADER = "x-sequence-data-token-service";
|
|
5
|
+
var MATERIALIZE_ACTOR = "orm:materialize";
|
|
6
|
+
JSON.stringify({ sub: MATERIALIZE_ACTOR, org: null, roles: [], capabilities: [] });
|
|
3
7
|
|
|
4
|
-
// src/client/
|
|
8
|
+
// src/client/errors.ts
|
|
5
9
|
var OrmClientError = class extends Error {
|
|
6
10
|
constructor(message, status = null) {
|
|
7
11
|
super(message);
|
|
8
12
|
this.status = status;
|
|
9
13
|
}
|
|
10
|
-
// Widened to `string` so subclasses (e.g. OrmOperationError) can rename.
|
|
11
14
|
name = "OrmClientError";
|
|
12
15
|
};
|
|
16
|
+
var OrmOperationError = class extends OrmClientError {
|
|
17
|
+
constructor(message, status, code, errors = []) {
|
|
18
|
+
super(message, status);
|
|
19
|
+
this.code = code;
|
|
20
|
+
this.errors = errors;
|
|
21
|
+
}
|
|
22
|
+
name = "OrmOperationError";
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/client/transport.ts
|
|
13
26
|
function createFetchTransport({
|
|
14
27
|
baseUrl,
|
|
15
28
|
getToken,
|
|
@@ -146,15 +159,45 @@ var TableQuery = class _TableQuery {
|
|
|
146
159
|
}
|
|
147
160
|
};
|
|
148
161
|
|
|
162
|
+
// src/client/response.ts
|
|
163
|
+
function isRecord(value) {
|
|
164
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
165
|
+
}
|
|
166
|
+
function isOperationError(value) {
|
|
167
|
+
if (!isRecord(value) || typeof value.message !== "string") return false;
|
|
168
|
+
if (value.extensions === void 0) return true;
|
|
169
|
+
return isRecord(value.extensions) && (value.extensions.code === void 0 || typeof value.extensions.code === "string");
|
|
170
|
+
}
|
|
171
|
+
function readOperationResponse({
|
|
172
|
+
ok,
|
|
173
|
+
status,
|
|
174
|
+
body
|
|
175
|
+
}) {
|
|
176
|
+
const payload = isRecord(body) ? body : null;
|
|
177
|
+
const rawErrors = payload?.errors;
|
|
178
|
+
if (rawErrors !== void 0 && (!Array.isArray(rawErrors) || !rawErrors.every(isOperationError))) {
|
|
179
|
+
throw new OrmOperationError("malformed response: invalid errors", status, null);
|
|
180
|
+
}
|
|
181
|
+
const errors = rawErrors ?? [];
|
|
182
|
+
if (!ok || errors.length > 0) {
|
|
183
|
+
const first = errors[0];
|
|
184
|
+
throw new OrmOperationError(first?.message ?? `HTTP ${status}`, status, first?.extensions?.code ?? null, errors);
|
|
185
|
+
}
|
|
186
|
+
if (!payload || payload.data === void 0 || payload.data === null) {
|
|
187
|
+
throw new OrmOperationError("malformed response: missing data", status, null);
|
|
188
|
+
}
|
|
189
|
+
if (!isRecord(payload.data)) {
|
|
190
|
+
throw new OrmOperationError("malformed response: data must be an object", status, null);
|
|
191
|
+
}
|
|
192
|
+
return payload.data;
|
|
193
|
+
}
|
|
194
|
+
|
|
149
195
|
// src/client/operations.ts
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
this.code = code;
|
|
154
|
-
this.errors = errors;
|
|
196
|
+
function validateIdempotencyKey(key) {
|
|
197
|
+
if (key !== void 0 && !/^[A-Za-z0-9._:-]{1,128}$/.test(key)) {
|
|
198
|
+
throw new OrmClientError("idempotencyKey must be 1\u2013128 letters, digits, dots, underscores, colons or hyphens");
|
|
155
199
|
}
|
|
156
|
-
|
|
157
|
-
};
|
|
200
|
+
}
|
|
158
201
|
var dataPlanePath = (namespace) => `/_data/v2/${namespace}`;
|
|
159
202
|
function resolveOpHash(manifest, op) {
|
|
160
203
|
if (op.startsWith("sha256:")) return op;
|
|
@@ -180,34 +223,25 @@ function createOperationExecutor({
|
|
|
180
223
|
throw new OrmClientError("provide exactly one of getToken (bearer) or getDataToken (delegated)");
|
|
181
224
|
}
|
|
182
225
|
const root = baseUrl.replace(/\/+$/, "");
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
errors
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
if (!payload || payload.data === void 0 || payload.data === null) {
|
|
206
|
-
throw new OrmOperationError("malformed response: missing data", response.status, null);
|
|
207
|
-
}
|
|
208
|
-
return payload.data;
|
|
209
|
-
}
|
|
210
|
-
};
|
|
226
|
+
async function execute(op, variables = {}, options = {}) {
|
|
227
|
+
validateIdempotencyKey(options.idempotencyKey);
|
|
228
|
+
if (typeof op !== "string" && op.namespace !== namespace) throw new OrmClientError("operation belongs to a different namespace");
|
|
229
|
+
const hash = typeof op === "string" ? resolveOpHash(manifest, op) : op.hash;
|
|
230
|
+
const token = await (getDataToken ?? getToken)();
|
|
231
|
+
if (!token) throw new OrmClientError("not authenticated \u2014 no token available");
|
|
232
|
+
const auth = getDataToken ? { [ORM_DATA_TOKEN_HEADER]: token } : { Authorization: `Bearer ${token}` };
|
|
233
|
+
const response = await fetchImpl(`${root}${dataPlanePath(namespace)}`, {
|
|
234
|
+
method: "POST",
|
|
235
|
+
headers: { ...auth, "Content-Type": "application/json" },
|
|
236
|
+
body: JSON.stringify({ op: hash, variables, idempotencyKey: options.idempotencyKey })
|
|
237
|
+
});
|
|
238
|
+
return readOperationResponse({
|
|
239
|
+
ok: response.ok,
|
|
240
|
+
status: response.status,
|
|
241
|
+
body: await response.json().catch(() => null)
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return { execute };
|
|
211
245
|
}
|
|
212
246
|
var configured = null;
|
|
213
247
|
function configureOrmOperations(config) {
|
|
@@ -216,14 +250,15 @@ function configureOrmOperations(config) {
|
|
|
216
250
|
}
|
|
217
251
|
async function executeOperation({
|
|
218
252
|
op,
|
|
219
|
-
variables
|
|
253
|
+
variables,
|
|
254
|
+
idempotencyKey
|
|
220
255
|
}) {
|
|
221
256
|
if (!configured) {
|
|
222
257
|
throw new OrmClientError(
|
|
223
258
|
"ORM operations client not configured \u2014 call configureOrmOperations({ baseUrl, namespace, manifest, getToken }) at startup"
|
|
224
259
|
);
|
|
225
260
|
}
|
|
226
|
-
return configured.execute(op, variables);
|
|
261
|
+
return configured.execute(op, variables, idempotencyKey === void 0 ? {} : { idempotencyKey });
|
|
227
262
|
}
|
|
228
263
|
function createOrmFetch({
|
|
229
264
|
baseUrl,
|
|
@@ -249,17 +284,60 @@ function createOrmFetch({
|
|
|
249
284
|
);
|
|
250
285
|
}
|
|
251
286
|
const hash = resolveOpHash(manifest, name);
|
|
287
|
+
const idempotencyKey = new Headers(init?.headers).get("Idempotency-Key") ?? void 0;
|
|
288
|
+
validateIdempotencyKey(idempotencyKey);
|
|
252
289
|
const token = await (getDataToken ?? getToken)();
|
|
253
290
|
if (!token) throw new OrmClientError("not authenticated \u2014 no token available");
|
|
254
291
|
const auth = getDataToken ? { [ORM_DATA_TOKEN_HEADER]: token } : { Authorization: `Bearer ${token}` };
|
|
255
292
|
return fetchImpl(url, {
|
|
256
293
|
method: "POST",
|
|
257
294
|
headers: { ...auth, "Content-Type": "application/json" },
|
|
258
|
-
body: JSON.stringify({ op: hash, variables: parsed.variables ?? {} })
|
|
295
|
+
body: JSON.stringify({ op: hash, variables: parsed.variables ?? {}, idempotencyKey }),
|
|
296
|
+
...init?.signal ? { signal: init.signal } : {}
|
|
259
297
|
});
|
|
260
298
|
};
|
|
261
299
|
}
|
|
262
300
|
|
|
301
|
+
// src/client/transport-executor.ts
|
|
302
|
+
var operationHash = /^sha256:[a-f0-9]{64}$/;
|
|
303
|
+
function readManifestHashes(manifest) {
|
|
304
|
+
if (!isRecord(manifest) || typeof manifest.schemaHash !== "string" || !manifest.schemaHash || !isRecord(manifest.operations)) {
|
|
305
|
+
throw new OrmClientError("invalid operations manifest \u2014 use operations.manifest.json from seq-studio orm generate");
|
|
306
|
+
}
|
|
307
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
308
|
+
for (const [name, entry] of Object.entries(manifest.operations)) {
|
|
309
|
+
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") {
|
|
310
|
+
throw new OrmClientError(`invalid operations manifest entry "${name}" \u2014 regenerate the manifest`);
|
|
311
|
+
}
|
|
312
|
+
hashes.set(name, entry.hash);
|
|
313
|
+
}
|
|
314
|
+
return hashes;
|
|
315
|
+
}
|
|
316
|
+
function createOperationExecutorWithTransport({ namespace, manifest, transport }) {
|
|
317
|
+
if (typeof namespace !== "string" || !NAMESPACE_PATTERN.test(namespace)) throw new OrmClientError("invalid ORM namespace \u2014 expected a lowercase identifier of at most 41 characters");
|
|
318
|
+
const hashes = readManifestHashes(manifest);
|
|
319
|
+
const knownHashes = new Set(hashes.values());
|
|
320
|
+
async function execute(op, variables = {}, options = {}) {
|
|
321
|
+
validateIdempotencyKey(options.idempotencyKey);
|
|
322
|
+
if (typeof op !== "string" && op.namespace !== namespace) throw new OrmClientError("operation belongs to a different namespace");
|
|
323
|
+
const selector = typeof op === "string" ? op : op.hash;
|
|
324
|
+
const hash = hashes.get(selector) ?? (knownHashes.has(selector) ? selector : void 0);
|
|
325
|
+
if (!hash) throw new OrmClientError(`unknown operation "${op}" \u2014 not in the manifest (${hashes.size} known). Re-run seq-studio orm generate.`);
|
|
326
|
+
if (!isRecord(variables)) throw new OrmClientError("operation variables must be an object");
|
|
327
|
+
const response = await transport({
|
|
328
|
+
namespace,
|
|
329
|
+
op: hash,
|
|
330
|
+
variables,
|
|
331
|
+
...options.idempotencyKey === void 0 ? {} : { idempotencyKey: options.idempotencyKey }
|
|
332
|
+
});
|
|
333
|
+
if (!response || typeof response.ok !== "boolean" || !Number.isInteger(response.status) || response.status < 100 || response.status > 599 || response.ok !== (response.status >= 200 && response.status < 300)) {
|
|
334
|
+
throw new OrmOperationError("malformed transport response", null, null);
|
|
335
|
+
}
|
|
336
|
+
return readOperationResponse(response);
|
|
337
|
+
}
|
|
338
|
+
return { execute };
|
|
339
|
+
}
|
|
340
|
+
|
|
263
341
|
// src/client/index.ts
|
|
264
342
|
function createOrmClient({
|
|
265
343
|
namespace,
|
|
@@ -327,6 +405,6 @@ function requireOption(value, name) {
|
|
|
327
405
|
return value;
|
|
328
406
|
}
|
|
329
407
|
|
|
330
|
-
export { OrmClientError, OrmOperationError, TableQuery, configureOrmOperations, createFetchTransport, createOperationExecutor, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
|
408
|
+
export { NAMESPACE_PATTERN, ORM_DATA_TOKEN_HEADER, ORM_SERVICE_DATA_TOKEN_HEADER, OrmClientError, OrmOperationError, TableQuery, configureOrmOperations, createFetchTransport, createOperationExecutor, createOperationExecutorWithTransport, createOrmClient, createOrmFetch, createServiceOrmClient, executeOperation };
|
|
331
409
|
//# sourceMappingURL=client.js.map
|
|
332
410
|
//# sourceMappingURL=client.js.map
|