busa-cli 0.11.0 → 0.11.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/bin/busabase-cli.mjs +4 -7
- package/dist/{chunk-QJJMAA3K.js → chunk-CEH54HWM.js} +731 -595
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
|
@@ -126,6 +126,11 @@ import { basename as basename2, extname as extname2 } from "path";
|
|
|
126
126
|
|
|
127
127
|
// ../../packages/busabase-contract/src/tasks/base-field.ts
|
|
128
128
|
var OPERATIONS = ["add", "update", "delete", "convert", "reorder", "restore"];
|
|
129
|
+
var mergeIntent = (input) => {
|
|
130
|
+
if (input.requireReview) return { autoMerge: false };
|
|
131
|
+
if (input.autoMerge) return { autoMerge: true };
|
|
132
|
+
return {};
|
|
133
|
+
};
|
|
129
134
|
var REQUIRED_BY_OPERATION = {
|
|
130
135
|
add: ["slug", "name"],
|
|
131
136
|
update: ["fieldId", "patch"],
|
|
@@ -147,7 +152,7 @@ var baseFieldChangeTask = {
|
|
|
147
152
|
name: "base_field_change_request",
|
|
148
153
|
cliPath: ["bases", "field-change-request"],
|
|
149
154
|
summary: "Propose a Base schema change (add / update / delete / convert / reorder / restore)",
|
|
150
|
-
guidance: "
|
|
155
|
+
guidance: "Review is permission-aware for add / update / reorder / restore, decided server-side: the change merges immediately when your key has write access on the Base's node and lands as a pending ChangeRequest otherwise \u2014 check the response's `status`. Pass requireReview to always propose instead. `delete` and `convert` are ALWAYS review-first regardless of permission, by design: delete soft-deletes the field's stored values with it, and convert can drop values. Pick `operation` first, then supply only that operation's arguments \u2014 add needs slug+name; update needs fieldId+patch; delete/restore need fieldId; convert needs fieldId+newType; reorder needs the complete fieldIds order. Before a convert, `bases_preview_field_conversion` shows what the data would become.",
|
|
151
156
|
annotations: { readOnly: false, destructive: false },
|
|
152
157
|
params: [
|
|
153
158
|
{ name: "baseId", kind: "string", required: true, description: "Base to change." },
|
|
@@ -220,7 +225,19 @@ var baseFieldChangeTask = {
|
|
|
220
225
|
description: "Complete field order (reorder only). Repeat the flag per field."
|
|
221
226
|
},
|
|
222
227
|
{ name: "message", kind: "string", description: "Explanation for the reviewer." },
|
|
223
|
-
{ name: "submittedBy", kind: "string", description: "Producer label recorded on the change." }
|
|
228
|
+
{ name: "submittedBy", kind: "string", description: "Producer label recorded on the change." },
|
|
229
|
+
{
|
|
230
|
+
name: "autoMerge",
|
|
231
|
+
kind: "boolean",
|
|
232
|
+
appliesWhen: { param: "operation", values: ["add", "update", "reorder", "restore"] },
|
|
233
|
+
description: "Skip review and apply the schema change immediately if you have write access. Not a permission override \u2014 a changeRequest-level key still gets a pending CR. Default is permission-aware: merge when you can, otherwise propose."
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: "requireReview",
|
|
237
|
+
kind: "boolean",
|
|
238
|
+
appliesWhen: { param: "operation", values: ["add", "update", "reorder", "restore"] },
|
|
239
|
+
description: "Always propose a pending ChangeRequest, even with write access. delete and convert are review-first regardless."
|
|
240
|
+
}
|
|
224
241
|
],
|
|
225
242
|
examples: [
|
|
226
243
|
"busabase-cli bases field-change-request --base-id bas_1 --operation add --slug status --name Status --field-type select",
|
|
@@ -232,7 +249,8 @@ var baseFieldChangeTask = {
|
|
|
232
249
|
const common = {
|
|
233
250
|
baseId: input.baseId,
|
|
234
251
|
...input.message ? { message: input.message } : {},
|
|
235
|
-
...input.submittedBy ? { submittedBy: input.submittedBy } : {}
|
|
252
|
+
...input.submittedBy ? { submittedBy: input.submittedBy } : {},
|
|
253
|
+
...mergeIntent(input)
|
|
236
254
|
};
|
|
237
255
|
switch (input.operation) {
|
|
238
256
|
case "add":
|
|
@@ -557,6 +575,11 @@ var nodeReadFileTask = {
|
|
|
557
575
|
type: resolveKind(input.kind)
|
|
558
576
|
})
|
|
559
577
|
};
|
|
578
|
+
var mergeIntent2 = (input) => {
|
|
579
|
+
if (input.requireReview) return { autoMerge: false };
|
|
580
|
+
if (input.autoMerge) return { autoMerge: true };
|
|
581
|
+
return {};
|
|
582
|
+
};
|
|
560
583
|
var nodeFilesChangeRequestTask = {
|
|
561
584
|
name: "node_files_change_request",
|
|
562
585
|
cliPath: ["nodes", "files-change-request"],
|
|
@@ -578,7 +601,7 @@ var nodeFilesChangeRequestTask = {
|
|
|
578
601
|
}
|
|
579
602
|
],
|
|
580
603
|
summary: "Propose file changes inside a Skill, Drive, or AirApp node",
|
|
581
|
-
guidance: '
|
|
604
|
+
guidance: 'Review is permission-aware, decided server-side: the change merges immediately when your key has write access on the node and lands as a pending ChangeRequest otherwise \u2014 check the response\'s `status`. Pass requireReview to always propose instead. A batch containing a `delete` is ALWAYS review-first regardless of permission, by design \u2014 deleting a mounted file destroys content, and a batch is never partially merged. Each operation is one of create / update / delete / metadata_update. Include `baseContentHash` (from `node_file_read`) on an update so a concurrent edit is caught. For kind "airapp", keep the project runnable by `npm run dev` \u2014 editing package.json must leave a "dev" script starting a plain Node server, not a bundler dev server.',
|
|
582
605
|
annotations: { readOnly: false, destructive: false },
|
|
583
606
|
params: [
|
|
584
607
|
kindParam,
|
|
@@ -594,10 +617,21 @@ var nodeFilesChangeRequestTask = {
|
|
|
594
617
|
kind: "string",
|
|
595
618
|
description: 'Explanation for the reviewer. Conventional-commit style, e.g. "Rewrite README quickstart for the new auth flow".'
|
|
596
619
|
},
|
|
597
|
-
{ name: "submittedBy", kind: "string", description: "Producer label recorded on the change." }
|
|
620
|
+
{ name: "submittedBy", kind: "string", description: "Producer label recorded on the change." },
|
|
621
|
+
{
|
|
622
|
+
name: "autoMerge",
|
|
623
|
+
kind: "boolean",
|
|
624
|
+
description: "Skip review and apply the file changes immediately if you have write access. Not a permission override, and ignored for a batch containing a delete. Default is permission-aware: merge when you can, otherwise propose."
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
name: "requireReview",
|
|
628
|
+
kind: "boolean",
|
|
629
|
+
description: "Always propose a pending ChangeRequest, even with write access."
|
|
630
|
+
}
|
|
598
631
|
],
|
|
599
632
|
examples: [
|
|
600
|
-
`busabase-cli nodes files-change-request --kind skill --node-id nod_123 --operations-json '[{"kind":"update","path":"SKILL.md","content":"# Hi"}]'
|
|
633
|
+
`busabase-cli nodes files-change-request --kind skill --node-id nod_123 --operations-json '[{"kind":"update","path":"SKILL.md","content":"# Hi"}]'`,
|
|
634
|
+
"busabase-cli nodes files-change-request --kind skill --node-id nod_123 --operations-json @ops.json --require-review"
|
|
601
635
|
],
|
|
602
636
|
execute: async (client, input) => {
|
|
603
637
|
if (!Array.isArray(input.operations) || input.operations.length === 0) {
|
|
@@ -608,7 +642,8 @@ var nodeFilesChangeRequestTask = {
|
|
|
608
642
|
type: resolveKind(input.kind),
|
|
609
643
|
operations: input.operations,
|
|
610
644
|
...input.message ? { message: input.message } : {},
|
|
611
|
-
...input.submittedBy ? { submittedBy: input.submittedBy } : {}
|
|
645
|
+
...input.submittedBy ? { submittedBy: input.submittedBy } : {},
|
|
646
|
+
...mergeIntent2(input)
|
|
612
647
|
};
|
|
613
648
|
return client.fileTrees.createChangeRequest(payload);
|
|
614
649
|
}
|
|
@@ -1119,7 +1154,7 @@ var rejectMismatchedPayload = (input) => {
|
|
|
1119
1154
|
);
|
|
1120
1155
|
}
|
|
1121
1156
|
};
|
|
1122
|
-
var
|
|
1157
|
+
var mergeIntent3 = (input) => {
|
|
1123
1158
|
if (input.requireReview) return { autoMerge: false };
|
|
1124
1159
|
if (input.autoMerge) return { autoMerge: true };
|
|
1125
1160
|
return {};
|
|
@@ -1248,7 +1283,7 @@ var nodeCreateTask = {
|
|
|
1248
1283
|
name: input.name,
|
|
1249
1284
|
description: input.description,
|
|
1250
1285
|
parentNodeId: input.parentNodeId,
|
|
1251
|
-
...
|
|
1286
|
+
...mergeIntent3(input)
|
|
1252
1287
|
};
|
|
1253
1288
|
if (FILE_TREE_TYPES.has(type)) {
|
|
1254
1289
|
const payload = {
|
|
@@ -1279,7 +1314,7 @@ var nodeCreateTask = {
|
|
|
1279
1314
|
return client.nodes.createChangeRequest({
|
|
1280
1315
|
message: input.message ?? `Create ${type} ${input.name}`,
|
|
1281
1316
|
submittedBy: input.submittedBy,
|
|
1282
|
-
...
|
|
1317
|
+
...mergeIntent3(input),
|
|
1283
1318
|
operations: [
|
|
1284
1319
|
{
|
|
1285
1320
|
kind: "create",
|
|
@@ -1296,11 +1331,16 @@ var nodeCreateTask = {
|
|
|
1296
1331
|
|
|
1297
1332
|
// ../../packages/busabase-contract/src/tasks/record-change.ts
|
|
1298
1333
|
var OPERATIONS2 = ["update", "delete", "restore"];
|
|
1334
|
+
var mergeIntent4 = (input) => {
|
|
1335
|
+
if (input.requireReview) return { autoMerge: false };
|
|
1336
|
+
if (input.autoMerge) return { autoMerge: true };
|
|
1337
|
+
return {};
|
|
1338
|
+
};
|
|
1299
1339
|
var recordChangeTask = {
|
|
1300
1340
|
name: "record_change_request",
|
|
1301
1341
|
cliPath: ["records", "change-request"],
|
|
1302
1342
|
summary: "Propose a change to an existing record (update / delete / restore)",
|
|
1303
|
-
guidance: "
|
|
1343
|
+
guidance: "Review is permission-aware, decided server-side: `update` merges immediately when your key has write access on the Base's node and lands as a pending ChangeRequest otherwise \u2014 check the response's `materialized` field to see which happened. Pass explicit `autoMerge: false` to force review even when you could write directly. `delete` and `restore` are always review-first regardless of permission, by design. `delete` ARCHIVES the record \u2014 it is reversible with `restore`, not an erase. For update, `fields` is keyed by field slug and only needs the fields you are changing; if you set the Base's PRIMARY (first) field, keep it a short human-readable title.",
|
|
1304
1344
|
annotations: { readOnly: false, destructive: false },
|
|
1305
1345
|
params: [
|
|
1306
1346
|
{ name: "recordId", kind: "string", required: true, description: "Record to change." },
|
|
@@ -1322,10 +1362,23 @@ var recordChangeTask = {
|
|
|
1322
1362
|
kind: "string",
|
|
1323
1363
|
description: 'Explanation for the reviewer \u2014 imperative verb + what + why, e.g. "Update deal stage to qualified \u2014 demo booked".'
|
|
1324
1364
|
},
|
|
1325
|
-
{ name: "submittedBy", kind: "string", description: "Producer label recorded on the change." }
|
|
1365
|
+
{ name: "submittedBy", kind: "string", description: "Producer label recorded on the change." },
|
|
1366
|
+
{
|
|
1367
|
+
name: "autoMerge",
|
|
1368
|
+
kind: "boolean",
|
|
1369
|
+
appliesWhen: { param: "operation", values: ["update"] },
|
|
1370
|
+
description: "Skip review and apply the update immediately if you have write access. Not a permission override \u2014 a changeRequest-level key still gets a pending CR. Default is permission-aware: merge when you can, otherwise propose."
|
|
1371
|
+
},
|
|
1372
|
+
{
|
|
1373
|
+
name: "requireReview",
|
|
1374
|
+
kind: "boolean",
|
|
1375
|
+
appliesWhen: { param: "operation", values: ["update"] },
|
|
1376
|
+
description: "Always propose a pending ChangeRequest for this update, even with write access. delete/restore are review-first regardless."
|
|
1377
|
+
}
|
|
1326
1378
|
],
|
|
1327
1379
|
examples: [
|
|
1328
1380
|
`busabase-cli records change-request --record-id rec_1 --operation update --fields-json '{"status":"published"}'`,
|
|
1381
|
+
`busabase-cli records change-request --record-id rec_1 --operation update --fields-json '{"status":"published"}' --require-review`,
|
|
1329
1382
|
"busabase-cli records change-request --record-id rec_1 --operation delete"
|
|
1330
1383
|
],
|
|
1331
1384
|
execute: async (client, input) => {
|
|
@@ -1341,7 +1394,10 @@ var recordChangeTask = {
|
|
|
1341
1394
|
return client.records.changeRequest({
|
|
1342
1395
|
...common,
|
|
1343
1396
|
operation: "update",
|
|
1344
|
-
fields: input.fields
|
|
1397
|
+
fields: input.fields,
|
|
1398
|
+
// Only `update` carries the merge intent — the endpoint's delete/restore
|
|
1399
|
+
// branches have no `autoMerge` in their schema at all, by design.
|
|
1400
|
+
...mergeIntent4(input)
|
|
1345
1401
|
});
|
|
1346
1402
|
}
|
|
1347
1403
|
if (input.operation === "delete") {
|
|
@@ -1402,7 +1458,7 @@ var recordQueryTask = {
|
|
|
1402
1458
|
{ path: ["records", "count"], preset: { countOnly: true }, summary: "Count records" }
|
|
1403
1459
|
],
|
|
1404
1460
|
summary: "List records with pagination, or count them",
|
|
1405
|
-
guidance:
|
|
1461
|
+
guidance: 'Always keyset-paginated: when `nextCursor` comes back non-null there ARE more records \u2014 page with it instead of raising `limit` (capped at 100). Pass countOnly to get the total without fetching rows \u2014 it is a real, exact SQL count (never an estimate), so it is the right tool for a dashboard total instead of paging through everything and counting client-side. countOnly accepts viewId and/or filters to count a scoped subset (e.g. "PRs on the main branch"); both require baseId. To find records by a field value use `record_find_by_field`; to search content use `search` or `grep`.',
|
|
1406
1462
|
annotations: { readOnly: true, destructive: false },
|
|
1407
1463
|
params: [
|
|
1408
1464
|
{ name: "baseId", kind: "string", description: "Restrict to one Base. Omit for the space." },
|
|
@@ -1417,20 +1473,29 @@ var recordQueryTask = {
|
|
|
1417
1473
|
{
|
|
1418
1474
|
name: "filters",
|
|
1419
1475
|
kind: "json",
|
|
1420
|
-
description: "View filters pushed down to the server."
|
|
1476
|
+
description: "View filters pushed down to the server. With countOnly, requires baseId; not every filter is a cheap SQL count (see the records.count API description) but the result is always exact."
|
|
1421
1477
|
},
|
|
1422
1478
|
{ name: "sort", kind: "json", description: "View sort (number/date fields only)." },
|
|
1423
|
-
{ name: "countOnly", kind: "boolean", description: "Return the total instead of rows." }
|
|
1479
|
+
{ name: "countOnly", kind: "boolean", description: "Return the total instead of rows." },
|
|
1480
|
+
{
|
|
1481
|
+
name: "viewId",
|
|
1482
|
+
kind: "string",
|
|
1483
|
+
description: "countOnly only: count the rows this saved View displays. Requires baseId."
|
|
1484
|
+
}
|
|
1424
1485
|
],
|
|
1425
1486
|
examples: [
|
|
1426
1487
|
"busabase-cli records query --base-id bas_123 --limit 100",
|
|
1427
|
-
"busabase-cli records count --base-id bas_123"
|
|
1488
|
+
"busabase-cli records count --base-id bas_123",
|
|
1489
|
+
`busabase-cli records count --base-id bas_123 --filters '[{"fieldSlug":"branch","fieldType":"text","operator":"equals","value":"main"}]'`,
|
|
1490
|
+
"busabase-cli records count --base-id bas_123 --view-id viw_456"
|
|
1428
1491
|
],
|
|
1429
1492
|
execute: async (client, input) => {
|
|
1430
1493
|
if (input.countOnly) {
|
|
1431
|
-
return client.records.count(
|
|
1432
|
-
input.baseId ? { baseId: input.baseId } : {}
|
|
1433
|
-
|
|
1494
|
+
return client.records.count({
|
|
1495
|
+
...input.baseId ? { baseId: input.baseId } : {},
|
|
1496
|
+
...input.viewId ? { viewId: input.viewId } : {},
|
|
1497
|
+
...Array.isArray(input.filters) ? { filters: input.filters } : {}
|
|
1498
|
+
});
|
|
1434
1499
|
}
|
|
1435
1500
|
return client.records.list({
|
|
1436
1501
|
...input.limit !== void 0 ? { limit: input.limit } : {},
|
|
@@ -1444,7 +1509,7 @@ var recordQueryTask = {
|
|
|
1444
1509
|
|
|
1445
1510
|
// ../../packages/busabase-contract/src/tasks/view-change.ts
|
|
1446
1511
|
var ACTIONS = ["create", "update", "delete", "restore"];
|
|
1447
|
-
var
|
|
1512
|
+
var mergeIntent5 = (input) => {
|
|
1448
1513
|
if (input.requireReview) return { autoMerge: false };
|
|
1449
1514
|
if (input.autoMerge) return { autoMerge: true };
|
|
1450
1515
|
return {};
|
|
@@ -1523,7 +1588,7 @@ var viewChangeTask = {
|
|
|
1523
1588
|
...input.submittedBy ? { submittedBy: input.submittedBy } : {},
|
|
1524
1589
|
// Tri-state, like node_create's: omitted keeps the endpoint's
|
|
1525
1590
|
// permission-aware default, explicit true/false forces the branch.
|
|
1526
|
-
...
|
|
1591
|
+
...mergeIntent5(input)
|
|
1527
1592
|
};
|
|
1528
1593
|
if (input.action === "create") {
|
|
1529
1594
|
if (!input.baseId || !input.name) {
|
|
@@ -2692,9 +2757,15 @@ async function ask2(question) {
|
|
|
2692
2757
|
function openBrowser(url) {
|
|
2693
2758
|
const platform = process.platform;
|
|
2694
2759
|
const [command, args] = platform === "darwin" ? ["open", [url]] : platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
|
|
2760
|
+
const reportFailure = () => {
|
|
2761
|
+
say2("Could not open a browser automatically. Open the URL above manually.");
|
|
2762
|
+
};
|
|
2695
2763
|
try {
|
|
2696
|
-
spawn(command, args, { stdio: "ignore", detached: true })
|
|
2764
|
+
const child = spawn(command, args, { stdio: "ignore", detached: true });
|
|
2765
|
+
child.once("error", reportFailure);
|
|
2766
|
+
child.unref();
|
|
2697
2767
|
} catch {
|
|
2768
|
+
reportFailure();
|
|
2698
2769
|
}
|
|
2699
2770
|
}
|
|
2700
2771
|
async function verifyAuth(baseUrl, token) {
|
|
@@ -3203,7 +3274,7 @@ import { readFile } from "fs/promises";
|
|
|
3203
3274
|
import { join as join3 } from "path";
|
|
3204
3275
|
|
|
3205
3276
|
// ../../packages/busabase-contract/src/domains/package/types.ts
|
|
3206
|
-
import { z as
|
|
3277
|
+
import { z as z10 } from "zod";
|
|
3207
3278
|
|
|
3208
3279
|
// ../../packages/openlib/i18n/i-string.ts
|
|
3209
3280
|
import { z as z5 } from "zod";
|
|
@@ -3222,15 +3293,21 @@ var iStringRecordSchema = z5.partialRecord(LocaleSchema, z5.string());
|
|
|
3222
3293
|
var iStringSchema = z5.union([z5.string(), iStringRecordSchema]).describe("i18n string");
|
|
3223
3294
|
|
|
3224
3295
|
// ../../packages/busabase-contract/src/domains/base/contract/base-schemas.ts
|
|
3296
|
+
import { z as z7 } from "zod";
|
|
3297
|
+
|
|
3298
|
+
// ../../packages/busabase-contract/src/contract/auto-merge.ts
|
|
3225
3299
|
import { z as z6 } from "zod";
|
|
3226
|
-
var
|
|
3227
|
-
|
|
3300
|
+
var autoMergeNotAccepted = (reason) => z6.literal(false, { error: `\`autoMerge: true\` is not accepted here: ${reason}` }).optional().describe(`Only \`false\` (or omitted) is accepted. ${reason}`);
|
|
3301
|
+
|
|
3302
|
+
// ../../packages/busabase-contract/src/domains/base/contract/base-schemas.ts
|
|
3303
|
+
var fieldNameSchema = z7.union([
|
|
3304
|
+
z7.string().min(1),
|
|
3228
3305
|
iStringRecordSchema.refine(
|
|
3229
3306
|
(record) => Object.values(record).some((value) => value && value.trim().length > 0),
|
|
3230
3307
|
"field name must have at least one non-empty locale value"
|
|
3231
3308
|
)
|
|
3232
3309
|
]);
|
|
3233
|
-
var fieldTypeSchema =
|
|
3310
|
+
var fieldTypeSchema = z7.enum([
|
|
3234
3311
|
"text",
|
|
3235
3312
|
"longtext",
|
|
3236
3313
|
"markdown",
|
|
@@ -3260,105 +3337,105 @@ var fieldTypeSchema = z6.enum([
|
|
|
3260
3337
|
"lookup",
|
|
3261
3338
|
"whiteboard"
|
|
3262
3339
|
]);
|
|
3263
|
-
var lookupRollupSchema =
|
|
3264
|
-
var fieldOptionsSchema =
|
|
3265
|
-
ai:
|
|
3266
|
-
model:
|
|
3267
|
-
prompt:
|
|
3268
|
-
reviewRequired:
|
|
3269
|
-
sourceFieldIds:
|
|
3340
|
+
var lookupRollupSchema = z7.enum(["values", "count", "sum", "average", "min", "max", "concatenate"]).default("values");
|
|
3341
|
+
var fieldOptionsSchema = z7.object({
|
|
3342
|
+
ai: z7.object({
|
|
3343
|
+
model: z7.string().optional(),
|
|
3344
|
+
prompt: z7.string().optional(),
|
|
3345
|
+
reviewRequired: z7.boolean().optional(),
|
|
3346
|
+
sourceFieldIds: z7.array(z7.string()).optional()
|
|
3270
3347
|
}).optional(),
|
|
3271
3348
|
// Per-field config for `attachment` columns (all optional; logic enforces a
|
|
3272
3349
|
// 25MB ceiling regardless).
|
|
3273
|
-
attachment:
|
|
3274
|
-
maxFiles:
|
|
3275
|
-
allowedMimeTypes:
|
|
3276
|
-
maxFileSize:
|
|
3350
|
+
attachment: z7.object({
|
|
3351
|
+
maxFiles: z7.number().int().positive().optional(),
|
|
3352
|
+
allowedMimeTypes: z7.array(z7.string()).optional(),
|
|
3353
|
+
maxFileSize: z7.number().int().positive().optional()
|
|
3277
3354
|
}).optional(),
|
|
3278
|
-
choices:
|
|
3279
|
-
|
|
3280
|
-
color:
|
|
3281
|
-
id:
|
|
3282
|
-
name:
|
|
3355
|
+
choices: z7.array(
|
|
3356
|
+
z7.object({
|
|
3357
|
+
color: z7.string().optional(),
|
|
3358
|
+
id: z7.string(),
|
|
3359
|
+
name: z7.string()
|
|
3283
3360
|
})
|
|
3284
3361
|
).optional(),
|
|
3285
|
-
code:
|
|
3286
|
-
language:
|
|
3362
|
+
code: z7.object({
|
|
3363
|
+
language: z7.string().optional()
|
|
3287
3364
|
}).optional(),
|
|
3288
|
-
embed:
|
|
3289
|
-
aspectRatio:
|
|
3290
|
-
height:
|
|
3291
|
-
providers:
|
|
3365
|
+
embed: z7.object({
|
|
3366
|
+
aspectRatio: z7.enum(["16:9", "4:3", "1:1"]).optional(),
|
|
3367
|
+
height: z7.number().int().positive().max(1200).optional(),
|
|
3368
|
+
providers: z7.array(z7.string()).optional()
|
|
3292
3369
|
}).optional(),
|
|
3293
3370
|
// `formula` fields are server-computed (like the other computed types) from
|
|
3294
3371
|
// `expression` at record write time — see packages/busabase-core's
|
|
3295
3372
|
// domains/base/formula/ engine. `{slug}` references a sibling field, including
|
|
3296
3373
|
// another `formula` field (chained formulas) — a dependency graph orders
|
|
3297
3374
|
// computation and rejects cycles at field create/edit time.
|
|
3298
|
-
formula:
|
|
3299
|
-
expression:
|
|
3375
|
+
formula: z7.object({
|
|
3376
|
+
expression: z7.string().min(1)
|
|
3300
3377
|
}).optional(),
|
|
3301
|
-
inverseFieldId:
|
|
3378
|
+
inverseFieldId: z7.string().optional(),
|
|
3302
3379
|
// `lookup` fields pull a field's values across a `relation` field on the same
|
|
3303
3380
|
// Base, optionally rolling them up into one scalar. Unlike every other computed
|
|
3304
3381
|
// type they are NOT stored on the commit: a lookup's value depends on OTHER
|
|
3305
3382
|
// records, which can change without this record ever being written, so it is
|
|
3306
3383
|
// resolved at read time (see busabase-core's domains/base/logic/lookup-values.ts).
|
|
3307
|
-
lookup:
|
|
3308
|
-
relationFieldSlug:
|
|
3309
|
-
targetFieldSlug:
|
|
3384
|
+
lookup: z7.object({
|
|
3385
|
+
relationFieldSlug: z7.string().min(1).describe("Slug of a `relation` field on THIS Base \u2014 the hop to follow."),
|
|
3386
|
+
targetFieldSlug: z7.string().min(1).describe("Slug of the field on the related Base whose values are pulled over."),
|
|
3310
3387
|
rollup: lookupRollupSchema.optional(),
|
|
3311
|
-
limit:
|
|
3388
|
+
limit: z7.enum(["all", "first"]).optional().describe("`first` looks at only the first linked record; default `all`.")
|
|
3312
3389
|
}).optional(),
|
|
3313
|
-
multiple:
|
|
3390
|
+
multiple: z7.boolean().optional(),
|
|
3314
3391
|
// Display formatting for `number` columns (Notion-style: one number type,
|
|
3315
3392
|
// a format option). `currency` renders via Intl.NumberFormat.
|
|
3316
|
-
number:
|
|
3317
|
-
format:
|
|
3318
|
-
currency:
|
|
3319
|
-
locale:
|
|
3393
|
+
number: z7.object({
|
|
3394
|
+
format: z7.enum(["plain", "currency"]).optional(),
|
|
3395
|
+
currency: z7.string().optional(),
|
|
3396
|
+
locale: z7.string().optional()
|
|
3320
3397
|
}).optional(),
|
|
3321
|
-
targetBaseId:
|
|
3322
|
-
targetBaseSlug:
|
|
3398
|
+
targetBaseId: z7.string().optional().describe("Relation target Base id (bse_\u2026). Or pass targetBaseSlug to name it by slug."),
|
|
3399
|
+
targetBaseSlug: z7.string().optional().describe(
|
|
3323
3400
|
"Relation target Base by slug \u2014 a convenience alias for targetBaseId, resolved server-side (active bases in the current space). If both are given, targetBaseId wins."
|
|
3324
3401
|
)
|
|
3325
3402
|
}).default({});
|
|
3326
|
-
var baseFieldSchema =
|
|
3327
|
-
id:
|
|
3328
|
-
baseId:
|
|
3329
|
-
slug:
|
|
3403
|
+
var baseFieldSchema = z7.object({
|
|
3404
|
+
id: z7.string(),
|
|
3405
|
+
baseId: z7.string(),
|
|
3406
|
+
slug: z7.string(),
|
|
3330
3407
|
name: fieldNameSchema,
|
|
3331
3408
|
type: fieldTypeSchema,
|
|
3332
|
-
required:
|
|
3333
|
-
position:
|
|
3409
|
+
required: z7.boolean(),
|
|
3410
|
+
position: z7.number(),
|
|
3334
3411
|
options: fieldOptionsSchema
|
|
3335
3412
|
});
|
|
3336
|
-
var baseSchema =
|
|
3337
|
-
id:
|
|
3338
|
-
nodeId:
|
|
3339
|
-
slug:
|
|
3340
|
-
name:
|
|
3341
|
-
description:
|
|
3342
|
-
reviewPolicy:
|
|
3343
|
-
kind:
|
|
3344
|
-
requiredApprovals:
|
|
3413
|
+
var baseSchema = z7.object({
|
|
3414
|
+
id: z7.string(),
|
|
3415
|
+
nodeId: z7.string(),
|
|
3416
|
+
slug: z7.string(),
|
|
3417
|
+
name: z7.string(),
|
|
3418
|
+
description: z7.string(),
|
|
3419
|
+
reviewPolicy: z7.object({
|
|
3420
|
+
kind: z7.literal("single"),
|
|
3421
|
+
requiredApprovals: z7.number()
|
|
3345
3422
|
}),
|
|
3346
|
-
createdAt:
|
|
3347
|
-
fields:
|
|
3423
|
+
createdAt: z7.string(),
|
|
3424
|
+
fields: z7.array(baseFieldSchema)
|
|
3348
3425
|
});
|
|
3349
|
-
var createBaseInputSchema =
|
|
3350
|
-
parentNodeId:
|
|
3426
|
+
var createBaseInputSchema = z7.object({
|
|
3427
|
+
parentNodeId: z7.string().optional().describe(
|
|
3351
3428
|
"Parent node id. Must be a folder or the space root; container-incapable node types (Base, Doc, AirApp, etc.) cannot hold children."
|
|
3352
3429
|
),
|
|
3353
|
-
slug:
|
|
3354
|
-
name:
|
|
3355
|
-
description:
|
|
3356
|
-
fields:
|
|
3357
|
-
|
|
3358
|
-
slug:
|
|
3430
|
+
slug: z7.string().min(1).regex(/^[a-z0-9-]+$/),
|
|
3431
|
+
name: z7.string().min(1),
|
|
3432
|
+
description: z7.string().optional().default(""),
|
|
3433
|
+
fields: z7.array(
|
|
3434
|
+
z7.object({
|
|
3435
|
+
slug: z7.string().min(1),
|
|
3359
3436
|
name: fieldNameSchema,
|
|
3360
3437
|
type: fieldTypeSchema.default("text"),
|
|
3361
|
-
required:
|
|
3438
|
+
required: z7.boolean().default(false),
|
|
3362
3439
|
options: fieldOptionsSchema.optional().default({})
|
|
3363
3440
|
})
|
|
3364
3441
|
).default([]),
|
|
@@ -3366,131 +3443,157 @@ var createBaseInputSchema = z6.object({
|
|
|
3366
3443
|
// write access on the parent node, otherwise falls back to a pending
|
|
3367
3444
|
// ChangeRequest (status "in_review"). Pass explicit `autoMerge: false` to
|
|
3368
3445
|
// force review even with write access.
|
|
3369
|
-
autoMerge:
|
|
3446
|
+
autoMerge: z7.boolean().optional()
|
|
3370
3447
|
});
|
|
3371
|
-
var createBaseFieldInputSchema =
|
|
3448
|
+
var createBaseFieldInputSchema = z7.object({
|
|
3372
3449
|
name: fieldNameSchema,
|
|
3373
3450
|
// Field slugs are snake_case identifiers (e.g. `cover_image`, `publish_date`) — the
|
|
3374
3451
|
// seed and the inline-fields path on `POST /bases` already allow underscores, so the
|
|
3375
3452
|
// add-field endpoint must too. (Base/folder/view slugs stay kebab-case: they go in URLs.)
|
|
3376
|
-
slug:
|
|
3453
|
+
slug: z7.string().min(1).regex(/^[a-z0-9_-]+$/),
|
|
3377
3454
|
type: fieldTypeSchema.default("text"),
|
|
3378
|
-
required:
|
|
3455
|
+
required: z7.boolean().optional().default(false),
|
|
3379
3456
|
options: fieldOptionsSchema.optional().default({})
|
|
3380
3457
|
});
|
|
3458
|
+
var fieldAutoMergeSchema = z7.boolean().optional().describe(
|
|
3459
|
+
"Whether to approve and merge this field change immediately. Omitted defaults to merging immediately if the actor has write access on the Base's node, otherwise falling back to a pending Change Request; pass explicit false to force review even with write access. Not accepted by the delete and convert operations, which always require review."
|
|
3460
|
+
);
|
|
3381
3461
|
var createFieldChangeRequestInputSchema = createBaseFieldInputSchema.extend({
|
|
3382
|
-
message:
|
|
3383
|
-
submittedBy:
|
|
3462
|
+
message: z7.string().optional().default("Add field"),
|
|
3463
|
+
submittedBy: z7.string().optional().default("local-editor"),
|
|
3464
|
+
autoMerge: fieldAutoMergeSchema
|
|
3384
3465
|
});
|
|
3385
|
-
var deleteFieldChangeRequestInputSchema =
|
|
3386
|
-
fieldId:
|
|
3387
|
-
message:
|
|
3388
|
-
submittedBy:
|
|
3466
|
+
var deleteFieldChangeRequestInputSchema = z7.object({
|
|
3467
|
+
fieldId: z7.string().min(1),
|
|
3468
|
+
message: z7.string().optional(),
|
|
3469
|
+
submittedBy: z7.string().optional().default("local-editor"),
|
|
3470
|
+
autoMerge: autoMergeNotAccepted(
|
|
3471
|
+
"deleting a field soft-deletes its stored values with it, so it always requires review. Omit the flag."
|
|
3472
|
+
)
|
|
3389
3473
|
});
|
|
3390
|
-
var updateFieldChangeRequestInputSchema =
|
|
3391
|
-
fieldId:
|
|
3392
|
-
patch:
|
|
3474
|
+
var updateFieldChangeRequestInputSchema = z7.object({
|
|
3475
|
+
fieldId: z7.string().min(1),
|
|
3476
|
+
patch: z7.object({
|
|
3393
3477
|
name: fieldNameSchema.optional(),
|
|
3394
|
-
required:
|
|
3478
|
+
required: z7.boolean().optional(),
|
|
3395
3479
|
options: fieldOptionsSchema.optional()
|
|
3396
3480
|
}),
|
|
3397
|
-
message:
|
|
3398
|
-
submittedBy:
|
|
3481
|
+
message: z7.string().optional(),
|
|
3482
|
+
submittedBy: z7.string().optional().default("local-editor"),
|
|
3483
|
+
autoMerge: fieldAutoMergeSchema
|
|
3399
3484
|
});
|
|
3400
|
-
var previewFieldConversionInputSchema =
|
|
3401
|
-
fieldId:
|
|
3485
|
+
var previewFieldConversionInputSchema = z7.object({
|
|
3486
|
+
fieldId: z7.string().min(1),
|
|
3402
3487
|
newType: fieldTypeSchema
|
|
3403
3488
|
});
|
|
3404
|
-
var previewFieldConversionOutputSchema =
|
|
3405
|
-
totalCount:
|
|
3406
|
-
convertibleCount:
|
|
3407
|
-
nullCount:
|
|
3408
|
-
conflicts:
|
|
3489
|
+
var previewFieldConversionOutputSchema = z7.object({
|
|
3490
|
+
totalCount: z7.number(),
|
|
3491
|
+
convertibleCount: z7.number(),
|
|
3492
|
+
nullCount: z7.number(),
|
|
3493
|
+
conflicts: z7.array(z7.object({ recordId: z7.string(), currentValue: z7.unknown() }))
|
|
3409
3494
|
});
|
|
3410
|
-
var convertFieldChangeRequestInputSchema =
|
|
3411
|
-
fieldId:
|
|
3495
|
+
var convertFieldChangeRequestInputSchema = z7.object({
|
|
3496
|
+
fieldId: z7.string().min(1),
|
|
3412
3497
|
newType: fieldTypeSchema,
|
|
3413
|
-
selectChoiceMode:
|
|
3414
|
-
message:
|
|
3415
|
-
submittedBy:
|
|
3498
|
+
selectChoiceMode: z7.enum(["auto_create", "null_on_missing"]).default("null_on_missing"),
|
|
3499
|
+
message: z7.string().optional(),
|
|
3500
|
+
submittedBy: z7.string().optional().default("local-editor"),
|
|
3501
|
+
autoMerge: autoMergeNotAccepted(
|
|
3502
|
+
"converting a field's type can drop values, so it always requires review. Run previewFieldConversion first to see what would change, then omit the flag."
|
|
3503
|
+
)
|
|
3416
3504
|
});
|
|
3417
|
-
var reorderFieldsChangeRequestInputSchema =
|
|
3418
|
-
fieldIds:
|
|
3419
|
-
message:
|
|
3420
|
-
submittedBy:
|
|
3505
|
+
var reorderFieldsChangeRequestInputSchema = z7.object({
|
|
3506
|
+
fieldIds: z7.array(z7.string()).min(1),
|
|
3507
|
+
message: z7.string().optional(),
|
|
3508
|
+
submittedBy: z7.string().optional().default("local-editor"),
|
|
3509
|
+
autoMerge: fieldAutoMergeSchema
|
|
3421
3510
|
});
|
|
3422
|
-
var archiveBaseInputSchema =
|
|
3423
|
-
message:
|
|
3424
|
-
submittedBy:
|
|
3511
|
+
var archiveBaseInputSchema = z7.object({
|
|
3512
|
+
message: z7.string().optional(),
|
|
3513
|
+
submittedBy: z7.string().optional().default("local-editor"),
|
|
3514
|
+
autoMerge: autoMergeNotAccepted(
|
|
3515
|
+
"archiving a Base removes it and every record in it from every listing at once, so it always requires review. Omit the flag."
|
|
3516
|
+
)
|
|
3425
3517
|
});
|
|
3426
|
-
var restoreBaseInputSchema =
|
|
3427
|
-
message:
|
|
3428
|
-
submittedBy:
|
|
3518
|
+
var restoreBaseInputSchema = z7.object({
|
|
3519
|
+
message: z7.string().optional(),
|
|
3520
|
+
submittedBy: z7.string().optional().default("local-editor"),
|
|
3521
|
+
// Restoring an archived Base is the undo of a destructive act — nothing is at
|
|
3522
|
+
// risk, so it takes the same permission-aware default as everything else.
|
|
3523
|
+
// `archiveBaseInputSchema` above deliberately has no `autoMerge`: archiving
|
|
3524
|
+
// takes a whole Base and every record in it out of every listing at once,
|
|
3525
|
+
// which is strictly larger than the record `delete` that is already review-only.
|
|
3526
|
+
autoMerge: z7.boolean().optional()
|
|
3429
3527
|
});
|
|
3430
|
-
var restoreFieldChangeRequestInputSchema =
|
|
3431
|
-
fieldId:
|
|
3432
|
-
message:
|
|
3433
|
-
submittedBy:
|
|
3528
|
+
var restoreFieldChangeRequestInputSchema = z7.object({
|
|
3529
|
+
fieldId: z7.string().min(1),
|
|
3530
|
+
message: z7.string().optional(),
|
|
3531
|
+
submittedBy: z7.string().optional().default("local-editor"),
|
|
3532
|
+
autoMerge: fieldAutoMergeSchema
|
|
3434
3533
|
});
|
|
3435
|
-
var withBaseId = { baseId:
|
|
3436
|
-
var fieldChangeRequestInputSchema =
|
|
3437
|
-
createFieldChangeRequestInputSchema.extend({ operation:
|
|
3438
|
-
updateFieldChangeRequestInputSchema.extend({ operation:
|
|
3439
|
-
deleteFieldChangeRequestInputSchema.extend({ operation:
|
|
3440
|
-
convertFieldChangeRequestInputSchema.extend({ operation:
|
|
3441
|
-
reorderFieldsChangeRequestInputSchema.extend({ operation:
|
|
3442
|
-
restoreFieldChangeRequestInputSchema.extend({ operation:
|
|
3534
|
+
var withBaseId = { baseId: z7.string().min(1) };
|
|
3535
|
+
var fieldChangeRequestInputSchema = z7.discriminatedUnion("operation", [
|
|
3536
|
+
createFieldChangeRequestInputSchema.extend({ operation: z7.literal("create"), ...withBaseId }),
|
|
3537
|
+
updateFieldChangeRequestInputSchema.extend({ operation: z7.literal("update"), ...withBaseId }),
|
|
3538
|
+
deleteFieldChangeRequestInputSchema.extend({ operation: z7.literal("delete"), ...withBaseId }),
|
|
3539
|
+
convertFieldChangeRequestInputSchema.extend({ operation: z7.literal("convert"), ...withBaseId }),
|
|
3540
|
+
reorderFieldsChangeRequestInputSchema.extend({ operation: z7.literal("reorder"), ...withBaseId }),
|
|
3541
|
+
restoreFieldChangeRequestInputSchema.extend({ operation: z7.literal("restore"), ...withBaseId })
|
|
3542
|
+
]);
|
|
3543
|
+
var baseLifecycleChangeRequestInputSchema = z7.discriminatedUnion("operation", [
|
|
3544
|
+
archiveBaseInputSchema.extend({ operation: z7.literal("archive"), ...withBaseId }),
|
|
3545
|
+
restoreBaseInputSchema.extend({ operation: z7.literal("restore"), ...withBaseId })
|
|
3443
3546
|
]);
|
|
3444
3547
|
|
|
3445
3548
|
// ../../packages/busabase-contract/src/domains/base/contract/view-schemas.ts
|
|
3446
|
-
import { z as
|
|
3549
|
+
import { z as z9 } from "zod";
|
|
3447
3550
|
|
|
3448
3551
|
// ../../packages/busabase-contract/src/contract/schemas.ts
|
|
3449
|
-
import { z as
|
|
3450
|
-
var nodeSchema =
|
|
3451
|
-
() =>
|
|
3452
|
-
id:
|
|
3453
|
-
parentId:
|
|
3454
|
-
type:
|
|
3455
|
-
slug:
|
|
3456
|
-
name:
|
|
3457
|
-
description:
|
|
3458
|
-
metadata:
|
|
3459
|
-
entryFile:
|
|
3460
|
-
visibility:
|
|
3461
|
-
version:
|
|
3462
|
-
assetId:
|
|
3463
|
-
}).catchall(
|
|
3464
|
-
position:
|
|
3465
|
-
createdAt:
|
|
3466
|
-
updatedAt:
|
|
3467
|
-
baseId:
|
|
3468
|
-
children:
|
|
3469
|
-
hasChildren:
|
|
3552
|
+
import { z as z8 } from "zod";
|
|
3553
|
+
var nodeSchema = z8.lazy(
|
|
3554
|
+
() => z8.object({
|
|
3555
|
+
id: z8.string(),
|
|
3556
|
+
parentId: z8.string().nullable(),
|
|
3557
|
+
type: z8.enum(NODE_TYPES),
|
|
3558
|
+
slug: z8.string(),
|
|
3559
|
+
name: z8.string(),
|
|
3560
|
+
description: z8.string(),
|
|
3561
|
+
metadata: z8.object({
|
|
3562
|
+
entryFile: z8.string().optional(),
|
|
3563
|
+
visibility: z8.enum(["private", "workspace", "public"]).optional(),
|
|
3564
|
+
version: z8.string().optional(),
|
|
3565
|
+
assetId: z8.string().optional()
|
|
3566
|
+
}).catchall(z8.unknown()).default({}),
|
|
3567
|
+
position: z8.number(),
|
|
3568
|
+
createdAt: z8.string(),
|
|
3569
|
+
updatedAt: z8.string(),
|
|
3570
|
+
baseId: z8.string().nullable(),
|
|
3571
|
+
children: z8.array(nodeSchema),
|
|
3572
|
+
hasChildren: z8.boolean().optional()
|
|
3470
3573
|
})
|
|
3471
3574
|
);
|
|
3472
|
-
var nodePrincipalSchema =
|
|
3473
|
-
id:
|
|
3474
|
-
nodeId:
|
|
3475
|
-
principalType:
|
|
3476
|
-
principalId:
|
|
3477
|
-
role:
|
|
3478
|
-
grantedBy:
|
|
3479
|
-
createdAt:
|
|
3480
|
-
updatedAt:
|
|
3575
|
+
var nodePrincipalSchema = z8.object({
|
|
3576
|
+
id: z8.string(),
|
|
3577
|
+
nodeId: z8.string(),
|
|
3578
|
+
principalType: z8.enum(["user", "team", "space"]),
|
|
3579
|
+
principalId: z8.string(),
|
|
3580
|
+
role: z8.enum(["read", "changeRequest", "write", "manage"]),
|
|
3581
|
+
grantedBy: z8.string(),
|
|
3582
|
+
createdAt: z8.string(),
|
|
3583
|
+
updatedAt: z8.string()
|
|
3481
3584
|
});
|
|
3482
|
-
var nodeShareSchema =
|
|
3483
|
-
nodeId:
|
|
3484
|
-
scope:
|
|
3485
|
-
capability:
|
|
3585
|
+
var nodeShareSchema = z8.object({
|
|
3586
|
+
nodeId: z8.string(),
|
|
3587
|
+
scope: z8.enum(["none", "public"]),
|
|
3588
|
+
capability: z8.enum(["read", "submit"]),
|
|
3486
3589
|
// Derived from `passwordHash != null` — the hash itself is never serialized.
|
|
3487
|
-
hasPassword:
|
|
3488
|
-
expiresAt:
|
|
3489
|
-
updatedAt:
|
|
3590
|
+
hasPassword: z8.boolean(),
|
|
3591
|
+
expiresAt: z8.string().nullable(),
|
|
3592
|
+
updatedAt: z8.string()
|
|
3490
3593
|
});
|
|
3491
|
-
var listNodesInputSchema =
|
|
3492
|
-
parentId:
|
|
3493
|
-
depth:
|
|
3594
|
+
var listNodesInputSchema = z8.object({
|
|
3595
|
+
parentId: z8.string().nullable().optional().describe("Node to start from. Omit or null to start from the space root."),
|
|
3596
|
+
depth: z8.coerce.number().int().min(1).max(5).optional().describe(
|
|
3494
3597
|
"How many levels beneath the start point to eagerly include (default 2 once either field is set). Capped at 5."
|
|
3495
3598
|
),
|
|
3496
3599
|
/**
|
|
@@ -3498,7 +3601,7 @@ var listNodesInputSchema = z7.object({
|
|
|
3498
3601
|
* soft-archived nodes for the Trash view — no `parentId`/`depth` walk, since
|
|
3499
3602
|
* archived nodes are shown as a list, not a tree.
|
|
3500
3603
|
*/
|
|
3501
|
-
status:
|
|
3604
|
+
status: z8.enum(["active", "archived"]).optional().default("active"),
|
|
3502
3605
|
/**
|
|
3503
3606
|
* Narrow to specific node types and return a FLAT list of lightweight node
|
|
3504
3607
|
* summaries (`children: []`) instead of walking the tree. This is what
|
|
@@ -3522,110 +3625,110 @@ var listNodesInputSchema = z7.object({
|
|
|
3522
3625
|
* bare string, not a 1-element array — only a REPEATED occurrence
|
|
3523
3626
|
* (`?types=doc&types=file`) becomes an array. Accept both and normalize.
|
|
3524
3627
|
*/
|
|
3525
|
-
types:
|
|
3628
|
+
types: z8.union([z8.array(z8.enum(NODE_TYPES)), z8.enum(NODE_TYPES)]).transform((value) => Array.isArray(value) ? value : [value]).optional().describe(
|
|
3526
3629
|
"Return a flat list of lightweight summaries for these node types instead of the tree. Read one node's full detail with GET /nodes/{nodeId}."
|
|
3527
3630
|
)
|
|
3528
3631
|
}).optional();
|
|
3529
|
-
var isDescendantInputSchema =
|
|
3530
|
-
nodeId:
|
|
3531
|
-
potentialAncestorId:
|
|
3632
|
+
var isDescendantInputSchema = z8.object({
|
|
3633
|
+
nodeId: z8.string(),
|
|
3634
|
+
potentialAncestorId: z8.string()
|
|
3532
3635
|
});
|
|
3533
|
-
var isDescendantOutputSchema =
|
|
3534
|
-
isDescendant:
|
|
3636
|
+
var isDescendantOutputSchema = z8.object({
|
|
3637
|
+
isDescendant: z8.boolean()
|
|
3535
3638
|
});
|
|
3536
|
-
var updateNodeMetadataInputSchema =
|
|
3537
|
-
nodeId:
|
|
3538
|
-
metadata:
|
|
3639
|
+
var updateNodeMetadataInputSchema = z8.object({
|
|
3640
|
+
nodeId: z8.string(),
|
|
3641
|
+
metadata: z8.record(z8.string(), z8.unknown())
|
|
3539
3642
|
});
|
|
3540
|
-
var searchNodesByNameInputSchema =
|
|
3541
|
-
query:
|
|
3542
|
-
limit:
|
|
3643
|
+
var searchNodesByNameInputSchema = z8.object({
|
|
3644
|
+
query: z8.string().min(1),
|
|
3645
|
+
limit: z8.number().int().min(1).max(50).optional().default(20)
|
|
3543
3646
|
});
|
|
3544
|
-
var nodeSearchResultSchema =
|
|
3545
|
-
id:
|
|
3546
|
-
type:
|
|
3547
|
-
name:
|
|
3548
|
-
slug:
|
|
3549
|
-
path:
|
|
3550
|
-
updatedAt:
|
|
3647
|
+
var nodeSearchResultSchema = z8.object({
|
|
3648
|
+
id: z8.string(),
|
|
3649
|
+
type: z8.enum(NODE_TYPES),
|
|
3650
|
+
name: z8.string(),
|
|
3651
|
+
slug: z8.string(),
|
|
3652
|
+
path: z8.string(),
|
|
3653
|
+
updatedAt: z8.string()
|
|
3551
3654
|
});
|
|
3552
|
-
var userRefSchema =
|
|
3553
|
-
id:
|
|
3554
|
-
name:
|
|
3555
|
-
email:
|
|
3556
|
-
image:
|
|
3557
|
-
role:
|
|
3655
|
+
var userRefSchema = z8.object({
|
|
3656
|
+
id: z8.string(),
|
|
3657
|
+
name: z8.string().nullable(),
|
|
3658
|
+
email: z8.string().nullable(),
|
|
3659
|
+
image: z8.string().nullable(),
|
|
3660
|
+
role: z8.string().nullable().optional()
|
|
3558
3661
|
});
|
|
3559
|
-
var commitSchema =
|
|
3560
|
-
id:
|
|
3561
|
-
baseId:
|
|
3562
|
-
targetType:
|
|
3563
|
-
nodeId:
|
|
3564
|
-
operationId:
|
|
3565
|
-
parentCommitId:
|
|
3566
|
-
fields:
|
|
3567
|
-
operation:
|
|
3568
|
-
message:
|
|
3569
|
-
author:
|
|
3662
|
+
var commitSchema = z8.object({
|
|
3663
|
+
id: z8.string(),
|
|
3664
|
+
baseId: z8.string().nullable(),
|
|
3665
|
+
targetType: z8.enum(["base", "node"]),
|
|
3666
|
+
nodeId: z8.string().nullable(),
|
|
3667
|
+
operationId: z8.string().nullable(),
|
|
3668
|
+
parentCommitId: z8.string().nullable(),
|
|
3669
|
+
fields: z8.record(z8.string(), z8.unknown()),
|
|
3670
|
+
operation: z8.enum(OPERATION_KINDS),
|
|
3671
|
+
message: z8.string(),
|
|
3672
|
+
author: z8.string(),
|
|
3570
3673
|
authorUser: userRefSchema.nullable().optional().default(null),
|
|
3571
|
-
createdAt:
|
|
3674
|
+
createdAt: z8.string()
|
|
3572
3675
|
});
|
|
3573
|
-
var operationSchema =
|
|
3574
|
-
id:
|
|
3575
|
-
changeRequestId:
|
|
3576
|
-
baseId:
|
|
3577
|
-
targetType:
|
|
3578
|
-
nodeId:
|
|
3579
|
-
operation:
|
|
3580
|
-
status:
|
|
3581
|
-
targetRecordId:
|
|
3582
|
-
targetViewId:
|
|
3583
|
-
filePath:
|
|
3584
|
-
sourceRecordId:
|
|
3585
|
-
sourceCommitId:
|
|
3586
|
-
baseCommitId:
|
|
3587
|
-
headCommitId:
|
|
3588
|
-
deleteMode:
|
|
3589
|
-
mergedRecordId:
|
|
3590
|
-
mergedViewId:
|
|
3591
|
-
position:
|
|
3592
|
-
createdAt:
|
|
3593
|
-
updatedAt:
|
|
3676
|
+
var operationSchema = z8.object({
|
|
3677
|
+
id: z8.string(),
|
|
3678
|
+
changeRequestId: z8.string(),
|
|
3679
|
+
baseId: z8.string().nullable(),
|
|
3680
|
+
targetType: z8.enum(["base", "node"]),
|
|
3681
|
+
nodeId: z8.string().nullable(),
|
|
3682
|
+
operation: z8.enum(OPERATION_KINDS),
|
|
3683
|
+
status: z8.enum(["pending", "merged", "archived", "failed"]),
|
|
3684
|
+
targetRecordId: z8.string().nullable(),
|
|
3685
|
+
targetViewId: z8.string().nullable(),
|
|
3686
|
+
filePath: z8.string().nullable(),
|
|
3687
|
+
sourceRecordId: z8.string().nullable(),
|
|
3688
|
+
sourceCommitId: z8.string().nullable(),
|
|
3689
|
+
baseCommitId: z8.string().nullable(),
|
|
3690
|
+
headCommitId: z8.string(),
|
|
3691
|
+
deleteMode: z8.enum(["archive"]),
|
|
3692
|
+
mergedRecordId: z8.string().nullable(),
|
|
3693
|
+
mergedViewId: z8.string().nullable(),
|
|
3694
|
+
position: z8.number(),
|
|
3695
|
+
createdAt: z8.string(),
|
|
3696
|
+
updatedAt: z8.string(),
|
|
3594
3697
|
headCommit: commitSchema,
|
|
3595
3698
|
// Resolved canonical "before" values for the operation's target, so the UI can
|
|
3596
3699
|
// render a true before → after field diff. Null for creations (no prior state)
|
|
3597
3700
|
// and for kinds whose prior state isn't a field map (e.g. skill files, whose
|
|
3598
3701
|
// previous content lives in storage). Records resolve from the base commit;
|
|
3599
3702
|
// views resolve from the current view row ({ name, description, config }).
|
|
3600
|
-
baseFields:
|
|
3703
|
+
baseFields: z8.record(z8.string(), z8.unknown()).nullable()
|
|
3601
3704
|
});
|
|
3602
|
-
var reviewSchema =
|
|
3603
|
-
id:
|
|
3604
|
-
changeRequestId:
|
|
3605
|
-
reviewerId:
|
|
3705
|
+
var reviewSchema = z8.object({
|
|
3706
|
+
id: z8.string(),
|
|
3707
|
+
changeRequestId: z8.string(),
|
|
3708
|
+
reviewerId: z8.string(),
|
|
3606
3709
|
reviewer: userRefSchema.nullable().optional().default(null),
|
|
3607
|
-
verdict:
|
|
3608
|
-
reason:
|
|
3609
|
-
visibleOperationHeads:
|
|
3610
|
-
createdAt:
|
|
3710
|
+
verdict: z8.enum(["approved", "rejected"]),
|
|
3711
|
+
reason: z8.string().nullable(),
|
|
3712
|
+
visibleOperationHeads: z8.record(z8.string(), z8.string()),
|
|
3713
|
+
createdAt: z8.string()
|
|
3611
3714
|
});
|
|
3612
|
-
var commentSubjectTypeSchema =
|
|
3613
|
-
var commentSchema =
|
|
3614
|
-
id:
|
|
3715
|
+
var commentSubjectTypeSchema = z8.enum(["record", "change_request", "operation", "commit"]);
|
|
3716
|
+
var commentSchema = z8.object({
|
|
3717
|
+
id: z8.string(),
|
|
3615
3718
|
subjectType: commentSubjectTypeSchema,
|
|
3616
|
-
subjectId:
|
|
3617
|
-
recordId:
|
|
3618
|
-
changeRequestId:
|
|
3619
|
-
operationId:
|
|
3620
|
-
commitId:
|
|
3621
|
-
authorId:
|
|
3719
|
+
subjectId: z8.string(),
|
|
3720
|
+
recordId: z8.string().nullable(),
|
|
3721
|
+
changeRequestId: z8.string().nullable(),
|
|
3722
|
+
operationId: z8.string().nullable(),
|
|
3723
|
+
commitId: z8.string().nullable(),
|
|
3724
|
+
authorId: z8.string(),
|
|
3622
3725
|
author: userRefSchema.nullable().optional().default(null),
|
|
3623
|
-
body:
|
|
3624
|
-
mentionsAi:
|
|
3625
|
-
createdAt:
|
|
3626
|
-
updatedAt:
|
|
3726
|
+
body: z8.string(),
|
|
3727
|
+
mentionsAi: z8.boolean(),
|
|
3728
|
+
createdAt: z8.string(),
|
|
3729
|
+
updatedAt: z8.string()
|
|
3627
3730
|
});
|
|
3628
|
-
var changeRequestStatusSchema =
|
|
3731
|
+
var changeRequestStatusSchema = z8.enum([
|
|
3629
3732
|
"in_review",
|
|
3630
3733
|
"changes_requested",
|
|
3631
3734
|
"approved",
|
|
@@ -3634,53 +3737,53 @@ var changeRequestStatusSchema = z7.enum([
|
|
|
3634
3737
|
"abandoned",
|
|
3635
3738
|
"conflict"
|
|
3636
3739
|
]);
|
|
3637
|
-
var changeRequestSchema =
|
|
3638
|
-
id:
|
|
3639
|
-
baseId:
|
|
3640
|
-
targetType:
|
|
3641
|
-
nodeId:
|
|
3740
|
+
var changeRequestSchema = z8.object({
|
|
3741
|
+
id: z8.string(),
|
|
3742
|
+
baseId: z8.string().nullable(),
|
|
3743
|
+
targetType: z8.enum(["base", "node"]),
|
|
3744
|
+
nodeId: z8.string().nullable(),
|
|
3642
3745
|
status: changeRequestStatusSchema,
|
|
3643
|
-
submittedBy:
|
|
3746
|
+
submittedBy: z8.string(),
|
|
3644
3747
|
submittedByUser: userRefSchema.nullable().optional().default(null),
|
|
3645
|
-
sourceMeta:
|
|
3646
|
-
reviewPolicySnapshot:
|
|
3647
|
-
mergeSummary:
|
|
3648
|
-
rejectedReason:
|
|
3649
|
-
reviewedAt:
|
|
3650
|
-
mergedAt:
|
|
3651
|
-
createdAt:
|
|
3652
|
-
updatedAt:
|
|
3748
|
+
sourceMeta: z8.record(z8.string(), z8.unknown()),
|
|
3749
|
+
reviewPolicySnapshot: z8.record(z8.string(), z8.unknown()),
|
|
3750
|
+
mergeSummary: z8.record(z8.string(), z8.unknown()),
|
|
3751
|
+
rejectedReason: z8.string().nullable(),
|
|
3752
|
+
reviewedAt: z8.string().nullable(),
|
|
3753
|
+
mergedAt: z8.string().nullable(),
|
|
3754
|
+
createdAt: z8.string(),
|
|
3755
|
+
updatedAt: z8.string(),
|
|
3653
3756
|
base: baseSchema.nullable(),
|
|
3654
3757
|
node: nodeSchema.nullable(),
|
|
3655
|
-
operations:
|
|
3758
|
+
operations: z8.array(operationSchema),
|
|
3656
3759
|
primaryOperation: operationSchema.nullable(),
|
|
3657
|
-
operationCount:
|
|
3658
|
-
reviews:
|
|
3760
|
+
operationCount: z8.number(),
|
|
3761
|
+
reviews: z8.array(reviewSchema)
|
|
3659
3762
|
});
|
|
3660
|
-
var agentTaskSchema =
|
|
3763
|
+
var agentTaskSchema = z8.object({
|
|
3661
3764
|
changeRequest: changeRequestSchema,
|
|
3662
|
-
trigger:
|
|
3663
|
-
reviewReason:
|
|
3664
|
-
aiComments:
|
|
3765
|
+
trigger: z8.enum(["changes_requested", "ai_mention"]),
|
|
3766
|
+
reviewReason: z8.string().nullable(),
|
|
3767
|
+
aiComments: z8.array(commentSchema)
|
|
3665
3768
|
});
|
|
3666
|
-
var searchResultSchema =
|
|
3667
|
-
id:
|
|
3668
|
-
kind:
|
|
3669
|
-
title:
|
|
3670
|
-
body:
|
|
3671
|
-
eyebrow:
|
|
3672
|
-
href:
|
|
3673
|
-
updatedAt:
|
|
3769
|
+
var searchResultSchema = z8.object({
|
|
3770
|
+
id: z8.string(),
|
|
3771
|
+
kind: z8.enum(["record", "change_request", "base", "file"]),
|
|
3772
|
+
title: z8.string(),
|
|
3773
|
+
body: z8.string(),
|
|
3774
|
+
eyebrow: z8.string(),
|
|
3775
|
+
href: z8.string(),
|
|
3776
|
+
updatedAt: z8.string().nullable()
|
|
3674
3777
|
});
|
|
3675
|
-
var searchResponseSchema =
|
|
3676
|
-
query:
|
|
3677
|
-
limit:
|
|
3678
|
-
offset:
|
|
3679
|
-
hasMore:
|
|
3680
|
-
results:
|
|
3778
|
+
var searchResponseSchema = z8.object({
|
|
3779
|
+
query: z8.string(),
|
|
3780
|
+
limit: z8.number(),
|
|
3781
|
+
offset: z8.number(),
|
|
3782
|
+
hasMore: z8.boolean(),
|
|
3783
|
+
results: z8.array(searchResultSchema)
|
|
3681
3784
|
});
|
|
3682
|
-
var liveEventSchema =
|
|
3683
|
-
kind:
|
|
3785
|
+
var liveEventSchema = z8.object({
|
|
3786
|
+
kind: z8.enum([
|
|
3684
3787
|
"change_request.created",
|
|
3685
3788
|
"change_request.updated",
|
|
3686
3789
|
"change_request.deleted",
|
|
@@ -3700,18 +3803,18 @@ var liveEventSchema = z7.object({
|
|
|
3700
3803
|
// stale whiteboard/workflow/HTML document until the next reload.
|
|
3701
3804
|
"node.metadata_updated"
|
|
3702
3805
|
]),
|
|
3703
|
-
spaceId:
|
|
3704
|
-
actorId:
|
|
3806
|
+
spaceId: z8.string(),
|
|
3807
|
+
actorId: z8.string(),
|
|
3705
3808
|
// Null for events that aren't about a change request at all
|
|
3706
3809
|
// (`node.metadata_updated`), which is every direct, auto-audited write.
|
|
3707
|
-
changeRequestId:
|
|
3708
|
-
baseId:
|
|
3709
|
-
nodeIds:
|
|
3710
|
-
recordIds:
|
|
3711
|
-
viewIds:
|
|
3712
|
-
operationCount:
|
|
3810
|
+
changeRequestId: z8.string().nullable(),
|
|
3811
|
+
baseId: z8.string().nullable(),
|
|
3812
|
+
nodeIds: z8.array(z8.string()),
|
|
3813
|
+
recordIds: z8.array(z8.string()),
|
|
3814
|
+
viewIds: z8.array(z8.string()),
|
|
3815
|
+
operationCount: z8.number()
|
|
3713
3816
|
});
|
|
3714
|
-
var auditActionSchema =
|
|
3817
|
+
var auditActionSchema = z8.enum([
|
|
3715
3818
|
"record.viewed",
|
|
3716
3819
|
"change_request.created",
|
|
3717
3820
|
"change_request.updated",
|
|
@@ -3736,158 +3839,174 @@ var auditActionSchema = z7.enum([
|
|
|
3736
3839
|
"node.metadata_updated",
|
|
3737
3840
|
"node.purged"
|
|
3738
3841
|
]);
|
|
3739
|
-
var auditEventSchema =
|
|
3740
|
-
id:
|
|
3842
|
+
var auditEventSchema = z8.object({
|
|
3843
|
+
id: z8.string(),
|
|
3741
3844
|
action: auditActionSchema,
|
|
3742
|
-
actorId:
|
|
3845
|
+
actorId: z8.string(),
|
|
3743
3846
|
actor: userRefSchema.nullable().optional().default(null),
|
|
3744
|
-
baseId:
|
|
3745
|
-
recordId:
|
|
3746
|
-
changeRequestId:
|
|
3747
|
-
operationId:
|
|
3748
|
-
commitId:
|
|
3749
|
-
metadata:
|
|
3750
|
-
createdAt:
|
|
3847
|
+
baseId: z8.string().nullable(),
|
|
3848
|
+
recordId: z8.string().nullable(),
|
|
3849
|
+
changeRequestId: z8.string().nullable(),
|
|
3850
|
+
operationId: z8.string().nullable(),
|
|
3851
|
+
commitId: z8.string().nullable(),
|
|
3852
|
+
metadata: z8.record(z8.string(), z8.unknown()),
|
|
3853
|
+
createdAt: z8.string()
|
|
3751
3854
|
});
|
|
3752
|
-
var createAuditEventInputSchema =
|
|
3855
|
+
var createAuditEventInputSchema = z8.object({
|
|
3753
3856
|
action: auditActionSchema,
|
|
3754
|
-
actorId:
|
|
3755
|
-
baseId:
|
|
3756
|
-
recordId:
|
|
3757
|
-
changeRequestId:
|
|
3758
|
-
operationId:
|
|
3759
|
-
commitId:
|
|
3760
|
-
metadata:
|
|
3857
|
+
actorId: z8.string().optional().default("local-viewer"),
|
|
3858
|
+
baseId: z8.string().optional().nullable(),
|
|
3859
|
+
recordId: z8.string().optional().nullable(),
|
|
3860
|
+
changeRequestId: z8.string().optional().nullable(),
|
|
3861
|
+
operationId: z8.string().optional().nullable(),
|
|
3862
|
+
commitId: z8.string().optional().nullable(),
|
|
3863
|
+
metadata: z8.record(z8.string(), z8.unknown()).optional().default({})
|
|
3761
3864
|
});
|
|
3762
|
-
var nodeOperationInputSchema =
|
|
3763
|
-
|
|
3764
|
-
kind:
|
|
3765
|
-
ref:
|
|
3865
|
+
var nodeOperationInputSchema = z8.discriminatedUnion("kind", [
|
|
3866
|
+
z8.object({
|
|
3867
|
+
kind: z8.literal("create"),
|
|
3868
|
+
ref: z8.string().min(1).optional().describe(
|
|
3766
3869
|
'Optional in-change-request temp id for this node. A later operation can set parentNodeRef to this value to nest under it \u2014 e.g. create a folder with ref "growth", then create Bases with parentNodeRef "growth", all in one change request.'
|
|
3767
3870
|
),
|
|
3768
|
-
parentNodeId:
|
|
3769
|
-
parentNodeRef:
|
|
3871
|
+
parentNodeId: z8.string().optional(),
|
|
3872
|
+
parentNodeRef: z8.string().min(1).optional().describe(
|
|
3770
3873
|
"Parent this node under a node an EARLIER operation in the same change request created (matched by its ref). Mutually exclusive with parentNodeId."
|
|
3771
3874
|
),
|
|
3772
|
-
nodeType:
|
|
3773
|
-
slug:
|
|
3774
|
-
name:
|
|
3775
|
-
description:
|
|
3776
|
-
metadata:
|
|
3875
|
+
nodeType: z8.enum(CREATABLE_NODE_TYPES),
|
|
3876
|
+
slug: z8.string().min(1).regex(/^[a-z0-9-]+$/),
|
|
3877
|
+
name: z8.string().min(1),
|
|
3878
|
+
description: z8.string().optional().default(""),
|
|
3879
|
+
metadata: z8.record(z8.string(), z8.unknown()).optional().default({}),
|
|
3777
3880
|
// Base fields (nodeType "base" only); a base needs at least one field.
|
|
3778
|
-
fields:
|
|
3779
|
-
|
|
3780
|
-
slug:
|
|
3881
|
+
fields: z8.array(
|
|
3882
|
+
z8.object({
|
|
3883
|
+
slug: z8.string().min(1).regex(/^[a-z0-9-]+$/),
|
|
3781
3884
|
name: fieldNameSchema,
|
|
3782
3885
|
type: fieldTypeSchema.default("text"),
|
|
3783
|
-
required:
|
|
3886
|
+
required: z8.boolean().optional().default(false),
|
|
3784
3887
|
options: fieldOptionsSchema.optional().default({})
|
|
3785
3888
|
})
|
|
3786
3889
|
).optional()
|
|
3787
3890
|
}),
|
|
3788
|
-
|
|
3789
|
-
kind:
|
|
3790
|
-
nodeId:
|
|
3791
|
-
slug:
|
|
3792
|
-
name:
|
|
3793
|
-
description:
|
|
3891
|
+
z8.object({
|
|
3892
|
+
kind: z8.literal("rename"),
|
|
3893
|
+
nodeId: z8.string(),
|
|
3894
|
+
slug: z8.string().min(1).regex(/^[a-z0-9-]+$/).optional(),
|
|
3895
|
+
name: z8.string().min(1).optional(),
|
|
3896
|
+
description: z8.string().optional()
|
|
3794
3897
|
}),
|
|
3795
|
-
|
|
3796
|
-
kind:
|
|
3797
|
-
nodeId:
|
|
3898
|
+
z8.object({
|
|
3899
|
+
kind: z8.literal("delete"),
|
|
3900
|
+
nodeId: z8.string()
|
|
3798
3901
|
}),
|
|
3799
|
-
|
|
3800
|
-
kind:
|
|
3801
|
-
nodeId:
|
|
3902
|
+
z8.object({
|
|
3903
|
+
kind: z8.literal("restore"),
|
|
3904
|
+
nodeId: z8.string()
|
|
3802
3905
|
}),
|
|
3803
|
-
|
|
3804
|
-
kind:
|
|
3805
|
-
nodeId:
|
|
3906
|
+
z8.object({
|
|
3907
|
+
kind: z8.literal("move"),
|
|
3908
|
+
nodeId: z8.string(),
|
|
3806
3909
|
// Exactly one of parentNodeId / parentNodeRef (a ref created earlier in this CR).
|
|
3807
|
-
parentNodeId:
|
|
3808
|
-
parentNodeRef:
|
|
3809
|
-
position:
|
|
3910
|
+
parentNodeId: z8.string().optional(),
|
|
3911
|
+
parentNodeRef: z8.string().min(1).optional(),
|
|
3912
|
+
position: z8.number().int().optional()
|
|
3810
3913
|
})
|
|
3811
3914
|
]);
|
|
3812
|
-
var createNodeChangeRequestInputSchema =
|
|
3813
|
-
message:
|
|
3915
|
+
var createNodeChangeRequestInputSchema = z8.object({
|
|
3916
|
+
message: z8.string().optional().default("Update node tree").describe(
|
|
3814
3917
|
'Explanation shown to the human reviewer. Write a conventional-commit style subject \u2014 imperative verb + what + why, e.g. "Reorganize marketing docs under a Campaigns folder".'
|
|
3815
3918
|
),
|
|
3816
|
-
submittedBy:
|
|
3817
|
-
autoMerge:
|
|
3919
|
+
submittedBy: z8.string().optional().default("local-producer"),
|
|
3920
|
+
autoMerge: z8.boolean().optional().describe(
|
|
3818
3921
|
"Whether to approve and merge this structural node change immediately. Omitted defaults to merging immediately if the actor has write access on every target node, otherwise falling back to a pending Change Request; pass explicit false to force review even with write access."
|
|
3819
3922
|
),
|
|
3820
|
-
operations:
|
|
3923
|
+
operations: z8.array(nodeOperationInputSchema).min(1)
|
|
3821
3924
|
});
|
|
3822
|
-
var moveNodeInputSchema =
|
|
3823
|
-
nodeId:
|
|
3824
|
-
parentNodeId:
|
|
3825
|
-
position:
|
|
3826
|
-
message:
|
|
3827
|
-
submittedBy:
|
|
3925
|
+
var moveNodeInputSchema = z8.object({
|
|
3926
|
+
nodeId: z8.string(),
|
|
3927
|
+
parentNodeId: z8.string().optional().describe("New parent folder node id. Omit to keep the current parent and only reorder."),
|
|
3928
|
+
position: z8.number().int().optional().describe("New position among the target parent's children."),
|
|
3929
|
+
message: z8.string().optional().describe("Reviewer-facing Change Request message."),
|
|
3930
|
+
submittedBy: z8.string().optional()
|
|
3828
3931
|
});
|
|
3829
|
-
var createDeleteChangeRequestInputSchema =
|
|
3830
|
-
message:
|
|
3932
|
+
var createDeleteChangeRequestInputSchema = z8.object({
|
|
3933
|
+
message: z8.string().optional().default("Delete record").describe(
|
|
3831
3934
|
'Explanation shown to the human reviewer. Say what is being removed and why, e.g. "Archive duplicate contact \u2014 merged into Acme Corp".'
|
|
3832
3935
|
),
|
|
3833
|
-
submittedBy:
|
|
3936
|
+
submittedBy: z8.string().optional().default("local-producer"),
|
|
3834
3937
|
// Only "archive" is supported — hard delete after retention was never
|
|
3835
3938
|
// implemented, so the API no longer accepts it (breaking change).
|
|
3836
|
-
deleteMode:
|
|
3939
|
+
deleteMode: z8.enum(["archive"]).optional().default("archive"),
|
|
3940
|
+
autoMerge: autoMergeNotAccepted(
|
|
3941
|
+
"archiving a record removes user content from every listing, so it always requires review. Omit the flag."
|
|
3942
|
+
)
|
|
3837
3943
|
});
|
|
3838
|
-
var reviseOperationInputSchema =
|
|
3839
|
-
fields:
|
|
3944
|
+
var reviseOperationInputSchema = z8.object({
|
|
3945
|
+
fields: z8.record(z8.string(), z8.unknown()).describe(
|
|
3840
3946
|
"Updated field values keyed by field slug. If you set the base's PRIMARY field (its first field), keep it a short human-readable name \u2014 it is the record's display title everywhere."
|
|
3841
3947
|
),
|
|
3842
|
-
message:
|
|
3948
|
+
message: z8.string().optional().default("Revise operation").describe(
|
|
3843
3949
|
'Explanation shown to the human reviewer. Write a conventional-commit style subject \u2014 imperative verb + what + why, e.g. "Update deal stage to qualified \u2014 demo booked for July 8".'
|
|
3844
3950
|
),
|
|
3845
|
-
author:
|
|
3846
|
-
baseCommitId:
|
|
3951
|
+
author: z8.string().optional().default("local-producer"),
|
|
3952
|
+
baseCommitId: z8.string().optional()
|
|
3847
3953
|
});
|
|
3848
|
-
var reviewChangeRequestInputSchema =
|
|
3849
|
-
verdict:
|
|
3850
|
-
reason:
|
|
3954
|
+
var reviewChangeRequestInputSchema = z8.object({
|
|
3955
|
+
verdict: z8.enum(["approved", "rejected"]),
|
|
3956
|
+
reason: z8.string().optional()
|
|
3851
3957
|
});
|
|
3852
|
-
var commentSubjectInputSchema =
|
|
3958
|
+
var commentSubjectInputSchema = z8.object({
|
|
3853
3959
|
subjectType: commentSubjectTypeSchema,
|
|
3854
|
-
subjectId:
|
|
3960
|
+
subjectId: z8.string().min(1)
|
|
3855
3961
|
});
|
|
3856
3962
|
var createCommentInputSchema = commentSubjectInputSchema.extend({
|
|
3857
|
-
authorId:
|
|
3858
|
-
body:
|
|
3859
|
-
mentionsAi:
|
|
3963
|
+
authorId: z8.string().optional().default("local-admin"),
|
|
3964
|
+
body: z8.string().trim().min(1),
|
|
3965
|
+
mentionsAi: z8.boolean().optional().default(false)
|
|
3860
3966
|
});
|
|
3861
|
-
var listInputSchema =
|
|
3862
|
-
limit:
|
|
3967
|
+
var listInputSchema = z8.object({
|
|
3968
|
+
limit: z8.coerce.number().int().min(1).max(100).optional().default(50)
|
|
3863
3969
|
}).optional().default({ limit: 50 });
|
|
3864
|
-
var listByStatusInputSchema =
|
|
3865
|
-
status:
|
|
3970
|
+
var listByStatusInputSchema = z8.object({
|
|
3971
|
+
status: z8.enum(["active", "archived"]).optional().default("active")
|
|
3866
3972
|
});
|
|
3867
|
-
var listChangeRequestsPagedInputSchema =
|
|
3868
|
-
limit:
|
|
3973
|
+
var listChangeRequestsPagedInputSchema = z8.object({
|
|
3974
|
+
limit: z8.coerce.number().int().min(1).max(100).optional().default(50),
|
|
3869
3975
|
/** Opaque base64 cursor (`createdAt|id`) for keyset pagination. */
|
|
3870
|
-
cursor:
|
|
3871
|
-
status:
|
|
3872
|
-
mine:
|
|
3976
|
+
cursor: z8.string().optional(),
|
|
3977
|
+
status: z8.array(changeRequestStatusSchema).optional(),
|
|
3978
|
+
mine: z8.boolean().optional()
|
|
3873
3979
|
}).optional().default({ limit: 50 });
|
|
3874
|
-
var listChangeRequestsResponseSchema =
|
|
3875
|
-
changeRequests:
|
|
3876
|
-
nextCursor:
|
|
3980
|
+
var listChangeRequestsResponseSchema = z8.object({
|
|
3981
|
+
changeRequests: z8.array(changeRequestSchema),
|
|
3982
|
+
nextCursor: z8.string().nullable()
|
|
3877
3983
|
});
|
|
3878
|
-
var
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3984
|
+
var listChangeRequestsPageInputSchema = z8.object({
|
|
3985
|
+
page: z8.coerce.number().int().min(1).optional().default(1),
|
|
3986
|
+
pageSize: z8.coerce.number().int().min(1).max(100).optional().default(50),
|
|
3987
|
+
status: z8.array(changeRequestStatusSchema).optional(),
|
|
3988
|
+
mine: z8.boolean().optional()
|
|
3989
|
+
}).optional().default({ page: 1, pageSize: 50 });
|
|
3990
|
+
var listChangeRequestsPageResponseSchema = z8.object({
|
|
3991
|
+
changeRequests: z8.array(changeRequestSchema),
|
|
3992
|
+
total: z8.number().int().nonnegative(),
|
|
3993
|
+
totalPages: z8.number().int().nonnegative(),
|
|
3994
|
+
page: z8.number().int().min(1),
|
|
3995
|
+
pageSize: z8.number().int().min(1).max(100)
|
|
3996
|
+
});
|
|
3997
|
+
var changeRequestCountsSchema = z8.object({
|
|
3998
|
+
review: z8.number().int().nonnegative(),
|
|
3999
|
+
changes: z8.number().int().nonnegative(),
|
|
4000
|
+
created: z8.number().int().nonnegative(),
|
|
4001
|
+
approved: z8.number().int().nonnegative(),
|
|
4002
|
+
merged: z8.number().int().nonnegative(),
|
|
4003
|
+
rejected: z8.number().int().nonnegative()
|
|
3885
4004
|
});
|
|
3886
4005
|
var SEARCH_SOURCES = ["records", "files", "names"];
|
|
3887
|
-
var searchInputSchema =
|
|
3888
|
-
query:
|
|
3889
|
-
limit:
|
|
3890
|
-
offset:
|
|
4006
|
+
var searchInputSchema = z8.object({
|
|
4007
|
+
query: z8.string().default(""),
|
|
4008
|
+
limit: z8.coerce.number().int().min(1).max(100).optional().default(20),
|
|
4009
|
+
offset: z8.coerce.number().int().min(0).optional().default(0),
|
|
3891
4010
|
/**
|
|
3892
4011
|
* Restrict which content this call searches. Omitted means all three
|
|
3893
4012
|
* (unchanged behavior for every caller before this parameter existed).
|
|
@@ -3897,13 +4016,13 @@ var searchInputSchema = z7.object({
|
|
|
3897
4016
|
* (`?sources=records&sources=files`) becomes an array. Accept both shapes
|
|
3898
4017
|
* and normalize to an array.
|
|
3899
4018
|
*/
|
|
3900
|
-
sources:
|
|
4019
|
+
sources: z8.union([z8.array(z8.enum(SEARCH_SOURCES)), z8.enum(SEARCH_SOURCES)]).transform((value) => Array.isArray(value) ? value : [value]).optional()
|
|
3901
4020
|
});
|
|
3902
|
-
var authSpaceSchema =
|
|
3903
|
-
id:
|
|
3904
|
-
name:
|
|
3905
|
-
slug:
|
|
3906
|
-
plan:
|
|
4021
|
+
var authSpaceSchema = z8.object({
|
|
4022
|
+
id: z8.string(),
|
|
4023
|
+
name: z8.string(),
|
|
4024
|
+
slug: z8.string().nullable(),
|
|
4025
|
+
plan: z8.string().nullable(),
|
|
3907
4026
|
/**
|
|
3908
4027
|
* The space's DEFAULT content visibility for its members — the same
|
|
3909
4028
|
* `spaces.nodeVisibilityMode` the cloud dashboard reads. `"open"` = a node
|
|
@@ -3919,20 +4038,20 @@ var authSpaceSchema = z7.object({
|
|
|
3919
4038
|
* (or a host that doesn't model a space default at all) simply omits it.
|
|
3920
4039
|
* Treat an absent value as `"open"` — the historical behaviour.
|
|
3921
4040
|
*/
|
|
3922
|
-
nodeVisibilityMode:
|
|
4041
|
+
nodeVisibilityMode: z8.enum(["open", "restricted"]).optional()
|
|
3923
4042
|
});
|
|
3924
|
-
var authUserSchema =
|
|
3925
|
-
id:
|
|
3926
|
-
name:
|
|
3927
|
-
email:
|
|
3928
|
-
image:
|
|
4043
|
+
var authUserSchema = z8.object({
|
|
4044
|
+
id: z8.string(),
|
|
4045
|
+
name: z8.string(),
|
|
4046
|
+
email: z8.string().nullable(),
|
|
4047
|
+
image: z8.string().nullable()
|
|
3929
4048
|
});
|
|
3930
|
-
var authMemberSchema =
|
|
3931
|
-
userId:
|
|
3932
|
-
spaceId:
|
|
3933
|
-
role:
|
|
4049
|
+
var authMemberSchema = z8.object({
|
|
4050
|
+
userId: z8.string(),
|
|
4051
|
+
spaceId: z8.string(),
|
|
4052
|
+
role: z8.string()
|
|
3934
4053
|
});
|
|
3935
|
-
var authInfoSchema =
|
|
4054
|
+
var authInfoSchema = z8.object({
|
|
3936
4055
|
/** The space this request is scoped to (explicit `x-busabase-space` header, else the default). */
|
|
3937
4056
|
space: authSpaceSchema,
|
|
3938
4057
|
user: authUserSchema,
|
|
@@ -3942,11 +4061,11 @@ var authInfoSchema = z7.object({
|
|
|
3942
4061
|
* space-scoped — when this has more than one entry, callers should confirm the
|
|
3943
4062
|
* intended space and target it explicitly via the `x-busabase-space` header.
|
|
3944
4063
|
*/
|
|
3945
|
-
spaces:
|
|
4064
|
+
spaces: z8.array(authSpaceSchema),
|
|
3946
4065
|
/** Cloud only: the server created this user's first Space during this exact request. */
|
|
3947
|
-
createdSpace:
|
|
4066
|
+
createdSpace: z8.boolean().optional(),
|
|
3948
4067
|
/** Cloud only: this auto-created Space still needs its idempotent starter initialization. */
|
|
3949
|
-
bootstrapRequired:
|
|
4068
|
+
bootstrapRequired: z8.boolean().optional()
|
|
3950
4069
|
});
|
|
3951
4070
|
|
|
3952
4071
|
// ../../packages/busabase-contract/src/domains/base/types.ts
|
|
@@ -3954,7 +4073,7 @@ var VIEW_FIELD_MIN_WIDTH = 92;
|
|
|
3954
4073
|
var VIEW_FIELD_MAX_WIDTH = 640;
|
|
3955
4074
|
|
|
3956
4075
|
// ../../packages/busabase-contract/src/domains/base/contract/view-schemas.ts
|
|
3957
|
-
var viewFilterOperatorSchema =
|
|
4076
|
+
var viewFilterOperatorSchema = z9.enum([
|
|
3958
4077
|
"contains",
|
|
3959
4078
|
"equals",
|
|
3960
4079
|
"not_empty",
|
|
@@ -3962,107 +4081,107 @@ var viewFilterOperatorSchema = z8.enum([
|
|
|
3962
4081
|
"is_true",
|
|
3963
4082
|
"is_false"
|
|
3964
4083
|
]);
|
|
3965
|
-
var viewFilterSchema =
|
|
3966
|
-
fieldSlug:
|
|
4084
|
+
var viewFilterSchema = z9.object({
|
|
4085
|
+
fieldSlug: z9.string(),
|
|
3967
4086
|
// Stable field identity — survives slug reuse; populated on merge.
|
|
3968
|
-
fieldId:
|
|
4087
|
+
fieldId: z9.string().optional(),
|
|
3969
4088
|
operator: viewFilterOperatorSchema,
|
|
3970
|
-
value:
|
|
4089
|
+
value: z9.unknown().optional()
|
|
3971
4090
|
});
|
|
3972
|
-
var viewSortSchema =
|
|
3973
|
-
direction:
|
|
3974
|
-
fieldSlug:
|
|
3975
|
-
fieldId:
|
|
4091
|
+
var viewSortSchema = z9.object({
|
|
4092
|
+
direction: z9.enum(["asc", "desc"]),
|
|
4093
|
+
fieldSlug: z9.string(),
|
|
4094
|
+
fieldId: z9.string().optional()
|
|
3976
4095
|
});
|
|
3977
|
-
var viewTypeSchema =
|
|
3978
|
-
var ganttScaleSchema =
|
|
3979
|
-
var galleryCoverFitSchema =
|
|
3980
|
-
var galleryCardSizeSchema =
|
|
3981
|
-
var viewConfigSchema =
|
|
3982
|
-
filters:
|
|
3983
|
-
sorts:
|
|
3984
|
-
visibleFieldSlugs:
|
|
3985
|
-
fieldWidths:
|
|
4096
|
+
var viewTypeSchema = z9.enum(["table", "gallery", "kanban", "calendar", "gantt"]);
|
|
4097
|
+
var ganttScaleSchema = z9.enum(["week", "month"]);
|
|
4098
|
+
var galleryCoverFitSchema = z9.enum(["cover", "fit"]);
|
|
4099
|
+
var galleryCardSizeSchema = z9.enum(["small", "medium", "large"]);
|
|
4100
|
+
var viewConfigSchema = z9.object({
|
|
4101
|
+
filters: z9.array(viewFilterSchema).default([]),
|
|
4102
|
+
sorts: z9.array(viewSortSchema).default([]),
|
|
4103
|
+
visibleFieldSlugs: z9.array(z9.string()).nullable().optional(),
|
|
4104
|
+
fieldWidths: z9.record(z9.string().min(1), z9.number().int().min(VIEW_FIELD_MIN_WIDTH).max(VIEW_FIELD_MAX_WIDTH)).optional(),
|
|
3986
4105
|
// ── Gallery-only presentation config (ignored by table views) ──
|
|
3987
4106
|
// Which attachment field supplies the cover image (null = no cover).
|
|
3988
|
-
coverFieldSlug:
|
|
4107
|
+
coverFieldSlug: z9.string().nullable().optional(),
|
|
3989
4108
|
coverFit: galleryCoverFitSchema.optional(),
|
|
3990
4109
|
cardSize: galleryCardSizeSchema.optional(),
|
|
3991
4110
|
// Whether to render the field label above each value on a card.
|
|
3992
|
-
showFieldLabels:
|
|
4111
|
+
showFieldLabels: z9.boolean().optional(),
|
|
3993
4112
|
// ── Kanban-only: which single-select field stacks records into columns.
|
|
3994
|
-
stackByFieldSlug:
|
|
4113
|
+
stackByFieldSlug: z9.string().nullable().optional(),
|
|
3995
4114
|
// ── Calendar-only: which date field positions records on the month grid.
|
|
3996
|
-
dateFieldSlug:
|
|
4115
|
+
dateFieldSlug: z9.string().nullable().optional(),
|
|
3997
4116
|
// ── Gantt-only: the start/end date fields bounding each record's bar, plus
|
|
3998
4117
|
// the time-axis granularity.
|
|
3999
|
-
startFieldSlug:
|
|
4000
|
-
endFieldSlug:
|
|
4118
|
+
startFieldSlug: z9.string().nullable().optional(),
|
|
4119
|
+
endFieldSlug: z9.string().nullable().optional(),
|
|
4001
4120
|
ganttScale: ganttScaleSchema.optional()
|
|
4002
4121
|
});
|
|
4003
|
-
var viewSchema =
|
|
4004
|
-
id:
|
|
4005
|
-
baseId:
|
|
4006
|
-
slug:
|
|
4007
|
-
name:
|
|
4008
|
-
description:
|
|
4122
|
+
var viewSchema = z9.object({
|
|
4123
|
+
id: z9.string(),
|
|
4124
|
+
baseId: z9.string(),
|
|
4125
|
+
slug: z9.string(),
|
|
4126
|
+
name: z9.string(),
|
|
4127
|
+
description: z9.string(),
|
|
4009
4128
|
type: viewTypeSchema,
|
|
4010
4129
|
config: viewConfigSchema,
|
|
4011
|
-
status:
|
|
4012
|
-
createdBy:
|
|
4130
|
+
status: z9.enum(["active", "archived"]),
|
|
4131
|
+
createdBy: z9.string(),
|
|
4013
4132
|
createdByUser: userRefSchema.nullable().optional().default(null),
|
|
4014
|
-
archivedAt:
|
|
4015
|
-
createdAt:
|
|
4016
|
-
updatedAt:
|
|
4133
|
+
archivedAt: z9.string().nullable(),
|
|
4134
|
+
createdAt: z9.string(),
|
|
4135
|
+
updatedAt: z9.string()
|
|
4017
4136
|
});
|
|
4018
|
-
var autoMergeSchema =
|
|
4137
|
+
var autoMergeSchema = z9.boolean().optional().describe(
|
|
4019
4138
|
"Whether to approve and merge this view change immediately. Omitted defaults to merging immediately if the actor has write access on the Base's node, otherwise falling back to a pending Change Request; pass explicit false to force review even with write access."
|
|
4020
4139
|
);
|
|
4021
|
-
var createViewInputSchema =
|
|
4140
|
+
var createViewInputSchema = z9.object({
|
|
4022
4141
|
config: viewConfigSchema.optional().default({ filters: [], sorts: [] }),
|
|
4023
|
-
description:
|
|
4024
|
-
message:
|
|
4025
|
-
name:
|
|
4142
|
+
description: z9.string().optional().default(""),
|
|
4143
|
+
message: z9.string().optional().default("Create view"),
|
|
4144
|
+
name: z9.string().min(1),
|
|
4026
4145
|
type: viewTypeSchema.optional().default("table"),
|
|
4027
|
-
slug:
|
|
4028
|
-
submittedBy:
|
|
4146
|
+
slug: z9.string().min(1).regex(/^[a-z0-9-]+$/).optional(),
|
|
4147
|
+
submittedBy: z9.string().optional().default("local-producer"),
|
|
4029
4148
|
autoMerge: autoMergeSchema
|
|
4030
4149
|
});
|
|
4031
|
-
var updateViewInputSchema =
|
|
4150
|
+
var updateViewInputSchema = z9.object({
|
|
4032
4151
|
config: viewConfigSchema.optional(),
|
|
4033
|
-
description:
|
|
4034
|
-
message:
|
|
4035
|
-
name:
|
|
4152
|
+
description: z9.string().optional(),
|
|
4153
|
+
message: z9.string().optional().default("Update view"),
|
|
4154
|
+
name: z9.string().min(1).optional(),
|
|
4036
4155
|
type: viewTypeSchema.optional(),
|
|
4037
|
-
submittedBy:
|
|
4156
|
+
submittedBy: z9.string().optional().default("local-producer"),
|
|
4038
4157
|
autoMerge: autoMergeSchema
|
|
4039
4158
|
});
|
|
4040
|
-
var deleteViewInputSchema =
|
|
4041
|
-
message:
|
|
4042
|
-
submittedBy:
|
|
4159
|
+
var deleteViewInputSchema = z9.object({
|
|
4160
|
+
message: z9.string().optional().default("Delete view"),
|
|
4161
|
+
submittedBy: z9.string().optional().default("local-producer"),
|
|
4043
4162
|
autoMerge: autoMergeSchema
|
|
4044
4163
|
});
|
|
4045
|
-
var restoreViewInputSchema =
|
|
4046
|
-
message:
|
|
4047
|
-
submittedBy:
|
|
4164
|
+
var restoreViewInputSchema = z9.object({
|
|
4165
|
+
message: z9.string().optional().default("Restore view"),
|
|
4166
|
+
submittedBy: z9.string().optional().default("local-producer"),
|
|
4048
4167
|
autoMerge: autoMergeSchema
|
|
4049
4168
|
});
|
|
4050
|
-
var viewChangeRequestInputSchema =
|
|
4169
|
+
var viewChangeRequestInputSchema = z9.discriminatedUnion("operation", [
|
|
4051
4170
|
createViewInputSchema.extend({
|
|
4052
|
-
operation:
|
|
4053
|
-
baseId:
|
|
4171
|
+
operation: z9.literal("create"),
|
|
4172
|
+
baseId: z9.string().min(1).describe("Base the new view belongs to.")
|
|
4054
4173
|
}),
|
|
4055
4174
|
updateViewInputSchema.extend({
|
|
4056
|
-
operation:
|
|
4057
|
-
viewId:
|
|
4175
|
+
operation: z9.literal("update"),
|
|
4176
|
+
viewId: z9.string().min(1)
|
|
4058
4177
|
}),
|
|
4059
4178
|
deleteViewInputSchema.extend({
|
|
4060
|
-
operation:
|
|
4061
|
-
viewId:
|
|
4179
|
+
operation: z9.literal("delete"),
|
|
4180
|
+
viewId: z9.string().min(1)
|
|
4062
4181
|
}),
|
|
4063
4182
|
restoreViewInputSchema.extend({
|
|
4064
|
-
operation:
|
|
4065
|
-
viewId:
|
|
4183
|
+
operation: z9.literal("restore"),
|
|
4184
|
+
viewId: z9.string().min(1)
|
|
4066
4185
|
})
|
|
4067
4186
|
]);
|
|
4068
4187
|
|
|
@@ -4104,141 +4223,141 @@ var PACKAGE_MAX_FILE_BYTES = 25 * 1024 * 1024;
|
|
|
4104
4223
|
var PACKAGE_MAX_TOTAL_BYTES = 250 * 1024 * 1024;
|
|
4105
4224
|
var PACKAGE_MAX_FILE_COUNT = 5e3;
|
|
4106
4225
|
var PACKAGE_MAX_RECORDS_PER_BASE = 5e4;
|
|
4107
|
-
var PackageManifestSchema =
|
|
4108
|
-
format:
|
|
4226
|
+
var PackageManifestSchema = z10.object({
|
|
4227
|
+
format: z10.literal(PACKAGE_FORMAT),
|
|
4109
4228
|
/** Default `--into-folder` name. Not the repo name — a repo can host many packages. */
|
|
4110
|
-
name:
|
|
4111
|
-
description:
|
|
4229
|
+
name: z10.string().min(1),
|
|
4230
|
+
description: z10.string().default(""),
|
|
4112
4231
|
/**
|
|
4113
4232
|
* Informational / reserved for a future marketplace index. The real version pin
|
|
4114
4233
|
* is always the git ref in the install URL.
|
|
4115
4234
|
*/
|
|
4116
|
-
version:
|
|
4117
|
-
author:
|
|
4118
|
-
license:
|
|
4119
|
-
homepage:
|
|
4120
|
-
tags:
|
|
4235
|
+
version: z10.string().optional(),
|
|
4236
|
+
author: z10.string().optional(),
|
|
4237
|
+
license: z10.string().optional(),
|
|
4238
|
+
homepage: z10.string().url().optional(),
|
|
4239
|
+
tags: z10.array(z10.string()).default([])
|
|
4121
4240
|
});
|
|
4122
|
-
var PackageFileTreeNodeMetaSchema =
|
|
4123
|
-
type:
|
|
4124
|
-
name:
|
|
4125
|
-
description:
|
|
4126
|
-
position:
|
|
4241
|
+
var PackageFileTreeNodeMetaSchema = z10.object({
|
|
4242
|
+
type: z10.enum(PACKAGE_FILE_TREE_NODE_TYPES),
|
|
4243
|
+
name: z10.string().min(1),
|
|
4244
|
+
description: z10.string().default(""),
|
|
4245
|
+
position: z10.number().int().optional()
|
|
4127
4246
|
});
|
|
4128
|
-
var PackageFolderMetaSchema =
|
|
4247
|
+
var PackageFolderMetaSchema = z10.object({
|
|
4129
4248
|
/** Defaults to the humanized slug when absent. */
|
|
4130
|
-
name:
|
|
4131
|
-
description:
|
|
4132
|
-
position:
|
|
4249
|
+
name: z10.string().optional(),
|
|
4250
|
+
description: z10.string().default(""),
|
|
4251
|
+
position: z10.number().int().optional()
|
|
4133
4252
|
});
|
|
4134
4253
|
var PackageFileNodeMetaSchema = PackageFolderMetaSchema;
|
|
4135
|
-
var PackageDocFrontmatterSchema =
|
|
4136
|
-
name:
|
|
4137
|
-
description:
|
|
4138
|
-
position:
|
|
4254
|
+
var PackageDocFrontmatterSchema = z10.object({
|
|
4255
|
+
name: z10.string().min(1),
|
|
4256
|
+
description: z10.string().default(""),
|
|
4257
|
+
position: z10.number().int().optional()
|
|
4139
4258
|
});
|
|
4140
|
-
var PackageFieldOptionsSchema =
|
|
4141
|
-
ai:
|
|
4142
|
-
model:
|
|
4143
|
-
prompt:
|
|
4144
|
-
reviewRequired:
|
|
4259
|
+
var PackageFieldOptionsSchema = z10.object({
|
|
4260
|
+
ai: z10.object({
|
|
4261
|
+
model: z10.string().optional(),
|
|
4262
|
+
prompt: z10.string().optional(),
|
|
4263
|
+
reviewRequired: z10.boolean().optional(),
|
|
4145
4264
|
/** Package-only — replaces `ai.sourceFieldIds`. */
|
|
4146
|
-
sourceFieldSlugs:
|
|
4265
|
+
sourceFieldSlugs: z10.array(z10.string()).optional()
|
|
4147
4266
|
}).optional(),
|
|
4148
|
-
attachment:
|
|
4149
|
-
maxFiles:
|
|
4150
|
-
allowedMimeTypes:
|
|
4151
|
-
maxFileSize:
|
|
4267
|
+
attachment: z10.object({
|
|
4268
|
+
maxFiles: z10.number().int().positive().optional(),
|
|
4269
|
+
allowedMimeTypes: z10.array(z10.string()).optional(),
|
|
4270
|
+
maxFileSize: z10.number().int().positive().optional()
|
|
4152
4271
|
}).optional(),
|
|
4153
|
-
choices:
|
|
4154
|
-
|
|
4155
|
-
color:
|
|
4156
|
-
id:
|
|
4157
|
-
name:
|
|
4272
|
+
choices: z10.array(
|
|
4273
|
+
z10.object({
|
|
4274
|
+
color: z10.string().optional(),
|
|
4275
|
+
id: z10.string(),
|
|
4276
|
+
name: z10.string()
|
|
4158
4277
|
})
|
|
4159
4278
|
).optional(),
|
|
4160
|
-
code:
|
|
4161
|
-
language:
|
|
4279
|
+
code: z10.object({
|
|
4280
|
+
language: z10.string().optional()
|
|
4162
4281
|
}).optional(),
|
|
4163
|
-
embed:
|
|
4164
|
-
aspectRatio:
|
|
4165
|
-
height:
|
|
4166
|
-
providers:
|
|
4282
|
+
embed: z10.object({
|
|
4283
|
+
aspectRatio: z10.enum(["16:9", "4:3", "1:1"]).optional(),
|
|
4284
|
+
height: z10.number().int().positive().max(1200).optional(),
|
|
4285
|
+
providers: z10.array(z10.string()).optional()
|
|
4167
4286
|
}).optional(),
|
|
4168
4287
|
/** Mirrors the API's `formula.expression` verbatim — `{slug}` references carry
|
|
4169
4288
|
* over unchanged since the package format keys everything by slug already. */
|
|
4170
|
-
formula:
|
|
4171
|
-
expression:
|
|
4289
|
+
formula: z10.object({
|
|
4290
|
+
expression: z10.string().min(1)
|
|
4172
4291
|
}).optional(),
|
|
4173
4292
|
/** Package-only — replaces `inverseFieldId`. */
|
|
4174
|
-
inverseFieldSlug:
|
|
4293
|
+
inverseFieldSlug: z10.string().optional(),
|
|
4175
4294
|
/** Carried verbatim: the API's own `lookup` config is already keyed entirely
|
|
4176
4295
|
* by slug (`relationFieldSlug` / `targetFieldSlug`), so it survives a
|
|
4177
4296
|
* re-id'ing install with no package-only alias. The companion `number`
|
|
4178
4297
|
* snapshot rides along in the `number` key above. */
|
|
4179
|
-
lookup:
|
|
4180
|
-
relationFieldSlug:
|
|
4181
|
-
targetFieldSlug:
|
|
4298
|
+
lookup: z10.object({
|
|
4299
|
+
relationFieldSlug: z10.string().min(1),
|
|
4300
|
+
targetFieldSlug: z10.string().min(1),
|
|
4182
4301
|
rollup: lookupRollupSchema.optional(),
|
|
4183
|
-
limit:
|
|
4302
|
+
limit: z10.enum(["all", "first"]).optional()
|
|
4184
4303
|
}).optional(),
|
|
4185
|
-
multiple:
|
|
4186
|
-
number:
|
|
4187
|
-
format:
|
|
4188
|
-
currency:
|
|
4189
|
-
locale:
|
|
4304
|
+
multiple: z10.boolean().optional(),
|
|
4305
|
+
number: z10.object({
|
|
4306
|
+
format: z10.enum(["plain", "currency"]).optional(),
|
|
4307
|
+
currency: z10.string().optional(),
|
|
4308
|
+
locale: z10.string().optional()
|
|
4190
4309
|
}).optional(),
|
|
4191
4310
|
/** Native API alias — the server resolves it to `targetBaseId`. */
|
|
4192
|
-
targetBaseSlug:
|
|
4311
|
+
targetBaseSlug: z10.string().optional()
|
|
4193
4312
|
}).default({});
|
|
4194
|
-
var PackageBaseFieldSchema =
|
|
4195
|
-
slug:
|
|
4313
|
+
var PackageBaseFieldSchema = z10.object({
|
|
4314
|
+
slug: z10.string().min(1),
|
|
4196
4315
|
name: fieldNameSchema,
|
|
4197
4316
|
type: fieldTypeSchema,
|
|
4198
|
-
required:
|
|
4199
|
-
position:
|
|
4317
|
+
required: z10.boolean().default(false),
|
|
4318
|
+
position: z10.number().int(),
|
|
4200
4319
|
options: PackageFieldOptionsSchema
|
|
4201
4320
|
});
|
|
4202
|
-
var PackageViewFilterSchema =
|
|
4203
|
-
fieldSlug:
|
|
4321
|
+
var PackageViewFilterSchema = z10.object({
|
|
4322
|
+
fieldSlug: z10.string().min(1),
|
|
4204
4323
|
operator: viewFilterOperatorSchema,
|
|
4205
|
-
value:
|
|
4324
|
+
value: z10.unknown().optional()
|
|
4206
4325
|
});
|
|
4207
|
-
var PackageViewSortSchema =
|
|
4208
|
-
direction:
|
|
4209
|
-
fieldSlug:
|
|
4326
|
+
var PackageViewSortSchema = z10.object({
|
|
4327
|
+
direction: z10.enum(["asc", "desc"]),
|
|
4328
|
+
fieldSlug: z10.string().min(1)
|
|
4210
4329
|
});
|
|
4211
|
-
var PackageViewConfigSchema =
|
|
4212
|
-
filters:
|
|
4213
|
-
sorts:
|
|
4214
|
-
visibleFieldSlugs:
|
|
4215
|
-
fieldWidths:
|
|
4330
|
+
var PackageViewConfigSchema = z10.object({
|
|
4331
|
+
filters: z10.array(PackageViewFilterSchema).default([]),
|
|
4332
|
+
sorts: z10.array(PackageViewSortSchema).default([]),
|
|
4333
|
+
visibleFieldSlugs: z10.array(z10.string()).nullable().optional(),
|
|
4334
|
+
fieldWidths: z10.record(z10.string().min(1), z10.number().int().min(VIEW_FIELD_MIN_WIDTH).max(VIEW_FIELD_MAX_WIDTH)).optional()
|
|
4216
4335
|
});
|
|
4217
|
-
var PackageViewSchema =
|
|
4218
|
-
slug:
|
|
4219
|
-
name:
|
|
4220
|
-
description:
|
|
4221
|
-
type:
|
|
4336
|
+
var PackageViewSchema = z10.object({
|
|
4337
|
+
slug: z10.string().min(1),
|
|
4338
|
+
name: z10.string().min(1),
|
|
4339
|
+
description: z10.string().default(""),
|
|
4340
|
+
type: z10.literal("table").default("table"),
|
|
4222
4341
|
config: PackageViewConfigSchema.default({ filters: [], sorts: [] })
|
|
4223
4342
|
});
|
|
4224
|
-
var PackageBaseSchema =
|
|
4225
|
-
name:
|
|
4226
|
-
description:
|
|
4227
|
-
position:
|
|
4343
|
+
var PackageBaseSchema = z10.object({
|
|
4344
|
+
name: z10.string().min(1),
|
|
4345
|
+
description: z10.string().default(""),
|
|
4346
|
+
position: z10.number().int().optional(),
|
|
4228
4347
|
/**
|
|
4229
4348
|
* Informational only — `reviewPolicy` is NOT settable via `bases.create`, so
|
|
4230
4349
|
* install cannot apply it and warns when it differs from the target's default.
|
|
4231
4350
|
*/
|
|
4232
|
-
reviewPolicy:
|
|
4233
|
-
kind:
|
|
4234
|
-
requiredApprovals:
|
|
4351
|
+
reviewPolicy: z10.object({
|
|
4352
|
+
kind: z10.literal("single"),
|
|
4353
|
+
requiredApprovals: z10.number()
|
|
4235
4354
|
}).optional(),
|
|
4236
|
-
fields:
|
|
4237
|
-
views:
|
|
4355
|
+
fields: z10.array(PackageBaseFieldSchema).default([]),
|
|
4356
|
+
views: z10.array(PackageViewSchema).default([])
|
|
4238
4357
|
});
|
|
4239
|
-
var PackageRecordLineSchema =
|
|
4240
|
-
key:
|
|
4241
|
-
fields:
|
|
4358
|
+
var PackageRecordLineSchema = z10.object({
|
|
4359
|
+
key: z10.string().min(1),
|
|
4360
|
+
fields: z10.record(z10.string(), z10.unknown()).default({})
|
|
4242
4361
|
});
|
|
4243
4362
|
|
|
4244
4363
|
// ../../packages/busabase-package/src/apply.ts
|
|
@@ -4414,9 +4533,18 @@ var applyInstall = async (client, plan, options) => {
|
|
|
4414
4533
|
fieldId,
|
|
4415
4534
|
patch: { options: patched },
|
|
4416
4535
|
message: `Wire up ${base.node.slug}.${field.slug} references`,
|
|
4417
|
-
submittedBy: options.submittedBy
|
|
4536
|
+
submittedBy: options.submittedBy,
|
|
4537
|
+
// Field wiring is STRUCTURE, like the Base and its views above — ask for it
|
|
4538
|
+
// outright rather than proposing it and immediately approving our own
|
|
4539
|
+
// proposal, which is what this used to do only because the endpoint had no
|
|
4540
|
+
// `autoMerge`.
|
|
4541
|
+
autoMerge: true
|
|
4418
4542
|
});
|
|
4419
|
-
|
|
4543
|
+
if (changeRequest.status !== "merged") {
|
|
4544
|
+
throw new Error(
|
|
4545
|
+
`Field reference wiring for ${base.node.slug}.${field.slug} was requested immediately but came back "${changeRequest.status}"; install cannot leave a Base's relation fields unwired.`
|
|
4546
|
+
);
|
|
4547
|
+
}
|
|
4420
4548
|
}
|
|
4421
4549
|
}
|
|
4422
4550
|
const recordIdsByKey = /* @__PURE__ */ new Map();
|
|
@@ -4741,7 +4869,13 @@ var createRecords = async (client, base, plan, options, state, recordIdsByKey) =
|
|
|
4741
4869
|
records: batch.map((record) => toCreatableFields(base.node, record.fields)),
|
|
4742
4870
|
message: `Install ${batch.length} record(s) into ${base.node.slug}`,
|
|
4743
4871
|
submittedBy: options.submittedBy,
|
|
4744
|
-
idempotencyKey: batchIdempotencyKey(plan.tree.manifest.name, batch[0].key)
|
|
4872
|
+
idempotencyKey: batchIdempotencyKey(plan.tree.manifest.name, batch[0].key),
|
|
4873
|
+
// Forwarded explicitly, load-bearing: `--auto-merge` is the ONLY thing that
|
|
4874
|
+
// decides whether an install's records go live, and that promise is what the
|
|
4875
|
+
// review-first install is. Leaving this to the endpoint's permission-aware
|
|
4876
|
+
// default would silently merge a review-first install's records for any
|
|
4877
|
+
// write-capable installer.
|
|
4878
|
+
autoMerge: options.autoMerge
|
|
4745
4879
|
});
|
|
4746
4880
|
if (!options.autoMerge) {
|
|
4747
4881
|
state.pendingChangeRequests++;
|
|
@@ -6344,21 +6478,21 @@ function parseJsonValue(raw, flagName) {
|
|
|
6344
6478
|
JSON parse error: ${reason}`);
|
|
6345
6479
|
}
|
|
6346
6480
|
}
|
|
6481
|
+
function formatIssues(issues) {
|
|
6482
|
+
if (!Array.isArray(issues) || issues.length === 0) return void 0;
|
|
6483
|
+
return issues.map((issue) => {
|
|
6484
|
+
if (!issue || typeof issue !== "object") return String(issue);
|
|
6485
|
+
const { path, message } = issue;
|
|
6486
|
+
const pathLabel = Array.isArray(path) && path.length > 0 ? path.join(".") : void 0;
|
|
6487
|
+
return pathLabel ? `${pathLabel}: ${message}` : String(message ?? issue);
|
|
6488
|
+
}).join("; ");
|
|
6489
|
+
}
|
|
6347
6490
|
function formatRawErrorBody(status, statusText, text) {
|
|
6348
6491
|
try {
|
|
6349
6492
|
const parsed = JSON.parse(text);
|
|
6350
6493
|
if (typeof parsed.error === "string") {
|
|
6351
|
-
const
|
|
6352
|
-
|
|
6353
|
-
if (Array.isArray(issues) && issues.length > 0) {
|
|
6354
|
-
const details = issues.map((issue) => {
|
|
6355
|
-
if (!issue || typeof issue !== "object") return String(issue);
|
|
6356
|
-
const { path, message: issueMessage } = issue;
|
|
6357
|
-
const pathLabel = Array.isArray(path) ? path.join(".") : void 0;
|
|
6358
|
-
return pathLabel ? `${pathLabel}: ${issueMessage}` : String(issueMessage ?? issue);
|
|
6359
|
-
}).join("; ");
|
|
6360
|
-
message = `${message} \u2014 ${details}`;
|
|
6361
|
-
}
|
|
6494
|
+
const details = formatIssues(parsed.data?.issues);
|
|
6495
|
+
const message = details ? `${parsed.error} \u2014 ${details}` : parsed.error;
|
|
6362
6496
|
return `HTTP ${status} ${statusText}: ${message}`;
|
|
6363
6497
|
}
|
|
6364
6498
|
} catch {
|
|
@@ -7360,7 +7494,9 @@ function renderedHelp() {
|
|
|
7360
7494
|
var HELP = renderedHelp();
|
|
7361
7495
|
function explainError(error, config) {
|
|
7362
7496
|
const base = config.baseUrl;
|
|
7363
|
-
const
|
|
7497
|
+
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
7498
|
+
const issueDetail = formatIssues(error.data?.issues);
|
|
7499
|
+
const msg = issueDetail ? `${rawMessage} \u2014 ${issueDetail}` : rawMessage;
|
|
7364
7500
|
const status = error.status;
|
|
7365
7501
|
const lower = msg.toLowerCase();
|
|
7366
7502
|
let body;
|