🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@howells/stow-client

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@howells/stow-client - npm Package Compare versions

Comparing version
2.4.0
to
2.6.0
+34
-33
dist/index.js

@@ -41,4 +41,5 @@ "use strict";

// src/index.ts
function uploadToR2(uploadUrl, file, onProgress) {
return new Promise((resolve, reject) => {
var uploadToR2 = (uploadUrl, file, onProgress) => (
// eslint-disable-next-line eslint-plugin-promise/avoid-new
new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();

@@ -52,3 +53,3 @@ xhr.upload.addEventListener("progress", (event) => {

if (xhr.status >= 200 && xhr.status < 300) {
resolve(void 0);
resolve();
return;

@@ -67,4 +68,4 @@ }

xhr.send(file);
});
}
})
);
var StowClient = class {

@@ -82,3 +83,3 @@ endpoint;

constructor(config) {
this.endpoint = typeof config === "string" ? config.replace(/\/+$/, "") : config.endpoint.replace(/\/+$/, "");
this.endpoint = typeof config === "string" ? config.replace(/\/+$/u, "") : config.endpoint.replace(/\/+$/u, "");
}

@@ -95,6 +96,6 @@ endpointUrl(path) {

}
if (confirmUrl.startsWith("/") || /^[a-z][a-z0-9+\-.]*:\/\//i.test(confirmUrl)) {
if (confirmUrl.startsWith("/") || /^[a-z][a-z0-9+\-.]*:\/\//iu.test(confirmUrl)) {
return confirmUrl;
}
return this.endpointUrl(`/${confirmUrl.replace(/^\/+/, "")}`);
return this.endpointUrl(`/${confirmUrl.replace(/^\/+/u, "")}`);
}

@@ -118,16 +119,16 @@ /**

loaded: 0,
total: file.size,
percent: 0,
phase: "presigning"
phase: "presigning",
total: file.size
});
const presignResponse = await fetch(this.endpointUrl("/presign"), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contentType: file.type || "application/octet-stream",
filename: file.name,
contentType: file.type || "application/octet-stream",
route,
size: file.size,
route,
...metadata ? { metadata } : {}
})
}),
headers: { "Content-Type": "application/json" },
method: "POST"
});

@@ -142,12 +143,12 @@ if (!presignResponse.ok) {

loaded: file.size,
total: file.size,
percent: 100,
phase: "confirming"
phase: "confirming",
total: file.size
});
return {
contentType: presign.contentType,
deduped: true,
key: presign.key,
url: presign.url,
size: presign.size,
contentType: presign.contentType,
deduped: true
url: presign.url
};

@@ -157,5 +158,5 @@ }

loaded: 0,
total: file.size,
percent: 0,
phase: "uploading"
phase: "uploading",
total: file.size
});

@@ -165,5 +166,5 @@ await uploadToR2(presign.uploadUrl, file, (loaded) => {

loaded,
total: file.size,
percent: Math.round(loaded / file.size * 100),
phase: "uploading"
phase: "uploading",
total: file.size
});

@@ -173,15 +174,15 @@ });

loaded: file.size,
total: file.size,
percent: 100,
phase: "confirming"
phase: "confirming",
total: file.size
});
const confirmResponse = await fetch(this.resolveConfirmUrl(presign.confirmUrl), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contentType: file.type || "application/octet-stream",
fileKey: presign.fileKey,
size: file.size,
contentType: file.type || "application/octet-stream",
...metadata ? { metadata } : {}
})
}),
headers: { "Content-Type": "application/json" },
method: "POST"
});

@@ -194,6 +195,6 @@ if (!confirmResponse.ok) {

return {
contentType: result.contentType,
key: result.key,
url: result.url,
size: result.size,
contentType: result.contentType
url: result.url
};

@@ -221,3 +222,3 @@ }

async uploadFiles(files, options) {
const fileArray = Array.from(files);
const fileArray = [...files];
const concurrency = Math.max(1, options?.concurrency ?? 3);

@@ -224,0 +225,0 @@ if (concurrency === 1) {

@@ -14,4 +14,5 @@ // src/stow-error.ts

// src/index.ts
function uploadToR2(uploadUrl, file, onProgress) {
return new Promise((resolve, reject) => {
var uploadToR2 = (uploadUrl, file, onProgress) => (
// eslint-disable-next-line eslint-plugin-promise/avoid-new
new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();

@@ -25,3 +26,3 @@ xhr.upload.addEventListener("progress", (event) => {

if (xhr.status >= 200 && xhr.status < 300) {
resolve(void 0);
resolve();
return;

@@ -40,4 +41,4 @@ }

xhr.send(file);
});
}
})
);
var StowClient = class {

@@ -55,3 +56,3 @@ endpoint;

constructor(config) {
this.endpoint = typeof config === "string" ? config.replace(/\/+$/, "") : config.endpoint.replace(/\/+$/, "");
this.endpoint = typeof config === "string" ? config.replace(/\/+$/u, "") : config.endpoint.replace(/\/+$/u, "");
}

@@ -68,6 +69,6 @@ endpointUrl(path) {

}
if (confirmUrl.startsWith("/") || /^[a-z][a-z0-9+\-.]*:\/\//i.test(confirmUrl)) {
if (confirmUrl.startsWith("/") || /^[a-z][a-z0-9+\-.]*:\/\//iu.test(confirmUrl)) {
return confirmUrl;
}
return this.endpointUrl(`/${confirmUrl.replace(/^\/+/, "")}`);
return this.endpointUrl(`/${confirmUrl.replace(/^\/+/u, "")}`);
}

@@ -91,16 +92,16 @@ /**

loaded: 0,
total: file.size,
percent: 0,
phase: "presigning"
phase: "presigning",
total: file.size
});
const presignResponse = await fetch(this.endpointUrl("/presign"), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contentType: file.type || "application/octet-stream",
filename: file.name,
contentType: file.type || "application/octet-stream",
route,
size: file.size,
route,
...metadata ? { metadata } : {}
})
}),
headers: { "Content-Type": "application/json" },
method: "POST"
});

@@ -115,12 +116,12 @@ if (!presignResponse.ok) {

loaded: file.size,
total: file.size,
percent: 100,
phase: "confirming"
phase: "confirming",
total: file.size
});
return {
contentType: presign.contentType,
deduped: true,
key: presign.key,
url: presign.url,
size: presign.size,
contentType: presign.contentType,
deduped: true
url: presign.url
};

@@ -130,5 +131,5 @@ }

loaded: 0,
total: file.size,
percent: 0,
phase: "uploading"
phase: "uploading",
total: file.size
});

@@ -138,5 +139,5 @@ await uploadToR2(presign.uploadUrl, file, (loaded) => {

loaded,
total: file.size,
percent: Math.round(loaded / file.size * 100),
phase: "uploading"
phase: "uploading",
total: file.size
});

@@ -146,15 +147,15 @@ });

loaded: file.size,
total: file.size,
percent: 100,
phase: "confirming"
phase: "confirming",
total: file.size
});
const confirmResponse = await fetch(this.resolveConfirmUrl(presign.confirmUrl), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contentType: file.type || "application/octet-stream",
fileKey: presign.fileKey,
size: file.size,
contentType: file.type || "application/octet-stream",
...metadata ? { metadata } : {}
})
}),
headers: { "Content-Type": "application/json" },
method: "POST"
});

@@ -167,6 +168,6 @@ if (!confirmResponse.ok) {

return {
contentType: result.contentType,
key: result.key,
url: result.url,
size: result.size,
contentType: result.contentType
url: result.url
};

@@ -194,3 +195,3 @@ }

async uploadFiles(files, options) {
const fileArray = Array.from(files);
const fileArray = [...files];
const concurrency = Math.max(1, options?.concurrency ?? 3);

@@ -197,0 +198,0 @@ if (concurrency === 1) {

{
"name": "@howells/stow-client",
"version": "2.4.0",
"description": "Client-side SDK for Stow file storage",
"version": "2.6.0",
"description": "Client-side SDK for Stow visual media infrastructure",
"keywords": [

@@ -33,14 +33,18 @@ "file-storage",

"devDependencies": {
"jsdom": "^29.0.0",
"@howells/typescript-config": "^0.1.6",
"jsdom": "^29.0.1",
"tsup": "^8.5.1",
"typescript": "^5.9.3",
"vite-plus": "latest",
"@stow/typescript-config": "0.0.0"
"typescript": "^5.9.3"
},
"engines": {
"node": ">=22.22.3"
},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"test": "vp test run",
"test:watch": "vp test"
"test": "vitest run",
"test:watch": "vitest",
"lint": "howells-check src",
"lint:fix": "howells-fix src"
}
}
# @howells/stow-client
Client-side SDK for [Stow](https://stow.sh) file storage. Upload files directly from the browser with progress tracking.
Client-side SDK for [Stow](https://stow.sh) visual media infrastructure. Upload files directly from the browser with progress tracking.

@@ -5,0 +5,0 @@ ## Installation