UNPKG

@bunny.net/storage-sdk

Version:
299 lines (292 loc) 10.4 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key2 of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key2) && key2 !== except) __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/lib.ts var lib_exports = {}; __export(lib_exports, { file: () => file_exports, regions: () => regions_exports, zone: () => zone_exports }); module.exports = __toCommonJS(lib_exports); // src/regions.ts var regions_exports = {}; __export(regions_exports, { StorageRegion: () => StorageRegion, addr: () => addr }); var StorageRegion = /* @__PURE__ */ ((StorageRegion2) => { StorageRegion2["Falkenstein"] = "de"; StorageRegion2["London"] = "uk"; StorageRegion2["NewYork"] = "ny"; StorageRegion2["LosAngeles"] = "la"; StorageRegion2["Singapore"] = "sg"; StorageRegion2["Stockholm"] = "se"; StorageRegion2["SaoPaulo"] = "br"; StorageRegion2["Johannesburg"] = "jh"; StorageRegion2["Sydney"] = "syd"; return StorageRegion2; })(StorageRegion || {}); function addr(value) { switch (value) { case "de" /* Falkenstein */: return new URL("https://storage.bunnycdn.com"); case "uk" /* London */: return new URL("https://uk.storage.bunnycdn.com"); case "ny" /* NewYork */: return new URL("https://ny.storage.bunnycdn.com"); case "la" /* LosAngeles */: return new URL("https://la.storage.bunnycdn.com"); case "sg" /* Singapore */: return new URL("https://sg.storage.bunnycdn.com"); case "se" /* Stockholm */: return new URL("https://se.storage.bunnycdn.com"); case "br" /* SaoPaulo */: return new URL("https://br.storage.bunnycdn.com"); case "jh" /* Johannesburg */: return new URL("https://jh.storage.bunnycdn.com"); case "syd" /* Sydney */: return new URL("https://syd.storage.bunnycdn.com"); default: throw new Error("Invalid Storage Region"); } } // src/file.ts var file_exports = {}; __export(file_exports, { ZoneSchema: () => ZoneSchema, createDirectory: () => createDirectory, download: () => download, get: () => get, list: () => list, remove: () => remove, removeDirectory: () => removeDirectory, upload: () => upload }); var import_zod2 = require("zod"); // src/zone.ts var zone_exports = {}; __export(zone_exports, { addr: () => addr2, connect_with_accesskey: () => connect_with_accesskey, key: () => key, name: () => name }); function addr2(value) { return new URL(`${addr(value.region)}${value.name}/`); } function name(value) { return value.name; } function key(value) { return ["AccessKey", value.accessKey]; } function connect_with_accesskey(region, name2, accessKey) { return { _tag: "StorageZone", region, name: name2, accessKey }; } // src/api.ts var import_zod = require("zod"); var ReplicatedZonesStringSchema = import_zod.z.string(); var ReplicatedZonesSchema = ReplicatedZonesStringSchema.transform((str) => { const zones = str.split(",").map((zone) => zone.trim()).filter((x) => x != ""); return zones.map((zone) => ZoneSchema.parse(zone)); }); var StorageFileSchemaDescribe = import_zod.z.object({ Guid: import_zod.z.string(), UserId: import_zod.z.string(), LastChanged: import_zod.z.coerce.date(), DateCreated: import_zod.z.coerce.date(), StorageZoneName: import_zod.z.string(), Path: import_zod.z.string(), ObjectName: import_zod.z.string(), Length: import_zod.z.number(), StorageZoneId: import_zod.z.number(), IsDirectory: import_zod.z.boolean(), ServerId: import_zod.z.number(), Checksum: import_zod.z.nullable(import_zod.z.string()), ReplicatedZones: import_zod.z.nullable(ReplicatedZonesSchema), ContentType: import_zod.z.string() }); var StorageFileListing = import_zod.z.array(StorageFileSchemaDescribe); // src/file.ts var ZoneSchema = import_zod2.z.union([ import_zod2.z.literal("SE"), import_zod2.z.literal("CZ"), import_zod2.z.literal("UK"), import_zod2.z.literal("ES"), import_zod2.z.literal("NY"), import_zod2.z.literal("WA"), import_zod2.z.literal("MI"), import_zod2.z.literal("LA"), import_zod2.z.literal("JH"), import_zod2.z.literal("HK"), import_zod2.z.literal("BR"), import_zod2.z.literal("SG"), import_zod2.z.literal("JP"), import_zod2.z.literal("SYD") ]); async function get(storageZone, path) { const url = addr2(storageZone); url.pathname = `${url.pathname}${path}`; const [auth_header, key2] = key(storageZone); const response = await fetch(url, { method: "DESCRIBE", headers: { "Accept": "application/json", [auth_header]: key2 } }); if (!response.ok) { throw statusCodeToException(storageZone, response.status, path); } const rawData = await response.json(); const processedData = { // eslint-disable-next-line @typescript-eslint/no-explicit-any ...rawData, // eslint-disable-next-line @typescript-eslint/no-explicit-any LastChanged: new Date(rawData.LastChanged), // eslint-disable-next-line @typescript-eslint/no-explicit-any DateCreated: new Date(rawData.DateCreated) }; const result = StorageFileSchemaDescribe.parse(processedData); return { _tag: "StorageFile", guid: result.Guid, userId: result.UserId, lastChanged: result.LastChanged, dateCreated: result.DateCreated, storageZoneName: result.StorageZoneName, path: result.Path, objectName: result.ObjectName, length: result.Length, storageZoneId: result.StorageZoneId, isDirectory: result.IsDirectory, serverId: result.ServerId, checksum: result.Checksum, replicatedZones: result.ReplicatedZones, contentType: result.ContentType, data: () => download(storageZone, path) }; } async function list(storageZone, path) { const url = addr2(storageZone); const directory_path = path.endsWith("/") ? path : `${path}/`; url.pathname = `${url.pathname}${directory_path}`; const [auth_header, key2] = key(storageZone); const response = await fetch(url, { method: "GET", headers: { "Accept": "application/json", [auth_header]: key2 } }); if (!response.ok) { throw statusCodeToException(storageZone, response.status, path); } const j = await response.json(); try { StorageFileListing.parse(j); } catch (e) { console.error(e); } return StorageFileListing.parse(j).map((result) => ({ _tag: "StorageFile", guid: result.Guid, userId: result.UserId, lastChanged: result.LastChanged, dateCreated: result.DateCreated, storageZoneName: result.StorageZoneName, path: result.Path, objectName: result.ObjectName, length: result.Length, storageZoneId: result.StorageZoneId, isDirectory: result.IsDirectory, serverId: result.ServerId, checksum: result.Checksum, replicatedZones: result.ReplicatedZones, contentType: result.ContentType, data: () => download(storageZone, result.Path) })); } async function remove(storageZone, path) { const url = addr2(storageZone); url.pathname = `${url.pathname}${path}`; const [auth_header, key2] = key(storageZone); const response = await fetch(url, { method: "DELETE", headers: { [auth_header]: key2 } }); return response.ok; } async function createDirectory(storageZone, path) { const url = addr2(storageZone); const directory_path = path.endsWith("/") ? path : `${path}/`; url.pathname = `${url.pathname}${directory_path}`; const [auth_header, key2] = key(storageZone); const response = await fetch(url, { method: "PUT", headers: { [auth_header]: key2 } }); return response.ok; } async function removeDirectory(storageZone, path) { const url = addr2(storageZone); const directory_path = path.endsWith("/") ? path : `${path}/`; url.pathname = `${url.pathname}${directory_path}`; const [auth_header, key2] = key(storageZone); const response = await fetch(url, { method: "DELETE", headers: { [auth_header]: key2 } }); return response.ok; } async function upload(storageZone, path, stream, options) { const url = addr2(storageZone); url.pathname = `${url.pathname}${path}`; const [auth_header, key2] = key(storageZone); const headers = { [auth_header]: key2, "Content-Type": "application/octet-stream" }; if (options?.contentType) headers["Override-Content-Type"] = options.contentType; if (options?.sha256Checksum) headers["Checksum"] = options.sha256Checksum; const response = await fetch(url, { method: "PUT", headers, body: stream, duplex: "half" }); if (!response.ok) { throw statusCodeToException(storageZone, response.status, path); } return response.ok; } async function download(storageZone, path) { const url = addr2(storageZone); url.pathname = `${url.pathname}${path}`; const [auth_header, key2] = key(storageZone); const response = await fetch(url, { method: "GET", headers: { [auth_header]: key2 } }); if (!response.ok) { throw statusCodeToException(storageZone, response.status, path); } const contentLength = response.headers.has("content-length") ? parseInt(response.headers.get("content-length")) : void 0; if (!response.body) { throw new Error("Response has no body"); } const stream = response.body; return { stream, response, length: contentLength }; } function statusCodeToException(storageZone, status, path) { switch (status) { case 404: return new Error(`File not found: ${path}`); case 400: return new Error("Unable to upload file. Either invalid path specified, either provided checksum invalid"); case 401: return new Error( `Unauthorized access to storage zone: ${name(storageZone)}` ); default: return new Error("An unknown error has occurred during the request."); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { file, regions, zone });