UNPKG

@inlang/paraglide-js

Version:

[![NPM Downloads](https://img.shields.io/npm/dw/%40inlang%2Fparaglide-js?logo=npm&logoColor=red&label=npm%20downloads)](https://www.npmjs.com/package/@inlang/paraglide-js) [![GitHub Issues](https://img.shields.io/github/issues-closed/opral/paraglide-js?lo

141 lines (121 loc) 6.93 kB
import fs from "node:fs"; /** * Returns the code for the `runtime.js` module */ export function createRuntimeFile(args) { const urlPatterns = args.compilerOptions.urlPatterns ?? []; const routeStrategies = args.compilerOptions.routeStrategies ?? []; let defaultUrlPatternUsed = false; // add default urlPatterns for a good out of the box experience if (args.compilerOptions.urlPatterns === undefined) { defaultUrlPatternUsed = true; urlPatterns.push({ pattern: `:protocol://:domain(.*)::port?/:path(.*)?`, localized: [], }); for (const locale of args.locales) { if (locale === args.baseLocale) { continue; } urlPatterns[0]?.localized.push([ locale, `:protocol://:domain(.*)::port?/${locale}/:path(.*)?`, ]); } urlPatterns[0]?.localized.push([ args.baseLocale, `:protocol://:domain(.*)::port?/:path(.*)?`, ]); } const strategiesUsedByRoutes = routeStrategies.flatMap((routeStrategy) => "strategy" in routeStrategy ? routeStrategy.strategy : []); const allUsedStrategies = new Set([ ...args.compilerOptions.strategy, ...strategiesUsedByRoutes, ]); const needsUrlPatternPolyfill = !defaultUrlPatternUsed || routeStrategies.length > 0; // verify that urlPatterns' locales are valid for (const urlPattern of urlPatterns) { for (const [locale] of urlPattern.localized) { if (!args.locales.includes(locale)) { throw new Error(`Invalid locale "${locale}" in urlPatterns. It must be one of the locales defined in the "locales" array.`); } } } const code = ` ${needsUrlPatternPolyfill ? `import "@inlang/paraglide-js/urlpattern-polyfill";` : "/** @type {any} */\nconst URLPattern = {}"} ${injectCode("./variables.js") .replace(`export const baseLocale = "en";`, `export const baseLocale = "${args.baseLocale}";`) .replace(`export const locales = /** @type {readonly string[]} */ (["en", "de"]);`, `export const locales = /** @type {const} */ (${JSON.stringify(args.locales)});`) .replace(`export const strategy = ["globalVariable"];`, `export const strategy = ${JSON.stringify(args.compilerOptions.strategy, null, 2)};`) .replace(`<cookie-name>`, `${args.compilerOptions.cookieName}`) .replace(`60 * 60 * 24 * 400`, `${args.compilerOptions.cookieMaxAge}`) .replace(`<cookie-domain>`, `${args.compilerOptions.cookieDomain}`) .replace(`export const routeStrategies = [];`, `export const routeStrategies = ${JSON.stringify(routeStrategies, null, 2)};`) .replace(`export const TREE_SHAKE_COOKIE_STRATEGY_USED = false;`, `const TREE_SHAKE_COOKIE_STRATEGY_USED = ${allUsedStrategies.has("cookie")};`) .replace(`export const TREE_SHAKE_URL_STRATEGY_USED = false;`, `const TREE_SHAKE_URL_STRATEGY_USED = ${allUsedStrategies.has("url")};`) .replace(`export const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = false;`, `const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = ${allUsedStrategies.has("globalVariable")};`) .replace(`export const TREE_SHAKE_PREFERRED_LANGUAGE_STRATEGY_USED = false;`, `const TREE_SHAKE_PREFERRED_LANGUAGE_STRATEGY_USED = ${allUsedStrategies.has("preferredLanguage")};`) .replace(`export const urlPatterns = [];`, `export const urlPatterns = ${JSON.stringify(urlPatterns, null, 2)};`) .replace(`export const disableAsyncLocalStorage = false;`, `export const disableAsyncLocalStorage = ${args.compilerOptions.disableAsyncLocalStorage};`) .replace(`export const TREE_SHAKE_DEFAULT_URL_PATTERN_USED = false;`, `const TREE_SHAKE_DEFAULT_URL_PATTERN_USED = ${defaultUrlPatternUsed};`) .replace(`export const experimentalMiddlewareLocaleSplitting = false;`, `export const experimentalMiddlewareLocaleSplitting = ${args.compilerOptions.experimentalMiddlewareLocaleSplitting};`) .replace(`export const isServer = typeof window === "undefined";`, `export const isServer = ${args.compilerOptions.isServer};`) .replace(`export const experimentalStaticLocale = undefined;`, args.compilerOptions.experimentalStaticLocale ? `export const experimentalStaticLocale = assertIsLocale(${args.compilerOptions.experimentalStaticLocale});` : `export const experimentalStaticLocale = undefined;`) .replace(`export const localStorageKey = "PARAGLIDE_LOCALE";`, `export const localStorageKey = "${args.compilerOptions.localStorageKey}";`) .replace(`export const TREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED = false;`, `const TREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED = ${allUsedStrategies.has("localStorage")};`)} /** @type {any} */ (globalThis).__paraglide = /** @type {any} */ (globalThis).__paraglide ?? {}; /** @type {any} */ (globalThis).__paraglide.ssr = /** @type {any} */ (globalThis).__paraglide.ssr ?? {}; ${injectCode("./get-locale.js")} ${injectCode("./get-text-direction.js")} ${injectCode("./set-locale.js")} ${injectCode("./get-url-origin.js")} ${injectCode("./check-locale.js")} ${injectCode("./extract-locale-from-request.js")} ${injectCode("./extract-locale-from-request-async.js")} ${injectCode("./extract-locale-from-cookie.js", { privateExports: ["clearLocaleCookieCache"], })} ${injectCode("./extract-locale-from-header.js")} ${injectCode("./extract-locale-from-navigator.js")} ${injectCode("./extract-locale-from-url.js")} ${injectCode("./localize-url.js")} ${injectCode("./should-redirect.js")} ${injectCode("./localize-href.js")} ${injectCode("./track-message-call.js")} ${injectCode("./generate-static-localized-urls.js")} ${injectCode("./strategy.js")} ${injectCode("./type-definitions.js").replace(`@typedef {string} Locale`, `@typedef {typeof locales[number]} Locale`)} `; return code; } /** * Load a file from the current directory. * * Prunes the imports on top of the file as the runtime is * self-contained. * * @param {string} path * @param {{ privateExports?: string[] }} [options] * @returns {string} */ function injectCode(path, options) { const code = fs.readFileSync(new URL(path, import.meta.url), "utf-8"); // Regex to match single-line and multi-line imports const importRegex = /import\s+[\s\S]*?from\s+['"][^'"]+['"]\s*;?/g; const sourceMapRegex = /\/\/# sourceMappingURL=.*$/gm; const blockSourceMapRegex = /\/\*# sourceMappingURL=.*?\*\//g; let injected = code .replace(importRegex, "") .replace(sourceMapRegex, "") .replace(blockSourceMapRegex, "") .trim(); for (const exportName of options?.privateExports ?? []) { injected = injected.replace(new RegExp(`\\bexport\\s+function\\s+${exportName}\\b`, "g"), `function ${exportName}`); } return injected; } //# sourceMappingURL=create-runtime.js.map