UNPKG

@lucidcms/plugin-s3

Version:
342 lines (329 loc) 9.8 kB
import { AwsClient } from "aws4fetch"; //#region src/clients/aws-client.ts let awsClient = null; const getS3Client = (pluginOptions) => { if (!awsClient) awsClient = new AwsClient(pluginOptions.clientOptions); return awsClient; }; var aws_client_default = getS3Client; //#endregion //#region src/translations/en-gb.json var object_body_undefined = "The object get request Body is undefined."; var object_missing_metadata = "An error occurred while fetching the object metadata."; var get_metadata_failed = "Get metadata failed with status {{status}} and message {{statusText}}."; var an_unknown_error_occurred = "An unknown error occurred"; var delete_multiple_failed = "Delete multiple failed with status {{status}} and message {{statusText}}."; var delete_single_failed = "Delete single failed with status {{status}} and message {{statusText}}."; var stream_failed = "Stream failed with status {{status}} and message {{statusText}}."; var upload_failed = "Upload failed with status {{status}} and message {{statusText}}."; var en_gb_default = { object_body_undefined, object_missing_metadata, get_metadata_failed, an_unknown_error_occurred, delete_multiple_failed, delete_single_failed, stream_failed, upload_failed }; //#endregion //#region src/translations/index.ts const selectedLang = en_gb_default; const T = (key, data) => { const translation = selectedLang[key]; if (!translation) return key; if (!data) return translation; return translation.replace(/\{\{(\w+)\}\}/g, (_, p1) => data[p1]); }; var translations_default = T; //#endregion //#region src/services/steam.ts var steam_default = (client, pluginOptions) => { const stream = async (key, options) => { try { const headers = {}; if (options?.range) { const start = options.range.start; const end = options.range.end; headers.Range = end !== void 0 ? `bytes=${start}-${end}` : `bytes=${start}-`; } const response = await client.sign(new Request(`${pluginOptions.endpoint}/${pluginOptions.bucket}/${key}`, { method: "GET", headers })); const result = await fetch(response); if (!result.ok) return { error: { message: translations_default("stream_failed", { status: result.status, statusText: result.statusText }) }, data: void 0 }; if (!result.body) return { error: { message: translations_default("object_body_undefined") }, data: void 0 }; let isPartialContent = false; let totalSize; let range; const contentRange = result.headers.get("content-range"); if (contentRange) { isPartialContent = true; const match = contentRange.match(/bytes (\d+)-(\d+)\/(\d+)/); if (match?.[1] && match[2] && match[3]) { range = { start: Number.parseInt(match[1], 10), end: Number.parseInt(match[2], 10) }; totalSize = Number.parseInt(match[3], 10); } } const contentLength = result.headers.get("content-length"); const contentType = result.headers.get("content-type"); return { error: void 0, data: { contentLength: contentLength ? Number.parseInt(contentLength, 10) : void 0, contentType: contentType || void 0, body: result.body, isPartialContent, totalSize: totalSize || (contentLength ? Number.parseInt(contentLength, 10) : void 0), range } }; } catch (e) { return { error: { type: "plugin", message: e instanceof Error ? e.message : translations_default("an_unknown_error_occurred") }, data: void 0 }; } }; return stream; }; //#endregion //#region src/services/delete-single.ts var delete_single_default = (client, pluginOptions) => { const deletSingle = async (key) => { try { const response = await client.sign(new Request(`${pluginOptions.endpoint}/${pluginOptions.bucket}/${key}`, { method: "DELETE" })); const result = await fetch(response); if (!result.ok) return { error: { type: "plugin", message: translations_default("delete_single_failed", { status: result.status, statusText: result.statusText }) }, data: void 0 }; return { error: void 0, data: void 0 }; } catch (e) { return { error: { type: "plugin", message: e instanceof Error ? e.message : translations_default("an_unknown_error_occurred") }, data: void 0 }; } }; return deletSingle; }; //#endregion //#region src/services/delete-multiple.ts var delete_multiple_default = (client, pluginOptions) => { const deleteMultiple = async (keys) => { try { const deleteXml = `<?xml version="1.0" encoding="UTF-8"?> <Delete> ${keys.map((key) => `<Object><Key>${key}</Key></Object>`).join("")} </Delete>`; const response = await client.sign(new Request(`${pluginOptions.endpoint}/${pluginOptions.bucket}?delete`, { method: "POST", body: deleteXml, headers: { "Content-Type": "application/xml" } })); const result = await fetch(response); if (!result.ok) return { error: { type: "plugin", message: translations_default("delete_multiple_failed", { status: result.status, statusText: result.statusText }) }, data: void 0 }; return { error: void 0, data: void 0 }; } catch (e) { return { error: { type: "plugin", message: e instanceof Error ? e.message : translations_default("an_unknown_error_occurred") }, data: void 0 }; } }; return deleteMultiple; }; //#endregion //#region src/services/upload-single.ts var upload_single_default = (client, pluginOptions) => { const uploadSingle = async (props) => { try { const headers = new Headers(); if (props.meta.mimeType) headers.set("Content-Type", props.meta.mimeType); if (props.meta.extension) headers.set("x-amz-meta-extension", props.meta.extension); const response = await client.sign(new Request(`${pluginOptions.endpoint}/${pluginOptions.bucket}/${props.key}`, { method: "PUT", body: props.data, headers })); const result = await fetch(response); if (!result.ok) return { error: { type: "plugin", message: translations_default("upload_failed", { status: result.status, statusText: result.statusText }) }, data: void 0 }; const etag = result.headers.get("etag")?.replace(/"/g, ""); return { error: void 0, data: { etag } }; } catch (e) { return { error: { type: "plugin", message: e instanceof Error ? e.message : translations_default("an_unknown_error_occurred") }, data: void 0 }; } }; return uploadSingle; }; //#endregion //#region src/constants.ts const PLUGIN_KEY = "plugin-s3"; const LUCID_VERSION = "0.x.x"; const PRESIGNED_URL_EXPIRY = 3600; //#endregion //#region src/services/get-presigned-url.ts var get_presigned_url_default = (client, pluginOptions) => { const getPresignedUrl = async (key, meta) => { try { const headers = new Headers(); if (meta.mimeType) headers.set("Content-Type", meta.mimeType); if (meta.extension) headers.set("x-amz-meta-extension", meta.extension); const response = await client.sign(new Request(`${pluginOptions.endpoint}/${pluginOptions.bucket}/${key}?X-Amz-Expires=${PRESIGNED_URL_EXPIRY}`, { method: "PUT" }), { headers, aws: { signQuery: true } }); return { error: void 0, data: { url: response.url.toString(), headers: Object.fromEntries(response.headers.entries()) } }; } catch (e) { return { error: { type: "plugin", message: e instanceof Error ? e.message : translations_default("an_unknown_error_occurred") }, data: void 0 }; } }; return getPresignedUrl; }; //#endregion //#region src/services/get-metadata.ts var get_metadata_default = (client, pluginOptions) => { const getMetadata = async (key) => { try { const response = await client.sign(new Request(`${pluginOptions.endpoint}/${pluginOptions.bucket}/${key}`, { method: "HEAD" })); const result = await fetch(response); if (!result.ok) return { error: { type: "plugin", message: translations_default("get_metadata_failed", { status: result.status, statusText: result.statusText }) }, data: void 0 }; const contentLength = result.headers.get("content-length"); if (!contentLength) return { error: { message: translations_default("object_missing_metadata") }, data: void 0 }; const contentType = result.headers.get("content-type"); const etag = result.headers.get("etag"); return { error: void 0, data: { size: Number.parseInt(contentLength, 10), mimeType: contentType || null, etag: etag || null } }; } catch (e) { return { error: { type: "plugin", message: e instanceof Error ? e.message : translations_default("an_unknown_error_occurred") }, data: void 0 }; } }; return getMetadata; }; //#endregion //#region src/plugin.ts const plugin = async (config, pluginOptions) => { const client = aws_client_default(pluginOptions); config.media = { ...config.media, strategy: { getPresignedUrl: get_presigned_url_default(client, pluginOptions), getMeta: get_metadata_default(client, pluginOptions), stream: steam_default(client, pluginOptions), uploadSingle: upload_single_default(client, pluginOptions), deleteSingle: delete_single_default(client, pluginOptions), deleteMultiple: delete_multiple_default(client, pluginOptions) } }; return { key: PLUGIN_KEY, lucid: LUCID_VERSION, config }; }; var plugin_default = plugin; //#endregion //#region src/index.ts const lucidS3Plugin = (pluginOptions) => (config) => plugin_default(config, pluginOptions); var src_default = lucidS3Plugin; //#endregion export { src_default as default }; //# sourceMappingURL=index.js.map