@arbidocs/sdk 0.3.47 → 0.3.49

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