busa-sdk 0.10.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +18740 -18489
- package/dist/index.js +230 -112
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -561,7 +561,33 @@ var listNodesInputSchema = z.object({
|
|
|
561
561
|
* soft-archived nodes for the Trash view — no `parentId`/`depth` walk, since
|
|
562
562
|
* archived nodes are shown as a list, not a tree.
|
|
563
563
|
*/
|
|
564
|
-
status: z.enum(["active", "archived"]).optional().default("active")
|
|
564
|
+
status: z.enum(["active", "archived"]).optional().default("active"),
|
|
565
|
+
/**
|
|
566
|
+
* Narrow to specific node types and return a FLAT list of lightweight node
|
|
567
|
+
* summaries (`children: []`) instead of walking the tree. This is what
|
|
568
|
+
* replaced the four retired narrow listings (`GET /docs`, `/files`,
|
|
569
|
+
* `/folders`, `/file-trees`); file-trees are selected with their real
|
|
570
|
+
* discriminators `skill` / `drive` / `airapp`, since there is no synthetic
|
|
571
|
+
* "file-tree" node type.
|
|
572
|
+
*
|
|
573
|
+
* Omitting `types` leaves every existing caller on exactly today's
|
|
574
|
+
* behaviour (full tree, or a `parentId`/`depth`-bounded walk, or the
|
|
575
|
+
* archived flat list) — the two modes never interfere.
|
|
576
|
+
*
|
|
577
|
+
* NOTE — no `projection` parameter, deliberately. The consolidation roadmap
|
|
578
|
+
* sketched `?projection=summary`, but it also rules out adding
|
|
579
|
+
* `projection=detail` in this batch (the retired detail lists were the
|
|
580
|
+
* N+1 payloads this change exists to remove). That would leave a parameter
|
|
581
|
+
* with exactly one legal value, which is noise in OpenAPI/MCP/CLI rather
|
|
582
|
+
* than a decision a caller gets to make. Detail is `GET /nodes/{nodeId}`.
|
|
583
|
+
*
|
|
584
|
+
* A GET query param that occurs exactly once (`?types=doc`) arrives as a
|
|
585
|
+
* bare string, not a 1-element array — only a REPEATED occurrence
|
|
586
|
+
* (`?types=doc&types=file`) becomes an array. Accept both and normalize.
|
|
587
|
+
*/
|
|
588
|
+
types: z.union([z.array(z.enum(NODE_TYPES)), z.enum(NODE_TYPES)]).transform((value) => Array.isArray(value) ? value : [value]).optional().describe(
|
|
589
|
+
"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}."
|
|
590
|
+
)
|
|
565
591
|
}).optional();
|
|
566
592
|
var isDescendantInputSchema = z.object({
|
|
567
593
|
nodeId: z.string(),
|
|
@@ -729,11 +755,19 @@ var liveEventSchema = z.object({
|
|
|
729
755
|
// via the audit funnel, but nothing needs reviewing). Consumed by
|
|
730
756
|
// `use-live-sync.ts` to pop a desktop Notification, and by
|
|
731
757
|
// busabase-cloud's host hook to persist an inbox notification row.
|
|
732
|
-
"change_request.pending_review"
|
|
758
|
+
"change_request.pending_review",
|
|
759
|
+
// A node's metadata was written directly, outside the change-request flow
|
|
760
|
+
// (`PATCH /api/v1/nodes/{nodeId}/metadata` — agents, the SDK, an MCP tool,
|
|
761
|
+
// and every rich-node editor's own Save). Carries the touched node in
|
|
762
|
+
// `nodeIds` so open dashboards refetch the node tree instead of showing a
|
|
763
|
+
// stale whiteboard/workflow/HTML document until the next reload.
|
|
764
|
+
"node.metadata_updated"
|
|
733
765
|
]),
|
|
734
766
|
spaceId: z.string(),
|
|
735
767
|
actorId: z.string(),
|
|
736
|
-
|
|
768
|
+
// Null for events that aren't about a change request at all
|
|
769
|
+
// (`node.metadata_updated`), which is every direct, auto-audited write.
|
|
770
|
+
changeRequestId: z.string().nullable(),
|
|
737
771
|
baseId: z.string().nullable(),
|
|
738
772
|
nodeIds: z.array(z.string()),
|
|
739
773
|
recordIds: z.array(z.string()),
|
|
@@ -1082,13 +1116,6 @@ var fileTreeRefSchema = z.object({
|
|
|
1082
1116
|
type: fileTreeNodeTypeSchema.optional()
|
|
1083
1117
|
});
|
|
1084
1118
|
var fileTreeContract = {
|
|
1085
|
-
list: oc.route({
|
|
1086
|
-
method: "GET",
|
|
1087
|
-
path: "/file-trees",
|
|
1088
|
-
tags: ["File Trees"],
|
|
1089
|
-
summary: "List file-tree nodes",
|
|
1090
|
-
successDescription: "Skill, Drive, and AirApp nodes with their Asset-backed file trees. Pass `type` to narrow to one kind."
|
|
1091
|
-
}).input(z.object({ type: fileTreeNodeTypeSchema.optional() })).output(z.array(fileTreeNodeSchema)),
|
|
1092
1119
|
create: oc.route({
|
|
1093
1120
|
method: "POST",
|
|
1094
1121
|
path: "/file-trees",
|
|
@@ -1101,13 +1128,6 @@ var fileTreeContract = {
|
|
|
1101
1128
|
changeRequestSchema.extend({ materialized: z.literal(false) })
|
|
1102
1129
|
])
|
|
1103
1130
|
),
|
|
1104
|
-
get: oc.route({
|
|
1105
|
-
method: "GET",
|
|
1106
|
-
path: "/file-trees/{nodeId}",
|
|
1107
|
-
tags: ["File Trees"],
|
|
1108
|
-
summary: "Get file-tree node",
|
|
1109
|
-
successDescription: "File-tree node detail and its file list."
|
|
1110
|
-
}).input(fileTreeRefSchema).output(fileTreeNodeSchema),
|
|
1111
1131
|
listFiles: oc.route({
|
|
1112
1132
|
method: "GET",
|
|
1113
1133
|
path: "/file-trees/{nodeId}/files",
|
|
@@ -1543,6 +1563,9 @@ var viewSchema = z.object({
|
|
|
1543
1563
|
createdAt: z.string(),
|
|
1544
1564
|
updatedAt: z.string()
|
|
1545
1565
|
});
|
|
1566
|
+
var autoMergeSchema = z.boolean().optional().describe(
|
|
1567
|
+
"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."
|
|
1568
|
+
);
|
|
1546
1569
|
var createViewInputSchema = z.object({
|
|
1547
1570
|
config: viewConfigSchema.optional().default({ filters: [], sorts: [] }),
|
|
1548
1571
|
description: z.string().optional().default(""),
|
|
@@ -1550,7 +1573,8 @@ var createViewInputSchema = z.object({
|
|
|
1550
1573
|
name: z.string().min(1),
|
|
1551
1574
|
type: viewTypeSchema.optional().default("table"),
|
|
1552
1575
|
slug: z.string().min(1).regex(/^[a-z0-9-]+$/).optional(),
|
|
1553
|
-
submittedBy: z.string().optional().default("local-producer")
|
|
1576
|
+
submittedBy: z.string().optional().default("local-producer"),
|
|
1577
|
+
autoMerge: autoMergeSchema
|
|
1554
1578
|
});
|
|
1555
1579
|
var updateViewInputSchema = z.object({
|
|
1556
1580
|
config: viewConfigSchema.optional(),
|
|
@@ -1558,15 +1582,18 @@ var updateViewInputSchema = z.object({
|
|
|
1558
1582
|
message: z.string().optional().default("Update view"),
|
|
1559
1583
|
name: z.string().min(1).optional(),
|
|
1560
1584
|
type: viewTypeSchema.optional(),
|
|
1561
|
-
submittedBy: z.string().optional().default("local-producer")
|
|
1585
|
+
submittedBy: z.string().optional().default("local-producer"),
|
|
1586
|
+
autoMerge: autoMergeSchema
|
|
1562
1587
|
});
|
|
1563
1588
|
var deleteViewInputSchema = z.object({
|
|
1564
1589
|
message: z.string().optional().default("Delete view"),
|
|
1565
|
-
submittedBy: z.string().optional().default("local-producer")
|
|
1590
|
+
submittedBy: z.string().optional().default("local-producer"),
|
|
1591
|
+
autoMerge: autoMergeSchema
|
|
1566
1592
|
});
|
|
1567
1593
|
var restoreViewInputSchema = z.object({
|
|
1568
1594
|
message: z.string().optional().default("Restore view"),
|
|
1569
|
-
submittedBy: z.string().optional().default("local-producer")
|
|
1595
|
+
submittedBy: z.string().optional().default("local-producer"),
|
|
1596
|
+
autoMerge: autoMergeSchema
|
|
1570
1597
|
});
|
|
1571
1598
|
var viewChangeRequestInputSchema = z.discriminatedUnion("operation", [
|
|
1572
1599
|
createViewInputSchema.extend({
|
|
@@ -1903,8 +1930,13 @@ var viewContract = {
|
|
|
1903
1930
|
path: "/views/change-requests",
|
|
1904
1931
|
tags: ["Views", "Change Requests"],
|
|
1905
1932
|
summary: "Create view change request",
|
|
1906
|
-
successDescription: "
|
|
1907
|
-
}).input(viewChangeRequestInputSchema).output(
|
|
1933
|
+
successDescription: "Proposes a view change. `operation` selects what to propose: `create` (addressed by `baseId`), or `update` / `delete` / `restore` (addressed by `viewId`). Review-first when the actor lacks write access or passes `autoMerge: false` \u2014 a pending ChangeRequest (`materialized: false`). Otherwise the change is approved and merged in the same call and the materialized View comes back instead (`materialized: true`)."
|
|
1934
|
+
}).input(viewChangeRequestInputSchema).output(
|
|
1935
|
+
z.union([
|
|
1936
|
+
viewSchema.extend({ materialized: z.literal(true) }),
|
|
1937
|
+
changeRequestSchema.extend({ materialized: z.literal(false) })
|
|
1938
|
+
])
|
|
1939
|
+
)
|
|
1908
1940
|
};
|
|
1909
1941
|
var ReadDocLinesInputSchema = z.object({
|
|
1910
1942
|
nodeId: z.string(),
|
|
@@ -1943,13 +1975,6 @@ var createDocChangeRequestInputSchema = z.object({
|
|
|
1943
1975
|
submittedBy: z.string().optional().default("local-producer")
|
|
1944
1976
|
});
|
|
1945
1977
|
var docContract = {
|
|
1946
|
-
list: oc.route({
|
|
1947
|
-
method: "GET",
|
|
1948
|
-
path: "/docs",
|
|
1949
|
-
tags: ["Docs"],
|
|
1950
|
-
summary: "List Doc nodes",
|
|
1951
|
-
successDescription: "Doc nodes with their storage-backed bodies."
|
|
1952
|
-
}).output(z.array(docSchema)),
|
|
1953
1978
|
create: oc.route({
|
|
1954
1979
|
method: "POST",
|
|
1955
1980
|
path: "/docs",
|
|
@@ -1962,19 +1987,12 @@ var docContract = {
|
|
|
1962
1987
|
changeRequestSchema.extend({ materialized: z.literal(false) })
|
|
1963
1988
|
])
|
|
1964
1989
|
),
|
|
1965
|
-
get: oc.route({
|
|
1966
|
-
method: "GET",
|
|
1967
|
-
path: "/docs/{nodeId}",
|
|
1968
|
-
tags: ["Docs"],
|
|
1969
|
-
summary: "Get Doc node",
|
|
1970
|
-
successDescription: "Doc node detail and body."
|
|
1971
|
-
}).input(z.object({ nodeId: z.string() })).output(docSchema),
|
|
1972
1990
|
readLines: oc.route({
|
|
1973
1991
|
method: "GET",
|
|
1974
1992
|
path: "/docs/{nodeId}/lines",
|
|
1975
1993
|
tags: ["Docs"],
|
|
1976
1994
|
summary: "Read an exact line range from a Doc body",
|
|
1977
|
-
successDescription: "Lines [startLine, endLine] (range capped at 2000 lines / ~2MB response) sliced from the Doc's full body \u2014 Docs are KB-scale, so the whole body is read in memory; no byte-range/checkpoint machinery like assets.readTextLines uses for potentially multi-GB files. The Doc-domain follow-up to a Unified Grep match with `source: \"docs\"`, so an agent can read just the lines around a match instead of `get`'s entire body."
|
|
1995
|
+
successDescription: "Lines [startLine, endLine] (range capped at 2000 lines / ~2MB response) sliced from the Doc's full body \u2014 Docs are KB-scale, so the whole body is read in memory; no byte-range/checkpoint machinery like assets.readTextLines uses for potentially multi-GB files. The Doc-domain follow-up to a Unified Grep match with `source: \"docs\"`, so an agent can read just the lines around a match instead of `nodes.get`'s entire body."
|
|
1978
1996
|
}).input(ReadDocLinesInputSchema).output(ReadLinesVOSchema),
|
|
1979
1997
|
updateBody: oc.route({
|
|
1980
1998
|
method: "PUT",
|
|
@@ -2140,13 +2158,6 @@ var createFileNodeInputSchema = z.object({
|
|
|
2140
2158
|
autoMerge: z.boolean().optional()
|
|
2141
2159
|
});
|
|
2142
2160
|
var fileContract = {
|
|
2143
|
-
list: oc.route({
|
|
2144
|
-
method: "GET",
|
|
2145
|
-
path: "/files",
|
|
2146
|
-
tags: ["Files"],
|
|
2147
|
-
summary: "List File nodes",
|
|
2148
|
-
successDescription: "Workspace File nodes with their backing Asset metadata."
|
|
2149
|
-
}).output(z.array(FileNodeVOSchema)),
|
|
2150
2161
|
create: oc.route({
|
|
2151
2162
|
method: "POST",
|
|
2152
2163
|
path: "/files",
|
|
@@ -2158,34 +2169,7 @@ var fileContract = {
|
|
|
2158
2169
|
FileNodeVOSchema.extend({ materialized: z.literal(true) }),
|
|
2159
2170
|
changeRequestSchema.extend({ materialized: z.literal(false) })
|
|
2160
2171
|
])
|
|
2161
|
-
)
|
|
2162
|
-
get: oc.route({
|
|
2163
|
-
method: "GET",
|
|
2164
|
-
path: "/files/{nodeId}",
|
|
2165
|
-
tags: ["Files"],
|
|
2166
|
-
summary: "Get File node",
|
|
2167
|
-
successDescription: "File node detail and backing Asset metadata."
|
|
2168
|
-
}).input(z.object({ nodeId: z.string() })).output(FileNodeVOSchema)
|
|
2169
|
-
};
|
|
2170
|
-
var folderSchema = z.object({
|
|
2171
|
-
node: nodeSchema,
|
|
2172
|
-
children: z.array(nodeSchema)
|
|
2173
|
-
});
|
|
2174
|
-
var folderContract = {
|
|
2175
|
-
list: oc.route({
|
|
2176
|
-
method: "GET",
|
|
2177
|
-
path: "/folders",
|
|
2178
|
-
tags: ["Folders"],
|
|
2179
|
-
summary: "List Folder nodes",
|
|
2180
|
-
successDescription: "Folder nodes with their direct children."
|
|
2181
|
-
}).output(z.array(folderSchema)),
|
|
2182
|
-
get: oc.route({
|
|
2183
|
-
method: "GET",
|
|
2184
|
-
path: "/folders/{nodeId}",
|
|
2185
|
-
tags: ["Folders"],
|
|
2186
|
-
summary: "Get Folder node",
|
|
2187
|
-
successDescription: "Folder node and its direct children."
|
|
2188
|
-
}).input(z.object({ nodeId: z.string() })).output(folderSchema)
|
|
2172
|
+
)
|
|
2189
2173
|
};
|
|
2190
2174
|
var FormFieldBindingSchema = z.object({
|
|
2191
2175
|
inputName: z.string().min(1),
|
|
@@ -2818,16 +2802,86 @@ var UnifiedGrepResultVOSchema = z.object({
|
|
|
2818
2802
|
/** True when any source truncated, or any source has `notReached > 0`. */
|
|
2819
2803
|
truncated: z.boolean()
|
|
2820
2804
|
});
|
|
2805
|
+
var folderSchema = z.object({
|
|
2806
|
+
node: nodeSchema,
|
|
2807
|
+
children: z.array(nodeSchema)
|
|
2808
|
+
});
|
|
2809
|
+
|
|
2810
|
+
// ../../packages/busabase-contract/src/contract/node-detail-schemas.ts
|
|
2811
|
+
var genericNodeDetailSchema = (type) => z.object({
|
|
2812
|
+
type: z.literal(type),
|
|
2813
|
+
node: nodeSchema
|
|
2814
|
+
});
|
|
2815
|
+
var NODE_DETAIL_VARIANTS = {
|
|
2816
|
+
folder: folderSchema.extend({ type: z.literal("folder") }),
|
|
2817
|
+
doc: docSchema.extend({ type: z.literal("doc") }),
|
|
2818
|
+
file: FileNodeVOSchema.extend({ type: z.literal("file") }),
|
|
2819
|
+
// Skills, Drives, and AirApps are one server-side shape (`fileTreeNodeSchema`)
|
|
2820
|
+
// but three real node types — there is no synthetic "file-tree" node type, so
|
|
2821
|
+
// each gets its own discriminated variant rather than a shared alias.
|
|
2822
|
+
skill: fileTreeNodeSchema.extend({ type: z.literal("skill") }),
|
|
2823
|
+
drive: fileTreeNodeSchema.extend({ type: z.literal("drive") }),
|
|
2824
|
+
airapp: fileTreeNodeSchema.extend({ type: z.literal("airapp") }),
|
|
2825
|
+
base: genericNodeDetailSchema("base"),
|
|
2826
|
+
form: genericNodeDetailSchema("form"),
|
|
2827
|
+
whiteboard: genericNodeDetailSchema("whiteboard"),
|
|
2828
|
+
workflow: genericNodeDetailSchema("workflow"),
|
|
2829
|
+
html: genericNodeDetailSchema("html")
|
|
2830
|
+
};
|
|
2831
|
+
var NodeDetailVOSchema = z.discriminatedUnion("type", [
|
|
2832
|
+
NODE_DETAIL_VARIANTS.folder,
|
|
2833
|
+
NODE_DETAIL_VARIANTS.doc,
|
|
2834
|
+
NODE_DETAIL_VARIANTS.file,
|
|
2835
|
+
NODE_DETAIL_VARIANTS.skill,
|
|
2836
|
+
NODE_DETAIL_VARIANTS.drive,
|
|
2837
|
+
NODE_DETAIL_VARIANTS.airapp,
|
|
2838
|
+
NODE_DETAIL_VARIANTS.base,
|
|
2839
|
+
NODE_DETAIL_VARIANTS.form,
|
|
2840
|
+
NODE_DETAIL_VARIANTS.whiteboard,
|
|
2841
|
+
NODE_DETAIL_VARIANTS.workflow,
|
|
2842
|
+
NODE_DETAIL_VARIANTS.html
|
|
2843
|
+
]);
|
|
2844
|
+
var getNodeInputSchema = z.object({
|
|
2845
|
+
nodeId: z.string().describe("Node id, or a slug that is unique within its type."),
|
|
2846
|
+
type: z.enum(NODE_TYPES).optional().describe(
|
|
2847
|
+
"Optional disambiguation hint, only needed when `nodeId` is a slug that exists under more than one node type."
|
|
2848
|
+
)
|
|
2849
|
+
});
|
|
2821
2850
|
|
|
2822
2851
|
// ../../packages/busabase-contract/src/contract/busabase.ts
|
|
2823
|
-
var
|
|
2852
|
+
var changeRequestBatchFailureSchema = z.object({
|
|
2853
|
+
changeRequestId: z.string(),
|
|
2854
|
+
ok: z.literal(false),
|
|
2855
|
+
error: z.string(),
|
|
2856
|
+
code: z.string().optional(),
|
|
2857
|
+
data: z.unknown().optional()
|
|
2858
|
+
});
|
|
2859
|
+
var changeRequestReviewBatchResultSchema = z.object({
|
|
2824
2860
|
results: z.array(
|
|
2825
|
-
z.
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2861
|
+
z.discriminatedUnion("ok", [
|
|
2862
|
+
z.object({
|
|
2863
|
+
changeRequestId: z.string(),
|
|
2864
|
+
ok: z.literal(true),
|
|
2865
|
+
status: z.string(),
|
|
2866
|
+
changeRequest: changeRequestSchema
|
|
2867
|
+
}),
|
|
2868
|
+
changeRequestBatchFailureSchema
|
|
2869
|
+
])
|
|
2870
|
+
)
|
|
2871
|
+
});
|
|
2872
|
+
var changeRequestMergeBatchResultSchema = z.object({
|
|
2873
|
+
results: z.array(
|
|
2874
|
+
z.discriminatedUnion("ok", [
|
|
2875
|
+
z.object({
|
|
2876
|
+
changeRequestId: z.string(),
|
|
2877
|
+
ok: z.literal(true),
|
|
2878
|
+
status: z.string(),
|
|
2879
|
+
changeRequest: changeRequestSchema,
|
|
2880
|
+
record: recordSchema.nullable(),
|
|
2881
|
+
view: viewSchema.nullable()
|
|
2882
|
+
}),
|
|
2883
|
+
changeRequestBatchFailureSchema
|
|
2884
|
+
])
|
|
2831
2885
|
)
|
|
2832
2886
|
});
|
|
2833
2887
|
var busabaseContractRoutes = {
|
|
@@ -2862,8 +2916,8 @@ var busabaseContractRoutes = {
|
|
|
2862
2916
|
method: "GET",
|
|
2863
2917
|
path: "/nodes",
|
|
2864
2918
|
tags: ["Nodes"],
|
|
2865
|
-
summary: "List
|
|
2866
|
-
successDescription: "Workspace node tree including folders, Bases, files, and agents. With no `parentId`/`depth`, returns the FULL tree (legacy behavior, still what every non-sidebar caller gets). Passing `parentId` and/or `depth` switches to a depth-bounded fetch: `parentId` omitted/null starts from the space root and returns it wrapped exactly like the legacy call (just depth-limited); an explicit `parentId` returns that node's children directly, ready to merge into its `NodeVO.children` for a sidebar's lazy per-folder expand. See `NodeVO.hasChildren` for how a depth boundary is surfaced."
|
|
2919
|
+
summary: "List nodes (workspace tree, or a flat summary list by type)",
|
|
2920
|
+
successDescription: "Workspace node tree including folders, Bases, files, and agents. With no `parentId`/`depth`, returns the FULL tree (legacy behavior, still what every non-sidebar caller gets). Passing `parentId` and/or `depth` switches to a depth-bounded fetch: `parentId` omitted/null starts from the space root and returns it wrapped exactly like the legacy call (just depth-limited); an explicit `parentId` returns that node's children directly, ready to merge into its `NodeVO.children` for a sidebar's lazy per-folder expand. See `NodeVO.hasChildren` for how a depth boundary is surfaced. Passing `types` instead returns a FLAT, ACL-filtered list of lightweight summaries (`children: []`) for just those node types \u2014 this is what replaced `GET /docs`, `/files`, `/folders`, and `/file-trees`, and it deliberately hydrates nothing heavy (no Doc bodies, backing Assets, folder children, or file inventories). Open one item with `GET /nodes/{nodeId}`."
|
|
2867
2921
|
}).input(listNodesInputSchema).output(z.array(nodeSchema)),
|
|
2868
2922
|
searchByName: oc.route({
|
|
2869
2923
|
method: "GET",
|
|
@@ -2933,6 +2987,21 @@ var busabaseContractRoutes = {
|
|
|
2933
2987
|
summary: "List the current actor's favorited nodes",
|
|
2934
2988
|
successDescription: "The acting user's favorited nodes, newest-favorited first, filtered through the same archived/deleted/visibility rules as the main tree \u2014 a favorited node that's later archived, purged, or (cloud) hidden from this actor silently drops out rather than erroring."
|
|
2935
2989
|
}).output(z.array(nodeSchema)),
|
|
2990
|
+
// Registered LAST among the `/nodes/...` GETs on purpose. `GET /nodes/search`
|
|
2991
|
+
// and `GET /nodes/favorites` are literal paths that now share a prefix with
|
|
2992
|
+
// this template. The oRPC OpenAPI matcher is a rou3 radix trie, which
|
|
2993
|
+
// prefers a static segment over a param segment independently of insertion
|
|
2994
|
+
// order — but keeping the literals declared first means the source order
|
|
2995
|
+
// matches the resolution order, so nobody has to know that to read this
|
|
2996
|
+
// file. `tests/openapi-node-routes.test.ts` proves the literals still win
|
|
2997
|
+
// against a real handler rather than resolving as `nodeId: "search"`.
|
|
2998
|
+
get: oc.route({
|
|
2999
|
+
method: "GET",
|
|
3000
|
+
path: "/nodes/{nodeId}",
|
|
3001
|
+
tags: ["Nodes"],
|
|
3002
|
+
summary: "Get one node's typed detail",
|
|
3003
|
+
successDescription: "The node's full detail, discriminated by its `type`. One entry point for every node type, so a caller holding an id never has to discover the type first: `folder` carries its direct `children`, `doc` its storage-backed `body`, `file` its backing `asset`, and `skill`/`drive`/`airapp` their Asset-backed `files`. Types with no richer detail yet (`base`, `form`, `whiteboard`, `workflow`, `html`) return just `node`. `nodeId` accepts an id or a slug; pass `type` when a slug exists under more than one type. Archived nodes are not returned (404), matching the typed gets this replaced."
|
|
3004
|
+
}).input(getNodeInputSchema).output(NodeDetailVOSchema),
|
|
2936
3005
|
principals: {
|
|
2937
3006
|
list: oc.route({
|
|
2938
3007
|
method: "GET",
|
|
@@ -3066,7 +3135,9 @@ var busabaseContractRoutes = {
|
|
|
3066
3135
|
airapps: airappRuntimeContract,
|
|
3067
3136
|
files: fileContract,
|
|
3068
3137
|
docs: docContract,
|
|
3069
|
-
folders:
|
|
3138
|
+
// No `folders` key: the Folder domain's only two operations were `GET /folders`
|
|
3139
|
+
// and `GET /folders/{nodeId}`, both now served by the unified Node surface
|
|
3140
|
+
// (`nodes.list({ types: ["folder"] })` / `nodes.get`).
|
|
3070
3141
|
forms: formContract,
|
|
3071
3142
|
assets: assetsContract,
|
|
3072
3143
|
vault: vaultContract,
|
|
@@ -3098,23 +3169,16 @@ var busabaseContractRoutes = {
|
|
|
3098
3169
|
successDescription: "Change Request detail."
|
|
3099
3170
|
}).input(z.object({ changeRequestId: z.string() })).output(changeRequestSchema),
|
|
3100
3171
|
review: oc.route({
|
|
3101
|
-
method: "POST",
|
|
3102
|
-
path: "/change-requests/{changeRequestId}/reviews",
|
|
3103
|
-
tags: ["Change Requests"],
|
|
3104
|
-
summary: "Review change request",
|
|
3105
|
-
successDescription: "Reviewed change request."
|
|
3106
|
-
}).input(reviewChangeRequestInputSchema.extend({ changeRequestId: z.string() })).output(changeRequestSchema),
|
|
3107
|
-
reviewMany: oc.route({
|
|
3108
3172
|
method: "POST",
|
|
3109
3173
|
path: "/change-requests/reviews",
|
|
3110
3174
|
tags: ["Change Requests"],
|
|
3111
|
-
summary: "Review
|
|
3175
|
+
summary: "Review change requests",
|
|
3112
3176
|
successDescription: "Per-change-request review results (failures isolated \u2014 one bad id does not abort the rest)."
|
|
3113
3177
|
}).input(
|
|
3114
3178
|
reviewChangeRequestInputSchema.extend({
|
|
3115
3179
|
changeRequestIds: z.array(z.string()).min(1).max(100)
|
|
3116
3180
|
})
|
|
3117
|
-
).output(
|
|
3181
|
+
).output(changeRequestReviewBatchResultSchema),
|
|
3118
3182
|
close: oc.route({
|
|
3119
3183
|
method: "POST",
|
|
3120
3184
|
path: "/change-requests/{changeRequestId}/close",
|
|
@@ -3123,25 +3187,12 @@ var busabaseContractRoutes = {
|
|
|
3123
3187
|
successDescription: "Closed change request (terminal \u2014 distinct from request changes)."
|
|
3124
3188
|
}).input(z.object({ changeRequestId: z.string(), reason: z.string().optional() })).output(changeRequestSchema),
|
|
3125
3189
|
merge: oc.route({
|
|
3126
|
-
method: "POST",
|
|
3127
|
-
path: "/change-requests/{changeRequestId}/merge",
|
|
3128
|
-
tags: ["Change Requests"],
|
|
3129
|
-
summary: "Merge change request into Base",
|
|
3130
|
-
successDescription: "Merged change request and canonical record."
|
|
3131
|
-
}).input(z.object({ changeRequestId: z.string() })).output(
|
|
3132
|
-
z.object({
|
|
3133
|
-
changeRequest: changeRequestSchema,
|
|
3134
|
-
record: recordSchema.nullable(),
|
|
3135
|
-
view: viewSchema.nullable()
|
|
3136
|
-
})
|
|
3137
|
-
),
|
|
3138
|
-
mergeMany: oc.route({
|
|
3139
3190
|
method: "POST",
|
|
3140
3191
|
path: "/change-requests/merge",
|
|
3141
3192
|
tags: ["Change Requests"],
|
|
3142
|
-
summary: "Merge
|
|
3193
|
+
summary: "Merge change requests",
|
|
3143
3194
|
successDescription: "Per-change-request merge results (each merged in its own transaction; failures isolated)."
|
|
3144
|
-
}).input(z.object({ changeRequestIds: z.array(z.string()).min(1).max(100) })).output(
|
|
3195
|
+
}).input(z.object({ changeRequestIds: z.array(z.string()).min(1).max(100) })).output(changeRequestMergeBatchResultSchema)
|
|
3145
3196
|
},
|
|
3146
3197
|
operations: {
|
|
3147
3198
|
revise: oc.route({
|
|
@@ -3482,6 +3533,10 @@ var getRecordByField = async (client, input) => {
|
|
|
3482
3533
|
};
|
|
3483
3534
|
|
|
3484
3535
|
// src/index.ts
|
|
3536
|
+
var batchItemError = (result) => Object.assign(new Error(result?.error ?? "Change request action returned no result"), {
|
|
3537
|
+
...result?.code ? { code: result.code } : {},
|
|
3538
|
+
...result?.data === void 0 ? {} : { data: result.data }
|
|
3539
|
+
});
|
|
3485
3540
|
var Busabase = class {
|
|
3486
3541
|
/** The underlying fully-typed oRPC client. Use it for anything not surfaced here. */
|
|
3487
3542
|
client;
|
|
@@ -3509,11 +3564,55 @@ var Busabase = class {
|
|
|
3509
3564
|
return this.client.views;
|
|
3510
3565
|
}
|
|
3511
3566
|
get changeRequests() {
|
|
3512
|
-
|
|
3567
|
+
const review = async (input) => {
|
|
3568
|
+
if ("changeRequestIds" in input) return this.client.changeRequests.review(input);
|
|
3569
|
+
const { changeRequestId, ...reviewInput } = input;
|
|
3570
|
+
const { results } = await this.client.changeRequests.review({
|
|
3571
|
+
...reviewInput,
|
|
3572
|
+
changeRequestIds: [changeRequestId]
|
|
3573
|
+
});
|
|
3574
|
+
const result = results[0];
|
|
3575
|
+
if (!result?.ok) throw batchItemError(result);
|
|
3576
|
+
return result.changeRequest;
|
|
3577
|
+
};
|
|
3578
|
+
const merge = async (input) => {
|
|
3579
|
+
if ("changeRequestIds" in input) return this.client.changeRequests.merge(input);
|
|
3580
|
+
const { results } = await this.client.changeRequests.merge({
|
|
3581
|
+
changeRequestIds: [input.changeRequestId]
|
|
3582
|
+
});
|
|
3583
|
+
const result = results[0];
|
|
3584
|
+
if (!result?.ok) throw batchItemError(result);
|
|
3585
|
+
return {
|
|
3586
|
+
changeRequest: result.changeRequest,
|
|
3587
|
+
record: result.record,
|
|
3588
|
+
view: result.view
|
|
3589
|
+
};
|
|
3590
|
+
};
|
|
3591
|
+
return new Proxy(this.client.changeRequests, {
|
|
3592
|
+
get(target, property, receiver) {
|
|
3593
|
+
if (property === "review") return review;
|
|
3594
|
+
if (property === "merge") return merge;
|
|
3595
|
+
return Reflect.get(target, property, receiver);
|
|
3596
|
+
}
|
|
3597
|
+
});
|
|
3513
3598
|
}
|
|
3514
3599
|
get operations() {
|
|
3515
3600
|
return this.client.operations;
|
|
3516
3601
|
}
|
|
3602
|
+
/**
|
|
3603
|
+
* The workspace node surface, and the single entry point for reading ONE node
|
|
3604
|
+
* of any type: `bb.nodes.get({ nodeId })` returns a `NodeDetailVO`
|
|
3605
|
+
* discriminated by `type` (`folder` carries `children`, `doc` a `body`, `file`
|
|
3606
|
+
* its `asset`, `skill`/`drive`/`airapp` their `files`). It replaced the four
|
|
3607
|
+
* typed gets (`docs`/`files`/`folders`/`fileTrees`), so a caller holding an id
|
|
3608
|
+
* no longer has to know the node's type before it can read it.
|
|
3609
|
+
*
|
|
3610
|
+
* `bb.nodes.list({ types })` is the matching list: a flat array of lightweight
|
|
3611
|
+
* summaries for just those types. Without `types` it still returns the full
|
|
3612
|
+
* workspace tree.
|
|
3613
|
+
*
|
|
3614
|
+
* There is no `bb.folders` any more — folders are `type: "folder"` here.
|
|
3615
|
+
*/
|
|
3517
3616
|
get nodes() {
|
|
3518
3617
|
return this.client.nodes;
|
|
3519
3618
|
}
|
|
@@ -3535,19 +3634,38 @@ var Busabase = class {
|
|
|
3535
3634
|
}
|
|
3536
3635
|
});
|
|
3537
3636
|
}
|
|
3538
|
-
/**
|
|
3637
|
+
/**
|
|
3638
|
+
* Skills, Drives, and AirApps — one surface, discriminated by `type`.
|
|
3639
|
+
*
|
|
3640
|
+
* Creation and per-file reads/writes live here. Listing them and reading one
|
|
3641
|
+
* node's detail moved to the unified Node surface:
|
|
3642
|
+
* `bb.nodes.list({ types: ["skill", "drive", "airapp"] })` and
|
|
3643
|
+
* `bb.nodes.get({ nodeId, type })`.
|
|
3644
|
+
*/
|
|
3539
3645
|
get fileTrees() {
|
|
3540
3646
|
return this.client.fileTrees;
|
|
3541
3647
|
}
|
|
3648
|
+
/**
|
|
3649
|
+
* File nodes. `create` only — list with `bb.nodes.list({ types: ["file"] })`
|
|
3650
|
+
* and read one (backing Asset included) with `bb.nodes.get({ nodeId })`.
|
|
3651
|
+
*/
|
|
3542
3652
|
get files() {
|
|
3543
3653
|
return this.client.files;
|
|
3544
3654
|
}
|
|
3655
|
+
/**
|
|
3656
|
+
* Docs. Create / read a line range / update the body / open a Change Request.
|
|
3657
|
+
* List with `bb.nodes.list({ types: ["doc"] })` and read one (body included)
|
|
3658
|
+
* with `bb.nodes.get({ nodeId })`.
|
|
3659
|
+
*
|
|
3660
|
+
* There is deliberately no `bb.docs.list()` shim. The retired `GET /docs`
|
|
3661
|
+
* returned every Doc *with its body*; the one-call replacement returns
|
|
3662
|
+
* lightweight summaries, and the only way to keep the old shape would be a
|
|
3663
|
+
* detail request per Doc. An SDK convenience that quietly turns one call into
|
|
3664
|
+
* N is worse than a compile error that points at `bb.nodes`.
|
|
3665
|
+
*/
|
|
3545
3666
|
get docs() {
|
|
3546
3667
|
return this.client.docs;
|
|
3547
3668
|
}
|
|
3548
|
-
get folders() {
|
|
3549
|
-
return this.client.folders;
|
|
3550
|
-
}
|
|
3551
3669
|
get agentTasks() {
|
|
3552
3670
|
return this.client.agentTasks;
|
|
3553
3671
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "busa-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Typed TypeScript/JavaScript SDK for the Busabase OpenAPI REST API. Talks to a local or remote `busabase server` (or Busabase Cloud). Short-name alias for busabase-sdk.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/busabase/busabase/tree/main/apps/busabase-sdk",
|