busabase-sdk 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/dist/index.d.ts +1468 -1419
- package/dist/index.js +138 -30
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -36,6 +36,9 @@ var LocaleSchema = z.enum(i18n.locales);
|
|
|
36
36
|
// ../../packages/openlib/i18n/i-string.ts
|
|
37
37
|
var iStringRecordSchema = z.partialRecord(LocaleSchema, z.string());
|
|
38
38
|
z.union([z.string(), iStringRecordSchema]).describe("i18n string");
|
|
39
|
+
var autoMergeNotAccepted = (reason) => z.literal(false, { error: `\`autoMerge: true\` is not accepted here: ${reason}` }).optional().describe(`Only \`false\` (or omitted) is accepted. ${reason}`);
|
|
40
|
+
|
|
41
|
+
// ../../packages/busabase-contract/src/domains/base/contract/base-schemas.ts
|
|
39
42
|
var fieldNameSchema = z.union([
|
|
40
43
|
z.string().min(1),
|
|
41
44
|
iStringRecordSchema.refine(
|
|
@@ -191,14 +194,21 @@ var createBaseFieldInputSchema = z.object({
|
|
|
191
194
|
required: z.boolean().optional().default(false),
|
|
192
195
|
options: fieldOptionsSchema.optional().default({})
|
|
193
196
|
});
|
|
197
|
+
var fieldAutoMergeSchema = z.boolean().optional().describe(
|
|
198
|
+
"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."
|
|
199
|
+
);
|
|
194
200
|
var createFieldChangeRequestInputSchema = createBaseFieldInputSchema.extend({
|
|
195
201
|
message: z.string().optional().default("Add field"),
|
|
196
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
202
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
203
|
+
autoMerge: fieldAutoMergeSchema
|
|
197
204
|
});
|
|
198
205
|
var deleteFieldChangeRequestInputSchema = z.object({
|
|
199
206
|
fieldId: z.string().min(1),
|
|
200
207
|
message: z.string().optional(),
|
|
201
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
208
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
209
|
+
autoMerge: autoMergeNotAccepted(
|
|
210
|
+
"deleting a field soft-deletes its stored values with it, so it always requires review. Omit the flag."
|
|
211
|
+
)
|
|
202
212
|
});
|
|
203
213
|
var updateFieldChangeRequestInputSchema = z.object({
|
|
204
214
|
fieldId: z.string().min(1),
|
|
@@ -208,7 +218,8 @@ var updateFieldChangeRequestInputSchema = z.object({
|
|
|
208
218
|
options: fieldOptionsSchema.optional()
|
|
209
219
|
}),
|
|
210
220
|
message: z.string().optional(),
|
|
211
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
221
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
222
|
+
autoMerge: fieldAutoMergeSchema
|
|
212
223
|
});
|
|
213
224
|
var previewFieldConversionInputSchema = z.object({
|
|
214
225
|
fieldId: z.string().min(1),
|
|
@@ -225,25 +236,39 @@ var convertFieldChangeRequestInputSchema = z.object({
|
|
|
225
236
|
newType: fieldTypeSchema,
|
|
226
237
|
selectChoiceMode: z.enum(["auto_create", "null_on_missing"]).default("null_on_missing"),
|
|
227
238
|
message: z.string().optional(),
|
|
228
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
239
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
240
|
+
autoMerge: autoMergeNotAccepted(
|
|
241
|
+
"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."
|
|
242
|
+
)
|
|
229
243
|
});
|
|
230
244
|
var reorderFieldsChangeRequestInputSchema = z.object({
|
|
231
245
|
fieldIds: z.array(z.string()).min(1),
|
|
232
246
|
message: z.string().optional(),
|
|
233
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
247
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
248
|
+
autoMerge: fieldAutoMergeSchema
|
|
234
249
|
});
|
|
235
250
|
var archiveBaseInputSchema = z.object({
|
|
236
251
|
message: z.string().optional(),
|
|
237
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
252
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
253
|
+
autoMerge: autoMergeNotAccepted(
|
|
254
|
+
"archiving a Base removes it and every record in it from every listing at once, so it always requires review. Omit the flag."
|
|
255
|
+
)
|
|
238
256
|
});
|
|
239
257
|
var restoreBaseInputSchema = z.object({
|
|
240
258
|
message: z.string().optional(),
|
|
241
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
259
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
260
|
+
// Restoring an archived Base is the undo of a destructive act — nothing is at
|
|
261
|
+
// risk, so it takes the same permission-aware default as everything else.
|
|
262
|
+
// `archiveBaseInputSchema` above deliberately has no `autoMerge`: archiving
|
|
263
|
+
// takes a whole Base and every record in it out of every listing at once,
|
|
264
|
+
// which is strictly larger than the record `delete` that is already review-only.
|
|
265
|
+
autoMerge: z.boolean().optional()
|
|
242
266
|
});
|
|
243
267
|
var restoreFieldChangeRequestInputSchema = z.object({
|
|
244
268
|
fieldId: z.string().min(1),
|
|
245
269
|
message: z.string().optional(),
|
|
246
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
270
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
271
|
+
autoMerge: fieldAutoMergeSchema
|
|
247
272
|
});
|
|
248
273
|
var withBaseId = { baseId: z.string().min(1) };
|
|
249
274
|
var fieldChangeRequestInputSchema = z.discriminatedUnion("operation", [
|
|
@@ -254,6 +279,10 @@ var fieldChangeRequestInputSchema = z.discriminatedUnion("operation", [
|
|
|
254
279
|
reorderFieldsChangeRequestInputSchema.extend({ operation: z.literal("reorder"), ...withBaseId }),
|
|
255
280
|
restoreFieldChangeRequestInputSchema.extend({ operation: z.literal("restore"), ...withBaseId })
|
|
256
281
|
]);
|
|
282
|
+
var baseLifecycleChangeRequestInputSchema = z.discriminatedUnion("operation", [
|
|
283
|
+
archiveBaseInputSchema.extend({ operation: z.literal("archive"), ...withBaseId }),
|
|
284
|
+
restoreBaseInputSchema.extend({ operation: z.literal("restore"), ...withBaseId })
|
|
285
|
+
]);
|
|
257
286
|
|
|
258
287
|
// ../../packages/busabase-contract/src/domains/filetree/definition.ts
|
|
259
288
|
var fileTreeOperations = (type) => [
|
|
@@ -896,7 +925,10 @@ var createDeleteChangeRequestInputSchema = z.object({
|
|
|
896
925
|
submittedBy: z.string().optional().default("local-producer"),
|
|
897
926
|
// Only "archive" is supported — hard delete after retention was never
|
|
898
927
|
// implemented, so the API no longer accepts it (breaking change).
|
|
899
|
-
deleteMode: z.enum(["archive"]).optional().default("archive")
|
|
928
|
+
deleteMode: z.enum(["archive"]).optional().default("archive"),
|
|
929
|
+
autoMerge: autoMergeNotAccepted(
|
|
930
|
+
"archiving a record removes user content from every listing, so it always requires review. Omit the flag."
|
|
931
|
+
)
|
|
900
932
|
});
|
|
901
933
|
var reviseOperationInputSchema = z.object({
|
|
902
934
|
fields: z.record(z.string(), z.unknown()).describe(
|
|
@@ -938,6 +970,19 @@ var listChangeRequestsResponseSchema = z.object({
|
|
|
938
970
|
changeRequests: z.array(changeRequestSchema),
|
|
939
971
|
nextCursor: z.string().nullable()
|
|
940
972
|
});
|
|
973
|
+
var listChangeRequestsPageInputSchema = z.object({
|
|
974
|
+
page: z.coerce.number().int().min(1).optional().default(1),
|
|
975
|
+
pageSize: z.coerce.number().int().min(1).max(100).optional().default(50),
|
|
976
|
+
status: z.array(changeRequestStatusSchema).optional(),
|
|
977
|
+
mine: z.boolean().optional()
|
|
978
|
+
}).optional().default({ page: 1, pageSize: 50 });
|
|
979
|
+
var listChangeRequestsPageResponseSchema = z.object({
|
|
980
|
+
changeRequests: z.array(changeRequestSchema),
|
|
981
|
+
total: z.number().int().nonnegative(),
|
|
982
|
+
totalPages: z.number().int().nonnegative(),
|
|
983
|
+
page: z.number().int().min(1),
|
|
984
|
+
pageSize: z.number().int().min(1).max(100)
|
|
985
|
+
});
|
|
941
986
|
var changeRequestCountsSchema = z.object({
|
|
942
987
|
review: z.number().int().nonnegative(),
|
|
943
988
|
changes: z.number().int().nonnegative(),
|
|
@@ -1107,7 +1152,16 @@ var createFileTreeChangeRequestInputSchema = z.object({
|
|
|
1107
1152
|
'Explanation shown to the human reviewer. Write a conventional-commit style subject \u2014 imperative verb + what + why, e.g. "Rewrite README.md quickstart for the new auth flow".'
|
|
1108
1153
|
),
|
|
1109
1154
|
submittedBy: z.string().optional().default("local-producer"),
|
|
1110
|
-
operations: z.array(fileTreeFileOperationInputSchema).min(1)
|
|
1155
|
+
operations: z.array(fileTreeFileOperationInputSchema).min(1),
|
|
1156
|
+
// Honoured only when EVERY operation in the batch is non-destructive
|
|
1157
|
+
// (create / update / metadata_update). A batch containing a `delete` stays
|
|
1158
|
+
// review-first no matter what this says, because deleting a mounted file
|
|
1159
|
+
// destroys content — the same line that keeps record `delete` review-only.
|
|
1160
|
+
// Server-side enforcement lives in the filetree handler, not here: the check
|
|
1161
|
+
// is over the operations array, which a per-field schema cannot express.
|
|
1162
|
+
autoMerge: z.boolean().optional().describe(
|
|
1163
|
+
"Whether to approve and merge these file changes immediately. Omitted defaults to merging immediately if the actor has write access on the node, otherwise falling back to a pending Change Request; pass explicit false to force review even with write access. IGNORED when any operation is a delete \u2014 those batches always require review."
|
|
1164
|
+
)
|
|
1111
1165
|
});
|
|
1112
1166
|
var FILE_TREE_NODE_TYPES = ["skill", "drive", "airapp"];
|
|
1113
1167
|
var fileTreeNodeTypeSchema = z.enum(FILE_TREE_NODE_TYPES);
|
|
@@ -1391,7 +1445,10 @@ var EditAssetContentInputSchema = z.object({
|
|
|
1391
1445
|
message: z.string().optional().default("Edit file content").describe(
|
|
1392
1446
|
'Explanation shown to the human reviewer. Write a conventional-commit style subject \u2014 imperative verb + what + why, e.g. "Fix typo in setup instructions".'
|
|
1393
1447
|
),
|
|
1394
|
-
submittedBy: z.string().optional().default("agent")
|
|
1448
|
+
submittedBy: z.string().optional().default("agent"),
|
|
1449
|
+
autoMerge: autoMergeNotAccepted(
|
|
1450
|
+
"editContent rewrites the real mounted file bytes, so it always requires review. Omit the flag."
|
|
1451
|
+
)
|
|
1395
1452
|
});
|
|
1396
1453
|
var AssetDownloadInputSchema = z.object({ assetId: z.string() });
|
|
1397
1454
|
var AssetDownloadVOSchema = z.object({
|
|
@@ -1674,9 +1731,42 @@ var listRecordsPageResponseSchema = z.object({
|
|
|
1674
1731
|
page: z.number().int().min(1),
|
|
1675
1732
|
pageSize: z.number().int().min(1).max(100)
|
|
1676
1733
|
});
|
|
1677
|
-
var
|
|
1678
|
-
baseId: z.string().optional()
|
|
1679
|
-
|
|
1734
|
+
var countRecordsShapeSchema = z.object({
|
|
1735
|
+
baseId: z.string().optional(),
|
|
1736
|
+
/**
|
|
1737
|
+
* Count only the rows a saved View would display (the View's filters
|
|
1738
|
+
* applied; its sort is ignored — a count doesn't need an order). A View
|
|
1739
|
+
* belongs to exactly one Base, so this requires `baseId`.
|
|
1740
|
+
*/
|
|
1741
|
+
viewId: z.string().optional(),
|
|
1742
|
+
/**
|
|
1743
|
+
* Ad-hoc filter conditions — same shape `records.list`'s `filters` uses —
|
|
1744
|
+
* for composing a condition set without a saved View (e.g. an AirApp
|
|
1745
|
+
* summary tile like "main-branch PRs"). Combined with the View's own
|
|
1746
|
+
* filters (AND) when `viewId` is also given. Requires `baseId`: a field
|
|
1747
|
+
* slug is only unambiguous within one Base, and proving a filter exact
|
|
1748
|
+
* (see `countRecords`) requires that Base's real field definitions —
|
|
1749
|
+
* never the caller-supplied `fieldType` hint, which elsewhere is only a
|
|
1750
|
+
* pushdown hint and isn't trustworthy enough for an exact count.
|
|
1751
|
+
*/
|
|
1752
|
+
filters: z.array(listRecordsFilterSchema).optional()
|
|
1753
|
+
}).superRefine((value, ctx) => {
|
|
1754
|
+
if (value.viewId && !value.baseId) {
|
|
1755
|
+
ctx.addIssue({
|
|
1756
|
+
code: "custom",
|
|
1757
|
+
path: ["baseId"],
|
|
1758
|
+
message: "baseId is required when viewId is given"
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
if (value.filters?.length && !value.baseId) {
|
|
1762
|
+
ctx.addIssue({
|
|
1763
|
+
code: "custom",
|
|
1764
|
+
path: ["baseId"],
|
|
1765
|
+
message: "baseId is required when filters is given"
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
});
|
|
1769
|
+
var countRecordsInputSchema = countRecordsShapeSchema.optional().default({});
|
|
1680
1770
|
var countRecordsResponseSchema = z.object({
|
|
1681
1771
|
/** Total active records in the space (optionally scoped to a base). */
|
|
1682
1772
|
total: z.number().int().nonnegative()
|
|
@@ -1711,7 +1801,13 @@ var createBulkChangeRequestInputSchema = z.object({
|
|
|
1711
1801
|
submittedBy: z.string().optional().default("local-producer"),
|
|
1712
1802
|
idempotencyKey: z.string().optional().describe(
|
|
1713
1803
|
"Optional client-supplied key that dedupes retries. Scoped per base + submitter: calling this endpoint again with the SAME idempotencyKey returns the bulk change request created by the first call instead of creating a duplicate. Omit for normal one-shot calls; only set it when you might retry."
|
|
1714
|
-
)
|
|
1804
|
+
),
|
|
1805
|
+
// Same permission-aware tri-state as the single-record endpoint above. N record
|
|
1806
|
+
// CREATES are purely additive, so there is nothing here the review gate is
|
|
1807
|
+
// protecting — and until now the published skill doc told agents to send N
|
|
1808
|
+
// separate single-record calls precisely because this one could not merge,
|
|
1809
|
+
// which is slower and produces N change requests instead of one.
|
|
1810
|
+
autoMerge: z.boolean().optional()
|
|
1715
1811
|
});
|
|
1716
1812
|
var recordFieldFilterInputSchema = z.object({
|
|
1717
1813
|
baseId: z.string().optional(),
|
|
@@ -1732,7 +1828,10 @@ var recordGetInputSchema = z.union([
|
|
|
1732
1828
|
]);
|
|
1733
1829
|
var restoreRecordInputSchema = z.object({
|
|
1734
1830
|
message: z.string().optional(),
|
|
1735
|
-
submittedBy: z.string().optional().default("local-editor")
|
|
1831
|
+
submittedBy: z.string().optional().default("local-editor"),
|
|
1832
|
+
autoMerge: autoMergeNotAccepted(
|
|
1833
|
+
"restoring a record brings archived content back into every listing, so it always requires review. Omit the flag."
|
|
1834
|
+
)
|
|
1736
1835
|
});
|
|
1737
1836
|
var withRecordId = { recordId: z.string().min(1) };
|
|
1738
1837
|
var recordChangeRequestInputSchema = z.discriminatedUnion("operation", [
|
|
@@ -1838,20 +1937,13 @@ var baseContract = {
|
|
|
1838
1937
|
summary: "Preview field type conversion",
|
|
1839
1938
|
successDescription: "Dry-run statistics for converting a field to a different type."
|
|
1840
1939
|
}).input(previewFieldConversionInputSchema.extend({ baseId: z.string() })).output(previewFieldConversionOutputSchema),
|
|
1841
|
-
|
|
1842
|
-
method: "POST",
|
|
1843
|
-
path: "/bases/{baseId}/archive/change-requests",
|
|
1844
|
-
tags: ["Bases", "Change Requests"],
|
|
1845
|
-
summary: "Archive base",
|
|
1846
|
-
successDescription: "Created change request that archives a base."
|
|
1847
|
-
}).input(archiveBaseInputSchema.extend({ baseId: z.string() })).output(changeRequestSchema),
|
|
1848
|
-
restoreChangeRequest: oc.route({
|
|
1940
|
+
lifecycleChangeRequest: oc.route({
|
|
1849
1941
|
method: "POST",
|
|
1850
|
-
path: "/bases/{baseId}/
|
|
1942
|
+
path: "/bases/{baseId}/lifecycle/change-requests",
|
|
1851
1943
|
tags: ["Bases", "Change Requests"],
|
|
1852
|
-
summary: "
|
|
1853
|
-
successDescription: "Created change request that
|
|
1854
|
-
}).input(
|
|
1944
|
+
summary: "Create Base lifecycle change request",
|
|
1945
|
+
successDescription: "Created change request that moves a Base between its lifecycle states. `operation` selects the direction: `archive` (soft-delete a live Base) or `restore` (bring an archived Base back)."
|
|
1946
|
+
}).input(baseLifecycleChangeRequestInputSchema).output(changeRequestSchema)
|
|
1855
1947
|
};
|
|
1856
1948
|
var recordContract = {
|
|
1857
1949
|
// One listing for records: always keyset-paginated, `baseId` always honoured,
|
|
@@ -1877,7 +1969,8 @@ var recordContract = {
|
|
|
1877
1969
|
path: "/records/count",
|
|
1878
1970
|
tags: ["Records"],
|
|
1879
1971
|
summary: "Count records",
|
|
1880
|
-
|
|
1972
|
+
description: "A real SQL COUNT \u2014 always the exact total, never a partial or capped number, so it's safe to render as a canonical figure (e.g. a dashboard summary tile). Plain `baseId` scoping is always cheap. Adding `viewId` and/or `filters` is exact too \u2014 provably-exact conditions (e.g. text equals/contains, not_empty/is_empty, checkbox is_true/is_false) stay a cheap SQL COUNT; everything else falls back to evaluating every matching row server-side, which is exact but not free on a large Base. Both `viewId` and `filters` require `baseId`.",
|
|
1973
|
+
successDescription: "Total active records matching the scope: the whole space, one Base, a saved View, an ad-hoc filter set, or a combination."
|
|
1881
1974
|
}).input(countRecordsInputSchema).output(countRecordsResponseSchema),
|
|
1882
1975
|
get: oc.route({
|
|
1883
1976
|
method: "GET",
|
|
@@ -1972,7 +2065,12 @@ var createDocChangeRequestInputSchema = z.object({
|
|
|
1972
2065
|
message: z.string().optional().default("Update doc").describe(
|
|
1973
2066
|
'Explanation shown to the human reviewer. Write a conventional-commit style subject \u2014 imperative verb + what + why, e.g. "Add rollback steps to the deploy runbook".'
|
|
1974
2067
|
),
|
|
1975
|
-
submittedBy: z.string().optional().default("local-producer")
|
|
2068
|
+
submittedBy: z.string().optional().default("local-producer"),
|
|
2069
|
+
// A Doc body update is the Doc-domain twin of a record `update`, which has taken
|
|
2070
|
+
// the permission-aware default since #5712 — and this node type already has a
|
|
2071
|
+
// direct-write bypass (`PUT /docs/{nodeId}/body`), so review-first here was never
|
|
2072
|
+
// an actual guarantee, just a slower path to the same place.
|
|
2073
|
+
autoMerge: z.boolean().optional()
|
|
1976
2074
|
});
|
|
1977
2075
|
var docContract = {
|
|
1978
2076
|
create: oc.route({
|
|
@@ -3154,6 +3252,16 @@ var busabaseContractRoutes = {
|
|
|
3154
3252
|
summary: "List change requests",
|
|
3155
3253
|
successDescription: "A page of change requests plus an opaque nextCursor (null at the end). Filter with `status` and/or `mine`."
|
|
3156
3254
|
}).input(listChangeRequestsPagedInputSchema).output(listChangeRequestsResponseSchema),
|
|
3255
|
+
// Numbered paging alongside the cursor listing, mirroring records.listPage.
|
|
3256
|
+
// Keyset is right for "keep scrolling"; a reviewer working a 2,000-item tab
|
|
3257
|
+
// needs to jump to page 30 and to see how many pages there are at all.
|
|
3258
|
+
listPage: oc.route({
|
|
3259
|
+
method: "GET",
|
|
3260
|
+
path: "/change-requests/page",
|
|
3261
|
+
tags: ["Change Requests"],
|
|
3262
|
+
summary: "List a numbered change request page",
|
|
3263
|
+
successDescription: "A random-access page of change requests plus the total across the whole filter. Same `status` / `mine` filters as the cursor listing."
|
|
3264
|
+
}).input(listChangeRequestsPageInputSchema).output(listChangeRequestsPageResponseSchema),
|
|
3157
3265
|
counts: oc.route({
|
|
3158
3266
|
method: "GET",
|
|
3159
3267
|
path: "/change-requests/counts",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "busabase-sdk",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Typed TypeScript/JavaScript SDK for the Busabase OpenAPI REST API. Talks to a local or remote `busabase server` (or Busabase Cloud).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/busabase/busabase/tree/main/apps/busabase-sdk",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"tsx": "^4.20.5",
|
|
50
50
|
"typescript": "^5.9.3",
|
|
51
51
|
"vitest": "^2.1.8",
|
|
52
|
-
"busabase-contract": "0.11.
|
|
53
|
-
"
|
|
54
|
-
"
|
|
52
|
+
"busabase-contract": "0.11.3",
|
|
53
|
+
"open-domains": "0.0.2",
|
|
54
|
+
"openlib": "0.1.1"
|
|
55
55
|
},
|
|
56
56
|
"engines": {
|
|
57
57
|
"node": ">=24.18.0"
|