primitive-admin 1.2.0-alpha.2 → 1.2.0-alpha.4
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/src/commands/agent-sessions.js +4 -0
- package/dist/src/commands/agent-sessions.js.map +1 -1
- package/dist/src/commands/databases.js +13 -38
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.d.ts +1 -1
- package/dist/src/commands/documents.js +70 -33
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/prompts.d.ts +7 -0
- package/dist/src/commands/prompts.js +44 -0
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/sync.d.ts +12 -29
- package/dist/src/commands/sync.js +128 -138
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/lib/aggregate-output.d.ts +25 -0
- package/dist/src/lib/aggregate-output.js +53 -0
- package/dist/src/lib/aggregate-output.js.map +1 -0
- package/dist/src/lib/api-client.d.ts +29 -16
- package/dist/src/lib/api-client.js +30 -28
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/config-object-descriptor.js +14 -5
- package/dist/src/lib/config-object-descriptor.js.map +1 -1
- package/dist/src/lib/db-codegen/dbGenerator.js +5 -16
- package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -1
- package/dist/src/lib/db-codegen/dbNaming.d.ts +3 -12
- package/dist/src/lib/db-codegen/dbNaming.js +3 -16
- package/dist/src/lib/db-codegen/dbNaming.js.map +1 -1
- package/dist/src/lib/db-codegen/dbTemplates.d.ts +7 -56
- package/dist/src/lib/db-codegen/dbTemplates.js +25 -125
- package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -1
- package/dist/src/lib/db-codegen/dbTypeIR.d.ts +1 -1
- package/dist/src/lib/function-sync.d.ts +3 -16
- package/dist/src/lib/function-sync.js +14 -18
- package/dist/src/lib/function-sync.js.map +1 -1
- package/dist/src/lib/generated-config-surfaces.d.ts +172 -47
- package/dist/src/lib/generated-config-surfaces.js +599 -90
- package/dist/src/lib/generated-config-surfaces.js.map +1 -1
- package/dist/src/lib/generated-sdk-types.d.ts +1 -1
- package/dist/src/lib/generated-sdk-types.js +1 -1
- package/dist/src/lib/generated-sdk-types.js.map +1 -1
- package/dist/src/lib/prompt-schema-codegen.js +5 -2
- package/dist/src/lib/prompt-schema-codegen.js.map +1 -1
- package/dist/src/lib/swift-codegen/dbGenerator.d.ts +4 -3
- package/dist/src/lib/swift-codegen/dbGenerator.js +14 -117
- package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -1
- package/dist/src/lib/swift-codegen/generator.d.ts +5 -5
- package/dist/src/lib/swift-codegen/generator.js +8 -13
- package/dist/src/lib/swift-codegen/generator.js.map +1 -1
- package/dist/src/lib/workflow-codegen/generator.d.ts +7 -7
- package/dist/src/lib/workflow-codegen/generator.js +16 -23
- package/dist/src/lib/workflow-codegen/generator.js.map +1 -1
- package/dist/src/lib/workflow-codegen/invokerIR.d.ts +6 -12
- package/dist/src/lib/workflow-codegen/invokerIR.js +4 -5
- package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -1
- package/dist/src/lib/workflow-toml-validator.d.ts +2 -0
- package/dist/src/lib/workflow-toml-validator.js +13 -0
- package/dist/src/lib/workflow-toml-validator.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** One aggregate row as the routes answer it. */
|
|
2
|
+
export interface AggregateOutputRow {
|
|
3
|
+
group?: Record<string, unknown>;
|
|
4
|
+
[operationKey: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
/** What the command asked for: the group levels and its one operation. */
|
|
7
|
+
export interface AggregateOutputRequest {
|
|
8
|
+
groupBy: string[];
|
|
9
|
+
op: string;
|
|
10
|
+
field?: string;
|
|
11
|
+
}
|
|
12
|
+
/** A rendered aggregate: a key/value line, or a ready-to-print table. */
|
|
13
|
+
export type RenderedAggregate = {
|
|
14
|
+
kind: "scalar";
|
|
15
|
+
label: string;
|
|
16
|
+
value: string;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "table";
|
|
19
|
+
text: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Render an aggregate's rows for a terminal. `rows` is the route body's
|
|
23
|
+
* `result`; anything that is not an array renders as no rows.
|
|
24
|
+
*/
|
|
25
|
+
export declare function renderAggregateResult(rows: unknown, request: AggregateOutputRequest): RenderedAggregate;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human output for `databases records aggregate` and
|
|
3
|
+
* `documents records aggregate`, shared so the two print alike.
|
|
4
|
+
*
|
|
5
|
+
* Both routes answer rows, `{ group, ...operationValues }`. Ungrouped, the one
|
|
6
|
+
* row's value is printed as a key/value line; grouped, as a table with one
|
|
7
|
+
* column per row group key and one value column. A `null` group value prints
|
|
8
|
+
* as `null` so it stays distinct from an empty string (an empty cell); a
|
|
9
|
+
* `null` operation value prints `—`.
|
|
10
|
+
*/
|
|
11
|
+
import { formatTable } from "./output.js";
|
|
12
|
+
const display = (value) => value === null || value === undefined ? "—" : String(value);
|
|
13
|
+
/**
|
|
14
|
+
* Render an aggregate's rows for a terminal. `rows` is the route body's
|
|
15
|
+
* `result`; anything that is not an array renders as no rows.
|
|
16
|
+
*/
|
|
17
|
+
export function renderAggregateResult(rows, request) {
|
|
18
|
+
const list = Array.isArray(rows) ? rows : [];
|
|
19
|
+
const operationKey = request.op === "count" ? "count" : `${request.op}_${request.field}`;
|
|
20
|
+
if (request.groupBy.length === 0) {
|
|
21
|
+
// The field name is reproduced verbatim in both labels — it is a
|
|
22
|
+
// user-supplied identifier, and case-folding it produced
|
|
23
|
+
// `avg(lastvalue)` for `--field lastValue` (issue #2357).
|
|
24
|
+
return {
|
|
25
|
+
kind: "scalar",
|
|
26
|
+
label: request.op === "count"
|
|
27
|
+
? "count"
|
|
28
|
+
: `${request.op.toLowerCase()}(${request.field})`,
|
|
29
|
+
value: display(list[0]?.[operationKey]),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const groupKeys = list.length > 0 ? Object.keys(list[0].group ?? {}) : request.groupBy;
|
|
33
|
+
const valueLabel = request.op === "count"
|
|
34
|
+
? "COUNT"
|
|
35
|
+
: `${request.op.toUpperCase()}(${request.field})`;
|
|
36
|
+
const table = list.map((row) => {
|
|
37
|
+
const cells = {};
|
|
38
|
+
groupKeys.forEach((key, index) => {
|
|
39
|
+
const value = row.group?.[key];
|
|
40
|
+
cells[`g${index}`] = value === null || value === undefined ? "null" : String(value);
|
|
41
|
+
});
|
|
42
|
+
cells.value = display(row[operationKey]);
|
|
43
|
+
return cells;
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
kind: "table",
|
|
47
|
+
text: formatTable(table, [
|
|
48
|
+
...groupKeys.map((key, index) => ({ header: key.toUpperCase(), key: `g${index}` })),
|
|
49
|
+
{ header: valueLabel, key: "value" },
|
|
50
|
+
]),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=aggregate-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-output.js","sourceRoot":"","sources":["../../../src/lib/aggregate-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAoB1C,MAAM,OAAO,GAAG,CAAC,KAAc,EAAU,EAAE,CACzC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAa,EACb,OAA+B;IAE/B,MAAM,IAAI,GAAyB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,YAAY,GAChB,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAEtE,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,iEAAiE;QACjE,yDAAyD;QACzD,0DAA0D;QAC1D,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,KAAK,EACH,OAAO,CAAC,EAAE,KAAK,OAAO;gBACpB,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,KAAK,GAAG;YACrD,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;SACxC,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACvF,MAAM,UAAU,GACd,OAAO,CAAC,EAAE,KAAK,OAAO;QACpB,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC;IACtD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7B,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YAC/B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;YAC/B,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtF,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IACH,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,WAAW,CAAC,KAAK,EAAE;YACvB,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;YACnF,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE;SACrC,CAAC;KACH,CAAC;AACJ,CAAC"}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { type ListEnvelope } from "./paginate.js";
|
|
2
2
|
import { type GlobalAppRef, type WorkflowUsageReport } from "./workflow-usage.js";
|
|
3
|
+
/**
|
|
4
|
+
* #4262 — an agent prompt's test case: its `[test.agent]` block on the wire.
|
|
5
|
+
* `agentHistory` is JSON text; context and the expected call are parsed.
|
|
6
|
+
*/
|
|
7
|
+
export interface AgentTestCaseWireFields {
|
|
8
|
+
agentHistory?: string | null;
|
|
9
|
+
agentContext?: Record<string, any> | null;
|
|
10
|
+
agentTimezone?: string | null;
|
|
11
|
+
agentLocale?: string | null;
|
|
12
|
+
agentExpectedToolCall?: Record<string, any> | null;
|
|
13
|
+
agentExpectedNoToolCall?: boolean | null;
|
|
14
|
+
}
|
|
3
15
|
/**
|
|
4
16
|
* Metadata for a single bucket blob, as returned by the metadata endpoint
|
|
5
17
|
* `GET blob-buckets/:bucketId/blobs/:blobId/metadata`. Mirrors the published
|
|
@@ -1358,7 +1370,7 @@ export declare class ApiClient {
|
|
|
1358
1370
|
evaluatorConfigId?: string;
|
|
1359
1371
|
/** The sidecar's file name — the case's identity (#2896). */
|
|
1360
1372
|
key?: string;
|
|
1361
|
-
}): Promise<any>;
|
|
1373
|
+
} & AgentTestCaseWireFields): Promise<any>;
|
|
1362
1374
|
updateTestCase(appId: string, blockType: "prompt" | "integration" | "workflow" | "script", blockId: string, testCaseId: string, payload: {
|
|
1363
1375
|
name?: string;
|
|
1364
1376
|
description?: string | null;
|
|
@@ -1371,7 +1383,7 @@ export declare class ApiClient {
|
|
|
1371
1383
|
evaluatorConfigId?: string | null;
|
|
1372
1384
|
/** The sidecar's file name, on a create-or-rename backfill (#2896). */
|
|
1373
1385
|
key?: string;
|
|
1374
|
-
}): Promise<any>;
|
|
1386
|
+
} & AgentTestCaseWireFields): Promise<any>;
|
|
1375
1387
|
deleteTestCase(appId: string, blockType: "prompt" | "integration" | "workflow" | "script", blockId: string, testCaseId: string): Promise<void>;
|
|
1376
1388
|
listTestCaseAttachments(appId: string, blockType: "prompt" | "integration" | "workflow" | "script", blockId: string, testCaseId: string): Promise<{
|
|
1377
1389
|
attachments: Array<{
|
|
@@ -1863,7 +1875,7 @@ export declare class ApiClient {
|
|
|
1863
1875
|
limit?: number;
|
|
1864
1876
|
cursor?: string;
|
|
1865
1877
|
direction?: number;
|
|
1866
|
-
},
|
|
1878
|
+
}, options?: {
|
|
1867
1879
|
timing?: boolean;
|
|
1868
1880
|
}): Promise<any>;
|
|
1869
1881
|
/**
|
|
@@ -1881,11 +1893,6 @@ export declare class ApiClient {
|
|
|
1881
1893
|
imported: number;
|
|
1882
1894
|
failed: number;
|
|
1883
1895
|
}>;
|
|
1884
|
-
/**
|
|
1885
|
-
* Make a request using a specific JWT token instead of the CLI's credentials.
|
|
1886
|
-
* Used for executing operations as a different user.
|
|
1887
|
-
*/
|
|
1888
|
-
requestWithToken<T = any>(path: string, token: string, options?: RequestInit): Promise<T>;
|
|
1889
1896
|
listDatabaseIndexes(appId: string, databaseId: string, modelName?: string): Promise<any>;
|
|
1890
1897
|
registerDatabaseIndex(appId: string, databaseId: string, data: {
|
|
1891
1898
|
modelName: string;
|
|
@@ -2285,14 +2292,14 @@ export declare class ApiClient {
|
|
|
2285
2292
|
limit?: number;
|
|
2286
2293
|
cursor?: string;
|
|
2287
2294
|
/** #3764 — the format the caller believes this document has. */
|
|
2288
|
-
documentFormat?: 1 | 2;
|
|
2295
|
+
documentFormat?: 1 | 2 | 3;
|
|
2289
2296
|
}): Promise<ListEnvelope>;
|
|
2290
2297
|
/**
|
|
2291
2298
|
* Count records in a document model (issue #1964 Phase 3). Returns `{ count }`.
|
|
2292
2299
|
*/
|
|
2293
2300
|
countDocumentRecords(appId: string, documentId: string, modelName: string, queryOptions?: {
|
|
2294
2301
|
filter?: Record<string, any>;
|
|
2295
|
-
documentFormat?: 1 | 2;
|
|
2302
|
+
documentFormat?: 1 | 2 | 3;
|
|
2296
2303
|
}): Promise<{
|
|
2297
2304
|
count: number;
|
|
2298
2305
|
}>;
|
|
@@ -2314,7 +2321,7 @@ export declare class ApiClient {
|
|
|
2314
2321
|
groupBy?: string[];
|
|
2315
2322
|
filter?: Record<string, any>;
|
|
2316
2323
|
}, extra?: {
|
|
2317
|
-
documentFormat?: 1 | 2;
|
|
2324
|
+
documentFormat?: 1 | 2 | 3;
|
|
2318
2325
|
}): Promise<{
|
|
2319
2326
|
result: unknown;
|
|
2320
2327
|
}>;
|
|
@@ -2323,6 +2330,12 @@ export declare class ApiClient {
|
|
|
2323
2330
|
* record/model/blob counts, approximate size, and last-modified timestamp.
|
|
2324
2331
|
*/
|
|
2325
2332
|
getDocumentStats(appId: string, documentId: string): Promise<any>;
|
|
2333
|
+
/**
|
|
2334
|
+
* A record-log document's room (#4306): `GET documents/:id/room` →
|
|
2335
|
+
* `{ ok, appId, documentId, documentFormat, room }`, `room` null for a
|
|
2336
|
+
* format that has no record room. App admins only.
|
|
2337
|
+
*/
|
|
2338
|
+
getDocumentRoom(appId: string, documentId: string): Promise<any>;
|
|
2326
2339
|
/**
|
|
2327
2340
|
* A large document's snapshot builds, newest first, one page (#3432).
|
|
2328
2341
|
* `GET documents/:id/snapshots` → `{ items, hasMore, nextCursor? }`.
|
|
@@ -2399,7 +2412,7 @@ export declare class ApiClient {
|
|
|
2399
2412
|
data: Record<string, unknown>;
|
|
2400
2413
|
options?: Record<string, unknown>;
|
|
2401
2414
|
}, extra?: {
|
|
2402
|
-
documentFormat?: 1 | 2;
|
|
2415
|
+
documentFormat?: 1 | 2 | 3;
|
|
2403
2416
|
}): Promise<{
|
|
2404
2417
|
record: unknown;
|
|
2405
2418
|
}>;
|
|
@@ -2412,7 +2425,7 @@ export declare class ApiClient {
|
|
|
2412
2425
|
data: Record<string, unknown>;
|
|
2413
2426
|
options?: Record<string, unknown>;
|
|
2414
2427
|
}, extra?: {
|
|
2415
|
-
documentFormat?: 1 | 2;
|
|
2428
|
+
documentFormat?: 1 | 2 | 3;
|
|
2416
2429
|
}): Promise<{
|
|
2417
2430
|
record: unknown;
|
|
2418
2431
|
}>;
|
|
@@ -2422,7 +2435,7 @@ export declare class ApiClient {
|
|
|
2422
2435
|
* a silent no-op per the facade contract. Returns `{ deleted: true }`.
|
|
2423
2436
|
*/
|
|
2424
2437
|
deleteDocumentRecord(appId: string, documentId: string, modelName: string, recordId: string, extra?: {
|
|
2425
|
-
documentFormat?: 1 | 2;
|
|
2438
|
+
documentFormat?: 1 | 2 | 3;
|
|
2426
2439
|
}): Promise<{
|
|
2427
2440
|
deleted: boolean;
|
|
2428
2441
|
}>;
|
|
@@ -2433,7 +2446,7 @@ export declare class ApiClient {
|
|
|
2433
2446
|
* `{ applied, added, updated, deleted }`.
|
|
2434
2447
|
*/
|
|
2435
2448
|
bulkDocumentRecords(appId: string, documentId: string, operations: Array<Record<string, unknown>>, extra?: {
|
|
2436
|
-
documentFormat?: 1 | 2;
|
|
2449
|
+
documentFormat?: 1 | 2 | 3;
|
|
2437
2450
|
}): Promise<{
|
|
2438
2451
|
applied: number;
|
|
2439
2452
|
added: Array<{
|
|
@@ -2457,7 +2470,7 @@ export declare class ApiClient {
|
|
|
2457
2470
|
documentId?: string;
|
|
2458
2471
|
tags?: string[];
|
|
2459
2472
|
createdBy?: string;
|
|
2460
|
-
documentFormat?: 1 | 2;
|
|
2473
|
+
documentFormat?: 1 | 2 | 3;
|
|
2461
2474
|
}): Promise<any>;
|
|
2462
2475
|
listDocumentPermissions(appId: string, documentId: string): Promise<any[]>;
|
|
2463
2476
|
grantDocumentPermission(appId: string, documentId: string, permissions: Array<{
|
|
@@ -11,6 +11,15 @@ import { drainAppsUntilConverged, } from "./workflow-usage.js";
|
|
|
11
11
|
* fewest round trips the contract allows; a larger value is clamped there.
|
|
12
12
|
*/
|
|
13
13
|
const ADMIN_INVENTORY_PAGE_SIZE = 100;
|
|
14
|
+
/** The agent block's wire keys, in the surface's order. */
|
|
15
|
+
const AGENT_TEST_CASE_WIRE_KEYS = [
|
|
16
|
+
"agentHistory",
|
|
17
|
+
"agentContext",
|
|
18
|
+
"agentTimezone",
|
|
19
|
+
"agentLocale",
|
|
20
|
+
"agentExpectedToolCall",
|
|
21
|
+
"agentExpectedNoToolCall",
|
|
22
|
+
];
|
|
14
23
|
export class ApiError extends Error {
|
|
15
24
|
statusCode;
|
|
16
25
|
code;
|
|
@@ -1529,6 +1538,13 @@ export class ApiClient {
|
|
|
1529
1538
|
if (payload.expectedJsonSubset) {
|
|
1530
1539
|
serverPayload.expectedJsonSubset = payload.expectedJsonSubset;
|
|
1531
1540
|
}
|
|
1541
|
+
// #4262 — an agent case's `[test.agent]` keys, each when the caller set it:
|
|
1542
|
+
// presence, not truthiness, so `agentExpectedNoToolCall: false` travels. A
|
|
1543
|
+
// chat case sets none, and its body is unchanged.
|
|
1544
|
+
for (const key of AGENT_TEST_CASE_WIRE_KEYS) {
|
|
1545
|
+
if (payload[key] !== undefined)
|
|
1546
|
+
serverPayload[key] = payload[key];
|
|
1547
|
+
}
|
|
1532
1548
|
return this.post(`/admin/api/apps/${appId}/blocks/${blockType}/${blockId}/test-cases`, serverPayload);
|
|
1533
1549
|
}
|
|
1534
1550
|
async updateTestCase(appId, blockType, blockId, testCaseId, payload) {
|
|
@@ -1563,6 +1579,11 @@ export class ApiClient {
|
|
|
1563
1579
|
}
|
|
1564
1580
|
if (payload.key !== undefined)
|
|
1565
1581
|
serverPayload.key = payload.key;
|
|
1582
|
+
// #4262 — as on create; an explicit `null` clears the field.
|
|
1583
|
+
for (const key of AGENT_TEST_CASE_WIRE_KEYS) {
|
|
1584
|
+
if (payload[key] !== undefined)
|
|
1585
|
+
serverPayload[key] = payload[key];
|
|
1586
|
+
}
|
|
1566
1587
|
return this.patch(`/admin/api/apps/${appId}/blocks/${blockType}/${blockId}/test-cases/${testCaseId}`, serverPayload);
|
|
1567
1588
|
}
|
|
1568
1589
|
async deleteTestCase(appId, blockType, blockId, testCaseId) {
|
|
@@ -2140,19 +2161,12 @@ export class ApiClient {
|
|
|
2140
2161
|
* else (a `count`, an `aggregate`, a mutation, a `returnField: "all"`
|
|
2141
2162
|
* pipeline) is returned exactly as the server sent it.
|
|
2142
2163
|
*/
|
|
2143
|
-
async executeDatabaseOperation(appId, databaseId, operationName, data,
|
|
2164
|
+
async executeDatabaseOperation(appId, databaseId, operationName, data, options) {
|
|
2144
2165
|
const path = `/app/${appId}/api/databases/${databaseId}/operations/${encodeURIComponent(operationName)}/execute`;
|
|
2145
2166
|
const extraHeaders = {};
|
|
2146
2167
|
if (options?.timing) {
|
|
2147
2168
|
extraHeaders["X-Timing"] = "true";
|
|
2148
2169
|
}
|
|
2149
|
-
if (token) {
|
|
2150
|
-
return normalizeDatabaseOperationResult(await this.requestWithToken(path, token, {
|
|
2151
|
-
method: "POST",
|
|
2152
|
-
body: JSON.stringify(data || {}),
|
|
2153
|
-
headers: extraHeaders,
|
|
2154
|
-
}));
|
|
2155
|
-
}
|
|
2156
2170
|
return normalizeDatabaseOperationResult(await this.request(path, {
|
|
2157
2171
|
method: "POST",
|
|
2158
2172
|
body: JSON.stringify(data || {}),
|
|
@@ -2171,26 +2185,6 @@ export class ApiClient {
|
|
|
2171
2185
|
async executeBatch(appId, databaseId, operationName, batch) {
|
|
2172
2186
|
return this.post(`/app/${appId}/api/databases/${databaseId}/operations/${encodeURIComponent(operationName)}/batch`, { batch });
|
|
2173
2187
|
}
|
|
2174
|
-
/**
|
|
2175
|
-
* Make a request using a specific JWT token instead of the CLI's credentials.
|
|
2176
|
-
* Used for executing operations as a different user.
|
|
2177
|
-
*/
|
|
2178
|
-
async requestWithToken(path, token, options = {}) {
|
|
2179
|
-
const credentials = await this.ensureAuthenticated();
|
|
2180
|
-
const url = `${credentials.serverUrl}${path}`;
|
|
2181
|
-
const headers = {
|
|
2182
|
-
Authorization: `Bearer ${token}`,
|
|
2183
|
-
"Content-Type": "application/json",
|
|
2184
|
-
...(options.headers || {}),
|
|
2185
|
-
};
|
|
2186
|
-
const response = await fetchWithTLS(url, { ...options, headers });
|
|
2187
|
-
const text = await response.text();
|
|
2188
|
-
if (!response.ok) {
|
|
2189
|
-
const parsed = parseErrorResponse(response, text, path);
|
|
2190
|
-
throw new ApiError(parsed.message, response.status, parsed.code, parsed.details);
|
|
2191
|
-
}
|
|
2192
|
-
return text ? JSON.parse(text) : null;
|
|
2193
|
-
}
|
|
2194
2188
|
// ============================================
|
|
2195
2189
|
// DATABASE INDEXES
|
|
2196
2190
|
// ============================================
|
|
@@ -2796,6 +2790,14 @@ export class ApiClient {
|
|
|
2796
2790
|
async getDocumentStats(appId, documentId) {
|
|
2797
2791
|
return this.get(`/app/${appId}/api/documents/${documentId}/stats`);
|
|
2798
2792
|
}
|
|
2793
|
+
/**
|
|
2794
|
+
* A record-log document's room (#4306): `GET documents/:id/room` →
|
|
2795
|
+
* `{ ok, appId, documentId, documentFormat, room }`, `room` null for a
|
|
2796
|
+
* format that has no record room. App admins only.
|
|
2797
|
+
*/
|
|
2798
|
+
async getDocumentRoom(appId, documentId) {
|
|
2799
|
+
return this.get(`/app/${appId}/api/documents/${documentId}/room`);
|
|
2800
|
+
}
|
|
2799
2801
|
/**
|
|
2800
2802
|
* A large document's snapshot builds, newest first, one page (#3432).
|
|
2801
2803
|
* `GET documents/:id/snapshots` → `{ items, hasMore, nextCursor? }`.
|