@arbidocs/sdk 0.3.46 → 0.3.48
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/{browser-HVCa8Ph5.d.cts → browser-EMgd4bP4.d.cts} +72 -18
- package/dist/{browser-HVCa8Ph5.d.ts → browser-EMgd4bP4.d.ts} +72 -18
- package/dist/browser.cjs +148 -38
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +148 -39
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +146 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -7
- package/dist/index.d.ts +10 -7
- package/dist/index.js +146 -84
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/browser.cjs
CHANGED
|
@@ -3637,6 +3637,23 @@ async function generateEncryptedWorkspaceKey(arbi, wrappedKey, serverSessionKey,
|
|
|
3637
3637
|
const workspaceKey = client.sealedBoxDecrypt(wrappedKey, encryptionKeyPair.secretKey);
|
|
3638
3638
|
return client.sealKeyForSession(workspaceKey, serverSessionKey);
|
|
3639
3639
|
}
|
|
3640
|
+
async function getRawWorkspaceKey(arbi, workspaceId, signingPrivateKeyBase64) {
|
|
3641
|
+
const { data: workspaces, error } = await arbi.fetch.GET("/v1/user/workspaces");
|
|
3642
|
+
if (error || !workspaces) {
|
|
3643
|
+
throw new ArbiError("Failed to fetch workspaces");
|
|
3644
|
+
}
|
|
3645
|
+
const ws = workspaces.find((w2) => w2.external_id === workspaceId);
|
|
3646
|
+
if (!ws || !ws.wrapped_key) {
|
|
3647
|
+
throw new ArbiError(`Workspace ${workspaceId} not found or has no encryption key`);
|
|
3648
|
+
}
|
|
3649
|
+
const signingPrivateKey = client.base64ToBytes(signingPrivateKeyBase64);
|
|
3650
|
+
const ed25519PublicKey = signingPrivateKey.slice(32, 64);
|
|
3651
|
+
const encryptionKeyPair = client.deriveEncryptionKeypairFromSigning({
|
|
3652
|
+
publicKey: ed25519PublicKey,
|
|
3653
|
+
secretKey: signingPrivateKey
|
|
3654
|
+
});
|
|
3655
|
+
return client.sealedBoxDecrypt(ws.wrapped_key, encryptionKeyPair.secretKey);
|
|
3656
|
+
}
|
|
3640
3657
|
async function selectWorkspaceById(arbi, workspaceId, serverSessionKey, signingPrivateKeyBase64) {
|
|
3641
3658
|
const { data: workspaces, error } = await arbi.fetch.GET("/v1/user/workspaces");
|
|
3642
3659
|
if (error || !workspaces) {
|
|
@@ -4106,6 +4123,7 @@ __export(documents_exports, {
|
|
|
4106
4123
|
listAll: () => listAll,
|
|
4107
4124
|
listDocuments: () => listDocuments,
|
|
4108
4125
|
listPaginated: () => listPaginated,
|
|
4126
|
+
mimeFromName: () => mimeFromName,
|
|
4109
4127
|
sanitizeFolderPath: () => sanitizeFolderPath,
|
|
4110
4128
|
updateDocuments: () => updateDocuments,
|
|
4111
4129
|
uploadDocumentsDirect: () => uploadDocumentsDirect,
|
|
@@ -4160,10 +4178,17 @@ async function listDocuments(arbi) {
|
|
|
4160
4178
|
return requireData(await arbi.fetch.GET("/v1/document/list"), "Failed to fetch documents");
|
|
4161
4179
|
}
|
|
4162
4180
|
async function* listPaginated(arbi, options = {}) {
|
|
4163
|
-
const {
|
|
4164
|
-
|
|
4181
|
+
const {
|
|
4182
|
+
pageSize = 5e3,
|
|
4183
|
+
firstPageSize,
|
|
4184
|
+
order = "id_asc",
|
|
4185
|
+
fields,
|
|
4186
|
+
signal,
|
|
4187
|
+
lookahead = 1
|
|
4188
|
+
} = options;
|
|
4189
|
+
const fetchPage = async (pageOffset, limit) => {
|
|
4165
4190
|
const query = {
|
|
4166
|
-
limit
|
|
4191
|
+
limit,
|
|
4167
4192
|
offset: pageOffset,
|
|
4168
4193
|
order
|
|
4169
4194
|
};
|
|
@@ -4186,19 +4211,21 @@ async function* listPaginated(arbi, options = {}) {
|
|
|
4186
4211
|
const queue = [];
|
|
4187
4212
|
const tryEnqueue = () => {
|
|
4188
4213
|
while (!done && queue.length < depth && issued < MAX_PAGES) {
|
|
4189
|
-
const
|
|
4190
|
-
|
|
4214
|
+
const limit = issued === 0 && firstPageSize !== void 0 ? firstPageSize : pageSize;
|
|
4215
|
+
const promise = fetchPage(nextOffsetToIssue, limit);
|
|
4216
|
+
promise.catch(() => {
|
|
4191
4217
|
});
|
|
4192
|
-
queue.push(
|
|
4193
|
-
nextOffsetToIssue +=
|
|
4218
|
+
queue.push({ limit, promise });
|
|
4219
|
+
nextOffsetToIssue += limit;
|
|
4194
4220
|
issued++;
|
|
4195
4221
|
}
|
|
4196
4222
|
};
|
|
4197
4223
|
tryEnqueue();
|
|
4198
4224
|
while (queue.length > 0 && !signal?.aborted) {
|
|
4199
|
-
const
|
|
4225
|
+
const { limit, promise } = queue.shift();
|
|
4226
|
+
const page = await promise;
|
|
4200
4227
|
if (signal?.aborted) return;
|
|
4201
|
-
const isShort = page.length <
|
|
4228
|
+
const isShort = page.length < limit;
|
|
4202
4229
|
if (isShort) done = true;
|
|
4203
4230
|
tryEnqueue();
|
|
4204
4231
|
if (page.length > 0) {
|
|
@@ -4246,11 +4273,11 @@ async function updateDocuments(arbi, documents) {
|
|
|
4246
4273
|
"Failed to update documents"
|
|
4247
4274
|
);
|
|
4248
4275
|
}
|
|
4249
|
-
async function uploadUrl(arbi, urls,
|
|
4276
|
+
async function uploadUrl(arbi, urls, shared = false) {
|
|
4250
4277
|
return requireData(
|
|
4251
4278
|
await arbi.fetch.POST("/v1/document/upload-url", {
|
|
4252
4279
|
params: {
|
|
4253
|
-
query: { urls,
|
|
4280
|
+
query: { urls, shared }
|
|
4254
4281
|
}
|
|
4255
4282
|
}),
|
|
4256
4283
|
"Failed to upload from URLs"
|
|
@@ -4263,29 +4290,31 @@ async function getParsedContent(auth, docId, stage) {
|
|
|
4263
4290
|
});
|
|
4264
4291
|
return res.json();
|
|
4265
4292
|
}
|
|
4266
|
-
async function uploadFile(auth,
|
|
4293
|
+
async function uploadFile(auth, fileData, fileName, options) {
|
|
4267
4294
|
const formData = new FormData();
|
|
4268
4295
|
formData.append("files", fileData, fileName);
|
|
4269
|
-
const params = new URLSearchParams(
|
|
4296
|
+
const params = new URLSearchParams();
|
|
4270
4297
|
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
4271
4298
|
if (options?.configExtId) params.set("config_ext_id", options.configExtId);
|
|
4299
|
+
const qs = params.toString();
|
|
4272
4300
|
const res = await authenticatedFetch({
|
|
4273
4301
|
...auth,
|
|
4274
|
-
path: `/v1/document/upload?${
|
|
4302
|
+
path: qs ? `/v1/document/upload?${qs}` : `/v1/document/upload`,
|
|
4275
4303
|
method: "POST",
|
|
4276
4304
|
body: formData
|
|
4277
4305
|
});
|
|
4278
4306
|
return res.json();
|
|
4279
4307
|
}
|
|
4280
|
-
async function uploadFiles(auth,
|
|
4308
|
+
async function uploadFiles(auth, files, options) {
|
|
4281
4309
|
const formData = new FormData();
|
|
4282
4310
|
for (const f2 of files) formData.append("files", f2.data, f2.name);
|
|
4283
|
-
const params = new URLSearchParams(
|
|
4311
|
+
const params = new URLSearchParams();
|
|
4284
4312
|
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
4285
4313
|
if (options?.configExtId) params.set("config_ext_id", options.configExtId);
|
|
4314
|
+
const qs = params.toString();
|
|
4286
4315
|
const res = await authenticatedFetch({
|
|
4287
4316
|
...auth,
|
|
4288
|
-
path: `/v1/document/upload?${
|
|
4317
|
+
path: qs ? `/v1/document/upload?${qs}` : `/v1/document/upload`,
|
|
4289
4318
|
method: "POST",
|
|
4290
4319
|
body: formData
|
|
4291
4320
|
});
|
|
@@ -4297,6 +4326,68 @@ async function downloadDocument(auth, docId) {
|
|
|
4297
4326
|
path: `/v1/document/${docId}/download`
|
|
4298
4327
|
});
|
|
4299
4328
|
}
|
|
4329
|
+
function mimeFromName(name) {
|
|
4330
|
+
const dot = name.lastIndexOf(".");
|
|
4331
|
+
const ext = dot === -1 ? "" : name.slice(dot).toLowerCase();
|
|
4332
|
+
switch (ext) {
|
|
4333
|
+
case ".pdf":
|
|
4334
|
+
return "application/pdf";
|
|
4335
|
+
case ".txt":
|
|
4336
|
+
return "text/plain";
|
|
4337
|
+
case ".md":
|
|
4338
|
+
return "text/markdown";
|
|
4339
|
+
case ".html":
|
|
4340
|
+
case ".htm":
|
|
4341
|
+
return "text/html";
|
|
4342
|
+
case ".doc":
|
|
4343
|
+
return "application/msword";
|
|
4344
|
+
case ".docx":
|
|
4345
|
+
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
|
4346
|
+
case ".xls":
|
|
4347
|
+
return "application/vnd.ms-excel";
|
|
4348
|
+
case ".xlsx":
|
|
4349
|
+
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
4350
|
+
case ".ppt":
|
|
4351
|
+
return "application/vnd.ms-powerpoint";
|
|
4352
|
+
case ".pptx":
|
|
4353
|
+
return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
|
4354
|
+
case ".eml":
|
|
4355
|
+
return "message/rfc822";
|
|
4356
|
+
default:
|
|
4357
|
+
return void 0;
|
|
4358
|
+
}
|
|
4359
|
+
}
|
|
4360
|
+
async function presignedPut(url, body, onProgress) {
|
|
4361
|
+
const XhrGlobal = globalThis.XMLHttpRequest;
|
|
4362
|
+
if (XhrGlobal) {
|
|
4363
|
+
await new Promise((resolve, reject) => {
|
|
4364
|
+
const xhr = new XhrGlobal();
|
|
4365
|
+
xhr.open("PUT", url);
|
|
4366
|
+
if (onProgress) {
|
|
4367
|
+
xhr.upload.addEventListener("progress", (e) => {
|
|
4368
|
+
if (e.lengthComputable) onProgress(e.loaded, e.total);
|
|
4369
|
+
});
|
|
4370
|
+
}
|
|
4371
|
+
xhr.addEventListener("load", () => {
|
|
4372
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
4373
|
+
resolve();
|
|
4374
|
+
} else {
|
|
4375
|
+
const snippet = (xhr.responseText || "").slice(0, 200);
|
|
4376
|
+
reject(new Error(`Presigned PUT failed: ${xhr.status} ${snippet}`));
|
|
4377
|
+
}
|
|
4378
|
+
});
|
|
4379
|
+
xhr.addEventListener("error", () => reject(new Error("Presigned PUT network error")));
|
|
4380
|
+
xhr.addEventListener("abort", () => reject(new Error("Presigned PUT aborted")));
|
|
4381
|
+
xhr.send(body);
|
|
4382
|
+
});
|
|
4383
|
+
return;
|
|
4384
|
+
}
|
|
4385
|
+
const putRes = await fetch(url, { method: "PUT", body });
|
|
4386
|
+
if (!putRes.ok) {
|
|
4387
|
+
const snippet = await putRes.text().catch(() => "");
|
|
4388
|
+
throw new Error(`Presigned PUT failed: ${putRes.status} ${snippet.slice(0, 200)}`);
|
|
4389
|
+
}
|
|
4390
|
+
}
|
|
4300
4391
|
async function uploadDocumentsDirect(arbi, workspaceKey, files, options) {
|
|
4301
4392
|
if (files.length === 0) return { doc_ext_ids: [], skipped: [] };
|
|
4302
4393
|
const SECRETBOX_ENVELOPE_OVERHEAD = 40;
|
|
@@ -4329,6 +4420,11 @@ async function uploadDocumentsDirect(arbi, workspaceKey, files, options) {
|
|
|
4329
4420
|
}
|
|
4330
4421
|
const skipped = [];
|
|
4331
4422
|
const toCommit = [];
|
|
4423
|
+
const indexByName = /* @__PURE__ */ new Map();
|
|
4424
|
+
files.forEach((f2, i2) => {
|
|
4425
|
+
if (!indexByName.has(f2.name)) indexByName.set(f2.name, []);
|
|
4426
|
+
indexByName.get(f2.name).push(i2);
|
|
4427
|
+
});
|
|
4332
4428
|
for (const item of items) {
|
|
4333
4429
|
if (item.status !== "uploading" || !item.upload_url || !item.doc_ext_id) {
|
|
4334
4430
|
skipped.push({
|
|
@@ -4338,21 +4434,34 @@ async function uploadDocumentsDirect(arbi, workspaceKey, files, options) {
|
|
|
4338
4434
|
continue;
|
|
4339
4435
|
}
|
|
4340
4436
|
const queue = bytesByName.get(item.file_name);
|
|
4341
|
-
|
|
4437
|
+
const idxQueue = indexByName.get(item.file_name);
|
|
4438
|
+
if (!queue || queue.length === 0 || !idxQueue || idxQueue.length === 0) {
|
|
4342
4439
|
throw new Error(`upload-init returned slot for unknown file: ${item.file_name}`);
|
|
4343
4440
|
}
|
|
4344
4441
|
const raw = queue.shift();
|
|
4442
|
+
const fileIndex = idxQueue.shift();
|
|
4345
4443
|
const ciphertext = client.encryptFile(raw, workspaceKey);
|
|
4346
|
-
const
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4444
|
+
const total = ciphertext.length;
|
|
4445
|
+
try {
|
|
4446
|
+
await presignedPut(item.upload_url, ciphertext, (loaded, putTotal) => {
|
|
4447
|
+
options?.onBytesProgress?.({
|
|
4448
|
+
fileIndex,
|
|
4449
|
+
fileName: item.file_name,
|
|
4450
|
+
loaded,
|
|
4451
|
+
total: putTotal
|
|
4452
|
+
});
|
|
4453
|
+
});
|
|
4454
|
+
} catch (err) {
|
|
4352
4455
|
throw new Error(
|
|
4353
|
-
`Presigned PUT for ${item.doc_ext_id} failed: ${
|
|
4456
|
+
`Presigned PUT for ${item.doc_ext_id} failed: ${err instanceof Error ? err.message : String(err)}`
|
|
4354
4457
|
);
|
|
4355
4458
|
}
|
|
4459
|
+
options?.onBytesProgress?.({
|
|
4460
|
+
fileIndex,
|
|
4461
|
+
fileName: item.file_name,
|
|
4462
|
+
loaded: total,
|
|
4463
|
+
total
|
|
4464
|
+
});
|
|
4356
4465
|
toCommit.push(item.doc_ext_id);
|
|
4357
4466
|
}
|
|
4358
4467
|
if (toCommit.length === 0) {
|
|
@@ -5193,19 +5302,19 @@ var Arbi = class {
|
|
|
5193
5302
|
get: (externalIds) => getDocuments(this.requireClient(), externalIds),
|
|
5194
5303
|
delete: (externalIds) => deleteDocuments(this.requireClient(), externalIds),
|
|
5195
5304
|
update: (documents) => updateDocuments(this.requireClient(), documents),
|
|
5196
|
-
uploadUrl: (urls, shared
|
|
5197
|
-
this.
|
|
5198
|
-
urls,
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5305
|
+
uploadUrl: (urls, shared) => {
|
|
5306
|
+
this.requireWorkspace();
|
|
5307
|
+
return uploadUrl(this.requireClient(), urls, shared);
|
|
5308
|
+
},
|
|
5309
|
+
uploadFile: (fileData, fileName, options) => {
|
|
5310
|
+
this.requireWorkspace();
|
|
5311
|
+
return uploadFile(
|
|
5312
|
+
this.getAuthHeaders(),
|
|
5313
|
+
fileData,
|
|
5314
|
+
fileName,
|
|
5315
|
+
options?.folder ? { folder: options.folder } : void 0
|
|
5316
|
+
);
|
|
5317
|
+
},
|
|
5209
5318
|
download: (docId) => downloadDocument(this.getAuthHeaders(), docId),
|
|
5210
5319
|
getParsedContent: (docId, stage) => getParsedContent(this.getAuthHeaders(), docId, stage)
|
|
5211
5320
|
};
|
|
@@ -5443,6 +5552,7 @@ exports.formatFileSize = formatFileSize;
|
|
|
5443
5552
|
exports.formatUserName = formatUserName;
|
|
5444
5553
|
exports.formatWorkspaceChoices = formatWorkspaceChoices;
|
|
5445
5554
|
exports.getErrorMessage = getErrorMessage;
|
|
5555
|
+
exports.getRawWorkspaceKey = getRawWorkspaceKey;
|
|
5446
5556
|
exports.health = health_exports;
|
|
5447
5557
|
exports.parseSSEEvents = parseSSEEvents;
|
|
5448
5558
|
exports.performPasswordLogin = performPasswordLogin;
|