busabase-sdk 0.9.13 → 0.9.15
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 +2210 -73
- package/dist/index.js +213 -29
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -44,8 +44,12 @@ var fieldTypeSchema = z.enum([
|
|
|
44
44
|
"ai_tags",
|
|
45
45
|
"code",
|
|
46
46
|
"json",
|
|
47
|
-
"yaml"
|
|
47
|
+
"yaml",
|
|
48
|
+
"formula",
|
|
49
|
+
"lookup",
|
|
50
|
+
"whiteboard"
|
|
48
51
|
]);
|
|
52
|
+
var lookupRollupSchema = z.enum(["values", "count", "sum", "average", "min", "max", "concatenate"]).default("values");
|
|
49
53
|
var fieldOptionsSchema = z.object({
|
|
50
54
|
ai: z.object({
|
|
51
55
|
model: z.string().optional(),
|
|
@@ -75,7 +79,26 @@ var fieldOptionsSchema = z.object({
|
|
|
75
79
|
height: z.number().int().positive().max(1200).optional(),
|
|
76
80
|
providers: z.array(z.string()).optional()
|
|
77
81
|
}).optional(),
|
|
82
|
+
// `formula` fields are server-computed (like the other computed types) from
|
|
83
|
+
// `expression` at record write time — see packages/busabase-core's
|
|
84
|
+
// domains/base/formula/ engine. `{slug}` references a sibling field, including
|
|
85
|
+
// another `formula` field (chained formulas) — a dependency graph orders
|
|
86
|
+
// computation and rejects cycles at field create/edit time.
|
|
87
|
+
formula: z.object({
|
|
88
|
+
expression: z.string().min(1)
|
|
89
|
+
}).optional(),
|
|
78
90
|
inverseFieldId: z.string().optional(),
|
|
91
|
+
// `lookup` fields pull a field's values across a `relation` field on the same
|
|
92
|
+
// Base, optionally rolling them up into one scalar. Unlike every other computed
|
|
93
|
+
// type they are NOT stored on the commit: a lookup's value depends on OTHER
|
|
94
|
+
// records, which can change without this record ever being written, so it is
|
|
95
|
+
// resolved at read time (see busabase-core's domains/base/logic/lookup-values.ts).
|
|
96
|
+
lookup: z.object({
|
|
97
|
+
relationFieldSlug: z.string().min(1).describe("Slug of a `relation` field on THIS Base \u2014 the hop to follow."),
|
|
98
|
+
targetFieldSlug: z.string().min(1).describe("Slug of the field on the related Base whose values are pulled over."),
|
|
99
|
+
rollup: lookupRollupSchema.optional(),
|
|
100
|
+
limit: z.enum(["all", "first"]).optional().describe("`first` looks at only the first linked record; default `all`.")
|
|
101
|
+
}).optional(),
|
|
79
102
|
multiple: z.boolean().optional(),
|
|
80
103
|
// Display formatting for `number` columns (Notion-style: one number type,
|
|
81
104
|
// a format option). `currency` renders via Intl.NumberFormat.
|
|
@@ -128,11 +151,11 @@ var createBaseInputSchema = z.object({
|
|
|
128
151
|
options: fieldOptionsSchema.optional().default({})
|
|
129
152
|
})
|
|
130
153
|
).default([]),
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
// review
|
|
135
|
-
autoMerge: z.boolean().optional()
|
|
154
|
+
// Permission-aware default: omitted merges immediately if the actor has
|
|
155
|
+
// write access on the parent node, otherwise falls back to a pending
|
|
156
|
+
// ChangeRequest (status "in_review"). Pass explicit `autoMerge: false` to
|
|
157
|
+
// force review even with write access.
|
|
158
|
+
autoMerge: z.boolean().optional()
|
|
136
159
|
});
|
|
137
160
|
var createBaseFieldInputSchema = z.object({
|
|
138
161
|
name: fieldNameSchema,
|
|
@@ -354,6 +377,15 @@ var folderNodeType = {
|
|
|
354
377
|
operations: []
|
|
355
378
|
};
|
|
356
379
|
|
|
380
|
+
// ../../packages/busabase-contract/src/domains/form/definition.ts
|
|
381
|
+
var formNodeType = {
|
|
382
|
+
type: "form",
|
|
383
|
+
label: "Form",
|
|
384
|
+
icon: "clipboard-list",
|
|
385
|
+
capabilities: { hasDetail: true, creatable: true },
|
|
386
|
+
operations: []
|
|
387
|
+
};
|
|
388
|
+
|
|
357
389
|
// ../../packages/busabase-contract/src/domains/html/definition.ts
|
|
358
390
|
var htmlNodeType = {
|
|
359
391
|
type: "html",
|
|
@@ -415,6 +447,7 @@ var BUILTIN_NODE_TYPES = [
|
|
|
415
447
|
airappNodeType,
|
|
416
448
|
fileNodeType,
|
|
417
449
|
docNodeType,
|
|
450
|
+
formNodeType,
|
|
418
451
|
whiteboardNodeType,
|
|
419
452
|
workflowNodeType,
|
|
420
453
|
htmlNodeType
|
|
@@ -476,6 +509,15 @@ var nodePrincipalSchema = z.object({
|
|
|
476
509
|
createdAt: z.string(),
|
|
477
510
|
updatedAt: z.string()
|
|
478
511
|
});
|
|
512
|
+
var nodeShareSchema = z.object({
|
|
513
|
+
nodeId: z.string(),
|
|
514
|
+
scope: z.enum(["none", "public"]),
|
|
515
|
+
capability: z.enum(["read", "submit"]),
|
|
516
|
+
// Derived from `passwordHash != null` — the hash itself is never serialized.
|
|
517
|
+
hasPassword: z.boolean(),
|
|
518
|
+
expiresAt: z.string().nullable(),
|
|
519
|
+
updatedAt: z.string()
|
|
520
|
+
});
|
|
479
521
|
var listNodesInputSchema = z.object({
|
|
480
522
|
parentId: z.string().nullable().optional().describe("Node to start from. Omit or null to start from the space root."),
|
|
481
523
|
depth: z.coerce.number().int().min(1).max(5).optional().describe(
|
|
@@ -762,8 +804,8 @@ var createNodeChangeRequestInputSchema = z.object({
|
|
|
762
804
|
'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".'
|
|
763
805
|
),
|
|
764
806
|
submittedBy: z.string().optional().default("local-producer"),
|
|
765
|
-
autoMerge: z.boolean().optional().
|
|
766
|
-
"Whether to approve and merge this structural node change immediately.
|
|
807
|
+
autoMerge: z.boolean().optional().describe(
|
|
808
|
+
"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."
|
|
767
809
|
),
|
|
768
810
|
operations: z.array(nodeOperationInputSchema).min(1)
|
|
769
811
|
});
|
|
@@ -936,11 +978,11 @@ var createFileTreeInputSchema = z.object({
|
|
|
936
978
|
visibility: z.enum(["private", "workspace", "public"]).optional().default("private"),
|
|
937
979
|
version: z.string().optional().default("0.1.0"),
|
|
938
980
|
files: z.array(z.union([assetFileInputSchema, textFileInputSchema])).optional().default([]),
|
|
939
|
-
//
|
|
940
|
-
//
|
|
941
|
-
//
|
|
942
|
-
// review
|
|
943
|
-
autoMerge: z.boolean().optional()
|
|
981
|
+
// Permission-aware default: omitted merges immediately if the actor has
|
|
982
|
+
// write access on the parent node, otherwise falls back to a pending
|
|
983
|
+
// ChangeRequest (status "in_review"). Pass explicit `autoMerge: false` to
|
|
984
|
+
// force review even with write access.
|
|
985
|
+
autoMerge: z.boolean().optional(),
|
|
944
986
|
// "merge" (default): `files` is layered on top of the config's default seed
|
|
945
987
|
// files by path — a caller supplying just a couple of extra files (e.g. a
|
|
946
988
|
// Skill's own reference doc) still gets the default scaffold (SKILL.md,
|
|
@@ -1540,12 +1582,14 @@ var createChangeRequestInputSchema = z.object({
|
|
|
1540
1582
|
idempotencyKey: z.string().optional().describe(
|
|
1541
1583
|
"Optional client-supplied key that dedupes retries. Scoped per base + submitter: calling this endpoint again with the SAME idempotencyKey (e.g. after a timeout or a 5xx where you couldn't tell if the first call succeeded) returns the 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."
|
|
1542
1584
|
),
|
|
1543
|
-
//
|
|
1544
|
-
//
|
|
1545
|
-
//
|
|
1546
|
-
// review
|
|
1547
|
-
// materialized record instead of the
|
|
1548
|
-
|
|
1585
|
+
// Permission-aware default: omitted merges immediately if the actor has
|
|
1586
|
+
// write access on the Base's node, otherwise falls back to a pending
|
|
1587
|
+
// ChangeRequest (status "in_review"). Pass explicit `autoMerge: false` to
|
|
1588
|
+
// force review even with write access; `autoMerge: true` approves and
|
|
1589
|
+
// merges right away, returning the materialized record instead of the
|
|
1590
|
+
// pending ChangeRequest (gracefully falls back to a pending CR if the
|
|
1591
|
+
// actor doesn't actually have write access).
|
|
1592
|
+
autoMerge: z.boolean().optional()
|
|
1549
1593
|
});
|
|
1550
1594
|
var createBulkChangeRequestInputSchema = z.object({
|
|
1551
1595
|
records: z.array(z.record(z.string(), z.unknown())).min(1).max(1e3).describe(
|
|
@@ -1565,6 +1609,11 @@ var recordFieldFilterInputSchema = z.object({
|
|
|
1565
1609
|
valueText: z.string().min(1),
|
|
1566
1610
|
limit: z.coerce.number().int().min(1).max(100).optional().default(50)
|
|
1567
1611
|
});
|
|
1612
|
+
var recordFieldGetInputSchema = z.object({
|
|
1613
|
+
baseId: z.string(),
|
|
1614
|
+
fieldSlug: z.string().min(1),
|
|
1615
|
+
valueText: z.string().min(1)
|
|
1616
|
+
});
|
|
1568
1617
|
var restoreRecordInputSchema = z.object({
|
|
1569
1618
|
message: z.string().optional(),
|
|
1570
1619
|
submittedBy: z.string().optional().default("local-editor")
|
|
@@ -1784,6 +1833,13 @@ var recordContract = {
|
|
|
1784
1833
|
summary: "Filter records by field text",
|
|
1785
1834
|
successDescription: "Canonical records matching a field text filter."
|
|
1786
1835
|
}).input(recordFieldFilterInputSchema).output(z.array(recordSchema)),
|
|
1836
|
+
getByField: oc.route({
|
|
1837
|
+
method: "GET",
|
|
1838
|
+
path: "/records/by-field",
|
|
1839
|
+
tags: ["Records"],
|
|
1840
|
+
summary: "Get record by field value",
|
|
1841
|
+
successDescription: "Single canonical record whose field value exactly matches, or null when none does \u2014 a scoped point lookup (e.g. by a unique slug or path field), not a list."
|
|
1842
|
+
}).input(recordFieldGetInputSchema).output(recordSchema.nullable()),
|
|
1787
1843
|
updateChangeRequest: oc.route({
|
|
1788
1844
|
method: "PUT",
|
|
1789
1845
|
path: "/records/{recordId}/change-requests",
|
|
@@ -1863,11 +1919,11 @@ var createDocInputSchema = z.object({
|
|
|
1863
1919
|
name: z.string().min(1),
|
|
1864
1920
|
description: z.string().optional().default(""),
|
|
1865
1921
|
body: z.string().optional().default(""),
|
|
1866
|
-
//
|
|
1867
|
-
//
|
|
1868
|
-
//
|
|
1869
|
-
// review
|
|
1870
|
-
autoMerge: z.boolean().optional()
|
|
1922
|
+
// Permission-aware default: omitted merges immediately if the actor has
|
|
1923
|
+
// write access on the parent node, otherwise falls back to a pending
|
|
1924
|
+
// ChangeRequest (status "in_review"). Pass explicit `autoMerge: false` to
|
|
1925
|
+
// force review even with write access.
|
|
1926
|
+
autoMerge: z.boolean().optional()
|
|
1871
1927
|
});
|
|
1872
1928
|
var updateDocInputSchema = z.object({
|
|
1873
1929
|
body: z.string()
|
|
@@ -2073,11 +2129,11 @@ var createFileNodeInputSchema = z.object({
|
|
|
2073
2129
|
name: z.string().min(1),
|
|
2074
2130
|
description: z.string().optional().default(""),
|
|
2075
2131
|
assetId: z.string().min(1),
|
|
2076
|
-
//
|
|
2077
|
-
//
|
|
2078
|
-
//
|
|
2079
|
-
// review
|
|
2080
|
-
autoMerge: z.boolean().optional()
|
|
2132
|
+
// Permission-aware default: omitted merges immediately if the actor has
|
|
2133
|
+
// write access on the parent node, otherwise falls back to a pending
|
|
2134
|
+
// ChangeRequest (status "in_review"). Pass explicit `autoMerge: false` to
|
|
2135
|
+
// force review even with write access.
|
|
2136
|
+
autoMerge: z.boolean().optional()
|
|
2081
2137
|
});
|
|
2082
2138
|
var fileContract = {
|
|
2083
2139
|
list: oc.route({
|
|
@@ -2127,6 +2183,102 @@ var folderContract = {
|
|
|
2127
2183
|
successDescription: "Folder node and its direct children."
|
|
2128
2184
|
}).input(z.object({ nodeId: z.string() })).output(folderSchema)
|
|
2129
2185
|
};
|
|
2186
|
+
var FormFieldBindingSchema = z.object({
|
|
2187
|
+
inputName: z.string().min(1),
|
|
2188
|
+
fieldSlug: z.string().min(1),
|
|
2189
|
+
required: z.boolean().optional(),
|
|
2190
|
+
label: z.string().optional(),
|
|
2191
|
+
help: z.string().optional()
|
|
2192
|
+
});
|
|
2193
|
+
var FormThemeSchema = z.object({
|
|
2194
|
+
logoUrl: z.string().optional(),
|
|
2195
|
+
coverUrl: z.string().optional(),
|
|
2196
|
+
brandColor: z.string().optional(),
|
|
2197
|
+
hideBranding: z.boolean().optional()
|
|
2198
|
+
});
|
|
2199
|
+
var FormPageSourceSchema = z.object({
|
|
2200
|
+
code: z.string().optional(),
|
|
2201
|
+
theme: FormThemeSchema.optional()
|
|
2202
|
+
});
|
|
2203
|
+
var FormShareSchema = z.object({
|
|
2204
|
+
isPublic: z.boolean().default(false),
|
|
2205
|
+
anonymousSubmit: z.boolean().default(false),
|
|
2206
|
+
submitLimit: z.number().int().positive().optional(),
|
|
2207
|
+
requireCaptcha: z.boolean().optional()
|
|
2208
|
+
});
|
|
2209
|
+
var FormVOSchema = z.object({
|
|
2210
|
+
id: z.string(),
|
|
2211
|
+
nodeId: z.string(),
|
|
2212
|
+
spaceId: z.string(),
|
|
2213
|
+
targetBaseId: z.string(),
|
|
2214
|
+
name: z.string(),
|
|
2215
|
+
description: z.string(),
|
|
2216
|
+
bindings: z.array(FormFieldBindingSchema),
|
|
2217
|
+
page: FormPageSourceSchema,
|
|
2218
|
+
share: FormShareSchema,
|
|
2219
|
+
/** Accepted submissions so far — backs server-side `share.submitLimit`. */
|
|
2220
|
+
submissionCount: z.number().int().nonnegative().default(0),
|
|
2221
|
+
status: z.enum(["active", "archived"]),
|
|
2222
|
+
createdBy: z.string(),
|
|
2223
|
+
createdAt: z.string(),
|
|
2224
|
+
updatedAt: z.string()
|
|
2225
|
+
});
|
|
2226
|
+
var CreateFormInputSchema = z.object({
|
|
2227
|
+
nodeId: z.string().min(1),
|
|
2228
|
+
targetBaseId: z.string().min(1),
|
|
2229
|
+
name: z.string().min(1),
|
|
2230
|
+
description: z.string().optional().default(""),
|
|
2231
|
+
bindings: z.array(FormFieldBindingSchema).optional().default([]),
|
|
2232
|
+
page: FormPageSourceSchema.optional().default({}),
|
|
2233
|
+
share: FormShareSchema.optional().default({ isPublic: false, anonymousSubmit: false })
|
|
2234
|
+
});
|
|
2235
|
+
var UpdateFormInputSchema = z.object({
|
|
2236
|
+
name: z.string().min(1).optional(),
|
|
2237
|
+
description: z.string().optional(),
|
|
2238
|
+
bindings: z.array(FormFieldBindingSchema).optional(),
|
|
2239
|
+
page: FormPageSourceSchema.optional(),
|
|
2240
|
+
share: FormShareSchema.optional()
|
|
2241
|
+
});
|
|
2242
|
+
var SubmitFormInputSchema = z.object({
|
|
2243
|
+
values: z.record(z.string(), z.unknown()),
|
|
2244
|
+
captchaToken: z.string().optional()
|
|
2245
|
+
});
|
|
2246
|
+
var FormSubmitResultSchema = z.object({
|
|
2247
|
+
changeRequestId: z.string(),
|
|
2248
|
+
status: z.literal("pending_review")
|
|
2249
|
+
});
|
|
2250
|
+
|
|
2251
|
+
// ../../packages/busabase-contract/src/domains/form/contract.ts
|
|
2252
|
+
var formContract = {
|
|
2253
|
+
getByNode: oc.route({
|
|
2254
|
+
method: "GET",
|
|
2255
|
+
path: "/forms/{nodeId}",
|
|
2256
|
+
tags: ["Forms"],
|
|
2257
|
+
summary: "Get a form by its node id",
|
|
2258
|
+
successDescription: "The form bound to this node, or 404."
|
|
2259
|
+
}).input(z.object({ nodeId: z.string() })).output(FormVOSchema),
|
|
2260
|
+
create: oc.route({
|
|
2261
|
+
method: "POST",
|
|
2262
|
+
path: "/forms",
|
|
2263
|
+
tags: ["Forms"],
|
|
2264
|
+
summary: "Create a form bound to a Base",
|
|
2265
|
+
successDescription: "The created form."
|
|
2266
|
+
}).input(CreateFormInputSchema).output(FormVOSchema),
|
|
2267
|
+
update: oc.route({
|
|
2268
|
+
method: "PUT",
|
|
2269
|
+
path: "/forms/{nodeId}",
|
|
2270
|
+
tags: ["Forms"],
|
|
2271
|
+
summary: "Update a form's config (owner-managed, not a change request)",
|
|
2272
|
+
successDescription: "The updated form."
|
|
2273
|
+
}).input(UpdateFormInputSchema.extend({ nodeId: z.string() })).output(FormVOSchema),
|
|
2274
|
+
submit: oc.route({
|
|
2275
|
+
method: "POST",
|
|
2276
|
+
path: "/forms/{nodeId}/submit",
|
|
2277
|
+
tags: ["Forms"],
|
|
2278
|
+
summary: "Submit a filled-in form",
|
|
2279
|
+
successDescription: "Creates an approval-first record-create ChangeRequest on the target Base."
|
|
2280
|
+
}).input(SubmitFormInputSchema.extend({ nodeId: z.string() })).output(FormSubmitResultSchema)
|
|
2281
|
+
};
|
|
2130
2282
|
var InstallPlanNodeTypeSchema = z.enum([
|
|
2131
2283
|
"folder",
|
|
2132
2284
|
"doc",
|
|
@@ -2824,6 +2976,37 @@ var busabaseContractRoutes = {
|
|
|
2824
2976
|
principalId: z.string().min(1)
|
|
2825
2977
|
})
|
|
2826
2978
|
).output(z.object({ removed: z.boolean() }))
|
|
2979
|
+
},
|
|
2980
|
+
share: {
|
|
2981
|
+
get: oc.route({
|
|
2982
|
+
method: "GET",
|
|
2983
|
+
path: "/nodes/{nodeId}/share",
|
|
2984
|
+
tags: ["Nodes", "Sharing"],
|
|
2985
|
+
summary: "Read a node's public link-sharing settings",
|
|
2986
|
+
successDescription: "The node's public-share settings, or null when the node was never shared. The stored password is never returned \u2014 only a `hasPassword` flag."
|
|
2987
|
+
}).input(z.object({ nodeId: z.string() })).output(nodeShareSchema.nullable()),
|
|
2988
|
+
set: oc.route({
|
|
2989
|
+
method: "POST",
|
|
2990
|
+
path: "/nodes/{nodeId}/share",
|
|
2991
|
+
tags: ["Nodes", "Sharing"],
|
|
2992
|
+
summary: "Enable or update a node's public link sharing",
|
|
2993
|
+
successDescription: "Turned public sharing on (or updated its capability/password/expiry) and re-materialized the effective public scope down the subtree. Requires `manage` level on the node."
|
|
2994
|
+
}).input(
|
|
2995
|
+
z.object({
|
|
2996
|
+
nodeId: z.string(),
|
|
2997
|
+
scope: z.enum(["none", "public"]),
|
|
2998
|
+
capability: z.enum(["read", "submit"]).optional(),
|
|
2999
|
+
password: z.string().nullable().optional(),
|
|
3000
|
+
expiresAt: z.string().datetime().nullable().optional()
|
|
3001
|
+
})
|
|
3002
|
+
).output(nodeShareSchema.nullable()),
|
|
3003
|
+
disable: oc.route({
|
|
3004
|
+
method: "DELETE",
|
|
3005
|
+
path: "/nodes/{nodeId}/share",
|
|
3006
|
+
tags: ["Nodes", "Sharing"],
|
|
3007
|
+
summary: "Revoke a node's public link sharing",
|
|
3008
|
+
successDescription: "Flipped the share scope to none in place (the link is kept so re-enabling produces the same URL). Requires `manage` level on the node."
|
|
3009
|
+
}).input(z.object({ nodeId: z.string() })).output(nodeShareSchema.nullable())
|
|
2827
3010
|
}
|
|
2828
3011
|
},
|
|
2829
3012
|
auditEvents: {
|
|
@@ -2888,6 +3071,7 @@ var busabaseContractRoutes = {
|
|
|
2888
3071
|
files: fileContract,
|
|
2889
3072
|
docs: docContract,
|
|
2890
3073
|
folders: folderContract,
|
|
3074
|
+
forms: formContract,
|
|
2891
3075
|
assets: assetsContract,
|
|
2892
3076
|
vault: vaultContract,
|
|
2893
3077
|
webhooks: webhookContract,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "busabase-sdk",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.15",
|
|
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",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"typescript": "^5.9.3",
|
|
43
43
|
"vitest": "^2.1.8",
|
|
44
44
|
"open-domains": "0.0.2",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
45
|
+
"busabase-contract": "0.9.15",
|
|
46
|
+
"openlib": "0.1.1"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=24.18.0"
|