UNPKG

@edge-store/react

Version:

Image Handling for React/Next.js

152 lines (151 loc) 5.97 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useEdgeStore = exports.EdgeStoreProvider = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const React = __importStar(require("react")); const EdgeStoreError_1 = __importDefault(require("./libs/errors/EdgeStoreError")); const EdgeStoreContext = React.createContext(undefined); const EdgeStoreProvider = ({ children, basePath }) => { const apiPath = basePath ? `${basePath}` : "/api/edgestore"; const [token, setToken] = React.useState(null); const [baseUrl, setBaseUrl] = React.useState(null); React.useEffect(() => { fetch(`${apiPath}/init`, { method: "POST", }).then((res) => { if (res.ok) { res.json().then((json) => { setToken(json.token); setBaseUrl(json.baseUrl); }); } }); }, []); const baseUploadImage = async (file, { path, name, overwrite, isPublic, onProgressChange, }) => { try { const res = await fetch(`${apiPath}/request-upload`, { method: "POST", body: JSON.stringify({ path, name, extension: file.name.split(".").pop(), size: file.size, overwrite, public: isPublic, }), headers: { "Content-Type": "application/json", }, }); const json = await res.json(); if (!json.signedUrl) { throw new EdgeStoreError_1.default("An error occurred"); } // Upload the file to the signed URL and get the progress await uploadFile(file, json.signedUrl, onProgressChange); return { url: `${baseUrl}${json.path}` }; } catch (e) { onProgressChange === null || onProgressChange === void 0 ? void 0 : onProgressChange(0); throw e; } finally { onProgressChange === null || onProgressChange === void 0 ? void 0 : onProgressChange(100); } }; const uploadImage = async (file, { path, name, overwrite, onProgressChange } = {}) => { return await baseUploadImage(file, { path, name, overwrite, isPublic: true, onProgressChange, }); }; const uploadProtectedImage = async (file, { path, name, overwrite, onProgressChange } = {}) => { return await baseUploadImage(file, { path, name, overwrite, isPublic: false, onProgressChange, }); }; const getImgSrc = (url) => { if (url.match(/^https?:\/\/[^\/]+\/[^\/]+\/_public\/.+/)) { return `${url}`; } else { return `${url}?token=${token}`; } }; return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(EdgeStoreContext.Provider, { value: { uploadImage, uploadProtectedImage, getImgSrc, }, children: children }) })); }; exports.EdgeStoreProvider = EdgeStoreProvider; const useEdgeStore = () => { if (!EdgeStoreContext) { throw new Error("React Context is unavailable in Server Components"); } // @ts-expect-error - We know that the context value should not be undefined const value = React.useContext(EdgeStoreContext); if (!value && process.env.NODE_ENV !== "production") { throw new Error("[edge-store]: `useEdgeStore` must be wrapped in a <EdgeStoreProvider />"); } return value; }; exports.useEdgeStore = useEdgeStore; const uploadFile = async (file, signedUrl, onProgressChange) => { const promise = new Promise((resolve, reject) => { const request = new XMLHttpRequest(); request.open("PUT", signedUrl); request.upload.addEventListener("progress", (e) => { if (e.lengthComputable) { onProgressChange === null || onProgressChange === void 0 ? void 0 : onProgressChange((e.loaded / e.total) * 100); } }); request.addEventListener("load", () => { onProgressChange === null || onProgressChange === void 0 ? void 0 : onProgressChange(100); }); request.addEventListener("error", () => { reject(new Error("Error uploading file")); }); request.addEventListener("abort", () => { reject(new Error("File upload aborted")); }); request.addEventListener("loadend", () => { resolve(); }); request.send(file); }); return promise; };