@arbidocs/sdk 0.3.47 → 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/index.cjs CHANGED
@@ -4655,6 +4655,7 @@ __export(documents_exports, {
4655
4655
  listAll: () => listAll,
4656
4656
  listDocuments: () => listDocuments,
4657
4657
  listPaginated: () => listPaginated,
4658
+ mimeFromName: () => mimeFromName,
4658
4659
  sanitizeFolderPath: () => sanitizeFolderPath,
4659
4660
  updateDocuments: () => updateDocuments,
4660
4661
  uploadDocumentsDirect: () => uploadDocumentsDirect,
@@ -4804,11 +4805,11 @@ async function updateDocuments(arbi, documents) {
4804
4805
  "Failed to update documents"
4805
4806
  );
4806
4807
  }
4807
- async function uploadUrl(arbi, urls, workspaceId, shared = false) {
4808
+ async function uploadUrl(arbi, urls, shared = false) {
4808
4809
  return requireData(
4809
4810
  await arbi.fetch.POST("/v1/document/upload-url", {
4810
4811
  params: {
4811
- query: { urls, workspace_ext_id: workspaceId, shared }
4812
+ query: { urls, shared }
4812
4813
  }
4813
4814
  }),
4814
4815
  "Failed to upload from URLs"
@@ -4821,29 +4822,31 @@ async function getParsedContent(auth, docId, stage) {
4821
4822
  });
4822
4823
  return res.json();
4823
4824
  }
4824
- async function uploadFile(auth, workspaceId, fileData, fileName, options) {
4825
+ async function uploadFile(auth, fileData, fileName, options) {
4825
4826
  const formData = new FormData();
4826
4827
  formData.append("files", fileData, fileName);
4827
- const params = new URLSearchParams({ workspace_ext_id: workspaceId });
4828
+ const params = new URLSearchParams();
4828
4829
  if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
4829
4830
  if (options?.configExtId) params.set("config_ext_id", options.configExtId);
4831
+ const qs = params.toString();
4830
4832
  const res = await authenticatedFetch({
4831
4833
  ...auth,
4832
- path: `/v1/document/upload?${params.toString()}`,
4834
+ path: qs ? `/v1/document/upload?${qs}` : `/v1/document/upload`,
4833
4835
  method: "POST",
4834
4836
  body: formData
4835
4837
  });
4836
4838
  return res.json();
4837
4839
  }
4838
- async function uploadFiles(auth, workspaceId, files, options) {
4840
+ async function uploadFiles(auth, files, options) {
4839
4841
  const formData = new FormData();
4840
4842
  for (const f2 of files) formData.append("files", f2.data, f2.name);
4841
- const params = new URLSearchParams({ workspace_ext_id: workspaceId });
4843
+ const params = new URLSearchParams();
4842
4844
  if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
4843
4845
  if (options?.configExtId) params.set("config_ext_id", options.configExtId);
4846
+ const qs = params.toString();
4844
4847
  const res = await authenticatedFetch({
4845
4848
  ...auth,
4846
- path: `/v1/document/upload?${params.toString()}`,
4849
+ path: qs ? `/v1/document/upload?${qs}` : `/v1/document/upload`,
4847
4850
  method: "POST",
4848
4851
  body: formData
4849
4852
  });
@@ -4855,6 +4858,68 @@ async function downloadDocument(auth, docId) {
4855
4858
  path: `/v1/document/${docId}/download`
4856
4859
  });
4857
4860
  }
4861
+ function mimeFromName(name) {
4862
+ const dot = name.lastIndexOf(".");
4863
+ const ext = dot === -1 ? "" : name.slice(dot).toLowerCase();
4864
+ switch (ext) {
4865
+ case ".pdf":
4866
+ return "application/pdf";
4867
+ case ".txt":
4868
+ return "text/plain";
4869
+ case ".md":
4870
+ return "text/markdown";
4871
+ case ".html":
4872
+ case ".htm":
4873
+ return "text/html";
4874
+ case ".doc":
4875
+ return "application/msword";
4876
+ case ".docx":
4877
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
4878
+ case ".xls":
4879
+ return "application/vnd.ms-excel";
4880
+ case ".xlsx":
4881
+ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
4882
+ case ".ppt":
4883
+ return "application/vnd.ms-powerpoint";
4884
+ case ".pptx":
4885
+ return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
4886
+ case ".eml":
4887
+ return "message/rfc822";
4888
+ default:
4889
+ return void 0;
4890
+ }
4891
+ }
4892
+ async function presignedPut(url, body, onProgress) {
4893
+ const XhrGlobal = globalThis.XMLHttpRequest;
4894
+ if (XhrGlobal) {
4895
+ await new Promise((resolve2, reject) => {
4896
+ const xhr = new XhrGlobal();
4897
+ xhr.open("PUT", url);
4898
+ if (onProgress) {
4899
+ xhr.upload.addEventListener("progress", (e) => {
4900
+ if (e.lengthComputable) onProgress(e.loaded, e.total);
4901
+ });
4902
+ }
4903
+ xhr.addEventListener("load", () => {
4904
+ if (xhr.status >= 200 && xhr.status < 300) {
4905
+ resolve2();
4906
+ } else {
4907
+ const snippet = (xhr.responseText || "").slice(0, 200);
4908
+ reject(new Error(`Presigned PUT failed: ${xhr.status} ${snippet}`));
4909
+ }
4910
+ });
4911
+ xhr.addEventListener("error", () => reject(new Error("Presigned PUT network error")));
4912
+ xhr.addEventListener("abort", () => reject(new Error("Presigned PUT aborted")));
4913
+ xhr.send(body);
4914
+ });
4915
+ return;
4916
+ }
4917
+ const putRes = await fetch(url, { method: "PUT", body });
4918
+ if (!putRes.ok) {
4919
+ const snippet = await putRes.text().catch(() => "");
4920
+ throw new Error(`Presigned PUT failed: ${putRes.status} ${snippet.slice(0, 200)}`);
4921
+ }
4922
+ }
4858
4923
  async function uploadDocumentsDirect(arbi, workspaceKey, files, options) {
4859
4924
  if (files.length === 0) return { doc_ext_ids: [], skipped: [] };
4860
4925
  const SECRETBOX_ENVELOPE_OVERHEAD = 40;
@@ -4887,6 +4952,11 @@ async function uploadDocumentsDirect(arbi, workspaceKey, files, options) {
4887
4952
  }
4888
4953
  const skipped = [];
4889
4954
  const toCommit = [];
4955
+ const indexByName = /* @__PURE__ */ new Map();
4956
+ files.forEach((f2, i2) => {
4957
+ if (!indexByName.has(f2.name)) indexByName.set(f2.name, []);
4958
+ indexByName.get(f2.name).push(i2);
4959
+ });
4890
4960
  for (const item of items) {
4891
4961
  if (item.status !== "uploading" || !item.upload_url || !item.doc_ext_id) {
4892
4962
  skipped.push({
@@ -4896,21 +4966,34 @@ async function uploadDocumentsDirect(arbi, workspaceKey, files, options) {
4896
4966
  continue;
4897
4967
  }
4898
4968
  const queue = bytesByName.get(item.file_name);
4899
- if (!queue || queue.length === 0) {
4969
+ const idxQueue = indexByName.get(item.file_name);
4970
+ if (!queue || queue.length === 0 || !idxQueue || idxQueue.length === 0) {
4900
4971
  throw new Error(`upload-init returned slot for unknown file: ${item.file_name}`);
4901
4972
  }
4902
4973
  const raw = queue.shift();
4974
+ const fileIndex = idxQueue.shift();
4903
4975
  const ciphertext = client.encryptFile(raw, workspaceKey);
4904
- const putRes = await fetch(item.upload_url, {
4905
- method: "PUT",
4906
- body: ciphertext
4907
- });
4908
- if (!putRes.ok) {
4909
- const body = await putRes.text().catch(() => "");
4976
+ const total = ciphertext.length;
4977
+ try {
4978
+ await presignedPut(item.upload_url, ciphertext, (loaded, putTotal) => {
4979
+ options?.onBytesProgress?.({
4980
+ fileIndex,
4981
+ fileName: item.file_name,
4982
+ loaded,
4983
+ total: putTotal
4984
+ });
4985
+ });
4986
+ } catch (err) {
4910
4987
  throw new Error(
4911
- `Presigned PUT for ${item.doc_ext_id} failed: ${putRes.status} ${body.slice(0, 200)}`
4988
+ `Presigned PUT for ${item.doc_ext_id} failed: ${err instanceof Error ? err.message : String(err)}`
4912
4989
  );
4913
4990
  }
4991
+ options?.onBytesProgress?.({
4992
+ fileIndex,
4993
+ fileName: item.file_name,
4994
+ loaded: total,
4995
+ total
4996
+ });
4914
4997
  toCommit.push(item.doc_ext_id);
4915
4998
  }
4916
4999
  if (toCommit.length === 0) {
@@ -5766,19 +5849,19 @@ var Arbi = class {
5766
5849
  get: (externalIds) => getDocuments(this.requireClient(), externalIds),
5767
5850
  delete: (externalIds) => deleteDocuments(this.requireClient(), externalIds),
5768
5851
  update: (documents) => updateDocuments(this.requireClient(), documents),
5769
- uploadUrl: (urls, shared, workspaceId) => uploadUrl(
5770
- this.requireClient(),
5771
- urls,
5772
- workspaceId ?? this.requireWorkspace(),
5773
- shared
5774
- ),
5775
- uploadFile: (fileData, fileName, options) => uploadFile(
5776
- this.getAuthHeaders(),
5777
- options?.workspaceId ?? this.requireWorkspace(),
5778
- fileData,
5779
- fileName,
5780
- options?.folder ? { folder: options.folder } : void 0
5781
- ),
5852
+ uploadUrl: (urls, shared) => {
5853
+ this.requireWorkspace();
5854
+ return uploadUrl(this.requireClient(), urls, shared);
5855
+ },
5856
+ uploadFile: (fileData, fileName, options) => {
5857
+ this.requireWorkspace();
5858
+ return uploadFile(
5859
+ this.getAuthHeaders(),
5860
+ fileData,
5861
+ fileName,
5862
+ options?.folder ? { folder: options.folder } : void 0
5863
+ );
5864
+ },
5782
5865
  download: (docId) => downloadDocument(this.getAuthHeaders(), docId),
5783
5866
  getParsedContent: (docId, stage) => getParsedContent(this.getAuthHeaders(), docId, stage)
5784
5867
  };
@@ -5976,7 +6059,8 @@ function chunk(arr, size) {
5976
6059
  }
5977
6060
  return chunks;
5978
6061
  }
5979
- function readFileAsBlob(filePath, fileSize) {
6062
+ function readFileAsBlob(filePath, fileSize, fileName) {
6063
+ const type = fileName ? mimeFromName(fileName) ?? "" : "";
5980
6064
  if (fileSize > NODE_BUFFER_LIMIT) {
5981
6065
  const chunks = [];
5982
6066
  const CHUNK = 256 * 1024 * 1024;
@@ -5990,15 +6074,15 @@ function readFileAsBlob(filePath, fileSize) {
5990
6074
  pos += len;
5991
6075
  }
5992
6076
  fs2__default.default.closeSync(fd);
5993
- return new Blob(chunks);
6077
+ return new Blob(chunks, { type });
5994
6078
  }
5995
- return new Blob([fs2__default.default.readFileSync(filePath)]);
6079
+ return new Blob([fs2__default.default.readFileSync(filePath)], { type });
5996
6080
  }
5997
- async function uploadLocalFile(auth, workspaceId, filePath, options) {
6081
+ async function uploadLocalFile(auth, filePath, options) {
5998
6082
  const stat = fs2__default.default.statSync(filePath);
5999
6083
  const fileName = path2__default.default.basename(filePath);
6000
- const blob = readFileAsBlob(filePath, stat.size);
6001
- const result = await uploadFile(auth, workspaceId, blob, fileName, options);
6084
+ const blob = readFileAsBlob(filePath, stat.size, fileName);
6085
+ const result = await uploadFile(auth, blob, fileName, options);
6002
6086
  return { ...result, fileName };
6003
6087
  }
6004
6088
  async function uploadLocalFilesDirect(arbi, workspaceKey, filePaths, options) {
@@ -6157,37 +6241,7 @@ async function uploadLocalArchiveDirect(arbi, workspaceKey, archivePath, options
6157
6241
  }
6158
6242
  }
6159
6243
  }
6160
- function mimeFromName(name) {
6161
- const ext = path2__default.default.extname(name).toLowerCase();
6162
- switch (ext) {
6163
- case ".pdf":
6164
- return "application/pdf";
6165
- case ".txt":
6166
- return "text/plain";
6167
- case ".md":
6168
- return "text/markdown";
6169
- case ".html":
6170
- case ".htm":
6171
- return "text/html";
6172
- case ".doc":
6173
- return "application/msword";
6174
- case ".docx":
6175
- return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
6176
- case ".xls":
6177
- return "application/vnd.ms-excel";
6178
- case ".xlsx":
6179
- return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
6180
- case ".ppt":
6181
- return "application/vnd.ms-powerpoint";
6182
- case ".pptx":
6183
- return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
6184
- case ".eml":
6185
- return "message/rfc822";
6186
- default:
6187
- return void 0;
6188
- }
6189
- }
6190
- async function uploadDirectory(auth, workspaceId, dirPath, options) {
6244
+ async function uploadDirectory(auth, dirPath, options) {
6191
6245
  const resolvedDir = path2__default.default.resolve(dirPath);
6192
6246
  const dirName = path2__default.default.basename(resolvedDir);
6193
6247
  const entries = collectFiles(resolvedDir);
@@ -6243,7 +6297,7 @@ async function uploadDirectory(auth, workspaceId, dirPath, options) {
6243
6297
  });
6244
6298
  } else {
6245
6299
  try {
6246
- uploadable.push({ data: readFileAsBlob(f2.absolutePath, f2.size), name: f2.name });
6300
+ uploadable.push({ data: readFileAsBlob(f2.absolutePath, f2.size, f2.name), name: f2.name });
6247
6301
  } catch (err) {
6248
6302
  batchSkipped.push({
6249
6303
  file_name: f2.name,
@@ -6254,7 +6308,7 @@ async function uploadDirectory(auth, workspaceId, dirPath, options) {
6254
6308
  }
6255
6309
  let result = { doc_ext_ids: [], skipped: [] };
6256
6310
  if (uploadable.length > 0) {
6257
- result = await uploadFiles(auth, workspaceId, uploadable, {
6311
+ result = await uploadFiles(auth, uploadable, {
6258
6312
  folder,
6259
6313
  configExtId: options?.configExtId
6260
6314
  });
@@ -6279,7 +6333,7 @@ async function uploadDirectory(auth, workspaceId, dirPath, options) {
6279
6333
  }
6280
6334
  return { doc_ext_ids: allDocIds, skipped: allSkipped, folders };
6281
6335
  }
6282
- async function uploadZip(auth, workspaceId, zipPath, options) {
6336
+ async function uploadZip(auth, zipPath, options) {
6283
6337
  const JSZip = (await import('jszip')).default;
6284
6338
  const zipBuffer = fs2__default.default.readFileSync(zipPath);
6285
6339
  const zip = await JSZip.loadAsync(zipBuffer);
@@ -6343,7 +6397,7 @@ async function uploadZip(auth, workspaceId, zipPath, options) {
6343
6397
  data: new Blob([f2.data]),
6344
6398
  name: f2.name
6345
6399
  }));
6346
- const result = await uploadFiles(auth, workspaceId, blobs, {
6400
+ const result = await uploadFiles(auth, blobs, {
6347
6401
  folder,
6348
6402
  configExtId: options?.configExtId
6349
6403
  });
@@ -6414,7 +6468,7 @@ function isTransientError(err) {
6414
6468
  function sleep2(ms) {
6415
6469
  return new Promise((r2) => setTimeout(r2, ms));
6416
6470
  }
6417
- async function uploadManifest(auth, workspaceId, paths, options) {
6471
+ async function uploadManifest(auth, paths, options) {
6418
6472
  const maxRetries = Math.max(1, options?.maxRetries ?? 3);
6419
6473
  const outcomes = [];
6420
6474
  const summary = {
@@ -6535,7 +6589,7 @@ async function uploadManifest(auth, workspaceId, paths, options) {
6535
6589
  const readable = [];
6536
6590
  for (const f2 of batch) {
6537
6591
  try {
6538
- const blob = readFileAsBlob(f2.absolutePath, f2.size);
6592
+ const blob = readFileAsBlob(f2.absolutePath, f2.size, f2.basename);
6539
6593
  readable.push({ f: f2, blob });
6540
6594
  } catch (err) {
6541
6595
  const msg = err instanceof Error ? err.message : String(err);
@@ -6563,7 +6617,6 @@ async function uploadManifest(auth, workspaceId, paths, options) {
6563
6617
  try {
6564
6618
  result = await uploadFiles(
6565
6619
  auth,
6566
- workspaceId,
6567
6620
  readable.map((r2) => ({ data: r2.blob, name: r2.f.basename })),
6568
6621
  { folder, configExtId: options?.configExtId }
6569
6622
  );
@@ -6677,7 +6730,7 @@ function walkSupportedFiles(dirPath) {
6677
6730
  }
6678
6731
  return out.sort();
6679
6732
  }
6680
- async function uploadArchive(auth, workspaceId, archivePath, options) {
6733
+ async function uploadArchive(auth, archivePath, options) {
6681
6734
  try {
6682
6735
  child_process.execSync("7z --help", { stdio: "ignore" });
6683
6736
  } catch {
@@ -6696,7 +6749,7 @@ async function uploadArchive(auth, workspaceId, archivePath, options) {
6696
6749
  fs2__default.default.renameSync(tmpDir, namedDir);
6697
6750
  uploadDir = namedDir;
6698
6751
  }
6699
- return await uploadDirectory(auth, workspaceId, uploadDir, options);
6752
+ return await uploadDirectory(auth, uploadDir, options);
6700
6753
  } finally {
6701
6754
  fs2__default.default.rmSync(tmpDir, { recursive: true, force: true });
6702
6755
  }