@abloatai/transaction 0.52.0 → 0.54.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/dist/auth/apiKey.d.ts +0 -6
- package/dist/auth/apiKey.d.ts.map +1 -1
- package/dist/auth/apiKey.js +13 -60
- package/dist/auth/apiKey.js.map +1 -1
- package/dist/auth/baseUrl.d.ts +38 -0
- package/dist/auth/baseUrl.d.ts.map +1 -0
- package/dist/auth/baseUrl.js +126 -0
- package/dist/auth/baseUrl.js.map +1 -0
- package/dist/auth/capability.js +1 -1
- package/dist/auth/index.d.ts +5 -5
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/branches.d.ts +31 -30
- package/dist/branches.d.ts.map +1 -1
- package/dist/branches.js +2 -4
- package/dist/branches.js.map +1 -1
- package/dist/errorCodes.d.ts +4 -1
- package/dist/errorCodes.d.ts.map +1 -1
- package/dist/errorCodes.js +4 -1
- package/dist/errorCodes.js.map +1 -1
- package/dist/errorObservation.d.ts.map +1 -1
- package/dist/errorObservation.js +9 -1
- package/dist/errorObservation.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/httpResources.d.ts +34 -2
- package/dist/resources/httpResources.d.ts.map +1 -1
- package/dist/resources/httpResources.js +10 -1
- package/dist/resources/httpResources.js.map +1 -1
- package/dist/resources/modelOperations.d.ts +12 -0
- package/dist/resources/modelOperations.d.ts.map +1 -1
- package/dist/resources/modelOperations.js.map +1 -1
- package/dist/resources/where.d.ts +67 -2
- package/dist/resources/where.d.ts.map +1 -1
- package/dist/resources/where.js +73 -0
- package/dist/resources/where.js.map +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/openapi.d.ts.map +1 -1
- package/dist/schema/openapi.js +59 -14
- package/dist/schema/openapi.js.map +1 -1
- package/dist/schema/schema.d.ts +1 -1
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +1 -1
- package/dist/schema/schema.js.map +1 -1
- package/dist/server/adapter.d.ts +2 -0
- package/dist/server/adapter.d.ts.map +1 -1
- package/dist/server/index.d.ts +3 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/readConfig.d.ts +109 -57
- package/dist/server/readConfig.d.ts.map +1 -1
- package/dist/server/readConfig.js +19 -5
- package/dist/server/readConfig.js.map +1 -1
- package/dist/source/adapters/kysely.d.ts.map +1 -1
- package/dist/source/adapters/kysely.js +64 -6
- package/dist/source/adapters/kysely.js.map +1 -1
- package/dist/source/contract.d.ts.map +1 -1
- package/dist/source/contract.js +2 -0
- package/dist/source/contract.js.map +1 -1
- package/dist/source/types.d.ts +21 -3
- package/dist/source/types.d.ts.map +1 -1
- package/dist/source/types.js.map +1 -1
- package/dist/transport/httpClient.d.ts +7 -2
- package/dist/transport/httpClient.d.ts.map +1 -1
- package/dist/transport/httpClient.js +4 -2
- package/dist/transport/httpClient.js.map +1 -1
- package/dist/transport/httpTransport.d.ts.map +1 -1
- package/dist/transport/httpTransport.js +29 -7
- package/dist/transport/httpTransport.js.map +1 -1
- package/dist/wire/accountResponses.d.ts +18 -13
- package/dist/wire/accountResponses.d.ts.map +1 -1
- package/dist/wire/accountResponses.js +3 -9
- package/dist/wire/accountResponses.js.map +1 -1
- package/dist/wire/auth.d.ts +1 -1
- package/dist/wire/auth.js +3 -3
- package/dist/wire/claims.d.ts +1 -0
- package/dist/wire/claims.d.ts.map +1 -1
- package/dist/wire/claims.js +7 -1
- package/dist/wire/claims.js.map +1 -1
- package/dist/wire/index.d.ts +1 -1
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +1 -1
- package/dist/wire/index.js.map +1 -1
- package/dist/wire/listEnvelope.d.ts +20 -0
- package/dist/wire/listEnvelope.d.ts.map +1 -1
- package/dist/wire/listEnvelope.js +20 -0
- package/dist/wire/listEnvelope.js.map +1 -1
- package/package.json +1 -1
- package/src/auth/apiKey.ts +13 -61
- package/src/auth/baseUrl.ts +144 -0
- package/src/auth/capability.ts +1 -1
- package/src/auth/index.ts +5 -5
- package/src/branches.ts +2 -4
- package/src/errorCodes.ts +19 -1
- package/src/errorObservation.ts +9 -1
- package/src/index.ts +2 -0
- package/src/resources/httpResources.ts +44 -2
- package/src/resources/modelOperations.ts +12 -0
- package/src/resources/where.ts +70 -4
- package/src/schema/index.ts +3 -0
- package/src/schema/openapi.ts +60 -14
- package/src/schema/schema.ts +3 -0
- package/src/server/adapter.ts +2 -0
- package/src/server/index.ts +8 -2
- package/src/server/readConfig.ts +111 -57
- package/src/source/adapters/kysely.ts +73 -8
- package/src/source/contract.ts +2 -0
- package/src/source/types.ts +21 -3
- package/src/transport/httpClient.ts +17 -4
- package/src/transport/httpTransport.ts +29 -7
- package/src/wire/accountResponses.ts +3 -9
- package/src/wire/auth.ts +3 -3
- package/src/wire/claims.ts +7 -1
- package/src/wire/index.ts +7 -1
- package/src/wire/listEnvelope.ts +23 -0
|
@@ -32,10 +32,12 @@ import type {
|
|
|
32
32
|
HttpTransportModel,
|
|
33
33
|
ModelReadOptions,
|
|
34
34
|
ModelMutationOptions,
|
|
35
|
+
ModelList,
|
|
35
36
|
CreateSessionParams,
|
|
36
37
|
AbloSession,
|
|
37
38
|
SessionResource,
|
|
38
39
|
} from '../resources/httpResources.js';
|
|
40
|
+
import { modelList } from '../resources/httpResources.js';
|
|
39
41
|
import type {
|
|
40
42
|
ModelCreateParams,
|
|
41
43
|
ModelDeleteParams,
|
|
@@ -128,7 +130,12 @@ export interface HttpModelClient<T, C = T> {
|
|
|
128
130
|
* Reads the rows matching a filter. Same resolution as `get`, in bulk,
|
|
129
131
|
* and deduplicated so concurrent identical calls share one request.
|
|
130
132
|
*/
|
|
131
|
-
|
|
133
|
+
/**
|
|
134
|
+
* The rows are an array as before; `hasMore` and `nextCursor` on the result
|
|
135
|
+
* say whether the collection continues past this page. Pass `nextCursor`
|
|
136
|
+
* back as `cursor`, with the same `where` and `orderBy`, to walk it.
|
|
137
|
+
*/
|
|
138
|
+
list(options?: ServerReadOptions<T>): Promise<ModelList<CapturedRow<T>>>;
|
|
132
139
|
/**
|
|
133
140
|
* Creates a row and returns it, including any framework-applied defaults.
|
|
134
141
|
* Passing an id that already exists is idempotent: the existing row is
|
|
@@ -427,10 +434,16 @@ function createHttpModelClient<T, C = T>(
|
|
|
427
434
|
return read.data as CapturedRow<T> | undefined;
|
|
428
435
|
};
|
|
429
436
|
|
|
430
|
-
const list = async (
|
|
437
|
+
const list = async (
|
|
438
|
+
options?: ServerReadOptions<T>,
|
|
439
|
+
): Promise<ModelList<CapturedRow<T>>> => {
|
|
431
440
|
const snapshot = await protocol.list(options);
|
|
441
|
+
const page = modelList<CapturedRow<T>>(
|
|
442
|
+
snapshot.data as readonly CapturedRow<T>[],
|
|
443
|
+
snapshot,
|
|
444
|
+
);
|
|
432
445
|
const registry = readSetContext?.getStore();
|
|
433
|
-
if (!registry) return
|
|
446
|
+
if (!registry) return page;
|
|
434
447
|
if (!snapshot.evidence) {
|
|
435
448
|
throw new AbloConnectionError(
|
|
436
449
|
`${modelName}.list did not return row evidence. Upgrade the Ablo server or use get({ id }).`,
|
|
@@ -451,7 +464,7 @@ function createHttpModelClient<T, C = T>(
|
|
|
451
464
|
}
|
|
452
465
|
capturePointRead(readSetContext, clientIdentity, modelName, id, row, stamp);
|
|
453
466
|
}
|
|
454
|
-
return
|
|
467
|
+
return page;
|
|
455
468
|
};
|
|
456
469
|
|
|
457
470
|
// Claim acquisition performs its authoritative read only after the grant.
|
|
@@ -84,6 +84,7 @@ import type {
|
|
|
84
84
|
ModelMutationOptions,
|
|
85
85
|
ModelReadOptions,
|
|
86
86
|
HttpTransportRead,
|
|
87
|
+
HttpTransportList,
|
|
87
88
|
HttpLogsResource,
|
|
88
89
|
ModelTarget,
|
|
89
90
|
CreateSessionParams,
|
|
@@ -151,6 +152,7 @@ import { declaredMeta, wireMeta } from '../coordination/claimMeta.js';
|
|
|
151
152
|
import type { Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim } from '../types/streams.js';
|
|
152
153
|
import type { CoordinationObservability } from '../observability.js';
|
|
153
154
|
import { assertWriteOptions } from '../resources/writeOptionsSchema.js';
|
|
155
|
+
import { normalizeWhere } from '../resources/where.js';
|
|
154
156
|
import {
|
|
155
157
|
createDurableHttpCommitEnvelope,
|
|
156
158
|
canonicalHttpCommitBody,
|
|
@@ -1493,9 +1495,12 @@ export function createHttpTransport(options: HttpTransportOptions): HttpTranspor
|
|
|
1493
1495
|
async function listModel<T>(
|
|
1494
1496
|
modelName: string,
|
|
1495
1497
|
options?: ServerReadOptions<T>,
|
|
1496
|
-
): Promise<
|
|
1498
|
+
): Promise<HttpTransportList<T>> {
|
|
1497
1499
|
const params = new URLSearchParams();
|
|
1498
1500
|
if (options?.limit !== undefined) params.set('limit', String(options.limit));
|
|
1501
|
+
if (options?.cursor !== undefined) {
|
|
1502
|
+
params.set('cursor', options.cursor);
|
|
1503
|
+
}
|
|
1499
1504
|
if (options?.orderBy) {
|
|
1500
1505
|
const [col, dir] = Object.entries(options.orderBy)[0] ?? [];
|
|
1501
1506
|
if (col) {
|
|
@@ -1503,12 +1508,27 @@ export function createHttpTransport(options: HttpTransportOptions): HttpTranspor
|
|
|
1503
1508
|
if (dir === 'desc') params.set('order', 'desc');
|
|
1504
1509
|
}
|
|
1505
1510
|
}
|
|
1506
|
-
// The
|
|
1507
|
-
//
|
|
1508
|
-
//
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1511
|
+
// The whole filter travels as the canonical clause list, so every operator
|
|
1512
|
+
// the grammar declares survives the trip. The previous encoding walked the
|
|
1513
|
+
// object's own entries and skipped any value that was an object, which
|
|
1514
|
+
// silently discarded `IN` filters and every tuple-form clause: the request
|
|
1515
|
+
// went out unfiltered and the caller read the result as a filtered one.
|
|
1516
|
+
const clauses = normalizeWhere(options?.where);
|
|
1517
|
+
if (clauses.length > 0) {
|
|
1518
|
+
params.set('where', JSON.stringify(clauses));
|
|
1519
|
+
// Plain equality also goes out in the older `?column=value` shorthand.
|
|
1520
|
+
// A server that predates the `where` parameter does not reserve the name
|
|
1521
|
+
// and does not declare it as a column, so it skips it — and a dropped
|
|
1522
|
+
// filter is not an error there, it is a wider answer than the caller
|
|
1523
|
+
// asked for. Sending both means a version skew loses only the operator
|
|
1524
|
+
// filters, which that server could not have honoured anyway. A current
|
|
1525
|
+
// server ignores a shorthand key the clause list already carries.
|
|
1526
|
+
for (const clause of clauses) {
|
|
1527
|
+
const [column] = clause;
|
|
1528
|
+
const value = clause.length === 2 ? clause[1] : clause[2];
|
|
1529
|
+
if (clause.length === 3 && clause[1] !== '=') continue;
|
|
1530
|
+
if (value === null || typeof value === 'object') continue;
|
|
1531
|
+
params.set(column, String(value));
|
|
1512
1532
|
}
|
|
1513
1533
|
}
|
|
1514
1534
|
const qs = params.toString();
|
|
@@ -1523,6 +1543,8 @@ export function createHttpTransport(options: HttpTransportOptions): HttpTranspor
|
|
|
1523
1543
|
// the typed facade above, which holds the model's schema.
|
|
1524
1544
|
return {
|
|
1525
1545
|
data: res.data as T[],
|
|
1546
|
+
hasMore: res.has_more,
|
|
1547
|
+
nextCursor: res.next_cursor,
|
|
1526
1548
|
...(res.evidence ? { evidence: res.evidence } : {}),
|
|
1527
1549
|
};
|
|
1528
1550
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { z } from 'zod';
|
|
17
|
+
import { listEnvelopeSchema } from './listEnvelope.js';
|
|
17
18
|
// Composed, never restated: these are the artifact's own shapes, and a
|
|
18
19
|
// hand-written mirror here would be a second copy of the exact record this
|
|
19
20
|
// response exists to stop withholding.
|
|
@@ -45,16 +46,9 @@ export type ProjectResponse = z.infer<typeof projectResponseSchema>;
|
|
|
45
46
|
/**
|
|
46
47
|
* `GET /v1/projects`.
|
|
47
48
|
*
|
|
48
|
-
*
|
|
49
|
-
* are returned whole, so the route emits `data` with no `has_more`/`next_cursor`
|
|
50
|
-
* beside it. That divergence is real and this schema states it rather than
|
|
51
|
-
* describing a pagination the endpoint does not implement — adding the two
|
|
52
|
-
* fields is an API change, not a documentation fix.
|
|
49
|
+
* Uses the canonical paginated list envelope shared by every collection.
|
|
53
50
|
*/
|
|
54
|
-
export const projectListResponseSchema =
|
|
55
|
-
object: z.literal('list'),
|
|
56
|
-
data: z.array(projectResponseSchema).readonly(),
|
|
57
|
-
});
|
|
51
|
+
export const projectListResponseSchema = listEnvelopeSchema(projectResponseSchema);
|
|
58
52
|
export type ProjectListResponse = z.infer<typeof projectListResponseSchema>;
|
|
59
53
|
|
|
60
54
|
/** One minted key, returned exactly once — the plaintext is never readable again. */
|
package/src/wire/auth.ts
CHANGED
|
@@ -27,7 +27,7 @@ export type EphemeralKeyUser = z.infer<typeof ephemeralKeyUserSchema>;
|
|
|
27
27
|
* Only a secret key (`sk_`) may call this: a session cannot mint itself. By
|
|
28
28
|
* default the key mints into the caller's own organization; naming a different
|
|
29
29
|
* `organizationId` is the multi-tenant case and requires the
|
|
30
|
-
* `
|
|
30
|
+
* `organization:act-as` scope, which is the same privilege that allows
|
|
31
31
|
* binding the session's schema to another organization's project.
|
|
32
32
|
*/
|
|
33
33
|
export const ephemeralKeyRequestSchema = z.object({
|
|
@@ -35,7 +35,7 @@ export const ephemeralKeyRequestSchema = z.object({
|
|
|
35
35
|
user: ephemeralKeyUserSchema,
|
|
36
36
|
/**
|
|
37
37
|
* Mint into this organization instead of the caller's own. Requires the
|
|
38
|
-
* `
|
|
38
|
+
* `organization:act-as` scope — without it a secret key can never mint a
|
|
39
39
|
* session into another tenant.
|
|
40
40
|
*/
|
|
41
41
|
organizationId: z.string().min(1).optional(),
|
|
@@ -43,7 +43,7 @@ export const ephemeralKeyRequestSchema = z.object({
|
|
|
43
43
|
* Override the shared project used to resolve this session's schema while
|
|
44
44
|
* its data stays scoped to the target organization. A cross-organization
|
|
45
45
|
* mint defaults both coordinates to the caller key's own project. Both
|
|
46
|
-
* fields are set together, and both require `
|
|
46
|
+
* fields are set together, and both require `organization:act-as`.
|
|
47
47
|
*/
|
|
48
48
|
schemaProjectId: z.string().min(1).optional(),
|
|
49
49
|
schemaOwnerOrgId: z.string().min(1).optional(),
|
package/src/wire/claims.ts
CHANGED
|
@@ -121,7 +121,13 @@ export const listQuerySchema = z.object({
|
|
|
121
121
|
limit: z.string().optional(),
|
|
122
122
|
order_by: z.string().optional(),
|
|
123
123
|
order: z.enum(['asc', 'desc']).optional(),
|
|
124
|
-
/**
|
|
124
|
+
/**
|
|
125
|
+
* Keyset cursor: the opaque `next_cursor` the previous page returned. It
|
|
126
|
+
* encodes the sort position it was issued for, so it is not a row id and is
|
|
127
|
+
* refused against a different `order_by`/`order`.
|
|
128
|
+
*/
|
|
129
|
+
cursor: z.string().optional(),
|
|
130
|
+
/** @deprecated The pre-0.53.0 spelling of `cursor`. Send `cursor`. */
|
|
125
131
|
starting_after: z.string().optional(),
|
|
126
132
|
});
|
|
127
133
|
export type ListQuery = z.infer<typeof listQuerySchema>;
|
package/src/wire/index.ts
CHANGED
|
@@ -22,7 +22,13 @@ export {
|
|
|
22
22
|
INTERNAL_ERROR_PUBLIC_MESSAGE,
|
|
23
23
|
} from './errorEnvelope.js';
|
|
24
24
|
export type { ErrorEnvelope } from './errorEnvelope.js';
|
|
25
|
-
export {
|
|
25
|
+
export {
|
|
26
|
+
listEnvelopeSchema,
|
|
27
|
+
listEnvelope,
|
|
28
|
+
CURSOR_PARAM,
|
|
29
|
+
CURSOR_PARAM_ALIAS,
|
|
30
|
+
CURSOR_PARAM_NAMES,
|
|
31
|
+
} from './listEnvelope.js';
|
|
26
32
|
export type { ListEnvelope } from './listEnvelope.js';
|
|
27
33
|
|
|
28
34
|
// The `GET /v1/logs` feed — the two arms, their envelope, and the cursor that
|
package/src/wire/listEnvelope.ts
CHANGED
|
@@ -10,6 +10,29 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* The query parameter a caller resumes a collection with, and the single alias
|
|
15
|
+
* retained for it.
|
|
16
|
+
*
|
|
17
|
+
* Declared beside the envelope that issues `next_cursor`, because the parameter
|
|
18
|
+
* and the field it consumes are one contract and both planes read them: the
|
|
19
|
+
* server to know which names are taken, the spec generator to document them,
|
|
20
|
+
* the client to send one. When the name lived in each of those separately, this
|
|
21
|
+
* spec described `starting_after` for a model list and `cursor` for a commit
|
|
22
|
+
* record list — the same concept under two names, in one document.
|
|
23
|
+
*
|
|
24
|
+
* `starting_after` is the spelling used through 0.52.0. It borrowed a name whose
|
|
25
|
+
* established meaning elsewhere is a row id, while this value has always been an
|
|
26
|
+
* opaque token bound to the sort it was issued for.
|
|
27
|
+
*/
|
|
28
|
+
export const CURSOR_PARAM = 'cursor';
|
|
29
|
+
|
|
30
|
+
/** @deprecated The pre-0.53.0 spelling of {@link CURSOR_PARAM}. */
|
|
31
|
+
export const CURSOR_PARAM_ALIAS = 'starting_after';
|
|
32
|
+
|
|
33
|
+
/** Both names a cursor may arrive under, for reserving them in a query string. */
|
|
34
|
+
export const CURSOR_PARAM_NAMES: readonly string[] = [CURSOR_PARAM, CURSOR_PARAM_ALIAS];
|
|
35
|
+
|
|
13
36
|
/**
|
|
14
37
|
* Builds the authoritative list-envelope schema for a row schema. Keeping the
|
|
15
38
|
* item validator generic lets every endpoint share the same envelope contract
|