UNPKG

@bunny.net/storage-sdk

Version:
276 lines (270 loc) 9.12 kB
var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; // 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 }); import { z as z2 } from "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 import { z } from "zod"; var ReplicatedZonesStringSchema = 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 = z.object({ Guid: z.string(), UserId: z.string(), LastChanged: z.coerce.date(), DateCreated: z.coerce.date(), StorageZoneName: z.string(), Path: z.string(), ObjectName: z.string(), Length: z.number(), StorageZoneId: z.number(), IsDirectory: z.boolean(), ServerId: z.number(), Checksum: z.nullable(z.string()), ReplicatedZones: z.nullable(ReplicatedZonesSchema), ContentType: z.string() }); var StorageFileListing = z.array(StorageFileSchemaDescribe); // src/file.ts var ZoneSchema = z2.union([ z2.literal("SE"), z2.literal("CZ"), z2.literal("UK"), z2.literal("ES"), z2.literal("NY"), z2.literal("WA"), z2.literal("MI"), z2.literal("LA"), z2.literal("JH"), z2.literal("HK"), z2.literal("BR"), z2.literal("SG"), z2.literal("JP"), z2.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."); } } export { file_exports as file, regions_exports as regions, zone_exports as zone };