busabase-sdk 0.9.14 → 0.9.16

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +2150 -13
  2. package/dist/index.js +183 -1
  3. package/package.json +4 -4
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.
@@ -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(
@@ -1567,6 +1609,11 @@ var recordFieldFilterInputSchema = z.object({
1567
1609
  valueText: z.string().min(1),
1568
1610
  limit: z.coerce.number().int().min(1).max(100).optional().default(50)
1569
1611
  });
1612
+ var recordFieldGetInputSchema = z.object({
1613
+ baseId: z.string(),
1614
+ fieldSlug: z.string().min(1),
1615
+ valueText: z.string().min(1)
1616
+ });
1570
1617
  var restoreRecordInputSchema = z.object({
1571
1618
  message: z.string().optional(),
1572
1619
  submittedBy: z.string().optional().default("local-editor")
@@ -1786,6 +1833,13 @@ var recordContract = {
1786
1833
  summary: "Filter records by field text",
1787
1834
  successDescription: "Canonical records matching a field text filter."
1788
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()),
1789
1843
  updateChangeRequest: oc.route({
1790
1844
  method: "PUT",
1791
1845
  path: "/records/{recordId}/change-requests",
@@ -2129,6 +2183,102 @@ var folderContract = {
2129
2183
  successDescription: "Folder node and its direct children."
2130
2184
  }).input(z.object({ nodeId: z.string() })).output(folderSchema)
2131
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
+ };
2132
2282
  var InstallPlanNodeTypeSchema = z.enum([
2133
2283
  "folder",
2134
2284
  "doc",
@@ -2826,6 +2976,37 @@ var busabaseContractRoutes = {
2826
2976
  principalId: z.string().min(1)
2827
2977
  })
2828
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())
2829
3010
  }
2830
3011
  },
2831
3012
  auditEvents: {
@@ -2890,6 +3071,7 @@ var busabaseContractRoutes = {
2890
3071
  files: fileContract,
2891
3072
  docs: docContract,
2892
3073
  folders: folderContract,
3074
+ forms: formContract,
2893
3075
  assets: assetsContract,
2894
3076
  vault: vaultContract,
2895
3077
  webhooks: webhookContract,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "busabase-sdk",
3
- "version": "0.9.14",
3
+ "version": "0.9.16",
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",
@@ -41,9 +41,9 @@
41
41
  "tsx": "^4.20.5",
42
42
  "typescript": "^5.9.3",
43
43
  "vitest": "^2.1.8",
44
- "busabase-contract": "0.9.14",
45
- "open-domains": "0.0.2",
46
- "openlib": "0.1.1"
44
+ "busabase-contract": "0.9.16",
45
+ "openlib": "0.1.1",
46
+ "open-domains": "0.0.2"
47
47
  },
48
48
  "engines": {
49
49
  "node": ">=24.18.0"