UNPKG

@scalar/nextjs-api-reference

Version:

a Next.js component to render API references from an OpenAPI file

227 lines (215 loc) 7.04 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const addIndent = (str, spaces = 2, initialIndent = false) => { const indent = " ".repeat(spaces); const lines = str.split("\n"); return lines.map((line, index) => { if (index === 0 && !initialIndent) { return line; } return `${indent}${line}`; }).join("\n"); }; const getStyles = (configuration, customTheme2) => { const styles = []; if (configuration.customCss) { styles.push("/* Custom CSS */"); styles.push(configuration.customCss); } if (!configuration.theme && customTheme2) { styles.push("/* Custom Theme */"); styles.push(customTheme2); } if (styles.length === 0) { return ""; } return ` <style type="text/css"> ${addIndent(styles.join("\n\n"), 6)} </style>`; }; const getHtmlDocument = (givenConfiguration, customTheme2 = "") => { const { cdn, pageTitle, customCss, theme, ...rest } = givenConfiguration; const configuration = getConfiguration({ ...rest, ...theme ? { theme } : {}, customCss }); const content = `<!doctype html> <html> <head> <title>${pageTitle ?? "Scalar API Reference"}</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" />${getStyles(configuration, customTheme2)} </head> <body> <div id="app"></div>${getScriptTags(configuration, cdn)} </body> </html>`; return content; }; function getScriptTags(configuration, cdn) { const restConfig = { ...configuration }; const functionProps = []; for (const [key, value] of Object.entries(configuration)) { if (typeof value === "function") { functionProps.push(`"${key}": ${value.toString()}`); delete restConfig[key]; } } const configString = JSON.stringify(restConfig, null, 2).split("\n").map((line, index) => index === 0 ? line : " " + line).join("\n").replace(/\s*}$/, ""); const functionPropsString = functionProps.length ? `, ${functionProps.join(",\n ")} }` : "}"; return ` <!-- Load the Script --> <script src="${cdn ?? "https://cdn.jsdelivr.net/npm/@scalar/api-reference"}"><\/script> <!-- Initialize the Scalar API Reference --> <script type="text/javascript"> Scalar.createApiReference('#app', ${configString}${functionPropsString}) <\/script>`; } const getConfiguration = (givenConfiguration) => { const configuration = { ...givenConfiguration }; if (typeof configuration.content === "function") { configuration.content = configuration.content(); } if (configuration.content && configuration.url) { delete configuration.content; } return configuration; }; const customTheme = ` /* basic theme */ .dark-mode { --scalar-color-1: rgba(255, 255, 255, 0.9); --scalar-color-2: rgba(255, 255, 255, 0.62); --scalar-color-3: rgba(255, 255, 255, 0.44); --scalar-color-accent: #3070ec; --scalar-background-1: #000000; --scalar-background-2: #1a1a1a; --scalar-background-3: #2a2828; --scalar-background-accent: transparent; --scalar-border-color: rgba(255, 255, 255, 0.1); } .light-mode .dark-mode, .light-mode { --scalar-color-1: #1b1b1b; --scalar-color-2: #757575; --scalar-color-3: #8e8e8e; --scalar-color-accent: #3070ec; --scalar-background-1: #fff; --scalar-background-2: #fafafa; --scalar-background-3: #e7e7e7; --scalar-background-accent: transparent; --scalar-border-color: rgba(0, 0, 0, 0.1); } .light-mode .scalar-card { --scalar-background-1: #fff; --scalar-background-2: #fff !important; --scalar-background-3: #fff !important; } .dark-mode .scalar-card { --scalar-background-1: #000000; --scalar-background-2: #000000 !important; --scalar-background-3: #000000 !important; } .light-mode .examples .scalar-card .scalar-card-header { --scalar-background-2: #fafafa; } .dark-mode .examples .scalar-card .scalar-card-header { --scalar-background-2: #1a1a1a; --scalar-border-color: #1a1a1a; } /* Document header */ .light-mode .t-doc__header, .dark-mode .t-doc__header { --scalar-header-background-1: rgba(255,255,255,.8); --scalar-header-border-color: var(--scalar-border-color); --scalar-header-color-1: var(--scalar-color-1); --scalar-header-color-2: var(--scalar-color-2); --scalar-header-background-toggle: var(--scalar-color-3); --scalar-header-call-to-action-color: var(--scalar-color-accent); backdrop-filter: saturate(180%) blur(5px); } .dark-mode .t-doc__header { --scalar-header-background-1: rgba(0,0,0,.5); } /* Document Sidebar */ .light-mode .t-doc__sidebar, .dark-mode .t-doc__sidebar { --scalar-sidebar-background-1: var(--scalar-background-1); --scalar-sidebar-item-hover-color: var(--scalar-sidebar-color-1); --scalar-sidebar-item-hover-background: transparent; --scalar-sidebar-item-active-background: var(--scalar-background-accent); --scalar-sidebar-border-color: transparent; --scalar-sidebar-color-1: var(--scalar-color-1); --scalar-sidebar-color-2: var(--scalar-color-2); --scalar-sidebar-color-active: var(--scalar-color-accent); --scalar-sidebar-search-background: var(--scalar-background-2); --scalar-sidebar-search-border-color: var(--scalar-background-2); --scalar-sidebar-search-color: var(--scalar-color-3); --scalar-sidebar-indent-border: var(--scalar-border-color); --scalar-sidebar-indent-border-active: #6aacf8; } .api-client-drawer .t-doc__sidebar { --scalar-sidebar-border-color: var(--scalar-border-color); } /* advanced */ .light-mode .dark-mode, .light-mode { --scalar-button-1: rgb(49 53 56); --scalar-button-1-color: #fff; --scalar-button-1-hover: rgb(28 31 33); --scalar-color-green: #417942; --scalar-color-red: #ae3763; --scalar-color-yellow: #edbe20; --scalar-color-blue: #2b66cf; --scalar-color-orange: #cf7a2b; --scalar-color-purple: #6e27b5; --scalar-scrollbar-color: rgba(0, 0, 0, 0.18); --scalar-scrollbar-color-active: rgba(0, 0, 0, 0.36); } .dark-mode { --scalar-button-1: #f6f6f6; --scalar-button-1-color: #000; --scalar-button-1-hover: #e7e7e7; --scalar-color-green: #7abe7b; --scalar-color-red: #e5698f; --scalar-color-yellow: #f8ea68; --scalar-color-blue: #68a6f8; --scalar-color-orange: #f89c68; --scalar-color-purple: #b57de9; --scalar-scrollbar-color: rgba(255, 255, 255, 0.24); --scalar-scrollbar-color-active: rgba(255, 255, 255, 0.48); } .sidebar .sidebar-indent-nested .sidebar-heading { padding-right: 0; } .sidebar-search-key { background: var(--scalar-background-1) !important; border: 1px solid var(--scalar-border-color); } `; const DEFAULT_CONFIGURATION = { _integration: "nextjs" }; const ApiReference = (givenConfiguration) => { const configuration = { ...DEFAULT_CONFIGURATION, ...givenConfiguration }; return async () => { return new Response(getHtmlDocument(configuration, customTheme), { status: 200, headers: { "Content-Type": "text/html" } }); }; }; exports.ApiReference = ApiReference;