@shipstatic/drop 0.3.6 → 1.0.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/index.cjs CHANGED
@@ -31,7 +31,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
 
32
32
  // node_modules/.pnpm/mime-db@1.54.0/node_modules/mime-db/db.json
33
33
  var require_db = __commonJS({
34
- "node_modules/.pnpm/mime-db@1.54.0/node_modules/mime-db/db.json"(exports$1, module) {
34
+ "node_modules/.pnpm/mime-db@1.54.0/node_modules/mime-db/db.json"(exports, module) {
35
35
  module.exports = {
36
36
  "application/1d-interleaved-parityfec": {
37
37
  source: "iana"
@@ -9379,10 +9379,43 @@ var require_db = __commonJS({
9379
9379
 
9380
9380
  // node_modules/.pnpm/mime-db@1.54.0/node_modules/mime-db/index.js
9381
9381
  var require_mime_db = __commonJS({
9382
- "node_modules/.pnpm/mime-db@1.54.0/node_modules/mime-db/index.js"(exports$1, module) {
9382
+ "node_modules/.pnpm/mime-db@1.54.0/node_modules/mime-db/index.js"(exports, module) {
9383
9383
  module.exports = require_db();
9384
9384
  }
9385
9385
  });
9386
+
9387
+ // node_modules/.pnpm/@shipstatic+types@1.0.0/node_modules/@shipstatic/types/dist/index.js
9388
+ var ErrorType = {
9389
+ /** Validation failed (400). Input shape is wrong. */
9390
+ Validation: "validation_failed",
9391
+ /** Resource not found (404). */
9392
+ NotFound: "not_found",
9393
+ /** Authenticated but not allowed (403). User lacks permission for this action. */
9394
+ Forbidden: "forbidden",
9395
+ /** Rate limit exceeded (429). */
9396
+ RateLimit: "rate_limit_exceeded",
9397
+ /** Authentication required or failed (401). Missing/invalid credentials. */
9398
+ Authentication: "authentication_failed",
9399
+ /** Business rule violation. Catch-all for 4xx state-rule errors that aren't more specific. */
9400
+ Business: "business_logic_error",
9401
+ /** API server error (500). Generic server-side fault. */
9402
+ Api: "internal_server_error",
9403
+ /** Network/connection error. Client-side only — set by HTTP clients on fetch failure; never produced server-side. */
9404
+ Network: "network_error",
9405
+ /** Operation was cancelled. Client-side only — set on `AbortSignal` abort; never produced server-side. */
9406
+ Cancelled: "operation_cancelled",
9407
+ /** File operation error. Client-side only — set by SDK during local file processing; never produced server-side. */
9408
+ File: "file_error",
9409
+ /** Configuration error. Client-side only — set by SDK during config parsing/validation; never produced server-side. */
9410
+ Config: "config_error"
9411
+ };
9412
+ var CLIENT_ONLY_ERROR_TYPES = /* @__PURE__ */ new Set([
9413
+ ErrorType.Network,
9414
+ ErrorType.Cancelled,
9415
+ ErrorType.File,
9416
+ ErrorType.Config
9417
+ ]);
9418
+ new Set(Object.values(ErrorType).filter((t) => !CLIENT_ONLY_ERROR_TYPES.has(t)));
9386
9419
  function isShipError(error) {
9387
9420
  return error !== null && typeof error === "object" && "name" in error && error.name === "ShipError" && "status" in error;
9388
9421
  }
@@ -9877,71 +9910,18 @@ function getMimeType(path) {
9877
9910
  const extension = path.includes(".") ? path.substring(path.lastIndexOf(".") + 1).toLowerCase() : "";
9878
9911
  return extensionToMimeMap[extension] || "";
9879
9912
  }
9880
-
9881
- // src/utils/zipExtractor.ts
9882
- async function extractZipToFiles(zipFile) {
9883
- try {
9884
- const arrayBuffer = await zipFile.arrayBuffer();
9885
- const entries = unzipSync(new Uint8Array(arrayBuffer));
9886
- const files = [];
9887
- const errors = [];
9888
- for (const [path, data] of Object.entries(entries)) {
9889
- if (path.endsWith("/") && data.length === 0) continue;
9890
- const sanitizedPath = normalizePath(path);
9891
- if (!sanitizedPath) {
9892
- errors.push(`Skipped invalid path: ${path}`);
9893
- continue;
9894
- }
9895
- const mimeType = getMimeType(sanitizedPath);
9896
- const filename = sanitizedPath.split("/").pop() || sanitizedPath;
9897
- const file = new File([new Uint8Array(data)], filename, {
9898
- type: mimeType
9899
- });
9900
- Object.defineProperty(file, "webkitRelativePath", {
9901
- value: sanitizedPath,
9902
- writable: false,
9903
- configurable: true
9904
- });
9905
- files.push(file);
9906
- }
9907
- return { files, errors };
9908
- } catch (error) {
9909
- return {
9910
- files: [],
9911
- errors: [`Failed to load ZIP file: ${error instanceof Error ? error.message : String(error)}`]
9912
- };
9913
- }
9914
- }
9915
- function normalizePath(path) {
9916
- const segments = path.split("/");
9917
- const normalized = [];
9918
- for (const segment of segments) {
9919
- if (segment === "" || segment === ".") {
9920
- continue;
9921
- }
9922
- if (segment === "..") {
9923
- if (normalized.length > 0) {
9924
- normalized.pop();
9925
- }
9926
- continue;
9927
- }
9928
- normalized.push(segment);
9929
- }
9930
- return normalized.join("/");
9931
- }
9932
- function isZipFile(file) {
9933
- return file.type === "application/zip" || file.type === "application/x-zip-compressed" || file.name.toLowerCase().endsWith(".zip");
9913
+ function setRelativePath(file, path) {
9914
+ Object.defineProperty(file, "webkitRelativePath", {
9915
+ value: path,
9916
+ writable: false,
9917
+ configurable: true
9918
+ });
9934
9919
  }
9935
- var formatFileSize = ship.formatFileSize;
9936
9920
  function createProcessedFile(file, options) {
9937
- const webkitPath = file.webkitRelativePath || "";
9938
- const path = options?.path || (webkitPath && webkitPath.trim() ? webkitPath : file.name);
9939
- const mimeFromDb = getMimeType(path);
9940
- const mimeFromBrowser = file.type;
9941
- const type = mimeFromDb || mimeFromBrowser;
9921
+ const path = options?.path || file.webkitRelativePath?.trim() || file.name;
9922
+ const type = getMimeType(path) || file.type;
9942
9923
  return {
9943
- // ProcessedFile properties
9944
- // Note: md5 is intentionally undefined - Ship SDK will calculate it during deployment
9924
+ // md5 is intentionally undefined — Ship SDK calculates it during deployment.
9945
9925
  id: crypto.randomUUID(),
9946
9926
  file,
9947
9927
  path,
@@ -9954,32 +9934,11 @@ function createProcessedFile(file, options) {
9954
9934
  }
9955
9935
  function stripCommonPrefix(files) {
9956
9936
  if (files.length === 0) return files;
9957
- const paths = files.map((f) => f.path);
9958
- const segments = paths[0].split("/");
9959
- let commonDepth = 0;
9960
- for (let i = 0; i < segments.length - 1; i++) {
9961
- const segment = segments[i];
9962
- if (paths.every((p) => p.split("/")[i] === segment)) {
9963
- commonDepth = i + 1;
9964
- } else {
9965
- break;
9966
- }
9967
- }
9968
- if (commonDepth === 0) return files;
9969
- const prefix = segments.slice(0, commonDepth).join("/") + "/";
9970
- return files.map((f) => {
9971
- const newPath = f.path.startsWith(prefix) ? f.path.slice(prefix.length) : f.path;
9972
- if (f.file) {
9973
- Object.defineProperty(f.file, "webkitRelativePath", {
9974
- value: newPath,
9975
- writable: false,
9976
- configurable: true
9977
- });
9978
- }
9979
- return {
9980
- ...f,
9981
- path: newPath
9982
- };
9937
+ const deployFiles = ship.optimizeDeployPaths(files.map((f) => f.path));
9938
+ return files.map((f, i) => {
9939
+ const newPath = deployFiles[i].path;
9940
+ setRelativePath(f.file, newPath);
9941
+ return { ...f, path: newPath };
9983
9942
  });
9984
9943
  }
9985
9944
  async function traverseFileTree(entry, files, currentPath = "") {
@@ -9989,11 +9948,7 @@ async function traverseFileTree(entry, files, currentPath = "") {
9989
9948
  entry.file(resolve, reject);
9990
9949
  });
9991
9950
  const relativePath = currentPath ? `${currentPath}/${file.name}` : file.name;
9992
- Object.defineProperty(file, "webkitRelativePath", {
9993
- value: relativePath,
9994
- writable: false,
9995
- configurable: true
9996
- });
9951
+ setRelativePath(file, relativePath);
9997
9952
  files.push(file);
9998
9953
  } else if (entry.isDirectory) {
9999
9954
  const dirReader = entry.createReader();
@@ -10022,6 +9977,57 @@ async function traverseFileTree(entry, files, currentPath = "") {
10022
9977
  console.warn(`Error traversing file tree for entry ${entry.name}:`, error);
10023
9978
  }
10024
9979
  }
9980
+
9981
+ // src/utils/zipExtractor.ts
9982
+ async function extractZipToFiles(zipFile) {
9983
+ try {
9984
+ const arrayBuffer = await zipFile.arrayBuffer();
9985
+ const entries = unzipSync(new Uint8Array(arrayBuffer));
9986
+ const files = [];
9987
+ const errors = [];
9988
+ for (const [path, data] of Object.entries(entries)) {
9989
+ if (path.endsWith("/") && data.length === 0) continue;
9990
+ const sanitizedPath = normalizePath(path);
9991
+ if (!sanitizedPath) {
9992
+ errors.push(`Skipped invalid path: ${path}`);
9993
+ continue;
9994
+ }
9995
+ const mimeType = getMimeType(sanitizedPath);
9996
+ const filename = sanitizedPath.split("/").pop() || sanitizedPath;
9997
+ const file = new File([new Uint8Array(data)], filename, {
9998
+ type: mimeType
9999
+ });
10000
+ setRelativePath(file, sanitizedPath);
10001
+ files.push(file);
10002
+ }
10003
+ return { files, errors };
10004
+ } catch (error) {
10005
+ return {
10006
+ files: [],
10007
+ errors: [`Failed to load ZIP file: ${error instanceof Error ? error.message : String(error)}`]
10008
+ };
10009
+ }
10010
+ }
10011
+ function normalizePath(path) {
10012
+ const segments = path.split("/");
10013
+ const normalized = [];
10014
+ for (const segment of segments) {
10015
+ if (segment === "" || segment === ".") {
10016
+ continue;
10017
+ }
10018
+ if (segment === "..") {
10019
+ if (normalized.length > 0) {
10020
+ normalized.pop();
10021
+ }
10022
+ continue;
10023
+ }
10024
+ normalized.push(segment);
10025
+ }
10026
+ return normalized.join("/");
10027
+ }
10028
+ function isZipFile(file) {
10029
+ return file.type === "application/zip" || file.type === "application/x-zip-compressed" || file.name.toLowerCase().endsWith(".zip");
10030
+ }
10025
10031
  var initialState = {
10026
10032
  value: "idle",
10027
10033
  files: [],
@@ -10091,10 +10097,7 @@ function useDrop(options) {
10091
10097
  } else {
10092
10098
  allFiles.push(...newFiles);
10093
10099
  }
10094
- const getFilePath = (f) => {
10095
- const webkitPath = f.webkitRelativePath;
10096
- return webkitPath && webkitPath.trim() ? webkitPath : f.name;
10097
- };
10100
+ const getFilePath = (f) => f.webkitRelativePath?.trim() || f.name;
10098
10101
  let filePaths = allFiles.map(getFilePath);
10099
10102
  const needsBuild = filePaths.some((p) => hasUnbuiltMarker(p));
10100
10103
  if (needsBuild) {
@@ -10150,7 +10153,7 @@ function useDrop(options) {
10150
10153
  files: filesWithStatus2,
10151
10154
  sourceName: detectedSourceName,
10152
10155
  needsBuild: true,
10153
- status: { title: "Ready", details: `${filesWithStatus2.length} file(s) ready \u2014 project will be built` }
10156
+ status: { title: "Ready", details: `${ship.pluralize(filesWithStatus2.length, "file", "files", true)} ready \u2014 project will be built` }
10154
10157
  });
10155
10158
  onFilesReady?.(filesWithStatus2);
10156
10159
  return;
@@ -10178,20 +10181,20 @@ function useDrop(options) {
10178
10181
  needsBuild: false,
10179
10182
  status: {
10180
10183
  title: "Validation Failed",
10181
- details: `${validation.errors.length} file(s) failed validation`,
10184
+ details: `${ship.pluralize(validation.errors.length, "file", "files", true)} failed validation`,
10182
10185
  errors: errorMessages
10183
10186
  }
10184
10187
  });
10185
10188
  onValidationError?.({
10186
10189
  error: "Validation Failed",
10187
- details: `${validation.errors.length} error(s)`,
10190
+ details: ship.pluralize(validation.errors.length, "error", "errors", true),
10188
10191
  errors: errorMessages,
10189
10192
  isClientError: true
10190
10193
  });
10191
10194
  } else if (validation.validFiles.length > 0) {
10192
- let details = `${validation.validFiles.length} file(s) ready`;
10195
+ let details = `${ship.pluralize(validation.validFiles.length, "file", "files", true)} ready`;
10193
10196
  if (validation.warnings.length > 0) {
10194
- details += ` (${validation.warnings.length} empty file(s) excluded)`;
10197
+ details += ` (${ship.pluralize(validation.warnings.length, "empty file", "empty files", true)} excluded)`;
10195
10198
  }
10196
10199
  setState({
10197
10200
  value: "ready",
@@ -10217,7 +10220,7 @@ function useDrop(options) {
10217
10220
  needsBuild: false,
10218
10221
  status: {
10219
10222
  title: "All files excluded",
10220
- details: `${validation.warnings.length} file(s) excluded (empty files cannot be deployed)`,
10223
+ details: `${ship.pluralize(validation.warnings.length, "file", "files", true)} excluded (empty files cannot be deployed)`,
10221
10224
  warnings: validation.warnings.map((w) => `${w.file}: ${w.message}`)
10222
10225
  }
10223
10226
  });
@@ -10307,11 +10310,7 @@ function useDrop(options) {
10307
10310
  } else {
10308
10311
  const file = item.getAsFile();
10309
10312
  if (file) {
10310
- Object.defineProperty(file, "webkitRelativePath", {
10311
- value: file.name,
10312
- writable: false,
10313
- configurable: true
10314
- });
10313
+ setRelativePath(file, file.name);
10315
10314
  files.push(file);
10316
10315
  }
10317
10316
  }
@@ -10399,13 +10398,17 @@ mime-db/index.js:
10399
10398
  *)
10400
10399
  */
10401
10400
 
10401
+ Object.defineProperty(exports, "formatFileSize", {
10402
+ enumerable: true,
10403
+ get: function () { return ship.formatFileSize; }
10404
+ });
10402
10405
  exports.FILE_STATUSES = FILE_STATUSES;
10403
10406
  exports.createProcessedFile = createProcessedFile;
10404
10407
  exports.extractZipToFiles = extractZipToFiles;
10405
- exports.formatFileSize = formatFileSize;
10406
10408
  exports.getMimeType = getMimeType;
10407
10409
  exports.isZipFile = isZipFile;
10408
10410
  exports.normalizePath = normalizePath;
10411
+ exports.setRelativePath = setRelativePath;
10409
10412
  exports.stripCommonPrefix = stripCommonPrefix;
10410
10413
  exports.traverseFileTree = traverseFileTree;
10411
10414
  exports.useDrop = useDrop;