busabase-sdk 0.70.0 → 0.72.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/airapp.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as BusabaseClient } from "./client-
|
|
1
|
+
import { t as BusabaseClient } from "./client-CZPoK0Uk.js";
|
|
2
2
|
//#region src/airapp.d.ts
|
|
3
3
|
type NodeChangeRequestInput = Parameters<BusabaseClient["nodes"]["createChangeRequest"]>[0];
|
|
4
4
|
type NodeOperationInput = NodeChangeRequestInput["operations"][number];
|
|
@@ -215,13 +215,37 @@ declare function inspectProvisionedResources(client: AirAppProvisioningClient, c
|
|
|
215
215
|
*/
|
|
216
216
|
declare function provisionDeclaredResources(client: AirAppProvisioningClient, config: AirAppResourceConfig): Promise<AirAppResources>;
|
|
217
217
|
/** The client surface `publishAirApp` needs, on top of provisioning. */
|
|
218
|
-
type AirAppPublishClient = AirAppProvisioningClient & Pick<BusabaseClient, "fileTrees" | "changeRequests">;
|
|
219
|
-
/**
|
|
220
|
-
|
|
218
|
+
type AirAppPublishClient = AirAppProvisioningClient & Pick<BusabaseClient, "fileTrees" | "changeRequests" | "assets">;
|
|
219
|
+
/**
|
|
220
|
+
* One file of the app's built AirApp bundle, as `publishAirApp` receives it.
|
|
221
|
+
*
|
|
222
|
+
* A file tree holds text inline but binaries as Assets — the server never
|
|
223
|
+
* stores image bytes in a file operation, it stores an `assetId` pointing at
|
|
224
|
+
* the Asset library. So a bundle that ships a favicon or an empty-state
|
|
225
|
+
* illustration needs a shape that can say "these are bytes", and until now
|
|
226
|
+
* this type could only say `content: string`. Callers did the only thing that
|
|
227
|
+
* type allowed: read the PNG as UTF-8 and publish the mojibake. That fails
|
|
228
|
+
* silently — the publish succeeds and the image is simply broken.
|
|
229
|
+
*
|
|
230
|
+
* `bytes` is resolved to an `assetId` by `resolveAirAppFileAssets`, which
|
|
231
|
+
* `publishAirApp` calls for you.
|
|
232
|
+
*/
|
|
233
|
+
type AirAppFileInput = {
|
|
221
234
|
path: string;
|
|
222
|
-
content: string;
|
|
223
235
|
mimeType?: string;
|
|
224
|
-
}
|
|
236
|
+
} & ({
|
|
237
|
+
content: string;
|
|
238
|
+
bytes?: never;
|
|
239
|
+
assetId?: never;
|
|
240
|
+
} | {
|
|
241
|
+
bytes: Uint8Array;
|
|
242
|
+
content?: never;
|
|
243
|
+
assetId?: never;
|
|
244
|
+
} | {
|
|
245
|
+
assetId: string;
|
|
246
|
+
content?: never;
|
|
247
|
+
bytes?: never;
|
|
248
|
+
});
|
|
225
249
|
/**
|
|
226
250
|
* What one publish did. `merged` is the question a caller actually has — did
|
|
227
251
|
* this bundle go live, or is it waiting for someone?
|
|
@@ -258,6 +282,16 @@ type AirAppPublishResult = {
|
|
|
258
282
|
* makes for a Base's fields (`additiveFieldsFor` only ever appends).
|
|
259
283
|
*/
|
|
260
284
|
declare function buildAirAppFileOperations(localFiles: AirAppFileInput[], deployedPaths: Iterable<string>): FileTreeCreateOrUpdateOperation[];
|
|
285
|
+
/**
|
|
286
|
+
* Upload every `bytes` file in a bundle and hand back the same list with
|
|
287
|
+
* `assetId` in their place. Text files pass through untouched — a bundle with
|
|
288
|
+
* no binaries makes no upload calls at all.
|
|
289
|
+
*
|
|
290
|
+
* Separate from `buildAirAppFileOperations` so that function can stay pure and
|
|
291
|
+
* directly testable; separate from `publishAirApp` so a caller assembling its
|
|
292
|
+
* own file operations (a Skill or Drive sync, say) can reuse it.
|
|
293
|
+
*/
|
|
294
|
+
declare function resolveAirAppFileAssets(client: AirAppPublishClient, files: AirAppFileInput[], fetchImpl?: typeof fetch): Promise<AirAppFileInput[]>;
|
|
261
295
|
/**
|
|
262
296
|
* Publish the app's own AirApp bundle: create it under the Folder when this
|
|
263
297
|
* Space has never had it, or propose the local files as an update when it
|
|
@@ -280,4 +314,4 @@ declare function buildAirAppFileOperations(localFiles: AirAppFileInput[], deploy
|
|
|
280
314
|
*/
|
|
281
315
|
declare function publishAirApp(client: AirAppPublishClient, config: AirAppResourceConfig, files: AirAppFileInput[]): Promise<AirAppPublishResult>;
|
|
282
316
|
//#endregion
|
|
283
|
-
export { AirAppBaseDeclaration, AirAppFieldDeclaration, AirAppFileInput, AirAppFolderDeclaration, AirAppNodeDeclaration, AirAppOwnershipRepair, AirAppProvisionedBase, AirAppProvisioningClient, AirAppPublishClient, AirAppPublishResult, AirAppResourceConfig, AirAppResourceOwnership, AirAppResources, AirAppSetupCode, AirAppSetupError, buildAirAppFileOperations, buildProvisionOperations, inspectProvisionedResources, isNotFound, provisionDeclaredResources, publishAirApp, resolveProvisionedFolder };
|
|
317
|
+
export { AirAppBaseDeclaration, AirAppFieldDeclaration, AirAppFileInput, AirAppFolderDeclaration, AirAppNodeDeclaration, AirAppOwnershipRepair, AirAppProvisionedBase, AirAppProvisioningClient, AirAppPublishClient, AirAppPublishResult, AirAppResourceConfig, AirAppResourceOwnership, AirAppResources, AirAppSetupCode, AirAppSetupError, buildAirAppFileOperations, buildProvisionOperations, inspectProvisionedResources, isNotFound, provisionDeclaredResources, publishAirApp, resolveAirAppFileAssets, resolveProvisionedFolder };
|
package/dist/airapp.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as APP_ROOT_RESOURCE_KEY } from "./template-
|
|
1
|
+
import { i as uploadAsset, t as APP_ROOT_RESOURCE_KEY } from "./template-DRMp6tKv.js";
|
|
2
2
|
//#region src/airapp.ts
|
|
3
3
|
/**
|
|
4
4
|
* AirApp resource provisioning — how an app claims (or creates) the Folder and
|
|
@@ -402,12 +402,50 @@ function provisionDeclaredResources(client, config) {
|
|
|
402
402
|
*/
|
|
403
403
|
function buildAirAppFileOperations(localFiles, deployedPaths) {
|
|
404
404
|
const deployed = new Set(deployedPaths);
|
|
405
|
-
return localFiles.map((file) =>
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
405
|
+
return localFiles.map((file) => {
|
|
406
|
+
if (file.bytes) throw new Error(`buildAirAppFileOperations: ${file.path} carries bytes — run resolveAirAppFileAssets first to turn them into an assetId`);
|
|
407
|
+
return {
|
|
408
|
+
kind: deployed.has(file.path) ? "update" : "create",
|
|
409
|
+
path: file.path,
|
|
410
|
+
...file.assetId ? { assetId: file.assetId } : { content: file.content },
|
|
411
|
+
...file.mimeType ? { mimeType: file.mimeType } : {}
|
|
412
|
+
};
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Upload every `bytes` file in a bundle and hand back the same list with
|
|
417
|
+
* `assetId` in their place. Text files pass through untouched — a bundle with
|
|
418
|
+
* no binaries makes no upload calls at all.
|
|
419
|
+
*
|
|
420
|
+
* Separate from `buildAirAppFileOperations` so that function can stay pure and
|
|
421
|
+
* directly testable; separate from `publishAirApp` so a caller assembling its
|
|
422
|
+
* own file operations (a Skill or Drive sync, say) can reuse it.
|
|
423
|
+
*/
|
|
424
|
+
async function resolveAirAppFileAssets(client, files, fetchImpl) {
|
|
425
|
+
const resolved = [];
|
|
426
|
+
for (const file of files) {
|
|
427
|
+
if (!file.bytes) {
|
|
428
|
+
resolved.push(file);
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
const mimeType = file.mimeType ?? "application/octet-stream";
|
|
432
|
+
const asset = await uploadAsset(client, file.bytes, {
|
|
433
|
+
fileName: basenameOf(file.path),
|
|
434
|
+
mimeType
|
|
435
|
+
}, fetchImpl);
|
|
436
|
+
if (!asset.assetId) throw new Error(`resolveAirAppFileAssets: ${file.path} uploaded but this host returned no assetId, so no file can reference it`);
|
|
437
|
+
resolved.push({
|
|
438
|
+
path: file.path,
|
|
439
|
+
assetId: asset.assetId,
|
|
440
|
+
mimeType
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
return resolved;
|
|
444
|
+
}
|
|
445
|
+
/** Last path segment — file trees always use POSIX separators. */
|
|
446
|
+
function basenameOf(filePath) {
|
|
447
|
+
const segments = filePath.split("/");
|
|
448
|
+
return segments[segments.length - 1] || filePath;
|
|
411
449
|
}
|
|
412
450
|
/**
|
|
413
451
|
* Find a still-pending ChangeRequest that already proposes creating this
|
|
@@ -461,6 +499,7 @@ async function publishAirApp(client, config, files) {
|
|
|
461
499
|
if (!airApp) throw setupError("SETUP_CONFLICT", "This app does not declare an airApp to publish");
|
|
462
500
|
const current = await inspectProvisionedResources(client, config);
|
|
463
501
|
if (!current.folder) throw setupError("SETUP_REQUIRED", "Provision the Folder and Bases with provisionDeclaredResources before publishing the AirApp");
|
|
502
|
+
const resolvedFiles = await resolveAirAppFileAssets(client, files);
|
|
464
503
|
if (!current.airApp) {
|
|
465
504
|
const pendingChangeRequestId = await findPendingAirAppCreate(client, airApp.slug);
|
|
466
505
|
if (pendingChangeRequestId) return {
|
|
@@ -474,7 +513,7 @@ async function publishAirApp(client, config, files) {
|
|
|
474
513
|
slug: airApp.slug,
|
|
475
514
|
name: airApp.name,
|
|
476
515
|
description: airApp.description ?? "",
|
|
477
|
-
files,
|
|
516
|
+
files: resolvedFiles,
|
|
478
517
|
mergeMode: "replace"
|
|
479
518
|
});
|
|
480
519
|
return result.materialized ? {
|
|
@@ -487,7 +526,7 @@ async function publishAirApp(client, config, files) {
|
|
|
487
526
|
changeRequestId: result.id
|
|
488
527
|
};
|
|
489
528
|
}
|
|
490
|
-
const operations = buildAirAppFileOperations(
|
|
529
|
+
const operations = buildAirAppFileOperations(resolvedFiles, (await client.fileTrees.listFiles({
|
|
491
530
|
nodeId: current.airApp.nodeId,
|
|
492
531
|
type: "airapp"
|
|
493
532
|
})).map((file) => file.path));
|
|
@@ -505,4 +544,4 @@ async function publishAirApp(client, config, files) {
|
|
|
505
544
|
};
|
|
506
545
|
}
|
|
507
546
|
//#endregion
|
|
508
|
-
export { AirAppSetupError, buildAirAppFileOperations, buildProvisionOperations, inspectProvisionedResources, isNotFound, provisionDeclaredResources, publishAirApp, resolveProvisionedFolder };
|
|
547
|
+
export { AirAppSetupError, buildAirAppFileOperations, buildProvisionOperations, inspectProvisionedResources, isNotFound, provisionDeclaredResources, publishAirApp, resolveAirAppFileAssets, resolveProvisionedFolder };
|
|
@@ -2855,6 +2855,36 @@ declare const cloudContract: {
|
|
|
2855
2855
|
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
2856
2856
|
};
|
|
2857
2857
|
share: {
|
|
2858
|
+
list: import("@orpc/contract").ContractProcedure<import("@orpc/contract").Schema<unknown, unknown>, z.ZodArray<z.ZodObject<{
|
|
2859
|
+
nodeId: z.ZodString;
|
|
2860
|
+
name: z.ZodString;
|
|
2861
|
+
slug: z.ZodString;
|
|
2862
|
+
type: z.ZodEnum<{
|
|
2863
|
+
[x: string]: string;
|
|
2864
|
+
}>;
|
|
2865
|
+
icon: z.ZodDefault<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
2866
|
+
type: z.ZodLiteral<"emoji">;
|
|
2867
|
+
value: z.ZodString;
|
|
2868
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
2869
|
+
type: z.ZodLiteral<"attachment">;
|
|
2870
|
+
url: z.ZodString;
|
|
2871
|
+
attachmentId: z.ZodString;
|
|
2872
|
+
originalUrl: z.ZodOptional<z.ZodString>;
|
|
2873
|
+
originalAttachmentId: z.ZodOptional<z.ZodString>;
|
|
2874
|
+
crop: z.ZodOptional<z.ZodObject<{
|
|
2875
|
+
x: z.ZodNumber;
|
|
2876
|
+
y: z.ZodNumber;
|
|
2877
|
+
zoom: z.ZodNumber;
|
|
2878
|
+
}, z.core.$strip>>;
|
|
2879
|
+
}, z.core.$strip>], "type">>>;
|
|
2880
|
+
capability: z.ZodEnum<{
|
|
2881
|
+
read: "read";
|
|
2882
|
+
submit: "submit";
|
|
2883
|
+
}>;
|
|
2884
|
+
hasPassword: z.ZodBoolean;
|
|
2885
|
+
expiresAt: z.ZodNullable<z.ZodString>;
|
|
2886
|
+
createdAt: z.ZodString;
|
|
2887
|
+
}, z.core.$strip>>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
2858
2888
|
get: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
2859
2889
|
nodeId: z.ZodString;
|
|
2860
2890
|
}, z.core.$strip>, z.ZodNullable<z.ZodObject<{
|
|
@@ -22941,6 +22971,78 @@ declare const cloudContract: {
|
|
|
22941
22971
|
}, z.core.$strip>;
|
|
22942
22972
|
};
|
|
22943
22973
|
}>>, Record<never, never>>;
|
|
22974
|
+
listPaged: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
22975
|
+
status: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
22976
|
+
active: "active";
|
|
22977
|
+
all: "all";
|
|
22978
|
+
expired: "expired";
|
|
22979
|
+
revoked: "revoked";
|
|
22980
|
+
}>>>;
|
|
22981
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
22982
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
22983
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
22984
|
+
items: z.ZodArray<z.ZodObject<{
|
|
22985
|
+
id: z.ZodString;
|
|
22986
|
+
type: z.ZodEnum<{
|
|
22987
|
+
"change-request": "change-request";
|
|
22988
|
+
node: "node";
|
|
22989
|
+
"record-detail": "record-detail";
|
|
22990
|
+
}>;
|
|
22991
|
+
typeId: z.ZodString;
|
|
22992
|
+
targetName: z.ZodString;
|
|
22993
|
+
nodeType: z.ZodNullable<z.ZodEnum<{
|
|
22994
|
+
airapp: "airapp";
|
|
22995
|
+
base: "base";
|
|
22996
|
+
doc: "doc";
|
|
22997
|
+
drive: "drive";
|
|
22998
|
+
file: "file";
|
|
22999
|
+
folder: "folder";
|
|
23000
|
+
skill: "skill";
|
|
23001
|
+
}>>;
|
|
23002
|
+
createdAt: z.ZodString;
|
|
23003
|
+
expiresAt: z.ZodString;
|
|
23004
|
+
revokedAt: z.ZodNullable<z.ZodString>;
|
|
23005
|
+
active: z.ZodBoolean;
|
|
23006
|
+
framePolicy: z.ZodObject<{
|
|
23007
|
+
mode: z.ZodEnum<{
|
|
23008
|
+
anywhere: "anywhere";
|
|
23009
|
+
origins: "origins";
|
|
23010
|
+
"top-level-only": "top-level-only";
|
|
23011
|
+
}>;
|
|
23012
|
+
allowedOrigins: z.ZodArray<z.ZodString>;
|
|
23013
|
+
}, z.core.$strip>;
|
|
23014
|
+
}, z.core.$strip>>;
|
|
23015
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
23016
|
+
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
|
|
23017
|
+
BAD_REQUEST: {
|
|
23018
|
+
status: number;
|
|
23019
|
+
message: string;
|
|
23020
|
+
data: z.ZodObject<{
|
|
23021
|
+
error: z.ZodString;
|
|
23022
|
+
}, z.core.$strip>;
|
|
23023
|
+
};
|
|
23024
|
+
UNAUTHORIZED: {
|
|
23025
|
+
status: number;
|
|
23026
|
+
message: string;
|
|
23027
|
+
data: z.ZodObject<{
|
|
23028
|
+
error: z.ZodString;
|
|
23029
|
+
}, z.core.$strip>;
|
|
23030
|
+
};
|
|
23031
|
+
FORBIDDEN: {
|
|
23032
|
+
status: number;
|
|
23033
|
+
message: string;
|
|
23034
|
+
data: z.ZodObject<{
|
|
23035
|
+
error: z.ZodString;
|
|
23036
|
+
}, z.core.$strip>;
|
|
23037
|
+
};
|
|
23038
|
+
NOT_FOUND: {
|
|
23039
|
+
status: number;
|
|
23040
|
+
message: string;
|
|
23041
|
+
data: z.ZodObject<{
|
|
23042
|
+
error: z.ZodString;
|
|
23043
|
+
}, z.core.$strip>;
|
|
23044
|
+
};
|
|
23045
|
+
}>>, Record<never, never>>;
|
|
22944
23046
|
revoke: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
22945
23047
|
id: z.ZodString;
|
|
22946
23048
|
}, z.core.$strip>, z.ZodObject<{
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as AssetTextStatus, A as NodeVO, At as GalleryCardSize, B as UpdatePreviewFileCredentialDTO, Bt as ViewSortVO, C as CommentVO, Ct as ListFormsDTO, D as MentionInboxItemVO, Dt as AssetAttachmentRef, E as LookupRollup, Et as UpdateFormDTO, F as SearchResponseVO, Ft as VIEW_FIELD_MAX_WIDTH, G as VaultItemKind, Gt as cloudContract, H as VaultAccessPolicy, Ht as ViewVO, I as SearchResultKind, It as VIEW_FIELD_MIN_WIDTH, J as VaultScopeType, Jt as CREATABLE_NODE_TYPES, K as VaultItemVO, Kt as NodeIcon, L as SearchResultVO, Lt as ViewConfigVO, M as OperationVO, Mt as GanttScale, N as ReviewVO, Nt as RecordLinkVO, O as MentionInboxPageVO, Ot as BaseFieldVO, P as ReviewVerdict, Pt as RecordVO, Q as AssetDetailVO, R as SourceAttributionVO, Rt as ViewFilterOperator, S as CommentSubjectType, St as FormVO, T as FieldType, Tt as SubmitFormDTO, U as VaultEnvironment, Ut as AttachmentRef, V as UpdateVaultSettingsDTO, Vt as ViewType, W as VaultItemInput, Wt as CloudContract, X as FileNodeMetadata, Xt as NodeType, Y as VaultSettingsVO, Yt as CreatableNodeType, Z as FileNodeVO, Zt as OperationKind, _ as ChangeRequestVO, _t as FormFieldBindingVO, a as createBusabaseClient, at as FilePreviewConfigurationStatus, b as CommentMentionTargetType, bt as FormSubmitResultVO, c as AuditAction, ct as FilePreviewUnavailableReason, d as ChangeRequestBatchFailureVO, dt as FileTreeNodeVO, et as AssetUsageVO, f as ChangeRequestCountsVO, ft as FileTreeReadFileVO, g as ChangeRequestTargetType, gt as FormBoundFieldVO, h as ChangeRequestStatus, ht as CreateFormDTO, i as ResolvedConfig, it as FilePreviewConfigVO, j as OperationStatus, jt as GalleryCoverFit, k as NodeSearchResultVO, kt as BaseVO, l as AuditEventVO, lt as FilePreviewVO, m as ChangeRequestReviewBatchResultVO, mt as ActivityItemVO, n as BusabaseConfig, nt as GrepInputDTO, o as resolveConfig, ot as FilePreviewCredentialSource, p as ChangeRequestMergeBatchResultVO, pt as NodeDetailVO, q as VaultRuntimeEnv, qt as NodeIconSchema, r as DEFAULT_BASE_URL, rt as GrepResultVO, s as AgentTaskVO, st as FilePreviewProvider, t as BusabaseClient, tt as AssetVO, u as BusabaseSourceChannel, ut as FileTreeFileVO, v as CommentMentionDispatchStatus, vt as FormPageSourceVO, w as CommitVO, wt as ListFormsVO, x as CommentMentionVO, xt as FormThemeVO, y as CommentMentionInputDTO, yt as FormShareVO, z as UserRefVO, zt as ViewFilterVO } from "./client-
|
|
1
|
+
import { $ as AssetTextStatus, A as NodeVO, At as GalleryCardSize, B as UpdatePreviewFileCredentialDTO, Bt as ViewSortVO, C as CommentVO, Ct as ListFormsDTO, D as MentionInboxItemVO, Dt as AssetAttachmentRef, E as LookupRollup, Et as UpdateFormDTO, F as SearchResponseVO, Ft as VIEW_FIELD_MAX_WIDTH, G as VaultItemKind, Gt as cloudContract, H as VaultAccessPolicy, Ht as ViewVO, I as SearchResultKind, It as VIEW_FIELD_MIN_WIDTH, J as VaultScopeType, Jt as CREATABLE_NODE_TYPES, K as VaultItemVO, Kt as NodeIcon, L as SearchResultVO, Lt as ViewConfigVO, M as OperationVO, Mt as GanttScale, N as ReviewVO, Nt as RecordLinkVO, O as MentionInboxPageVO, Ot as BaseFieldVO, P as ReviewVerdict, Pt as RecordVO, Q as AssetDetailVO, R as SourceAttributionVO, Rt as ViewFilterOperator, S as CommentSubjectType, St as FormVO, T as FieldType, Tt as SubmitFormDTO, U as VaultEnvironment, Ut as AttachmentRef, V as UpdateVaultSettingsDTO, Vt as ViewType, W as VaultItemInput, Wt as CloudContract, X as FileNodeMetadata, Xt as NodeType, Y as VaultSettingsVO, Yt as CreatableNodeType, Z as FileNodeVO, Zt as OperationKind, _ as ChangeRequestVO, _t as FormFieldBindingVO, a as createBusabaseClient, at as FilePreviewConfigurationStatus, b as CommentMentionTargetType, bt as FormSubmitResultVO, c as AuditAction, ct as FilePreviewUnavailableReason, d as ChangeRequestBatchFailureVO, dt as FileTreeNodeVO, et as AssetUsageVO, f as ChangeRequestCountsVO, ft as FileTreeReadFileVO, g as ChangeRequestTargetType, gt as FormBoundFieldVO, h as ChangeRequestStatus, ht as CreateFormDTO, i as ResolvedConfig, it as FilePreviewConfigVO, j as OperationStatus, jt as GalleryCoverFit, k as NodeSearchResultVO, kt as BaseVO, l as AuditEventVO, lt as FilePreviewVO, m as ChangeRequestReviewBatchResultVO, mt as ActivityItemVO, n as BusabaseConfig, nt as GrepInputDTO, o as resolveConfig, ot as FilePreviewCredentialSource, p as ChangeRequestMergeBatchResultVO, pt as NodeDetailVO, q as VaultRuntimeEnv, qt as NodeIconSchema, r as DEFAULT_BASE_URL, rt as GrepResultVO, s as AgentTaskVO, st as FilePreviewProvider, t as BusabaseClient, tt as AssetVO, u as BusabaseSourceChannel, ut as FileTreeFileVO, v as CommentMentionDispatchStatus, vt as FormPageSourceVO, w as CommitVO, wt as ListFormsVO, x as CommentMentionVO, xt as FormThemeVO, y as CommentMentionInputDTO, yt as FormShareVO, z as UserRefVO, zt as ViewFilterVO } from "./client-CZPoK0Uk.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
//#region src/url.d.ts
|
|
4
4
|
/**
|
|
@@ -114,6 +114,53 @@ declare const toFilesOnlyGrepResult: (result: UnifiedGrepResultVO) => GrepResult
|
|
|
114
114
|
/** Call unified grep as files-only while preserving the former asset helper result shape. */
|
|
115
115
|
declare const grepAssets: (client: Pick<BusabaseClient, "grep">, input: GrepInputDTO) => Promise<GrepResultVO>;
|
|
116
116
|
//#endregion
|
|
117
|
+
//#region src/asset-upload.d.ts
|
|
118
|
+
/** An uploaded file, as the rest of the SDK needs to refer to it. */
|
|
119
|
+
interface BusabaseUploadedAsset {
|
|
120
|
+
/** What a file-tree operation references. Absent on hosts with no Asset library. */
|
|
121
|
+
assetId?: string;
|
|
122
|
+
/** What a record's attachment cell references. */
|
|
123
|
+
attachmentId: string;
|
|
124
|
+
/** Publicly resolvable URL — safe to embed in Markdown. */
|
|
125
|
+
url: string;
|
|
126
|
+
fileName: string;
|
|
127
|
+
mimeType: string;
|
|
128
|
+
size: number;
|
|
129
|
+
/** `sha256:<hex>`, when this runtime could compute one. */
|
|
130
|
+
contentHash?: string;
|
|
131
|
+
}
|
|
132
|
+
interface UploadAssetOptions {
|
|
133
|
+
fileName: string;
|
|
134
|
+
mimeType: string;
|
|
135
|
+
/** Optional grouping hint the server records alongside the asset. */
|
|
136
|
+
context?: string;
|
|
137
|
+
spaceId?: string;
|
|
138
|
+
}
|
|
139
|
+
/** The slice of the client an upload needs — keeps this testable with a stub. */
|
|
140
|
+
type AssetUploadClient = Pick<BusabaseClient, "assets">;
|
|
141
|
+
/**
|
|
142
|
+
* SHA-256 of the bytes, or `undefined` where WebCrypto is unavailable.
|
|
143
|
+
*
|
|
144
|
+
* Undefined is a real answer, not a failure: the hash only buys deduplication,
|
|
145
|
+
* so a runtime without WebCrypto uploads the bytes it would otherwise have
|
|
146
|
+
* skipped. Failing the upload over a missing optimization would be worse.
|
|
147
|
+
*/
|
|
148
|
+
declare function hashBytes(bytes: Uint8Array): Promise<string | undefined>;
|
|
149
|
+
/**
|
|
150
|
+
* Upload bytes and get back every id the rest of the SDK might need.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* const asset = await uploadAsset(client, png, {
|
|
155
|
+
* fileName: "user-journey.png",
|
|
156
|
+
* mimeType: "image/png",
|
|
157
|
+
* });
|
|
158
|
+
* // asset.assetId -> reference it from a Skill/Drive/AirApp file operation
|
|
159
|
+
* // asset.url -> embed it in Markdown
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
declare function uploadAsset(client: AssetUploadClient, bytes: Uint8Array, options: UploadAssetOptions, fetchImpl?: typeof fetch): Promise<BusabaseUploadedAsset>;
|
|
163
|
+
//#endregion
|
|
117
164
|
//#region src/record-get.d.ts
|
|
118
165
|
interface RecordByFieldInput {
|
|
119
166
|
baseId: string;
|
|
@@ -403,6 +450,25 @@ declare class Busabase {
|
|
|
403
450
|
* ```
|
|
404
451
|
*/
|
|
405
452
|
putText(assetId: string, text: string): Promise<Awaited<ReturnType<BusabaseClient["assets"]["putText"]>>>;
|
|
453
|
+
/**
|
|
454
|
+
* Put a file into this Space's Asset library in one call, and get back every
|
|
455
|
+
* id the rest of the SDK asks for: `assetId` for a file-tree entry,
|
|
456
|
+
* `attachmentId` for a record's attachment cell, `url` to embed in Markdown.
|
|
457
|
+
*
|
|
458
|
+
* Hides the three-step flow (`assets.createUploadUrl` → PUT →
|
|
459
|
+
* `assets.confirm`) and its dedup short-circuit, the same way `putText`
|
|
460
|
+
* does for text slots.
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```ts
|
|
464
|
+
* const shot = await bb.uploadAsset(png, {
|
|
465
|
+
* fileName: "user-journey.png",
|
|
466
|
+
* mimeType: "image/png",
|
|
467
|
+
* });
|
|
468
|
+
* body += ``;
|
|
469
|
+
* ```
|
|
470
|
+
*/
|
|
471
|
+
uploadAsset(bytes: Uint8Array, options: UploadAssetOptions): Promise<BusabaseUploadedAsset>;
|
|
406
472
|
/** Service health — reaches the server without requiring auth. */
|
|
407
473
|
health(): import("@orpc/client").ClientPromiseResult<{
|
|
408
474
|
status: string;
|
|
@@ -427,4 +493,4 @@ declare class Busabase {
|
|
|
427
493
|
}>>>>;
|
|
428
494
|
}
|
|
429
495
|
//#endregion
|
|
430
|
-
export { type ActivityItemVO, type AgentTaskVO, type FileTreeFileVO as AirAppFileVO, type FileTreeFileVO as DriveFileVO, type FileTreeFileVO, type FileTreeFileVO as SkillFileVO, type FileTreeReadFileVO as AirAppReadFileVO, type FileTreeReadFileVO as DriveReadFileVO, type FileTreeReadFileVO, type FileTreeReadFileVO as SkillReadFileVO, type FileTreeNodeVO as AirAppVO, type FileTreeNodeVO as DriveVO, type FileTreeNodeVO, type FileTreeNodeVO as SkillVO, type AssetAttachmentRef, type AssetDetailVO, type AssetTextStatus, type AssetUsageVO, type AssetVO, type AttachmentRef, type AuditAction, type AuditEventVO, type BaseFieldVO, type BaseVO, Busabase, type BusabaseAssetsClient, BusabaseChangeRequestsClient, type BusabaseClient, type BusabaseConfig, type BusabaseRecordsClient, type BusabaseSourceChannel, CREATABLE_NODE_TYPES, type ChangeRequestBatchFailureVO, type ChangeRequestCountsVO, type ChangeRequestMergeBatchResultVO, type ChangeRequestReviewBatchResultVO, type ChangeRequestStatus, type ChangeRequestTargetType, type ChangeRequestVO, type CloudContract, type CommentMentionDispatchStatus, type CommentMentionInputDTO, type CommentMentionTargetType, type CommentMentionVO, type CommentSubjectType, type CommentVO, type CommitVO, type CreatableNodeType, type CreateFormDTO, DEFAULT_BASE_URL, type FieldType, type FileNodeMetadata, type FileNodeVO, type FilePreviewConfigVO, type FilePreviewConfigurationStatus, type FilePreviewCredentialSource, type FilePreviewProvider, type FilePreviewUnavailableReason, type FilePreviewVO, type FormBoundFieldVO, type FormFieldBindingVO, type FormPageSourceVO, type FormShareVO, type FormSubmitResultVO, type FormThemeVO, type FormVO, type GalleryCardSize, type GalleryCoverFit, type GanttScale, type ListFormsDTO, type ListFormsVO, type LookupRollup, type MentionInboxItemVO, type MentionInboxPageVO, type NodeDetailVO, type NodeIcon, type NodeIconSchema, type NodeSearchResultVO, type NodeType, type NodeVO, type NodeWebUrlInput, type OperationKind, type OperationStatus, type OperationVO, type RecordByFieldInput, type RecordLinkVO, type RecordVO, type ResolvedConfig, type ReviewVO, type ReviewVerdict, type SearchResponseVO, type SearchResultKind, type SearchResultVO, type SourceAttributionVO, type SubmitFormDTO, type UpdateFormDTO, type UpdatePreviewFileCredentialDTO, type UpdateVaultSettingsDTO, type UserRefVO, type VIEW_FIELD_MAX_WIDTH, type VIEW_FIELD_MIN_WIDTH, type VaultAccessPolicy, type VaultEnvironment, type VaultItemInput, type VaultItemKind, type VaultItemVO, type VaultRuntimeEnv, type VaultScopeType, type VaultSettingsVO, type ViewConfigVO, type ViewFilterOperator, type ViewFilterVO, type ViewSortVO, type ViewType, type ViewVO, cloudContract, createBusabaseClient, getRecordByField, grepAssets, nodeWebUrl, normalizeBaseUrl, resolveConfig, toFilesOnlyGrepResult, toUnifiedFilesGrepInput };
|
|
496
|
+
export { type ActivityItemVO, type AgentTaskVO, type FileTreeFileVO as AirAppFileVO, type FileTreeFileVO as DriveFileVO, type FileTreeFileVO, type FileTreeFileVO as SkillFileVO, type FileTreeReadFileVO as AirAppReadFileVO, type FileTreeReadFileVO as DriveReadFileVO, type FileTreeReadFileVO, type FileTreeReadFileVO as SkillReadFileVO, type FileTreeNodeVO as AirAppVO, type FileTreeNodeVO as DriveVO, type FileTreeNodeVO, type FileTreeNodeVO as SkillVO, type AssetAttachmentRef, type AssetDetailVO, type AssetTextStatus, type AssetUsageVO, type AssetVO, type AttachmentRef, type AuditAction, type AuditEventVO, type BaseFieldVO, type BaseVO, Busabase, type BusabaseAssetsClient, BusabaseChangeRequestsClient, type BusabaseClient, type BusabaseConfig, type BusabaseRecordsClient, type BusabaseSourceChannel, type BusabaseUploadedAsset, CREATABLE_NODE_TYPES, type ChangeRequestBatchFailureVO, type ChangeRequestCountsVO, type ChangeRequestMergeBatchResultVO, type ChangeRequestReviewBatchResultVO, type ChangeRequestStatus, type ChangeRequestTargetType, type ChangeRequestVO, type CloudContract, type CommentMentionDispatchStatus, type CommentMentionInputDTO, type CommentMentionTargetType, type CommentMentionVO, type CommentSubjectType, type CommentVO, type CommitVO, type CreatableNodeType, type CreateFormDTO, DEFAULT_BASE_URL, type FieldType, type FileNodeMetadata, type FileNodeVO, type FilePreviewConfigVO, type FilePreviewConfigurationStatus, type FilePreviewCredentialSource, type FilePreviewProvider, type FilePreviewUnavailableReason, type FilePreviewVO, type FormBoundFieldVO, type FormFieldBindingVO, type FormPageSourceVO, type FormShareVO, type FormSubmitResultVO, type FormThemeVO, type FormVO, type GalleryCardSize, type GalleryCoverFit, type GanttScale, type ListFormsDTO, type ListFormsVO, type LookupRollup, type MentionInboxItemVO, type MentionInboxPageVO, type NodeDetailVO, type NodeIcon, type NodeIconSchema, type NodeSearchResultVO, type NodeType, type NodeVO, type NodeWebUrlInput, type OperationKind, type OperationStatus, type OperationVO, type RecordByFieldInput, type RecordLinkVO, type RecordVO, type ResolvedConfig, type ReviewVO, type ReviewVerdict, type SearchResponseVO, type SearchResultKind, type SearchResultVO, type SourceAttributionVO, type SubmitFormDTO, type UpdateFormDTO, type UpdatePreviewFileCredentialDTO, type UpdateVaultSettingsDTO, type UploadAssetOptions, type UserRefVO, type VIEW_FIELD_MAX_WIDTH, type VIEW_FIELD_MIN_WIDTH, type VaultAccessPolicy, type VaultEnvironment, type VaultItemInput, type VaultItemKind, type VaultItemVO, type VaultRuntimeEnv, type VaultScopeType, type VaultSettingsVO, type ViewConfigVO, type ViewFilterOperator, type ViewFilterVO, type ViewSortVO, type ViewType, type ViewVO, cloudContract, createBusabaseClient, getRecordByField, grepAssets, hashBytes, nodeWebUrl, normalizeBaseUrl, resolveConfig, toFilesOnlyGrepResult, toUnifiedFilesGrepInput, uploadAsset };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as TemplateRiskLevelSchema } from "./template-
|
|
1
|
+
import { i as uploadAsset, n as TemplateRiskLevelSchema, r as hashBytes } from "./template-DRMp6tKv.js";
|
|
2
2
|
import { t as normalizeBaseUrl } from "./url-B8GMXalA.js";
|
|
3
3
|
import { ORPCError, createORPCClient } from "@orpc/client";
|
|
4
4
|
import { OpenAPILink } from "@orpc/openapi-client/fetch";
|
|
@@ -1345,6 +1345,25 @@ const nodeShareSchema = z.object({
|
|
|
1345
1345
|
expiresAt: z.string().nullable(),
|
|
1346
1346
|
updatedAt: z.string()
|
|
1347
1347
|
});
|
|
1348
|
+
const sharedNodeSchema = z.object({
|
|
1349
|
+
nodeId: z.string(),
|
|
1350
|
+
name: z.string(),
|
|
1351
|
+
slug: z.string(),
|
|
1352
|
+
type: z.enum(NODE_TYPES),
|
|
1353
|
+
icon: NodeIconSchema.nullable().default(null),
|
|
1354
|
+
capability: z.enum(["read", "submit"]),
|
|
1355
|
+
hasPassword: z.boolean(),
|
|
1356
|
+
expiresAt: z.string().nullable(),
|
|
1357
|
+
/**
|
|
1358
|
+
* When this share ROW was first created — NOT "public continuously since".
|
|
1359
|
+
* `disableNodeShare` flips `scope` to `"none"` and keeps the row, so a node
|
|
1360
|
+
* that was shared, revoked, and shared again still reports the original
|
|
1361
|
+
* date. There is no column recording when `scope` last became `"public"`,
|
|
1362
|
+
* so the UI says "first shared {time}" rather than claiming an exposure
|
|
1363
|
+
* window the data cannot support. Adding that column is the follow-up.
|
|
1364
|
+
*/
|
|
1365
|
+
createdAt: z.string()
|
|
1366
|
+
});
|
|
1348
1367
|
const listNodesInputSchema = z.object({
|
|
1349
1368
|
parentId: z.string().nullable().optional().describe("Node to start from. Omit or null to start from the space root."),
|
|
1350
1369
|
depth: z.coerce.number().int().min(1).max(5).optional().describe("How many levels beneath the start point to eagerly include (default 2 once either field is set). Capped at 5."),
|
|
@@ -4726,6 +4745,17 @@ const ListEmbedLinksInputSchema = z.object({
|
|
|
4726
4745
|
type: EmbedTargetTypeSchema.optional().describe("Which kind of target the links point at. Omitting it returns links of every kind."),
|
|
4727
4746
|
typeId: z.string().min(1).optional().describe("The target's id, interpreted according to `type`.")
|
|
4728
4747
|
}).optional().default({});
|
|
4748
|
+
const EmbedLinkAuditStatusSchema = z.enum([
|
|
4749
|
+
"active",
|
|
4750
|
+
"expired",
|
|
4751
|
+
"revoked",
|
|
4752
|
+
"all"
|
|
4753
|
+
]);
|
|
4754
|
+
const ListEmbedLinksPagedInputSchema = z.object({
|
|
4755
|
+
status: EmbedLinkAuditStatusSchema.optional().default("active").describe("Filter the workspace audit to active, expired, revoked, or all embed links."),
|
|
4756
|
+
limit: z.coerce.number().int().min(1).max(100).optional().default(50).describe("Embed links per page. Capped at 100; continue with `cursor`."),
|
|
4757
|
+
cursor: z.string().optional().describe("Opaque page cursor: pass back the `nextCursor` from the previous response. Do not construct or parse it.")
|
|
4758
|
+
});
|
|
4729
4759
|
const RevokeEmbedLinkInputSchema = z.object({ id: z.string().min(1) });
|
|
4730
4760
|
const EmbedLinkVOSchema = z.object({
|
|
4731
4761
|
id: z.string(),
|
|
@@ -4739,6 +4769,10 @@ const EmbedLinkVOSchema = z.object({
|
|
|
4739
4769
|
active: z.boolean(),
|
|
4740
4770
|
framePolicy: EmbedFramePolicyVOSchema
|
|
4741
4771
|
});
|
|
4772
|
+
const EmbedLinksPageVOSchema = z.object({
|
|
4773
|
+
items: z.array(EmbedLinkVOSchema),
|
|
4774
|
+
nextCursor: z.string().nullable()
|
|
4775
|
+
});
|
|
4742
4776
|
const CreatedEmbedLinkVOSchema = EmbedLinkVOSchema.extend({
|
|
4743
4777
|
url: z.string().url(),
|
|
4744
4778
|
iframeUrl: z.string().url()
|
|
@@ -5312,6 +5346,13 @@ const busabaseContractRoutes = {
|
|
|
5312
5346
|
summary: "List embed links the caller can manage",
|
|
5313
5347
|
successDescription: "Embed link metadata without capability secrets."
|
|
5314
5348
|
}).errors(embedLinkErrors).input(ListEmbedLinksInputSchema).output(z.array(EmbedLinkVOSchema)),
|
|
5349
|
+
listPaged: oc.route({
|
|
5350
|
+
method: "GET",
|
|
5351
|
+
path: "/embed-links/paged",
|
|
5352
|
+
tags: ["Embed Links"],
|
|
5353
|
+
summary: "Audit workspace embed links with status filtering and keyset pagination",
|
|
5354
|
+
successDescription: "A bounded page of manageable embed-link metadata without capability secrets."
|
|
5355
|
+
}).errors(embedLinkErrors).input(ListEmbedLinksPagedInputSchema).output(EmbedLinksPageVOSchema),
|
|
5315
5356
|
revoke: oc.route({
|
|
5316
5357
|
method: "DELETE",
|
|
5317
5358
|
path: "/embed-links/{id}",
|
|
@@ -5492,6 +5533,13 @@ const busabaseContractRoutes = {
|
|
|
5492
5533
|
})).output(z.object({ removed: z.boolean() }))
|
|
5493
5534
|
},
|
|
5494
5535
|
share: {
|
|
5536
|
+
list: oc.route({
|
|
5537
|
+
method: "GET",
|
|
5538
|
+
path: "/node-shares",
|
|
5539
|
+
tags: ["Nodes", "Sharing"],
|
|
5540
|
+
summary: "List every node in the space carrying its own live public share",
|
|
5541
|
+
successDescription: "One row per node that someone explicitly published and that is still live — `scope: \"public\"` and unexpired — joined to just enough of the node (name, slug, type, icon) to render and open it. Rows the caller cannot see are omitted (same node-visibility ACL as `nodes.list`), and the stored share password is never returned, only a `hasPassword` flag. Deliberately does NOT include nodes that are merely reachable because an ANCESTOR is shared: this is the list of grants a person made, each revocable on its own with `nodes.share.disable`, which is the same set the workbench sidebar marks with a globe (`NodeVO.shared`)."
|
|
5542
|
+
}).output(z.array(sharedNodeSchema)),
|
|
5495
5543
|
get: oc.route({
|
|
5496
5544
|
method: "GET",
|
|
5497
5545
|
path: "/nodes/{nodeId}/share",
|
|
@@ -6190,6 +6238,27 @@ var Busabase = class {
|
|
|
6190
6238
|
storageKey: upload.storageKey
|
|
6191
6239
|
});
|
|
6192
6240
|
}
|
|
6241
|
+
/**
|
|
6242
|
+
* Put a file into this Space's Asset library in one call, and get back every
|
|
6243
|
+
* id the rest of the SDK asks for: `assetId` for a file-tree entry,
|
|
6244
|
+
* `attachmentId` for a record's attachment cell, `url` to embed in Markdown.
|
|
6245
|
+
*
|
|
6246
|
+
* Hides the three-step flow (`assets.createUploadUrl` → PUT →
|
|
6247
|
+
* `assets.confirm`) and its dedup short-circuit, the same way `putText`
|
|
6248
|
+
* does for text slots.
|
|
6249
|
+
*
|
|
6250
|
+
* @example
|
|
6251
|
+
* ```ts
|
|
6252
|
+
* const shot = await bb.uploadAsset(png, {
|
|
6253
|
+
* fileName: "user-journey.png",
|
|
6254
|
+
* mimeType: "image/png",
|
|
6255
|
+
* });
|
|
6256
|
+
* body += ``;
|
|
6257
|
+
* ```
|
|
6258
|
+
*/
|
|
6259
|
+
uploadAsset(bytes, options) {
|
|
6260
|
+
return uploadAsset(this.client, bytes, options, this.config.fetch ?? fetch);
|
|
6261
|
+
}
|
|
6193
6262
|
/** Service health — reaches the server without requiring auth. */
|
|
6194
6263
|
health() {
|
|
6195
6264
|
return this.client.system.health();
|
|
@@ -6200,4 +6269,4 @@ var Busabase = class {
|
|
|
6200
6269
|
}
|
|
6201
6270
|
};
|
|
6202
6271
|
//#endregion
|
|
6203
|
-
export { Busabase, CREATABLE_NODE_TYPES, DEFAULT_BASE_URL, cloudContract, createBusabaseClient, getRecordByField, grepAssets, nodeWebUrl, normalizeBaseUrl, resolveConfig, toFilesOnlyGrepResult, toUnifiedFilesGrepInput };
|
|
6272
|
+
export { Busabase, CREATABLE_NODE_TYPES, DEFAULT_BASE_URL, cloudContract, createBusabaseClient, getRecordByField, grepAssets, hashBytes, nodeWebUrl, normalizeBaseUrl, resolveConfig, toFilesOnlyGrepResult, toUnifiedFilesGrepInput, uploadAsset };
|
|
@@ -1,4 +1,82 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
//#region src/asset-upload.ts
|
|
3
|
+
/**
|
|
4
|
+
* SHA-256 of the bytes, or `undefined` where WebCrypto is unavailable.
|
|
5
|
+
*
|
|
6
|
+
* Undefined is a real answer, not a failure: the hash only buys deduplication,
|
|
7
|
+
* so a runtime without WebCrypto uploads the bytes it would otherwise have
|
|
8
|
+
* skipped. Failing the upload over a missing optimization would be worse.
|
|
9
|
+
*/
|
|
10
|
+
async function hashBytes(bytes) {
|
|
11
|
+
const subtle = globalThis.crypto?.subtle;
|
|
12
|
+
if (!subtle) return void 0;
|
|
13
|
+
const buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
14
|
+
const digest = await subtle.digest("SHA-256", buffer);
|
|
15
|
+
return `sha256:${Array.from(new Uint8Array(digest)).map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Upload bytes and get back every id the rest of the SDK might need.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const asset = await uploadAsset(client, png, {
|
|
23
|
+
* fileName: "user-journey.png",
|
|
24
|
+
* mimeType: "image/png",
|
|
25
|
+
* });
|
|
26
|
+
* // asset.assetId -> reference it from a Skill/Drive/AirApp file operation
|
|
27
|
+
* // asset.url -> embed it in Markdown
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
async function uploadAsset(client, bytes, options, fetchImpl = fetch) {
|
|
31
|
+
const { fileName, mimeType, context, spaceId } = options;
|
|
32
|
+
if (!bytes.byteLength) throw new Error(`uploadAsset: ${fileName} is empty — there are no bytes to upload`);
|
|
33
|
+
const contentHash = await hashBytes(bytes);
|
|
34
|
+
const upload = await client.assets.createUploadUrl({
|
|
35
|
+
fileName,
|
|
36
|
+
mimeType,
|
|
37
|
+
sizeBytes: bytes.byteLength,
|
|
38
|
+
...context ? { context } : {},
|
|
39
|
+
...spaceId ? { spaceId } : {},
|
|
40
|
+
...contentHash ? { contentHash } : {}
|
|
41
|
+
});
|
|
42
|
+
if (upload.duplicate && upload.attachmentId) return {
|
|
43
|
+
...upload.assetId ? { assetId: upload.assetId } : {},
|
|
44
|
+
attachmentId: upload.attachmentId,
|
|
45
|
+
url: upload.publicUrl,
|
|
46
|
+
fileName,
|
|
47
|
+
mimeType,
|
|
48
|
+
size: bytes.byteLength,
|
|
49
|
+
...contentHash ? { contentHash } : {}
|
|
50
|
+
};
|
|
51
|
+
const response = await fetchImpl(upload.uploadUrl, {
|
|
52
|
+
method: "PUT",
|
|
53
|
+
headers: { "content-type": mimeType },
|
|
54
|
+
body: bytes
|
|
55
|
+
});
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
const detail = await response.text().catch(() => "");
|
|
58
|
+
throw new Error(`uploadAsset: presigned upload of ${fileName} failed (${response.status} ${response.statusText})${detail ? `: ${detail}` : ""}`);
|
|
59
|
+
}
|
|
60
|
+
const confirmed = await client.assets.confirm({
|
|
61
|
+
storageKey: upload.storageKey,
|
|
62
|
+
fileName,
|
|
63
|
+
mimeType,
|
|
64
|
+
sizeBytes: bytes.byteLength,
|
|
65
|
+
...context ? { context } : {},
|
|
66
|
+
...spaceId ? { spaceId } : {},
|
|
67
|
+
...contentHash ? { contentHash } : {}
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
...confirmed.assetId ? { assetId: confirmed.assetId } : {},
|
|
71
|
+
attachmentId: confirmed.attachmentId,
|
|
72
|
+
url: confirmed.publicUrl,
|
|
73
|
+
fileName,
|
|
74
|
+
mimeType,
|
|
75
|
+
size: bytes.byteLength,
|
|
76
|
+
...contentHash ? { contentHash } : {}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
2
80
|
//#region ../../packages/busabase-contract/src/domains/skill/frontmatter.ts
|
|
3
81
|
/**
|
|
4
82
|
* `SKILL.md` frontmatter — the generic shape, independent of Busabase.
|
|
@@ -157,4 +235,4 @@ z.object({
|
|
|
157
235
|
["isTemplateSkill"]: z.literal(true)
|
|
158
236
|
});
|
|
159
237
|
//#endregion
|
|
160
|
-
export { TemplateRiskLevelSchema as n, APP_ROOT_RESOURCE_KEY as t };
|
|
238
|
+
export { uploadAsset as i, TemplateRiskLevelSchema as n, hashBytes as r, APP_ROOT_RESOURCE_KEY as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "busabase-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.72.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).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/busabase/busabase/tree/main/apps/busabase-sdk",
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"tsx": "^4.20.5",
|
|
68
68
|
"typescript": "^7.0.2",
|
|
69
69
|
"vitest": "^4.1.11",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
70
|
+
"open-domains": "0.0.2",
|
|
71
|
+
"busabase-contract": "0.72.0",
|
|
72
|
+
"openlib": "0.1.1"
|
|
73
73
|
},
|
|
74
74
|
"engines": {
|
|
75
75
|
"node": ">=24.18.0"
|