import require$$0 from 'url'; import nodePath from 'node:path'; import React, { createElement } from 'react'; import ReactDOM from 'react-dom/server'; function normalizeLF(code) { return code.replace(/\r\n|\r(?!\n)|\n/g, "\n"); } function codeFrame(src, loc) { if (!loc || loc.line === void 0 || loc.column === void 0) { return ""; } const lines = normalizeLF(src).split("\n").map((ln) => ln.replace(/\t/g, " ")); const visibleLines = []; for (let n = -2; n <= 2; n++) { if (lines[loc.line + n]) visibleLines.push(loc.line + n); } let gutterWidth = 0; for (const lineNo of visibleLines) { let w = `> ${lineNo}`; if (w.length > gutterWidth) gutterWidth = w.length; } let output = ""; for (const lineNo of visibleLines) { const isFocusedLine = lineNo === loc.line - 1; output += isFocusedLine ? "> " : " "; output += `${lineNo + 1} | ${lines[lineNo]} `; if (isFocusedLine) output += `${Array.from({ length: gutterWidth }).join(" ")} | ${Array.from({ length: loc.column }).join(" ")}^ `; } return output; } class AstroError extends Error { loc; title; hint; frame; type = "AstroError"; constructor(props, options) { const { name, title, message, stack, location, hint, frame } = props; super(message, options); this.title = title; this.name = name; if (message) this.message = message; this.stack = stack ? stack : this.stack; this.loc = location; this.hint = hint; this.frame = frame; } setLocation(location) { this.loc = location; } setName(name) { this.name = name; } setMessage(message) { this.message = message; } setHint(hint) { this.hint = hint; } setFrame(source, location) { this.frame = codeFrame(source, location); } static is(err) { return err?.type === "AstroError"; } } const ClientAddressNotAvailable = { name: "ClientAddressNotAvailable", title: "`Astro.clientAddress` is not available in current adapter.", message: (adapterName) => `\`Astro.clientAddress\` is not available in the \`${adapterName}\` adapter. File an issue with the adapter to add support.` }; const PrerenderClientAddressNotAvailable = { name: "PrerenderClientAddressNotAvailable", title: "`Astro.clientAddress` cannot be used inside prerendered routes.", message: (name) => `\`Astro.clientAddress\` cannot be used inside prerendered route ${name}` }; const StaticClientAddressNotAvailable = { name: "StaticClientAddressNotAvailable", title: "`Astro.clientAddress` is not available in prerendered pages.", message: "`Astro.clientAddress` is only available on pages that are server-rendered.", hint: "See https://docs.astro.build/en/guides/on-demand-rendering/ for more information on how to enable SSR." }; const NoMatchingStaticPathFound = { name: "NoMatchingStaticPathFound", title: "No static path found for requested path.", message: (pathName) => `A \`getStaticPaths()\` route pattern was matched, but no matching static path was found for requested path \`${pathName}\`.`, hint: (possibleRoutes) => `Possible dynamic routes being matched: ${possibleRoutes.join(", ")}.` }; const OnlyResponseCanBeReturned = { name: "OnlyResponseCanBeReturned", title: "Invalid type returned by Astro page.", message: (route, returnedValue) => `Route \`${route ? route : ""}\` returned a \`${returnedValue}\`. Only a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) can be returned from Astro files.`, hint: "See https://docs.astro.build/en/guides/on-demand-rendering/#response for more information." }; const MissingMediaQueryDirective = { name: "MissingMediaQueryDirective", title: "Missing value for `client:media` directive.", message: 'Media query not provided for `client:media` directive. A media query similar to `client:media="(max-width: 600px)"` must be provided' }; const NoMatchingRenderer = { name: "NoMatchingRenderer", title: "No matching renderer found.", message: (componentName, componentExtension, plural, validRenderersCount) => `Unable to render \`${componentName}\`. ${validRenderersCount > 0 ? `There ${plural ? "are" : "is"} ${validRenderersCount} renderer${plural ? "s" : ""} configured in your \`astro.config.mjs\` file, but ${plural ? "none were" : "it was not"} able to server-side render \`${componentName}\`.` : `No valid renderer was found ${componentExtension ? `for the \`.${componentExtension}\` file extension.` : `for this file extension.`}`}`, hint: (probableRenderers) => `Did you mean to enable the ${probableRenderers} integration? See https://docs.astro.build/en/guides/framework-components/ for more information on how to install and configure integrations.` }; const NoClientOnlyHint = { name: "NoClientOnlyHint", title: "Missing hint on client:only directive.", message: (componentName) => `Unable to render \`${componentName}\`. When using the \`client:only\` hydration strategy, Astro needs a hint to use the correct renderer.`, hint: (probableRenderers) => `Did you mean to pass \`client:only="${probableRenderers}"\`? See https://docs.astro.build/en/reference/directives-reference/#clientonly for more information on client:only` }; const InvalidGetStaticPathsEntry = { name: "InvalidGetStaticPathsEntry", title: "Invalid entry inside getStaticPath's return value", message: (entryType) => `Invalid entry returned by getStaticPaths. Expected an object, got \`${entryType}\``, hint: "If you're using a `.map` call, you might be looking for `.flatMap()` instead. See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." }; const InvalidGetStaticPathsReturn = { name: "InvalidGetStaticPathsReturn", title: "Invalid value returned by getStaticPaths.", message: (returnType) => `Invalid type returned by \`getStaticPaths\`. Expected an \`array\`, got \`${returnType}\``, hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." }; const GetStaticPathsExpectedParams = { name: "GetStaticPathsExpectedParams", title: "Missing params property on `getStaticPaths` route.", message: "Missing or empty required `params` property on `getStaticPaths` route.", hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." }; const GetStaticPathsInvalidRouteParam = { name: "GetStaticPathsInvalidRouteParam", title: "Invalid route parameter returned by `getStaticPaths()`.", message: (key, value, valueType) => `Invalid \`getStaticPaths()\` route parameter for \`${key}\`. Expected a string or undefined, received \`${valueType}\` (\`${value}\`)`, hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." }; const GetStaticPathsRequired = { name: "GetStaticPathsRequired", title: "`getStaticPaths()` function required for dynamic routes.", message: "`getStaticPaths()` function is required for dynamic routes. Make sure that you `export` a `getStaticPaths` function from your dynamic route.", hint: `See https://docs.astro.build/en/guides/routing/#dynamic-routes for more information on dynamic routes. If you meant for this route to be server-rendered, set \`export const prerender = false;\` in the page.` }; const ReservedSlotName = { name: "ReservedSlotName", title: "Invalid slot name.", message: (slotName) => `Unable to create a slot named \`${slotName}\`. \`${slotName}\` is a reserved slot name. Please update the name of this slot.` }; const NoMatchingImport = { name: "NoMatchingImport", title: "No import found for component.", message: (componentName) => `Could not render \`${componentName}\`. No matching import has been found for \`${componentName}\`.`, hint: "Please make sure the component is properly imported." }; const InvalidComponentArgs = { name: "InvalidComponentArgs", title: "Invalid component arguments.", message: (name) => `Invalid arguments passed to${name ? ` <${name}>` : ""} component.`, hint: "Astro components cannot be rendered directly via function call, such as `Component()` or `{items.map(Component)}`." }; const PageNumberParamNotFound = { name: "PageNumberParamNotFound", title: "Page number param not found.", message: (paramName) => `[paginate()] page number param \`${paramName}\` not found in your filepath.`, hint: "Rename your file to `[page].astro` or `[...page].astro`." }; const ImageMissingAlt = { name: "ImageMissingAlt", title: 'Image missing required "alt" property.', message: 'Image missing "alt" property. "alt" text is required to describe important images on the page.', hint: 'Use an empty string ("") for decorative images.' }; const InvalidImageService = { name: "InvalidImageService", title: "Error while loading image service.", message: "There was an error loading the configured image service. Please see the stack trace for more information." }; const MissingImageDimension = { name: "MissingImageDimension", title: "Missing image dimensions", message: (missingDimension, imageURL) => `Missing ${missingDimension === "both" ? "width and height attributes" : `${missingDimension} attribute`} for ${imageURL}. When using remote images, both dimensions are required in order to avoid CLS.`, hint: "If your image is inside your `src` folder, you probably meant to import it instead. See [the Imports guide for more information](https://docs.astro.build/en/guides/imports/#other-assets). You can also use `inferSize={true}` for remote images to get the original dimensions." }; const FailedToFetchRemoteImageDimensions = { name: "FailedToFetchRemoteImageDimensions", title: "Failed to retrieve remote image dimensions", message: (imageURL) => `Failed to get the dimensions for ${imageURL}.`, hint: "Verify your remote image URL is accurate, and that you are not using `inferSize` with a file located in your `public/` folder." }; const RemoteImageNotAllowed = { name: "RemoteImageNotAllowed", title: "Remote image is not allowed", message: (imageURL) => `Remote image ${imageURL} is not allowed by your image configuration.`, hint: "Update `image.domains` or `image.remotePatterns`, or remove `inferSize` for this image." }; const UnsupportedImageFormat = { name: "UnsupportedImageFormat", title: "Unsupported image format", message: (format, imagePath, supportedFormats) => `Received unsupported format \`${format}\` from \`${imagePath}\`. Currently only ${supportedFormats.join( ", " )} are supported by our image services.`, hint: "Using an `img` tag directly instead of the `Image` component might be what you're looking for." }; const UnsupportedImageConversion = { name: "UnsupportedImageConversion", title: "Unsupported image conversion", message: "Converting between vector (such as SVGs) and raster (such as PNGs and JPEGs) images is not currently supported." }; const PrerenderDynamicEndpointPathCollide = { name: "PrerenderDynamicEndpointPathCollide", title: "Prerendered dynamic endpoint has path collision.", message: (pathname) => `Could not render \`${pathname}\` with an \`undefined\` param as the generated path will collide during prerendering. Prevent passing \`undefined\` as \`params\` for the endpoint's \`getStaticPaths()\` function, or add an additional extension to the endpoint's filename.`, hint: (filename) => `Rename \`${filename}\` to \`${filename.replace(/\.(?:js|ts)/, (m) => `.json` + m)}\`` }; const ExpectedImage = { name: "ExpectedImage", title: "Expected src to be an image.", message: (src, typeofOptions, fullOptions) => `Expected \`src\` property for \`getImage\` or \`\` to be either an ESM imported image or a string with the path of a remote image. Received \`${src}\` (type: \`${typeofOptions}\`). Full serialized options received: \`${fullOptions}\`.`, hint: "This error can often happen because of a wrong path. Make sure the path to your image is correct. If you're passing an async function, make sure to call and await it." }; const ExpectedImageOptions = { name: "ExpectedImageOptions", title: "Expected image options.", message: (options) => `Expected getImage() parameter to be an object. Received \`${options}\`.` }; const ExpectedNotESMImage = { name: "ExpectedNotESMImage", title: "Expected image options, not an ESM-imported image.", message: "An ESM-imported image cannot be passed directly to `getImage()`. Instead, pass an object with the image in the `src` property.", hint: "Try changing `getImage(myImage)` to `getImage({ src: myImage })`" }; const IncompatibleDescriptorOptions = { name: "IncompatibleDescriptorOptions", title: "Cannot set both `densities` and `widths`", message: "Only one of `densities` or `widths` can be specified. In most cases, you'll probably want to use only `widths` if you require specific widths.", hint: "Those attributes are used to construct a `srcset` attribute, which cannot have both `x` and `w` descriptors." }; const NoImageMetadata = { name: "NoImageMetadata", title: "Could not process image metadata.", message: (imagePath) => `Could not process image metadata${imagePath ? ` for \`${imagePath}\`` : ""}.`, hint: "This is often caused by a corrupted or malformed image. Re-exporting the image from your image editor may fix this issue." }; const ResponseSentError = { name: "ResponseSentError", title: "Unable to set response.", message: "The response has already been sent to the browser and cannot be altered." }; const MiddlewareNoDataOrNextCalled = { name: "MiddlewareNoDataOrNextCalled", title: "The middleware didn't return a `Response`.", message: "Make sure your middleware returns a `Response` object, either directly or by returning the `Response` from calling the `next` function." }; const MiddlewareNotAResponse = { name: "MiddlewareNotAResponse", title: "The middleware returned something that is not a `Response` object.", message: "Any data returned from middleware must be a valid `Response` object." }; const EndpointDidNotReturnAResponse = { name: "EndpointDidNotReturnAResponse", title: "The endpoint did not return a `Response`.", message: "An endpoint must return either a `Response`, or a `Promise` that resolves with a `Response`." }; const LocalsNotAnObject = { name: "LocalsNotAnObject", title: "Value assigned to `locals` is not accepted.", message: "`locals` can only be assigned to an object. Other values like numbers, strings, etc. are not accepted.", hint: "If you tried to remove some information from the `locals` object, try to use `delete` or set the property to `undefined`." }; const LocalsReassigned = { name: "LocalsReassigned", title: "`locals` must not be reassigned.", message: "`locals` cannot be assigned directly.", hint: "Set a `locals` property instead." }; const AstroResponseHeadersReassigned = { name: "AstroResponseHeadersReassigned", title: "`Astro.response.headers` must not be reassigned.", message: "Individual headers can be added to and removed from `Astro.response.headers`, but it must not be replaced with another instance of `Headers` altogether.", hint: "Consider using `Astro.response.headers.add()`, and `Astro.response.headers.delete()`." }; const LocalImageUsedWrongly = { name: "LocalImageUsedWrongly", title: "Local images must be imported.", message: (imageFilePath) => `\`Image\`'s and \`getImage\`'s \`src\` parameter must be an imported image or an URL, it cannot be a string filepath. Received \`${imageFilePath}\`.`, hint: "If you want to use an image from your `src` folder, you need to either import it or if the image is coming from a content collection, use the [image() schema helper](https://docs.astro.build/en/guides/images/#images-in-content-collections). See https://docs.astro.build/en/guides/images/#src-required for more information on the `src` property." }; const MissingSharp = { name: "MissingSharp", title: "Could not find Sharp.", message: "Could not find Sharp. Please install Sharp (`sharp`) manually into your project or migrate to another image service.", hint: "See Sharp's installation instructions for more information: https://sharp.pixelplumbing.com/install. If you are not relying on `astro:assets` to optimize, transform, or process any images, you can configure a passthrough image service instead of installing Sharp. See https://docs.astro.build/en/reference/errors/missing-sharp for more information.\n\nSee https://docs.astro.build/en/guides/images/#default-image-service for more information on how to migrate to another image service." }; const i18nNoLocaleFoundInPath = { name: "i18nNoLocaleFoundInPath", title: "The path doesn't contain any locale", message: "You tried to use an i18n utility on a path that doesn't contain any locale. You can use `pathHasLocale` first to determine if the path has a locale." }; const RewriteWithBodyUsed = { name: "RewriteWithBodyUsed", title: "Cannot use Astro.rewrite after the request body has been read", message: "Astro.rewrite() cannot be used if the request body has already been read. If you need to read the body, first clone the request." }; const ForbiddenRewrite = { name: "ForbiddenRewrite", title: "Forbidden rewrite to a static route.", message: (from, to, component) => `You tried to rewrite the on-demand route '${from}' with the static route '${to}', when using the 'server' output. The static route '${to}' is rendered by the component '${component}', which is marked as prerendered. This is a forbidden operation because during the build, the component '${component}' is compiled to an HTML file, which can't be retrieved at runtime by Astro.`, hint: (component) => `Add \`export const prerender = false\` to the component '${component}', or use a Astro.redirect().` }; const FontFamilyNotFound = { name: "FontFamilyNotFound", title: "Font family not found", message: (family) => `No data was found for the \`"${family}"\` family passed to the \`\` component.`, hint: "This is often caused by a typo. Check that the `` component is using a `cssVariable` specified in your config." }; const ActionsReturnedInvalidDataError = { name: "ActionsReturnedInvalidDataError", title: "Action handler returned invalid data.", message: (error) => `Action handler returned invalid data. Handlers should return serializable data types like objects, arrays, strings, and numbers. Parse error: ${error}`, hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue" }; const ActionNotFoundError = { name: "ActionNotFoundError", title: "Action not found.", message: (actionName) => `The server received a request for an action named \`${actionName}\` but could not find a match. If you renamed an action, check that you've updated your \`actions/index\` file and your calling code to match.`, hint: "You can run `astro check` to detect type errors caused by mismatched action names." }; const SessionStorageInitError = { name: "SessionStorageInitError", title: "Session storage could not be initialized.", message: (error, driver) => `Error when initializing session storage${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``, hint: "For more information, see https://docs.astro.build/en/guides/sessions/" }; const SessionStorageSaveError = { name: "SessionStorageSaveError", title: "Session data could not be saved.", message: (error, driver) => `Error when saving session data${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``, hint: "For more information, see https://docs.astro.build/en/guides/sessions/" }; const CacheNotEnabled = { name: "CacheNotEnabled", title: "Cache is not enabled.", message: "`Astro.cache` is not available because the cache feature is not enabled. To use caching, configure a cache provider in your Astro config under `experimental.cache`.", hint: 'Use an adapter that provides a default cache provider, or set one explicitly: `experimental: { cache: { provider: "..." } }`. See https://docs.astro.build/en/reference/experimental-flags/route-caching/.' }; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function getAugmentedNamespace(n) { if (Object.prototype.hasOwnProperty.call(n, '__esModule')) return n; var f = n.default; if (typeof f == "function") { var a = function a () { var isInstance = false; try { isInstance = this instanceof a; } catch {} if (isInstance) { return Reflect.construct(f, arguments, this.constructor); } return f.apply(this, arguments); }; a.prototype = f.prototype; } else a = {}; Object.defineProperty(a, '__esModule', {value: true}); Object.keys(n).forEach(function (k) { var d = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d.get ? d : { enumerable: true, get: function () { return n[k]; } }); }); return a; } var dist$1 = {exports: {}}; /** * Tokenize input string. */ function lexer$1(str) { var tokens = []; var i = 0; while (i < str.length) { var char = str[i]; if (char === "*" || char === "+" || char === "?") { tokens.push({ type: "MODIFIER", index: i, value: str[i++] }); continue; } if (char === "\\") { tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] }); continue; } if (char === "{") { tokens.push({ type: "OPEN", index: i, value: str[i++] }); continue; } if (char === "}") { tokens.push({ type: "CLOSE", index: i, value: str[i++] }); continue; } if (char === ":") { var name = ""; var j = i + 1; while (j < str.length) { var code = str.charCodeAt(j); if ( // `0-9` (code >= 48 && code <= 57) || // `A-Z` (code >= 65 && code <= 90) || // `a-z` (code >= 97 && code <= 122) || // `_` code === 95) { name += str[j++]; continue; } break; } if (!name) throw new TypeError("Missing parameter name at " + i); tokens.push({ type: "NAME", index: i, value: name }); i = j; continue; } if (char === "(") { var count = 1; var pattern = ""; var j = i + 1; if (str[j] === "?") { throw new TypeError("Pattern cannot start with \"?\" at " + j); } while (j < str.length) { if (str[j] === "\\") { pattern += str[j++] + str[j++]; continue; } if (str[j] === ")") { count--; if (count === 0) { j++; break; } } else if (str[j] === "(") { count++; if (str[j + 1] !== "?") { throw new TypeError("Capturing groups are not allowed at " + j); } } pattern += str[j++]; } if (count) throw new TypeError("Unbalanced pattern at " + i); if (!pattern) throw new TypeError("Missing pattern at " + i); tokens.push({ type: "PATTERN", index: i, value: pattern }); i = j; continue; } tokens.push({ type: "CHAR", index: i, value: str[i++] }); } tokens.push({ type: "END", index: i, value: "" }); return tokens; } /** * Parse a string for the raw tokens. */ function parse$3(str, options) { if (options === void 0) { options = {}; } var tokens = lexer$1(str); var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a; var defaultPattern = "[^" + escapeString$1(options.delimiter || "/#?") + "]+?"; var result = []; var key = 0; var i = 0; var path = ""; var tryConsume = function (type) { if (i < tokens.length && tokens[i].type === type) return tokens[i++].value; }; var mustConsume = function (type) { var value = tryConsume(type); if (value !== undefined) return value; var _a = tokens[i], nextType = _a.type, index = _a.index; throw new TypeError("Unexpected " + nextType + " at " + index + ", expected " + type); }; var consumeText = function () { var result = ""; var value; // tslint:disable-next-line while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) { result += value; } return result; }; while (i < tokens.length) { var char = tryConsume("CHAR"); var name = tryConsume("NAME"); var pattern = tryConsume("PATTERN"); if (name || pattern) { var prefix = char || ""; if (prefixes.indexOf(prefix) === -1) { path += prefix; prefix = ""; } if (path) { result.push(path); path = ""; } result.push({ name: name || key++, prefix: prefix, suffix: "", pattern: pattern || defaultPattern, modifier: tryConsume("MODIFIER") || "" }); continue; } var value = char || tryConsume("ESCAPED_CHAR"); if (value) { path += value; continue; } if (path) { result.push(path); path = ""; } var open = tryConsume("OPEN"); if (open) { var prefix = consumeText(); var name_1 = tryConsume("NAME") || ""; var pattern_1 = tryConsume("PATTERN") || ""; var suffix = consumeText(); mustConsume("CLOSE"); result.push({ name: name_1 || (pattern_1 ? key++ : ""), pattern: name_1 && !pattern_1 ? defaultPattern : pattern_1, prefix: prefix, suffix: suffix, modifier: tryConsume("MODIFIER") || "" }); continue; } mustConsume("END"); } return result; } /** * Compile a string to a template function for the path. */ function compile$1(str, options) { return tokensToFunction$1(parse$3(str, options), options); } /** * Expose a method for transforming tokens into the path function. */ function tokensToFunction$1(tokens, options) { if (options === void 0) { options = {}; } var reFlags = flags$1(options); var _a = options.encode, encode = _a === void 0 ? function (x) { return x; } : _a, _b = options.validate, validate = _b === void 0 ? true : _b; // Compile all the tokens into regexps. var matches = tokens.map(function (token) { if (typeof token === "object") { return new RegExp("^(?:" + token.pattern + ")$", reFlags); } }); return function (data) { var path = ""; for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; if (typeof token === "string") { path += token; continue; } var value = data ? data[token.name] : undefined; var optional = token.modifier === "?" || token.modifier === "*"; var repeat = token.modifier === "*" || token.modifier === "+"; if (Array.isArray(value)) { if (!repeat) { throw new TypeError("Expected \"" + token.name + "\" to not repeat, but got an array"); } if (value.length === 0) { if (optional) continue; throw new TypeError("Expected \"" + token.name + "\" to not be empty"); } for (var j = 0; j < value.length; j++) { var segment = encode(value[j], token); if (validate && !matches[i].test(segment)) { throw new TypeError("Expected all \"" + token.name + "\" to match \"" + token.pattern + "\", but got \"" + segment + "\""); } path += token.prefix + segment + token.suffix; } continue; } if (typeof value === "string" || typeof value === "number") { var segment = encode(String(value), token); if (validate && !matches[i].test(segment)) { throw new TypeError("Expected \"" + token.name + "\" to match \"" + token.pattern + "\", but got \"" + segment + "\""); } path += token.prefix + segment + token.suffix; continue; } if (optional) continue; var typeOfMessage = repeat ? "an array" : "a string"; throw new TypeError("Expected \"" + token.name + "\" to be " + typeOfMessage); } return path; }; } /** * Create path match function from `path-to-regexp` spec. */ function match$1(str, options) { var keys = []; var re = pathToRegexp$1(str, keys, options); return regexpToFunction$1(re, keys, options); } /** * Create a path match function from `path-to-regexp` output. */ function regexpToFunction$1(re, keys, options) { if (options === void 0) { options = {}; } var _a = options.decode, decode = _a === void 0 ? function (x) { return x; } : _a; return function (pathname) { var m = re.exec(pathname); if (!m) return false; var path = m[0], index = m.index; var params = Object.create(null); var _loop_1 = function (i) { // tslint:disable-next-line if (m[i] === undefined) return "continue"; var key = keys[i - 1]; if (key.modifier === "*" || key.modifier === "+") { params[key.name] = m[i].split(key.prefix + key.suffix).map(function (value) { return decode(value, key); }); } else { params[key.name] = decode(m[i], key); } }; for (var i = 1; i < m.length; i++) { _loop_1(i); } return { path: path, index: index, params: params }; }; } /** * Escape a regular expression string. */ function escapeString$1(str) { return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1"); } /** * Get the flags for a regexp from the options. */ function flags$1(options) { return options && options.sensitive ? "" : "i"; } /** * Pull out keys from a regexp. */ function regexpToRegexp$1(path, keys) { if (!keys) return path; // Use a negative lookahead to match only capturing groups. var groups = path.source.match(/\((?!\?)/g); if (groups) { for (var i = 0; i < groups.length; i++) { keys.push({ name: i, prefix: "", suffix: "", modifier: "", pattern: "" }); } } return path; } /** * Transform an array into a regexp. */ function arrayToRegexp$1(paths, keys, options) { var parts = paths.map(function (path) { return pathToRegexp$1(path, keys, options).source; }); return new RegExp("(?:" + parts.join("|") + ")", flags$1(options)); } /** * Create a path regexp from string input. */ function stringToRegexp$1(path, keys, options) { return tokensToRegexp$1(parse$3(path, options), keys, options); } /** * Expose a function for taking tokens and returning a RegExp. */ function tokensToRegexp$1(tokens, keys, options) { if (options === void 0) { options = {}; } var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function (x) { return x; } : _d; var endsWith = "[" + escapeString$1(options.endsWith || "") + "]|$"; var delimiter = "[" + escapeString$1(options.delimiter || "/#?") + "]"; var route = start ? "^" : ""; // Iterate over the tokens and create our regexp string. for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) { var token = tokens_1[_i]; if (typeof token === "string") { route += escapeString$1(encode(token)); } else { var prefix = escapeString$1(encode(token.prefix)); var suffix = escapeString$1(encode(token.suffix)); if (token.pattern) { if (keys) keys.push(token); if (prefix || suffix) { if (token.modifier === "+" || token.modifier === "*") { var mod = token.modifier === "*" ? "?" : ""; route += "(?:" + prefix + "((?:" + token.pattern + ")(?:" + suffix + prefix + "(?:" + token.pattern + "))*)" + suffix + ")" + mod; } else { route += "(?:" + prefix + "(" + token.pattern + ")" + suffix + ")" + token.modifier; } } else { route += "(" + token.pattern + ")" + token.modifier; } } else { route += "(?:" + prefix + suffix + ")" + token.modifier; } } } if (end) { if (!strict) route += delimiter + "?"; route += !options.endsWith ? "$" : "(?=" + endsWith + ")"; } else { var endToken = tokens[tokens.length - 1]; var isEndDelimited = typeof endToken === "string" ? delimiter.indexOf(endToken[endToken.length - 1]) > -1 : // tslint:disable-next-line endToken === undefined; if (!strict) { route += "(?:" + delimiter + "(?=" + endsWith + "))?"; } if (!isEndDelimited) { route += "(?=" + delimiter + "|" + endsWith + ")"; } } return new RegExp(route, flags$1(options)); } /** * Normalize the given path string, returning a regular expression. * * An empty array can be passed in for the keys, which will hold the * placeholder key descriptions. For example, using `/user/:id`, `keys` will * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. */ function pathToRegexp$1(path, keys, options) { if (path instanceof RegExp) return regexpToRegexp$1(path, keys); if (Array.isArray(path)) return arrayToRegexp$1(path, keys, options); return stringToRegexp$1(path, keys, options); } const dist_es2015$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ __proto__: null, compile: compile$1, match: match$1, parse: parse$3, pathToRegexp: pathToRegexp$1, regexpToFunction: regexpToFunction$1, tokensToFunction: tokensToFunction$1, tokensToRegexp: tokensToRegexp$1 }, Symbol.toStringTag, { value: 'Module' })); const require$$1 = /*@__PURE__*/getAugmentedNamespace(dist_es2015$1); /** * Tokenize input string. */ function lexer(str) { var tokens = []; var i = 0; while (i < str.length) { var char = str[i]; if (char === "*" || char === "+" || char === "?") { tokens.push({ type: "MODIFIER", index: i, value: str[i++] }); continue; } if (char === "\\") { tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] }); continue; } if (char === "{") { tokens.push({ type: "OPEN", index: i, value: str[i++] }); continue; } if (char === "}") { tokens.push({ type: "CLOSE", index: i, value: str[i++] }); continue; } if (char === ":") { var name = ""; var j = i + 1; while (j < str.length) { var code = str.charCodeAt(j); if ( // `0-9` (code >= 48 && code <= 57) || // `A-Z` (code >= 65 && code <= 90) || // `a-z` (code >= 97 && code <= 122) || // `_` code === 95) { name += str[j++]; continue; } break; } if (!name) throw new TypeError("Missing parameter name at ".concat(i)); tokens.push({ type: "NAME", index: i, value: name }); i = j; continue; } if (char === "(") { var count = 1; var pattern = ""; var j = i + 1; if (str[j] === "?") { throw new TypeError("Pattern cannot start with \"?\" at ".concat(j)); } while (j < str.length) { if (str[j] === "\\") { pattern += str[j++] + str[j++]; continue; } if (str[j] === ")") { count--; if (count === 0) { j++; break; } } else if (str[j] === "(") { count++; if (str[j + 1] !== "?") { throw new TypeError("Capturing groups are not allowed at ".concat(j)); } } pattern += str[j++]; } if (count) throw new TypeError("Unbalanced pattern at ".concat(i)); if (!pattern) throw new TypeError("Missing pattern at ".concat(i)); tokens.push({ type: "PATTERN", index: i, value: pattern }); i = j; continue; } tokens.push({ type: "CHAR", index: i, value: str[i++] }); } tokens.push({ type: "END", index: i, value: "" }); return tokens; } /** * Parse a string for the raw tokens. */ function parse$2(str, options) { if (options === void 0) { options = {}; } var tokens = lexer(str); var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a, _b = options.delimiter, delimiter = _b === void 0 ? "/#?" : _b; var result = []; var key = 0; var i = 0; var path = ""; var tryConsume = function (type) { if (i < tokens.length && tokens[i].type === type) return tokens[i++].value; }; var mustConsume = function (type) { var value = tryConsume(type); if (value !== undefined) return value; var _a = tokens[i], nextType = _a.type, index = _a.index; throw new TypeError("Unexpected ".concat(nextType, " at ").concat(index, ", expected ").concat(type)); }; var consumeText = function () { var result = ""; var value; while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) { result += value; } return result; }; var isSafe = function (value) { for (var _i = 0, delimiter_1 = delimiter; _i < delimiter_1.length; _i++) { var char = delimiter_1[_i]; if (value.indexOf(char) > -1) return true; } return false; }; var safePattern = function (prefix) { var prev = result[result.length - 1]; var prevText = prefix || (prev && typeof prev === "string" ? prev : ""); if (prev && !prevText) { throw new TypeError("Must have text between two parameters, missing text after \"".concat(prev.name, "\"")); } if (!prevText || isSafe(prevText)) return "[^".concat(escapeString(delimiter), "]+?"); return "(?:(?!".concat(escapeString(prevText), ")[^").concat(escapeString(delimiter), "])+?"); }; while (i < tokens.length) { var char = tryConsume("CHAR"); var name = tryConsume("NAME"); var pattern = tryConsume("PATTERN"); if (name || pattern) { var prefix = char || ""; if (prefixes.indexOf(prefix) === -1) { path += prefix; prefix = ""; } if (path) { result.push(path); path = ""; } result.push({ name: name || key++, prefix: prefix, suffix: "", pattern: pattern || safePattern(prefix), modifier: tryConsume("MODIFIER") || "", }); continue; } var value = char || tryConsume("ESCAPED_CHAR"); if (value) { path += value; continue; } if (path) { result.push(path); path = ""; } var open = tryConsume("OPEN"); if (open) { var prefix = consumeText(); var name_1 = tryConsume("NAME") || ""; var pattern_1 = tryConsume("PATTERN") || ""; var suffix = consumeText(); mustConsume("CLOSE"); result.push({ name: name_1 || (pattern_1 ? key++ : ""), pattern: name_1 && !pattern_1 ? safePattern(prefix) : pattern_1, prefix: prefix, suffix: suffix, modifier: tryConsume("MODIFIER") || "", }); continue; } mustConsume("END"); } return result; } /** * Compile a string to a template function for the path. */ function compile(str, options) { return tokensToFunction(parse$2(str, options), options); } /** * Expose a method for transforming tokens into the path function. */ function tokensToFunction(tokens, options) { if (options === void 0) { options = {}; } var reFlags = flags(options); var _a = options.encode, encode = _a === void 0 ? function (x) { return x; } : _a, _b = options.validate, validate = _b === void 0 ? true : _b; // Compile all the tokens into regexps. var matches = tokens.map(function (token) { if (typeof token === "object") { return new RegExp("^(?:".concat(token.pattern, ")$"), reFlags); } }); return function (data) { var path = ""; for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; if (typeof token === "string") { path += token; continue; } var value = data ? data[token.name] : undefined; var optional = token.modifier === "?" || token.modifier === "*"; var repeat = token.modifier === "*" || token.modifier === "+"; if (Array.isArray(value)) { if (!repeat) { throw new TypeError("Expected \"".concat(token.name, "\" to not repeat, but got an array")); } if (value.length === 0) { if (optional) continue; throw new TypeError("Expected \"".concat(token.name, "\" to not be empty")); } for (var j = 0; j < value.length; j++) { var segment = encode(value[j], token); if (validate && !matches[i].test(segment)) { throw new TypeError("Expected all \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\"")); } path += token.prefix + segment + token.suffix; } continue; } if (typeof value === "string" || typeof value === "number") { var segment = encode(String(value), token); if (validate && !matches[i].test(segment)) { throw new TypeError("Expected \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\"")); } path += token.prefix + segment + token.suffix; continue; } if (optional) continue; var typeOfMessage = repeat ? "an array" : "a string"; throw new TypeError("Expected \"".concat(token.name, "\" to be ").concat(typeOfMessage)); } return path; }; } /** * Create path match function from `path-to-regexp` spec. */ function match(str, options) { var keys = []; var re = pathToRegexp(str, keys, options); return regexpToFunction(re, keys, options); } /** * Create a path match function from `path-to-regexp` output. */ function regexpToFunction(re, keys, options) { if (options === void 0) { options = {}; } var _a = options.decode, decode = _a === void 0 ? function (x) { return x; } : _a; return function (pathname) { var m = re.exec(pathname); if (!m) return false; var path = m[0], index = m.index; var params = Object.create(null); var _loop_1 = function (i) { if (m[i] === undefined) return "continue"; var key = keys[i - 1]; if (key.modifier === "*" || key.modifier === "+") { params[key.name] = m[i].split(key.prefix + key.suffix).map(function (value) { return decode(value, key); }); } else { params[key.name] = decode(m[i], key); } }; for (var i = 1; i < m.length; i++) { _loop_1(i); } return { path: path, index: index, params: params }; }; } /** * Escape a regular expression string. */ function escapeString(str) { return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1"); } /** * Get the flags for a regexp from the options. */ function flags(options) { return options && options.sensitive ? "" : "i"; } /** * Pull out keys from a regexp. */ function regexpToRegexp(path, keys) { if (!keys) return path; var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g; var index = 0; var execResult = groupsRegex.exec(path.source); while (execResult) { keys.push({ // Use parenthesized substring match if available, index otherwise name: execResult[1] || index++, prefix: "", suffix: "", modifier: "", pattern: "", }); execResult = groupsRegex.exec(path.source); } return path; } /** * Transform an array into a regexp. */ function arrayToRegexp(paths, keys, options) { var parts = paths.map(function (path) { return pathToRegexp(path, keys, options).source; }); return new RegExp("(?:".concat(parts.join("|"), ")"), flags(options)); } /** * Create a path regexp from string input. */ function stringToRegexp(path, keys, options) { return tokensToRegexp(parse$2(path, options), keys, options); } /** * Expose a function for taking tokens and returning a RegExp. */ function tokensToRegexp(tokens, keys, options) { if (options === void 0) { options = {}; } var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function (x) { return x; } : _d, _e = options.delimiter, delimiter = _e === void 0 ? "/#?" : _e, _f = options.endsWith, endsWith = _f === void 0 ? "" : _f; var endsWithRe = "[".concat(escapeString(endsWith), "]|$"); var delimiterRe = "[".concat(escapeString(delimiter), "]"); var route = start ? "^" : ""; // Iterate over the tokens and create our regexp string. for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) { var token = tokens_1[_i]; if (typeof token === "string") { route += escapeString(encode(token)); } else { var prefix = escapeString(encode(token.prefix)); var suffix = escapeString(encode(token.suffix)); if (token.pattern) { if (keys) keys.push(token); if (prefix || suffix) { if (token.modifier === "+" || token.modifier === "*") { var mod = token.modifier === "*" ? "?" : ""; route += "(?:".concat(prefix, "((?:").concat(token.pattern, ")(?:").concat(suffix).concat(prefix, "(?:").concat(token.pattern, "))*)").concat(suffix, ")").concat(mod); } else { route += "(?:".concat(prefix, "(").concat(token.pattern, ")").concat(suffix, ")").concat(token.modifier); } } else { if (token.modifier === "+" || token.modifier === "*") { throw new TypeError("Can not repeat \"".concat(token.name, "\" without a prefix and suffix")); } route += "(".concat(token.pattern, ")").concat(token.modifier); } } else { route += "(?:".concat(prefix).concat(suffix, ")").concat(token.modifier); } } } if (end) { if (!strict) route += "".concat(delimiterRe, "?"); route += !options.endsWith ? "$" : "(?=".concat(endsWithRe, ")"); } else { var endToken = tokens[tokens.length - 1]; var isEndDelimited = typeof endToken === "string" ? delimiterRe.indexOf(endToken[endToken.length - 1]) > -1 : endToken === undefined; if (!strict) { route += "(?:".concat(delimiterRe, "(?=").concat(endsWithRe, "))?"); } if (!isEndDelimited) { route += "(?=".concat(delimiterRe, "|").concat(endsWithRe, ")"); } } return new RegExp(route, flags(options)); } /** * Normalize the given path string, returning a regular expression. * * An empty array can be passed in for the keys, which will hold the * placeholder key descriptions. For example, using `/user/:id`, `keys` will * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. */ function pathToRegexp(path, keys, options) { if (path instanceof RegExp) return regexpToRegexp(path, keys); if (Array.isArray(path)) return arrayToRegexp(path, keys, options); return stringToRegexp(path, keys, options); } const dist_es2015 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ __proto__: null, compile, match, parse: parse$2, pathToRegexp, regexpToFunction, tokensToFunction, tokensToRegexp }, Symbol.toStringTag, { value: 'Module' })); const require$$2 = /*@__PURE__*/getAugmentedNamespace(dist_es2015); var superstatic; var hasRequiredSuperstatic; function requireSuperstatic () { if (hasRequiredSuperstatic) return superstatic; hasRequiredSuperstatic = 1; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var superstatic_exports = {}; __export(superstatic_exports, { collectHasSegments: () => collectHasSegments, convertCleanUrls: () => convertCleanUrls, convertHeaders: () => convertHeaders, convertRedirects: () => convertRedirects, convertRewrites: () => convertRewrites, convertTrailingSlash: () => convertTrailingSlash, getCleanUrls: () => getCleanUrls, pathToRegexp: () => pathToRegexp, sourceToRegex: () => sourceToRegex }); superstatic = __toCommonJS(superstatic_exports); var import_url = require$$0; var import_path_to_regexp = require$$1; var import_path_to_regexp_updated = require$$2; function cloneKeys(keys) { if (typeof keys === "undefined") { return void 0; } return keys.slice(0); } function compareKeys(left, right) { const leftSerialized = typeof left === "undefined" ? "undefined" : left.toString(); const rightSerialized = typeof right === "undefined" ? "undefined" : right.toString(); return leftSerialized === rightSerialized; } function pathToRegexp(callerId, path, keys, options) { const newKeys = cloneKeys(keys); const currentRegExp = (0, import_path_to_regexp.pathToRegexp)(path, keys, options); try { const currentKeys = keys; const newRegExp = (0, import_path_to_regexp_updated.pathToRegexp)(path, newKeys, options); const isDiffRegExp = currentRegExp.toString() !== newRegExp.toString(); if (process.env.FORCE_PATH_TO_REGEXP_LOG || isDiffRegExp) { const message = JSON.stringify({ path, currentRegExp: currentRegExp.toString(), newRegExp: newRegExp.toString() }); console.error(`[vc] PATH TO REGEXP PATH DIFF @ #${callerId}: ${message}`); } const isDiffKeys = !compareKeys(keys, newKeys); if (process.env.FORCE_PATH_TO_REGEXP_LOG || isDiffKeys) { const message = JSON.stringify({ isDiffKeys, currentKeys, newKeys }); console.error(`[vc] PATH TO REGEXP KEYS DIFF @ #${callerId}: ${message}`); } } catch (err) { const error = err; const message = JSON.stringify({ path, error: error.message }); console.error(`[vc] PATH TO REGEXP ERROR @ #${callerId}: ${message}`); } return currentRegExp; } const UN_NAMED_SEGMENT = "__UN_NAMED_SEGMENT__"; function getCleanUrls(filePaths) { const htmlFiles = filePaths.map(toRoute).filter((f) => f.endsWith(".html")).map((f) => ({ html: f, clean: f.slice(0, -5) })); return htmlFiles; } function convertCleanUrls(cleanUrls, trailingSlash, status = 308) { const routes = []; if (cleanUrls) { const loc = trailingSlash ? "/$1/" : "/$1"; routes.push({ src: "^/(?:(.+)/)?index(?:\\.html)?/?$", headers: { Location: loc }, status }); routes.push({ src: "^/(.*)\\.html/?$", headers: { Location: loc }, status }); } return routes; } function convertRedirects(redirects, defaultStatus = 308) { return redirects.map((r) => { const { src, segments } = sourceToRegex(r.source); const hasSegments = collectHasSegments(r.has); normalizeHasKeys(r.has); normalizeHasKeys(r.missing); try { const loc = replaceSegments(segments, hasSegments, r.destination, true); let status; if (typeof r.permanent === "boolean") { status = r.permanent ? 308 : 307; } else if (r.statusCode) { status = r.statusCode; } else { status = defaultStatus; } const route = { src, headers: { Location: loc }, status }; if (typeof r.env !== "undefined") { route.env = r.env; } if (r.has) { route.has = r.has; } if (r.missing) { route.missing = r.missing; } return route; } catch (e) { throw new Error(`Failed to parse redirect: ${JSON.stringify(r)}`); } }); } function convertRewrites(rewrites, internalParamNames) { return rewrites.map((r) => { const { src, segments } = sourceToRegex(r.source); const hasSegments = collectHasSegments(r.has); normalizeHasKeys(r.has); normalizeHasKeys(r.missing); try { const dest = replaceSegments( segments, hasSegments, r.destination, false, internalParamNames ); const route = { src, dest, check: true }; if (typeof r.env !== "undefined") { route.env = r.env; } if (r.has) { route.has = r.has; } if (r.missing) { route.missing = r.missing; } if (r.statusCode) { route.status = r.statusCode; } return route; } catch (e) { throw new Error(`Failed to parse rewrite: ${JSON.stringify(r)}`); } }); } function convertHeaders(headers) { return headers.map((h) => { const obj = {}; const { src, segments } = sourceToRegex(h.source); const hasSegments = collectHasSegments(h.has); normalizeHasKeys(h.has); normalizeHasKeys(h.missing); const namedSegments = segments.filter((name) => name !== UN_NAMED_SEGMENT); const indexes = {}; segments.forEach((name, index) => { indexes[name] = toSegmentDest(index); }); hasSegments.forEach((name) => { indexes[name] = "$" + name; }); h.headers.forEach(({ key, value }) => { if (namedSegments.length > 0 || hasSegments.length > 0) { if (key.includes(":")) { key = safelyCompile(key, indexes); } if (value.includes(":")) { value = safelyCompile(value, indexes); } } obj[key] = value; }); const route = { src, headers: obj, continue: true }; if (h.has) { route.has = h.has; } if (h.missing) { route.missing = h.missing; } return route; }); } function convertTrailingSlash(enable, status = 308) { const routes = []; if (enable) { routes.push({ src: "^/\\.well-known(?:/.*)?$" }); routes.push({ src: "^/((?:[^/]+/)*[^/\\.]+)$", headers: { Location: "/$1/" }, status }); routes.push({ src: "^/((?:[^/]+/)*[^/]+\\.\\w+)/$", headers: { Location: "/$1" }, status }); } else { routes.push({ src: "^/(.*)\\/$", headers: { Location: "/$1" }, status }); } return routes; } function sourceToRegex(source) { const keys = []; const r = pathToRegexp("632", source, keys, { strict: true, sensitive: true, delimiter: "/" }); const segments = keys.map((k) => k.name).map((name) => { if (typeof name !== "string") { return UN_NAMED_SEGMENT; } return name; }); return { src: r.source, segments }; } const namedGroupsRegex = /\(\?<([a-zA-Z][a-zA-Z0-9_]*)>/g; const normalizeHasKeys = (hasItems = []) => { for (const hasItem of hasItems) { if ("key" in hasItem && hasItem.type === "header") { hasItem.key = hasItem.key.toLowerCase(); } } return hasItems; }; function getStringValueForRegex(value) { if (typeof value === "string") { return value; } if (value && typeof value === "object" && value !== null) { if ("re" in value && typeof value.re === "string") { return value.re; } } return null; } function collectHasSegments(has) { const hasSegments = /* @__PURE__ */ new Set(); for (const hasItem of has || []) { if (!hasItem.value && "key" in hasItem) { hasSegments.add(hasItem.key); } const stringValue = getStringValueForRegex(hasItem.value); if (stringValue) { for (const match of stringValue.matchAll(namedGroupsRegex)) { if (match[1]) { hasSegments.add(match[1]); } } if (hasItem.type === "host") { hasSegments.add("host"); } } } return [...hasSegments]; } const escapeSegment = (str, segmentName) => str.replace(new RegExp(`:${segmentName}`, "g"), `__ESC_COLON_${segmentName}`); const unescapeSegments = (str) => str.replace(/__ESC_COLON_/gi, ":"); function replaceSegments(segments, hasItemSegments, destination, isRedirect, internalParamNames) { const namedSegments = segments.filter((name) => name !== UN_NAMED_SEGMENT); const canNeedReplacing = destination.includes(":") && namedSegments.length > 0 || hasItemSegments.length > 0 || !isRedirect; if (!canNeedReplacing) { return destination; } let escapedDestination = destination; const indexes = {}; segments.forEach((name, index) => { indexes[name] = toSegmentDest(index); escapedDestination = escapeSegment(escapedDestination, name); }); hasItemSegments.forEach((name) => { indexes[name] = "$" + name; escapedDestination = escapeSegment(escapedDestination, name); }); const parsedDestination = (0, import_url.parse)(escapedDestination, true); delete parsedDestination.href; delete parsedDestination.path; delete parsedDestination.search; delete parsedDestination.host; let { pathname, hash, query, hostname, ...rest } = parsedDestination; pathname = unescapeSegments(pathname || ""); hash = unescapeSegments(hash || ""); hostname = unescapeSegments(hostname || ""); let destParams = /* @__PURE__ */ new Set(); const pathnameKeys = []; const hashKeys = []; const hostnameKeys = []; try { pathToRegexp("528", pathname, pathnameKeys); pathToRegexp("834", hash || "", hashKeys); pathToRegexp("712", hostname || "", hostnameKeys); } catch (_) { } destParams = new Set( [...pathnameKeys, ...hashKeys, ...hostnameKeys].map((key) => key.name).filter((val) => typeof val === "string") ); pathname = safelyCompile(pathname, indexes, true); hash = hash ? safelyCompile(hash, indexes, true) : null; hostname = hostname ? safelyCompile(hostname, indexes, true) : null; for (const [key, strOrArray] of Object.entries(query)) { if (Array.isArray(strOrArray)) { query[key] = strOrArray.map( (str) => safelyCompile(unescapeSegments(str), indexes, true) ); } else { query[key] = safelyCompile( unescapeSegments(strOrArray), indexes, true ); } } const paramKeys = Object.keys(indexes); const needsQueryUpdating = ( // we do not consider an internal param since it is added automatically !isRedirect && !paramKeys.some( (param) => !(internalParamNames && internalParamNames.includes(param)) && destParams.has(param) ) ); if (needsQueryUpdating) { for (const param of paramKeys) { if (!(param in query) && param !== UN_NAMED_SEGMENT) { query[param] = indexes[param]; } } } destination = (0, import_url.format)({ ...rest, hostname, pathname, query, hash }); return destination.replace(/%24/g, "$"); } function safelyCompile(value, indexes, attemptDirectCompile) { if (!value) { return value; } if (attemptDirectCompile) { try { return (0, import_path_to_regexp.compile)(value, { validate: false })(indexes); } catch (e) { } } for (const key of Object.keys(indexes)) { if (value.includes(`:${key}`)) { value = value.replace( new RegExp(`:${key}\\*`, "g"), `:${key}--ESCAPED_PARAM_ASTERISK` ).replace( new RegExp(`:${key}\\?`, "g"), `:${key}--ESCAPED_PARAM_QUESTION` ).replace(new RegExp(`:${key}\\+`, "g"), `:${key}--ESCAPED_PARAM_PLUS`).replace( new RegExp(`:${key}(?!\\w)`, "g"), `--ESCAPED_PARAM_COLON${key}` ); } } value = value.replace(/(:|\*|\?|\+|\(|\)|\{|\})/g, "\\$1").replace(/--ESCAPED_PARAM_PLUS/g, "+").replace(/--ESCAPED_PARAM_COLON/g, ":").replace(/--ESCAPED_PARAM_QUESTION/g, "?").replace(/--ESCAPED_PARAM_ASTERISK/g, "*"); return (0, import_path_to_regexp.compile)(`/${value}`, { validate: false })(indexes).slice(1); } function toSegmentDest(index) { const i = index + 1; return "$" + i.toString(); } function toRoute(filePath) { return filePath.startsWith("/") ? filePath : "/" + filePath; } return superstatic; } var append; var hasRequiredAppend; function requireAppend () { if (hasRequiredAppend) return append; hasRequiredAppend = 1; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var append_exports = {}; __export(append_exports, { appendRoutesToPhase: () => appendRoutesToPhase }); append = __toCommonJS(append_exports); var import_index = requireDist$1(); function appendRoutesToPhase({ routes: prevRoutes, newRoutes, phase }) { const routes = prevRoutes ? [...prevRoutes] : []; if (newRoutes === null || newRoutes.length === 0) { return routes; } let isInPhase = false; let insertIndex = -1; routes.forEach((r, i) => { if ((0, import_index.isHandler)(r)) { if (r.handle === phase) { isInPhase = true; } else if (isInPhase) { insertIndex = i; isInPhase = false; } } }); if (isInPhase) { routes.push(...newRoutes); } else if (phase === null) { const lastPhase = routes.findIndex((r) => (0, import_index.isHandler)(r) && r.handle); if (lastPhase === -1) { routes.push(...newRoutes); } else { routes.splice(lastPhase, 0, ...newRoutes); } } else if (insertIndex > -1) { routes.splice(insertIndex, 0, ...newRoutes); } else { routes.push({ handle: phase }); routes.push(...newRoutes); } return routes; } return append; } var merge; var hasRequiredMerge; function requireMerge () { if (hasRequiredMerge) return merge; hasRequiredMerge = 1; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var merge_exports = {}; __export(merge_exports, { mergeRoutes: () => mergeRoutes }); merge = __toCommonJS(merge_exports); var import_index = requireDist$1(); function getBuilderRoutesMapping(builds) { const builderRoutes = {}; for (const { entrypoint, routes, use } of builds) { if (routes) { if (!builderRoutes[entrypoint]) { builderRoutes[entrypoint] = {}; } builderRoutes[entrypoint][use] = routes; } } return builderRoutes; } function getCheckAndContinue(routes) { const checks = []; const continues = []; const others = []; for (const route of routes) { if ((0, import_index.isHandler)(route)) { throw new Error( `Unexpected route found in getCheckAndContinue(): ${JSON.stringify( route )}` ); } else if (route.check && !route.override) { checks.push(route); } else if (route.continue && !route.override) { continues.push(route); } else { others.push(route); } } return { checks, continues, others }; } function mergeRoutes({ userRoutes, builds }) { const userHandleMap = /* @__PURE__ */ new Map(); let userPrevHandle = null; (userRoutes || []).forEach((route) => { if ((0, import_index.isHandler)(route)) { userPrevHandle = route.handle; } else { const routes = userHandleMap.get(userPrevHandle); if (!routes) { userHandleMap.set(userPrevHandle, [route]); } else { routes.push(route); } } }); const builderHandleMap = /* @__PURE__ */ new Map(); const builderRoutes = getBuilderRoutesMapping(builds); const sortedPaths = Object.keys(builderRoutes).sort(); sortedPaths.forEach((path) => { const br = builderRoutes[path]; const sortedBuilders = Object.keys(br).sort(); sortedBuilders.forEach((use) => { let builderPrevHandle = null; br[use].forEach((route) => { if ((0, import_index.isHandler)(route)) { builderPrevHandle = route.handle; } else { const routes = builderHandleMap.get(builderPrevHandle); if (!routes) { builderHandleMap.set(builderPrevHandle, [route]); } else { routes.push(route); } } }); }); }); const outputRoutes = []; const uniqueHandleValues = /* @__PURE__ */ new Set([ null, ...userHandleMap.keys(), ...builderHandleMap.keys() ]); for (const handle of uniqueHandleValues) { const userRoutes2 = userHandleMap.get(handle) || []; const builderRoutes2 = builderHandleMap.get(handle) || []; const builderSorted = getCheckAndContinue(builderRoutes2); if (handle !== null && (userRoutes2.length > 0 || builderRoutes2.length > 0)) { outputRoutes.push({ handle }); } outputRoutes.push(...builderSorted.continues); outputRoutes.push(...userRoutes2); outputRoutes.push(...builderSorted.checks); outputRoutes.push(...builderSorted.others); } return outputRoutes; } return merge; } var serviceRouteOwnership; var hasRequiredServiceRouteOwnership; function requireServiceRouteOwnership () { if (hasRequiredServiceRouteOwnership) return serviceRouteOwnership; hasRequiredServiceRouteOwnership = 1; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var service_route_ownership_exports = {}; __export(service_route_ownership_exports, { getOwnershipGuard: () => getOwnershipGuard, normalizeRoutePrefix: () => normalizeRoutePrefix, scopeRouteSourceToOwnership: () => scopeRouteSourceToOwnership }); serviceRouteOwnership = __toCommonJS(service_route_ownership_exports); function normalizeRoutePrefix(routePrefix) { let normalized = routePrefix.startsWith("/") ? routePrefix : `/${routePrefix}`; if (normalized !== "/" && normalized.endsWith("/")) { normalized = normalized.slice(0, -1); } return normalized || "/"; } function escapeForRegex(value) { return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&"); } function toPrefixMatcher(routePrefix) { return `${escapeForRegex(routePrefix)}(?:/|$)`; } function isDescendantPrefix(candidate, prefix) { return candidate !== prefix && candidate.startsWith(`${prefix}/`); } function getOwnershipGuard(ownerPrefix, allRoutePrefixes) { const owner = normalizeRoutePrefix(ownerPrefix); const normalizedPrefixes = Array.from( new Set(allRoutePrefixes.map(normalizeRoutePrefix)) ); const nonRootPrefixes = normalizedPrefixes.filter((prefix) => prefix !== "/").sort((a, b) => b.length - a.length); if (owner === "/") { return nonRootPrefixes.map((prefix) => `(?!${toPrefixMatcher(prefix)})`).join(""); } const descendants = nonRootPrefixes.filter( (prefix) => isDescendantPrefix(prefix, owner) ); const positive = `(?=${toPrefixMatcher(owner)})`; const negative = descendants.map((prefix) => `(?!${toPrefixMatcher(prefix)})`).join(""); return `${positive}${negative}`; } function scopeRouteSourceToOwnership(source, ownershipGuard) { if (!ownershipGuard) { return source; } const inner = source.startsWith("^") ? source.slice(1) : source; return `^${ownershipGuard}(?:${inner})`; } return serviceRouteOwnership; } var schemas; var hasRequiredSchemas; function requireSchemas () { if (hasRequiredSchemas) return schemas; hasRequiredSchemas = 1; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var schemas_exports = {}; __export(schemas_exports, { bulkRedirectsSchema: () => bulkRedirectsSchema, cleanUrlsSchema: () => cleanUrlsSchema, hasSchema: () => hasSchema, headersSchema: () => headersSchema, redirectsSchema: () => redirectsSchema, rewritesSchema: () => rewritesSchema, routesSchema: () => routesSchema, trailingSlashSchema: () => trailingSlashSchema }); schemas = __toCommonJS(schemas_exports); const mitigateSchema = { description: "Mitigation action to take on a route", type: "object", additionalProperties: false, required: ["action"], properties: { action: { description: "The mitigation action to take", type: "string", enum: ["challenge", "deny"] } } }; const matchableValueSchema = { description: "A value to match against. Can be a string (regex) or a condition operation object", anyOf: [ { description: "A regular expression used to match thev value. Named groups can be used in the destination.", type: "string", maxLength: 4096 }, { description: "A condition operation object", type: "object", additionalProperties: false, minProperties: 1, properties: { eq: { description: "Equal to", anyOf: [ { type: "string", maxLength: 4096 }, { type: "number" } ] }, neq: { description: "Not equal", type: "string", maxLength: 4096 }, inc: { description: "In array", type: "array", items: { type: "string", maxLength: 4096 } }, ninc: { description: "Not in array", type: "array", items: { type: "string", maxLength: 4096 } }, pre: { description: "Starts with", type: "string", maxLength: 4096 }, suf: { description: "Ends with", type: "string", maxLength: 4096 }, re: { description: "Regex", type: "string", maxLength: 4096 }, gt: { description: "Greater than", type: "number" }, gte: { description: "Greater than or equal to", type: "number" }, lt: { description: "Less than", type: "number" }, lte: { description: "Less than or equal to", type: "number" } } } ] }; const hasSchema = { description: "An array of requirements that are needed to match", type: "array", maxItems: 16, items: { anyOf: [ { type: "object", additionalProperties: false, required: ["type", "value"], properties: { type: { description: "The type of request element to check", type: "string", enum: ["host"] }, value: matchableValueSchema } }, { type: "object", additionalProperties: false, required: ["type", "key"], properties: { type: { description: "The type of request element to check", type: "string", enum: ["header", "cookie", "query"] }, key: { description: "The name of the element contained in the particular type", type: "string", maxLength: 4096 }, value: matchableValueSchema } } ] } }; const transformsSchema = { description: "A list of transform rules to adjust the query parameters of a request or HTTP headers of request or response", type: "array", minItems: 1, items: { type: "object", additionalProperties: false, required: ["type", "op", "target"], properties: { type: { description: "The scope of the transform to apply", type: "string", enum: ["request.headers", "request.query", "response.headers"] }, op: { description: "The operation to perform on the target", type: "string", enum: ["append", "set", "delete"] }, target: { description: "The target of the transform", type: "object", required: ["key"], properties: { // re is not supported for transforms. Once supported, replace target.key with matchableValueSchema key: { description: "A value to match against. Can be a string or a condition operation object (without regex support)", anyOf: [ { description: "A valid header name (letters, numbers, hyphens, underscores)", type: "string", maxLength: 4096 }, { description: "A condition operation object", type: "object", additionalProperties: false, minProperties: 1, properties: { eq: { description: "Equal to", anyOf: [ { type: "string", maxLength: 4096 }, { type: "number" } ] }, neq: { description: "Not equal", type: "string", maxLength: 4096 }, inc: { description: "In array", type: "array", items: { type: "string", maxLength: 4096 } }, ninc: { description: "Not in array", type: "array", items: { type: "string", maxLength: 4096 } }, pre: { description: "Starts with", type: "string", maxLength: 4096 }, suf: { description: "Ends with", type: "string", maxLength: 4096 }, gt: { description: "Greater than", type: "number" }, gte: { description: "Greater than or equal to", type: "number" }, lt: { description: "Less than", type: "number" }, lte: { description: "Less than or equal to", type: "number" } } } ] } } }, args: { description: "The arguments to the operation", anyOf: [ { type: "string", maxLength: 4096 }, { type: "array", minItems: 1, items: { type: "string", maxLength: 4096 } } ] }, env: { description: "An array of environment variable names that should be replaced at runtime in the args value", type: "array", minItems: 1, maxItems: 64, items: { type: "string", maxLength: 256 } } }, allOf: [ { if: { properties: { op: { enum: ["append", "set"] } } }, then: { required: ["args"] } }, { if: { allOf: [ { properties: { type: { enum: ["request.headers", "response.headers"] } } }, { properties: { op: { enum: ["set", "append"] } } } ] }, then: { properties: { target: { properties: { key: { if: { type: "string" }, then: { pattern: "^[a-zA-Z0-9_-]+$" } } } }, args: { anyOf: [ { type: "string", pattern: "^[a-zA-Z0-9_ :;.,\"'?!(){}\\[\\]@<>=+*#$&`|~\\^%/-]+$" }, { type: "array", items: { type: "string", pattern: "^[a-zA-Z0-9_ :;.,\"'?!(){}\\[\\]@<>=+*#$&`|~\\^%/-]+$" } } ] } } } } ] } }; const routesSchema = { type: "array", deprecated: true, description: "A list of routes objects used to rewrite paths to point towards other internal or external paths", example: [{ dest: "https://docs.example.com", src: "/docs" }], items: { anyOf: [ { type: "object", required: ["src"], additionalProperties: false, properties: { src: { type: "string", maxLength: 4096 }, dest: { type: "string", maxLength: 4096 }, headers: { type: "object", additionalProperties: false, minProperties: 1, maxProperties: 100, patternProperties: { "^.{1,256}$": { type: "string", maxLength: 32768 } } }, methods: { type: "array", maxItems: 10, items: { type: "string", maxLength: 32 } }, caseSensitive: { type: "boolean" }, important: { type: "boolean" }, user: { type: "boolean" }, continue: { type: "boolean" }, override: { type: "boolean" }, check: { type: "boolean" }, isInternal: { type: "boolean" }, status: { type: "integer", minimum: 100, maximum: 999 }, locale: { type: "object", additionalProperties: false, minProperties: 1, properties: { redirect: { type: "object", additionalProperties: false, minProperties: 1, maxProperties: 100, patternProperties: { "^.{1,256}$": { type: "string", maxLength: 4096 } } }, value: { type: "string", maxLength: 4096 }, path: { type: "string", maxLength: 4096 }, cookie: { type: "string", maxLength: 4096 }, default: { type: "string", maxLength: 4096 } } }, middleware: { type: "number" }, middlewarePath: { type: "string" }, middlewareRawSrc: { type: "array", items: { type: "string" } }, has: hasSchema, missing: hasSchema, mitigate: mitigateSchema, transforms: transformsSchema, env: { description: "An array of environment variable names that should be replaced at runtime in the destination or headers", type: "array", minItems: 1, maxItems: 64, items: { type: "string", maxLength: 256 } }, respectOriginCacheControl: { description: "When set to true (default), external rewrites will respect the Cache-Control header from the origin. When false, caching is disabled for this rewrite.", type: "boolean" } } }, { type: "object", required: ["handle"], additionalProperties: false, properties: { handle: { type: "string", maxLength: 32, enum: ["error", "filesystem", "hit", "miss", "resource", "rewrite"] } } } ] } }; const rewritesSchema = { type: "array", maxItems: 2048, description: "A list of rewrite definitions.", items: { type: "object", additionalProperties: false, required: ["source", "destination"], properties: { source: { description: "A pattern that matches each incoming pathname (excluding querystring).", type: "string", maxLength: 4096 }, destination: { description: "An absolute pathname to an existing resource or an external URL.", type: "string", maxLength: 4096 }, has: hasSchema, missing: hasSchema, statusCode: { description: "An optional integer to override the status code of the response.", type: "integer", minimum: 100, maximum: 999 }, env: { description: "An array of environment variable names that should be replaced at runtime in the destination", type: "array", minItems: 1, maxItems: 64, items: { type: "string", maxLength: 256 } }, respectOriginCacheControl: { description: "When set to true (default), external rewrites will respect the Cache-Control header from the origin. When false, caching is disabled for this rewrite.", type: "boolean" } } } }; const redirectsSchema = { title: "Redirects", type: "array", maxItems: 2048, description: "A list of redirect definitions.", items: { type: "object", additionalProperties: false, required: ["source", "destination"], properties: { source: { description: "A pattern that matches each incoming pathname (excluding querystring).", type: "string", maxLength: 4096 }, destination: { description: "A location destination defined as an absolute pathname or external URL.", type: "string", maxLength: 4096 }, permanent: { description: "A boolean to toggle between permanent and temporary redirect. When `true`, the status code is `308`. When `false` the status code is `307`.", type: "boolean" }, statusCode: { description: "An optional integer to define the status code of the redirect.", private: true, type: "integer", minimum: 100, maximum: 999 }, has: hasSchema, missing: hasSchema, env: { description: "An array of environment variable names that should be replaced at runtime in the destination", type: "array", minItems: 1, maxItems: 64, items: { type: "string", maxLength: 256 } } } } }; const headersSchema = { type: "array", maxItems: 2048, description: "A list of header definitions.", items: { type: "object", additionalProperties: false, required: ["source", "headers"], properties: { source: { description: "A pattern that matches each incoming pathname (excluding querystring)", type: "string", maxLength: 4096 }, headers: { description: "An array of key/value pairs representing each response header.", type: "array", maxItems: 1024, items: { type: "object", additionalProperties: false, required: ["key", "value"], properties: { key: { type: "string", maxLength: 4096 }, value: { type: "string", maxLength: 32768 } } } }, has: hasSchema, missing: hasSchema } } }; const cleanUrlsSchema = { description: "When set to `true`, all HTML files and Serverless Functions will have their extension removed. When visiting a path that ends with the extension, a 308 response will redirect the client to the extensionless path.", type: "boolean" }; const trailingSlashSchema = { description: "When `false`, visiting a path that ends with a forward slash will respond with a `308` status code and redirect to the path without the trailing slash.", type: "boolean" }; const bulkRedirectsSchema = { type: "array", description: "A list of bulk redirect definitions.", items: { type: "object", additionalProperties: false, required: ["source", "destination"], properties: { source: { description: "The exact URL path or pattern to match.", type: "string", maxLength: 2048 }, destination: { description: "The target URL path where traffic should be redirected.", type: "string", maxLength: 2048 }, permanent: { description: "A boolean to toggle between permanent and temporary redirect. When `true`, the status code is `308`. When `false` the status code is `307`.", type: "boolean" }, statusCode: { description: "An optional integer to define the status code of the redirect.", type: "integer", enum: [301, 302, 307, 308] }, sensitive: { description: "A boolean to toggle between case-sensitive and case-insensitive redirect. When `true`, the redirect is case-sensitive. When `false` the redirect is case-insensitive.", type: "boolean" }, query: { description: "Whether the query string should be preserved by the redirect. The default is `false`.", type: "boolean" } } } }; return schemas; } var types$1; var hasRequiredTypes; function requireTypes () { if (hasRequiredTypes) return types$1; hasRequiredTypes = 1; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var types_exports = {}; types$1 = __toCommonJS(types_exports); return types$1; } var hasRequiredDist$1; function requireDist$1 () { if (hasRequiredDist$1) return dist$1.exports; hasRequiredDist$1 = 1; (function (module) { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var src_exports = {}; __export(src_exports, { appendRoutesToPhase: () => import_append.appendRoutesToPhase, getCleanUrls: () => import_superstatic2.getCleanUrls, getOwnershipGuard: () => import_service_route_ownership.getOwnershipGuard, getTransformedRoutes: () => getTransformedRoutes, isHandler: () => isHandler, isValidHandleValue: () => isValidHandleValue, mergeRoutes: () => import_merge.mergeRoutes, normalizeRoutePrefix: () => import_service_route_ownership.normalizeRoutePrefix, normalizeRoutes: () => normalizeRoutes, scopeRouteSourceToOwnership: () => import_service_route_ownership.scopeRouteSourceToOwnership, sourceToRegex: () => import_superstatic2.sourceToRegex }); module.exports = __toCommonJS(src_exports); var import_url = require$$0; var import_superstatic = requireSuperstatic(); var import_append = requireAppend(); var import_merge = requireMerge(); var import_service_route_ownership = requireServiceRouteOwnership(); __reExport(src_exports, requireSchemas(), module.exports); var import_superstatic2 = requireSuperstatic(); __reExport(src_exports, requireTypes(), module.exports); const VALID_HANDLE_VALUES = [ "filesystem", "hit", "miss", "rewrite", "error", "resource" ]; const validHandleValues = new Set(VALID_HANDLE_VALUES); function isHandler(route) { return typeof route.handle !== "undefined"; } function isValidHandleValue(handle) { return validHandleValues.has(handle); } function normalizeRoutes(inputRoutes) { if (!inputRoutes || inputRoutes.length === 0) { return { routes: inputRoutes, error: null }; } const routes = []; const handling = []; const errors = []; inputRoutes.forEach((r, i) => { const route = { ...r }; routes.push(route); const keys = Object.keys(route); if (isHandler(route)) { const { handle } = route; if (keys.length !== 1) { const unknownProp = keys.find((prop) => prop !== "handle"); errors.push( `Route at index ${i} has unknown property \`${unknownProp}\`.` ); } else if (!isValidHandleValue(handle)) { errors.push( `Route at index ${i} has unknown handle value \`handle: ${handle}\`.` ); } else if (handling.includes(handle)) { errors.push( `Route at index ${i} is a duplicate. Please use one \`handle: ${handle}\` at most.` ); } else { handling.push(handle); } } else if (route.src) { if (!route.src.startsWith("^")) { route.src = `^${route.src}`; } if (!route.src.endsWith("$")) { route.src = `${route.src}$`; } route.src = route.src.replace(/\\\//g, "/"); const regError = checkRegexSyntax("Route", i, route.src); if (regError) { errors.push(regError); } const handleValue = handling[handling.length - 1]; if (handleValue === "hit") { if (route.dest) { errors.push( `Route at index ${i} cannot define \`dest\` after \`handle: hit\`.` ); } if (route.status) { errors.push( `Route at index ${i} cannot define \`status\` after \`handle: hit\`.` ); } if (!route.continue) { errors.push( `Route at index ${i} must define \`continue: true\` after \`handle: hit\`.` ); } } else if (handleValue === "miss") { if (route.dest && !route.check) { errors.push( `Route at index ${i} must define \`check: true\` after \`handle: miss\`.` ); } else if (!route.dest && !route.continue) { errors.push( `Route at index ${i} must define \`continue: true\` after \`handle: miss\`.` ); } } } else { errors.push( `Route at index ${i} must define either \`handle\` or \`src\` property.` ); } }); const error = errors.length > 0 ? createError( "invalid_route", errors, "https://vercel.link/routes-json", "Learn More" ) : null; return { routes, error }; } function checkRegexSyntax(type, index, src) { try { new RegExp(src); } catch (err) { const prop = type === "Route" ? "src" : "source"; return `${type} at index ${index} has invalid \`${prop}\` regular expression "${src}".`; } return null; } function checkPatternSyntax(type, index, { source, destination, has }) { let sourceSegments = /* @__PURE__ */ new Set(); const destinationSegments = /* @__PURE__ */ new Set(); try { sourceSegments = new Set((0, import_superstatic.sourceToRegex)(source).segments); } catch (err) { return { message: `${type} at index ${index} has invalid \`source\` pattern "${source}".`, link: "https://vercel.link/invalid-route-source-pattern" }; } if (destination) { try { const { hostname, pathname, query } = (0, import_url.parse)(destination, true); (0, import_superstatic.sourceToRegex)(hostname || "").segments.forEach( (name) => destinationSegments.add(name) ); (0, import_superstatic.sourceToRegex)(pathname || "").segments.forEach( (name) => destinationSegments.add(name) ); for (const strOrArray of Object.values(query)) { const value = Array.isArray(strOrArray) ? strOrArray[0] : strOrArray; (0, import_superstatic.sourceToRegex)(value || "").segments.forEach( (name) => destinationSegments.add(name) ); } } catch (err) { } const hasSegments = (0, import_superstatic.collectHasSegments)(has); for (const segment of destinationSegments) { if (!sourceSegments.has(segment) && !hasSegments.includes(segment)) { return { message: `${type} at index ${index} has segment ":${segment}" in \`destination\` property but not in \`source\` or \`has\` property.`, link: "https://vercel.link/invalid-route-destination-segment" }; } } } return null; } function checkRedirect(r, index) { if (typeof r.permanent !== "undefined" && typeof r.statusCode !== "undefined") { return `Redirect at index ${index} cannot define both \`permanent\` and \`statusCode\` properties.`; } return null; } function createError(code, allErrors, link, action) { const errors = Array.isArray(allErrors) ? allErrors : [allErrors]; const message = errors[0]; const error = { name: "RouteApiError", code, message, link, action, errors }; return error; } function notEmpty(value) { return value !== null && value !== void 0; } function getTransformedRoutes(vercelConfig) { const { cleanUrls, rewrites, redirects, headers, trailingSlash } = vercelConfig; let { routes = null } = vercelConfig; if (routes) { const hasNewProperties = typeof cleanUrls !== "undefined" || typeof trailingSlash !== "undefined" || typeof redirects !== "undefined" || typeof headers !== "undefined" || typeof rewrites !== "undefined"; if (hasNewProperties) { const error = createError( "invalid_mixed_routes", "If `rewrites`, `redirects`, `headers`, `cleanUrls` or `trailingSlash` are used, then `routes` cannot be present.", "https://vercel.link/mix-routing-props", "Learn More" ); return { routes, error }; } return normalizeRoutes(routes); } if (typeof cleanUrls !== "undefined") { const normalized = normalizeRoutes( (0, import_superstatic.convertCleanUrls)(cleanUrls, trailingSlash) ); if (normalized.error) { normalized.error.code = "invalid_clean_urls"; return { routes, error: normalized.error }; } routes = routes || []; routes.push(...normalized.routes || []); } if (typeof trailingSlash !== "undefined") { const normalized = normalizeRoutes((0, import_superstatic.convertTrailingSlash)(trailingSlash)); if (normalized.error) { normalized.error.code = "invalid_trailing_slash"; return { routes, error: normalized.error }; } routes = routes || []; routes.push(...normalized.routes || []); } if (typeof redirects !== "undefined") { const code = "invalid_redirect"; const regexErrorMessage = redirects.map((r, i) => checkRegexSyntax("Redirect", i, r.source)).find(notEmpty); if (regexErrorMessage) { return { routes, error: createError( "invalid_redirect", regexErrorMessage, "https://vercel.link/invalid-route-source-pattern", "Learn More" ) }; } const patternError = redirects.map((r, i) => checkPatternSyntax("Redirect", i, r)).find(notEmpty); if (patternError) { return { routes, error: createError( code, patternError.message, patternError.link, "Learn More" ) }; } const redirectErrorMessage = redirects.map(checkRedirect).find(notEmpty); if (redirectErrorMessage) { return { routes, error: createError( code, redirectErrorMessage, "https://vercel.link/redirects-json", "Learn More" ) }; } const normalized = normalizeRoutes((0, import_superstatic.convertRedirects)(redirects)); if (normalized.error) { normalized.error.code = code; return { routes, error: normalized.error }; } routes = routes || []; routes.push(...normalized.routes || []); } if (typeof headers !== "undefined") { const code = "invalid_header"; const regexErrorMessage = headers.map((r, i) => checkRegexSyntax("Header", i, r.source)).find(notEmpty); if (regexErrorMessage) { return { routes, error: createError( code, regexErrorMessage, "https://vercel.link/invalid-route-source-pattern", "Learn More" ) }; } const patternError = headers.map((r, i) => checkPatternSyntax("Header", i, r)).find(notEmpty); if (patternError) { return { routes, error: createError( code, patternError.message, patternError.link, "Learn More" ) }; } const normalized = normalizeRoutes((0, import_superstatic.convertHeaders)(headers)); if (normalized.error) { normalized.error.code = code; return { routes, error: normalized.error }; } routes = routes || []; routes.push(...normalized.routes || []); } if (typeof rewrites !== "undefined") { const code = "invalid_rewrite"; const regexErrorMessage = rewrites.map((r, i) => checkRegexSyntax("Rewrite", i, r.source)).find(notEmpty); if (regexErrorMessage) { return { routes, error: createError( code, regexErrorMessage, "https://vercel.link/invalid-route-source-pattern", "Learn More" ) }; } const patternError = rewrites.map((r, i) => checkPatternSyntax("Rewrite", i, r)).find(notEmpty); if (patternError) { return { routes, error: createError( code, patternError.message, patternError.link, "Learn More" ) }; } const normalized = normalizeRoutes((0, import_superstatic.convertRewrites)(rewrites)); if (normalized.error) { normalized.error.code = code; return { routes, error: normalized.error }; } routes = routes || []; routes.push({ handle: "filesystem" }); routes.push(...normalized.routes || []); } return { routes, error: null }; } } (dist$1)); return dist$1.exports; } requireDist$1(); function matchPattern(url, remotePattern) { return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true); } function matchPort(url, port) { return !port || port === url.port; } function matchProtocol(url, protocol) { return !protocol || protocol === url.protocol.slice(0, -1); } function matchHostname(url, hostname, allowWildcard = false) { if (!hostname) { return true; } else if (!allowWildcard || !hostname.startsWith("*")) { return hostname === url.hostname; } else if (hostname.startsWith("**.")) { const slicedHostname = hostname.slice(2); return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname); } else if (hostname.startsWith("*.")) { const slicedHostname = hostname.slice(1); if (!url.hostname.endsWith(slicedHostname)) { return false; } const subdomainWithDot = url.hostname.slice(0, -(slicedHostname.length - 1)); return subdomainWithDot.endsWith(".") && !subdomainWithDot.slice(0, -1).includes("."); } return false; } function matchPathname(url, pathname, allowWildcard = false) { if (!pathname) { return true; } else if (!allowWildcard || !pathname.endsWith("*")) { return pathname === url.pathname; } else if (pathname.endsWith("/**")) { const slicedPathname = pathname.slice(0, -2); return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname); } else if (pathname.endsWith("/*")) { const slicedPathname = pathname.slice(0, -1); if (!url.pathname.startsWith(slicedPathname)) { return false; } const additionalPathChunks = url.pathname.slice(slicedPathname.length).split("/").filter(Boolean); return additionalPathChunks.length === 1; } return false; } function isRemoteAllowed(src, { domains, remotePatterns }) { if (!URL.canParse(src)) { return false; } const url = new URL(src); if (!["http:", "https:", "data:"].includes(url.protocol)) { return false; } return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern)); } const decoder$2 = new TextDecoder(); const toUTF8String = (input, start = 0, end = input.length) => decoder$2.decode(input.slice(start, end)); const toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + `0${i.toString(16)}`.slice(-2), ""); const getView = (input, offset) => new DataView(input.buffer, input.byteOffset + offset); const readInt16LE = (input, offset = 0) => getView(input, offset).getInt16(0, true); const readUInt16BE = (input, offset = 0) => getView(input, offset).getUint16(0, false); const readUInt16LE = (input, offset = 0) => getView(input, offset).getUint16(0, true); const readUInt24LE = (input, offset = 0) => { const view = getView(input, offset); return view.getUint16(0, true) + (view.getUint8(2) << 16); }; const readInt32LE = (input, offset = 0) => getView(input, offset).getInt32(0, true); const readUInt32BE = (input, offset = 0) => getView(input, offset).getUint32(0, false); const readUInt32LE = (input, offset = 0) => getView(input, offset).getUint32(0, true); const readUInt64 = (input, offset, isBigEndian) => getView(input, offset).getBigUint64(0, !isBigEndian); const methods = { readUInt16BE, readUInt16LE, readUInt32BE, readUInt32LE }; function readUInt(input, bits, offset = 0, isBigEndian = false) { const endian = isBigEndian ? "BE" : "LE"; const methodName = `readUInt${bits}${endian}`; return methods[methodName](input, offset); } function readBox(input, offset) { if (input.length - offset < 4) return; const boxSize = readUInt32BE(input, offset); if (input.length - offset < boxSize) return; return { name: toUTF8String(input, 4 + offset, 8 + offset), offset, size: boxSize }; } function findBox(input, boxName, currentOffset) { while (currentOffset < input.length) { const box = readBox(input, currentOffset); if (!box) break; if (box.name === boxName) return box; currentOffset += box.size > 0 ? box.size : 8; } } const BMP = { validate: (input) => toUTF8String(input, 0, 2) === "BM", calculate: (input) => ({ height: Math.abs(readInt32LE(input, 22)), width: readUInt32LE(input, 18) }) }; const TYPE_ICON = 1; const SIZE_HEADER$1 = 2 + 2 + 2; const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4; function getSizeFromOffset(input, offset) { const value = input[offset]; return value === 0 ? 256 : value; } function getImageSize$1(input, imageIndex) { const offset = SIZE_HEADER$1 + imageIndex * SIZE_IMAGE_ENTRY; return { height: getSizeFromOffset(input, offset + 1), width: getSizeFromOffset(input, offset) }; } const ICO = { validate(input) { const reserved = readUInt16LE(input, 0); const imageCount = readUInt16LE(input, 4); if (reserved !== 0 || imageCount === 0) return false; const imageType = readUInt16LE(input, 2); return imageType === TYPE_ICON; }, calculate(input) { const nbImages = readUInt16LE(input, 4); const imageSize = getImageSize$1(input, 0); if (nbImages === 1) return imageSize; const images = []; for (let imageIndex = 0; imageIndex < nbImages; imageIndex += 1) { images.push(getImageSize$1(input, imageIndex)); } return { width: imageSize.width, height: imageSize.height, images }; } }; const TYPE_CURSOR = 2; const CUR = { validate(input) { const reserved = readUInt16LE(input, 0); const imageCount = readUInt16LE(input, 4); if (reserved !== 0 || imageCount === 0) return false; const imageType = readUInt16LE(input, 2); return imageType === TYPE_CURSOR; }, calculate: (input) => ICO.calculate(input) }; const DDS = { validate: (input) => readUInt32LE(input, 0) === 542327876, calculate: (input) => ({ height: readUInt32LE(input, 12), width: readUInt32LE(input, 16) }) }; const gifRegexp = /^GIF8[79]a/; const GIF = { validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)), calculate: (input) => ({ height: readUInt16LE(input, 8), width: readUInt16LE(input, 6) }) }; const brandMap = { avif: "avif", avis: "avif", // avif-sequence mif1: "heif", msf1: "heif", // heif-sequence heic: "heic", heix: "heic", hevc: "heic", // heic-sequence hevx: "heic" // heic-sequence }; function detectType(input, start, end) { let hasAvif = false; let hasHeic = false; let hasHeif = false; for (let i = start; i <= end; i += 4) { const brand = toUTF8String(input, i, i + 4); if (brand === "avif" || brand === "avis") hasAvif = true; else if (brand === "heic" || brand === "heix" || brand === "hevc" || brand === "hevx") hasHeic = true; else if (brand === "mif1" || brand === "msf1") hasHeif = true; } if (hasAvif) return "avif"; if (hasHeic) return "heic"; if (hasHeif) return "heif"; } const HEIF = { validate(input) { const boxType = toUTF8String(input, 4, 8); if (boxType !== "ftyp") return false; const ftypBox = findBox(input, "ftyp", 0); if (!ftypBox) return false; const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12); return brand in brandMap; }, calculate(input) { const metaBox = findBox(input, "meta", 0); const iprpBox = metaBox && findBox(input, "iprp", metaBox.offset + 12); const ipcoBox = iprpBox && findBox(input, "ipco", iprpBox.offset + 8); if (!ipcoBox) { throw new TypeError("Invalid HEIF, no ipco box found"); } const type = detectType(input, 8, metaBox.offset); const images = []; let currentOffset = ipcoBox.offset + 8; while (currentOffset < ipcoBox.offset + ipcoBox.size) { const ispeBox = findBox(input, "ispe", currentOffset); if (!ispeBox) break; const rawWidth = readUInt32BE(input, ispeBox.offset + 12); const rawHeight = readUInt32BE(input, ispeBox.offset + 16); const clapBox = findBox(input, "clap", currentOffset); let width = rawWidth; let height = rawHeight; if (clapBox && clapBox.offset < ipcoBox.offset + ipcoBox.size) { const cropRight = readUInt32BE(input, clapBox.offset + 12); width = rawWidth - cropRight; } images.push({ height, width }); currentOffset = ispeBox.offset + ispeBox.size; } if (images.length === 0) { throw new TypeError("Invalid HEIF, no sizes found"); } return { width: images[0].width, height: images[0].height, type, ...images.length > 1 ? { images } : {} }; } }; const SIZE_HEADER = 4 + 4; const FILE_LENGTH_OFFSET = 4; const ENTRY_LENGTH_OFFSET = 4; const ICON_TYPE_SIZE = { ICON: 32, "ICN#": 32, // m => 16 x 16 "icm#": 16, icm4: 16, icm8: 16, // s => 16 x 16 "ics#": 16, ics4: 16, ics8: 16, is32: 16, s8mk: 16, icp4: 16, // l => 32 x 32 icl4: 32, icl8: 32, il32: 32, l8mk: 32, icp5: 32, ic11: 32, // h => 48 x 48 ich4: 48, ich8: 48, ih32: 48, h8mk: 48, // . => 64 x 64 icp6: 64, ic12: 32, // t => 128 x 128 it32: 128, t8mk: 128, ic07: 128, // . => 256 x 256 ic08: 256, ic13: 256, // . => 512 x 512 ic09: 512, ic14: 512, // . => 1024 x 1024 ic10: 1024 }; function readImageHeader(input, imageOffset) { const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET; return [ toUTF8String(input, imageOffset, imageLengthOffset), readUInt32BE(input, imageLengthOffset) ]; } function getImageSize(type) { const size = ICON_TYPE_SIZE[type]; return { width: size, height: size, type }; } const ICNS = { validate: (input) => toUTF8String(input, 0, 4) === "icns", calculate(input) { const inputLength = input.length; const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET); let imageOffset = SIZE_HEADER; const images = []; while (imageOffset < fileLength && imageOffset < inputLength) { const imageHeader = readImageHeader(input, imageOffset); const imageSize = getImageSize(imageHeader[0]); images.push(imageSize); imageOffset += imageHeader[1]; } if (images.length === 0) { throw new TypeError("Invalid ICNS, no sizes found"); } return { width: images[0].width, height: images[0].height, ...images.length > 1 ? { images } : {} }; } }; const J2C = { // TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC validate: (input) => readUInt32BE(input, 0) === 4283432785, calculate: (input) => ({ height: readUInt32BE(input, 12), width: readUInt32BE(input, 8) }) }; const JP2 = { validate(input) { const boxType = toUTF8String(input, 4, 8); if (boxType !== "jP ") return false; const ftypBox = findBox(input, "ftyp", 0); if (!ftypBox) return false; const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12); return brand === "jp2 "; }, calculate(input) { const jp2hBox = findBox(input, "jp2h", 0); const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8); if (ihdrBox) { return { height: readUInt32BE(input, ihdrBox.offset + 8), width: readUInt32BE(input, ihdrBox.offset + 12) }; } throw new TypeError("Unsupported JPEG 2000 format"); } }; const EXIF_MARKER = "45786966"; const APP1_DATA_SIZE_BYTES = 2; const EXIF_HEADER_BYTES = 6; const TIFF_BYTE_ALIGN_BYTES = 2; const BIG_ENDIAN_BYTE_ALIGN = "4d4d"; const LITTLE_ENDIAN_BYTE_ALIGN = "4949"; const IDF_ENTRY_BYTES = 12; const NUM_DIRECTORY_ENTRIES_BYTES = 2; function isEXIF(input) { return toHexString(input, 2, 6) === EXIF_MARKER; } function extractSize(input, index) { return { height: readUInt16BE(input, index), width: readUInt16BE(input, index + 2) }; } function extractOrientation(exifBlock, isBigEndian) { const idfOffset = 8; const offset = EXIF_HEADER_BYTES + idfOffset; const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian); for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES; const end = start + IDF_ENTRY_BYTES; if (start > exifBlock.length) { return; } const block = exifBlock.slice(start, end); const tagNumber = readUInt(block, 16, 0, isBigEndian); if (tagNumber === 274) { const dataFormat = readUInt(block, 16, 2, isBigEndian); if (dataFormat !== 3) { return; } const numberOfComponents = readUInt(block, 32, 4, isBigEndian); if (numberOfComponents !== 1) { return; } return readUInt(block, 16, 8, isBigEndian); } } } function validateExifBlock(input, index) { const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index); const byteAlign = toHexString( exifBlock, EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES ); const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN; const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN; if (isBigEndian || isLittleEndian) { return extractOrientation(exifBlock, isBigEndian); } } function validateInput(input, index) { if (index > input.length) { throw new TypeError("Corrupt JPG, exceeded buffer limits"); } } const JPG = { validate: (input) => toHexString(input, 0, 2) === "ffd8", calculate(_input) { let input = _input.slice(4); let orientation; let next; while (input.length) { const i = readUInt16BE(input, 0); validateInput(input, i); if (input[i] !== 255) { input = input.slice(1); continue; } if (isEXIF(input)) { orientation = validateExifBlock(input, i); } next = input[i + 1]; if (next === 192 || next === 193 || next === 194) { const size = extractSize(input, i + 5); if (!orientation) { return size; } return { height: size.height, orientation, width: size.width }; } input = input.slice(i + 2); } throw new TypeError("Invalid JPG, no size found"); } }; class BitReader { // Skip the first 16 bits (2 bytes) of signature byteOffset = 2; bitOffset = 0; input; endianness; constructor(input, endianness) { this.input = input; this.endianness = endianness; } /** Reads a specified number of bits, and move the offset */ getBits(length = 1) { let result = 0; let bitsRead = 0; while (bitsRead < length) { if (this.byteOffset >= this.input.length) { throw new Error("Reached end of input"); } const currentByte = this.input[this.byteOffset]; const bitsLeft = 8 - this.bitOffset; const bitsToRead = Math.min(length - bitsRead, bitsLeft); if (this.endianness === "little-endian") { const mask = (1 << bitsToRead) - 1; const bits = currentByte >> this.bitOffset & mask; result |= bits << bitsRead; } else { const mask = (1 << bitsToRead) - 1 << 8 - this.bitOffset - bitsToRead; const bits = (currentByte & mask) >> 8 - this.bitOffset - bitsToRead; result = result << bitsToRead | bits; } bitsRead += bitsToRead; this.bitOffset += bitsToRead; if (this.bitOffset === 8) { this.byteOffset++; this.bitOffset = 0; } } return result; } } function calculateImageDimension(reader, isSmallImage) { if (isSmallImage) { return 8 * (1 + reader.getBits(5)); } const sizeClass = reader.getBits(2); const extraBits = [9, 13, 18, 30][sizeClass]; return 1 + reader.getBits(extraBits); } function calculateImageWidth(reader, isSmallImage, widthMode, height) { if (isSmallImage && widthMode === 0) { return 8 * (1 + reader.getBits(5)); } if (widthMode === 0) { return calculateImageDimension(reader, false); } const aspectRatios = [1, 1.2, 4 / 3, 1.5, 16 / 9, 5 / 4, 2]; return Math.floor(height * aspectRatios[widthMode - 1]); } const JXLStream = { validate: (input) => { return toHexString(input, 0, 2) === "ff0a"; }, calculate(input) { const reader = new BitReader(input, "little-endian"); const isSmallImage = reader.getBits(1) === 1; const height = calculateImageDimension(reader, isSmallImage); const widthMode = reader.getBits(3); const width = calculateImageWidth(reader, isSmallImage, widthMode, height); return { width, height }; } }; function extractCodestream(input) { const jxlcBox = findBox(input, "jxlc", 0); if (jxlcBox) { return input.slice(jxlcBox.offset + 8, jxlcBox.offset + jxlcBox.size); } const partialStreams = extractPartialStreams(input); if (partialStreams.length > 0) { return concatenateCodestreams(partialStreams); } return void 0; } function extractPartialStreams(input) { const partialStreams = []; let offset = 0; while (offset < input.length) { const jxlpBox = findBox(input, "jxlp", offset); if (!jxlpBox) break; partialStreams.push( input.slice(jxlpBox.offset + 12, jxlpBox.offset + jxlpBox.size) ); offset = jxlpBox.offset + jxlpBox.size; } return partialStreams; } function concatenateCodestreams(partialCodestreams) { const totalLength = partialCodestreams.reduce( (acc, curr) => acc + curr.length, 0 ); const codestream = new Uint8Array(totalLength); let position = 0; for (const partial of partialCodestreams) { codestream.set(partial, position); position += partial.length; } return codestream; } const JXL = { validate: (input) => { const boxType = toUTF8String(input, 4, 8); if (boxType !== "JXL ") return false; const ftypBox = findBox(input, "ftyp", 0); if (!ftypBox) return false; const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12); return brand === "jxl "; }, calculate(input) { const codestream = extractCodestream(input); if (codestream) return JXLStream.calculate(codestream); throw new Error("No codestream found in JXL container"); } }; const KTX = { validate: (input) => { const signature = toUTF8String(input, 1, 7); return ["KTX 11", "KTX 20"].includes(signature); }, calculate: (input) => { const type = input[5] === 49 ? "ktx" : "ktx2"; const offset = type === "ktx" ? 36 : 20; return { height: readUInt32LE(input, offset + 4), width: readUInt32LE(input, offset), type }; } }; const pngSignature = "PNG\r\n\n"; const pngImageHeaderChunkName = "IHDR"; const pngFriedChunkName = "CgBI"; const PNG = { validate(input) { if (pngSignature === toUTF8String(input, 1, 8)) { let chunkName = toUTF8String(input, 12, 16); if (chunkName === pngFriedChunkName) { chunkName = toUTF8String(input, 28, 32); } if (chunkName !== pngImageHeaderChunkName) { throw new TypeError("Invalid PNG"); } return true; } return false; }, calculate(input) { if (toUTF8String(input, 12, 16) === pngFriedChunkName) { return { height: readUInt32BE(input, 36), width: readUInt32BE(input, 32) }; } return { height: readUInt32BE(input, 20), width: readUInt32BE(input, 16) }; } }; const PNMTypes = { P1: "pbm/ascii", P2: "pgm/ascii", P3: "ppm/ascii", P4: "pbm", P5: "pgm", P6: "ppm", P7: "pam", PF: "pfm" }; const handlers = { default: (lines) => { let dimensions = []; while (lines.length > 0) { const line = lines.shift(); if (line[0] === "#") { continue; } dimensions = line.split(" "); break; } if (dimensions.length === 2) { return { height: Number.parseInt(dimensions[1], 10), width: Number.parseInt(dimensions[0], 10) }; } throw new TypeError("Invalid PNM"); }, pam: (lines) => { const size = {}; while (lines.length > 0) { const line = lines.shift(); if (line.length > 16 || line.charCodeAt(0) > 128) { continue; } const [key, value] = line.split(" "); if (key && value) { size[key.toLowerCase()] = Number.parseInt(value, 10); } if (size.height && size.width) { break; } } if (size.height && size.width) { return { height: size.height, width: size.width }; } throw new TypeError("Invalid PAM"); } }; const PNM = { validate: (input) => toUTF8String(input, 0, 2) in PNMTypes, calculate(input) { const signature = toUTF8String(input, 0, 2); const type = PNMTypes[signature]; const lines = toUTF8String(input, 3).split(/[\r\n]+/); const handler = handlers[type] || handlers.default; return handler(lines); } }; const PSD = { validate: (input) => toUTF8String(input, 0, 4) === "8BPS", calculate: (input) => ({ height: readUInt32BE(input, 14), width: readUInt32BE(input, 18) }) }; const svgReg = /"']|"[^"]*"|'[^']*')*>/; const extractorRegExps = { height: /\sheight=(['"])([^%]+?)\1/, root: svgReg, viewbox: /\sviewBox=(['"])(.+?)\1/i, width: /\swidth=(['"])([^%]+?)\1/ }; const INCH_CM = 2.54; const units = { in: 96, cm: 96 / INCH_CM, em: 16, ex: 8, m: 96 / INCH_CM * 100, mm: 96 / INCH_CM / 10, pc: 96 / 72 / 12, pt: 96 / 72, px: 1 }; const unitsReg = new RegExp( `^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join("|")})?$` ); function parseLength(len) { const m = unitsReg.exec(len); if (!m) { return void 0; } return Math.round(Number(m[1]) * (units[m[2]] || 1)); } function parseViewbox(viewbox) { const bounds = viewbox.split(" "); return { height: parseLength(bounds[3]), width: parseLength(bounds[2]) }; } function parseAttributes(root) { const width = extractorRegExps.width.exec(root); const height = extractorRegExps.height.exec(root); const viewbox = extractorRegExps.viewbox.exec(root); return { height: height && parseLength(height[2]), viewbox: viewbox && parseViewbox(viewbox[2]), width: width && parseLength(width[2]) }; } function calculateByDimensions(attrs) { return { height: attrs.height, width: attrs.width }; } function calculateByViewbox(attrs, viewbox) { const ratio = viewbox.width / viewbox.height; if (attrs.width) { return { height: Math.floor(attrs.width / ratio), width: attrs.width }; } if (attrs.height) { return { height: attrs.height, width: Math.floor(attrs.height * ratio) }; } return { height: viewbox.height, width: viewbox.width }; } const SVG = { // Scan only the first kilo-byte to speed up the check on larger files validate: (input) => svgReg.test(toUTF8String(input, 0, 1e3)), calculate(input) { const root = extractorRegExps.root.exec(toUTF8String(input)); if (root) { const attrs = parseAttributes(root[0]); if (attrs.width && attrs.height) { return calculateByDimensions(attrs); } if (attrs.viewbox) { return calculateByViewbox(attrs, attrs.viewbox); } } throw new TypeError("Invalid SVG"); } }; const TGA = { validate(input) { return readUInt16LE(input, 0) === 0 && readUInt16LE(input, 4) === 0; }, calculate(input) { return { height: readUInt16LE(input, 14), width: readUInt16LE(input, 12) }; } }; const CONSTANTS = { TAG: { WIDTH: 256, HEIGHT: 257, COMPRESSION: 259 }, TYPE: { SHORT: 3, LONG: 4, LONG8: 16 }, ENTRY_SIZE: { STANDARD: 12, BIG: 20 }, COUNT_SIZE: { STANDARD: 2, BIG: 8 } }; function readIFD(input, { isBigEndian, isBigTiff }) { const ifdOffset = isBigTiff ? Number(readUInt64(input, 8, isBigEndian)) : readUInt(input, 32, 4, isBigEndian); const entryCountSize = isBigTiff ? CONSTANTS.COUNT_SIZE.BIG : CONSTANTS.COUNT_SIZE.STANDARD; return input.slice(ifdOffset + entryCountSize); } function readTagValue(input, type, offset, isBigEndian) { switch (type) { case CONSTANTS.TYPE.SHORT: return readUInt(input, 16, offset, isBigEndian); case CONSTANTS.TYPE.LONG: return readUInt(input, 32, offset, isBigEndian); case CONSTANTS.TYPE.LONG8: { const value = Number(readUInt64(input, offset, isBigEndian)); if (value > Number.MAX_SAFE_INTEGER) { throw new TypeError("Value too large"); } return value; } default: return 0; } } function nextTag(input, isBigTiff) { const entrySize = isBigTiff ? CONSTANTS.ENTRY_SIZE.BIG : CONSTANTS.ENTRY_SIZE.STANDARD; if (input.length > entrySize) { return input.slice(entrySize); } } function extractTags(input, { isBigEndian, isBigTiff }) { const tags = {}; let temp = input; while (temp?.length) { const code = readUInt(temp, 16, 0, isBigEndian); const type = readUInt(temp, 16, 2, isBigEndian); const length = isBigTiff ? Number(readUInt64(temp, 4, isBigEndian)) : readUInt(temp, 32, 4, isBigEndian); if (code === 0) break; if (length === 1 && (type === CONSTANTS.TYPE.SHORT || type === CONSTANTS.TYPE.LONG || isBigTiff && type === CONSTANTS.TYPE.LONG8)) { const valueOffset = isBigTiff ? 12 : 8; tags[code] = readTagValue(temp, type, valueOffset, isBigEndian); } temp = nextTag(temp, isBigTiff); } return tags; } function determineFormat(input) { const signature = toUTF8String(input, 0, 2); const version = readUInt(input, 16, 2, signature === "MM"); return { isBigEndian: signature === "MM", isBigTiff: version === 43 }; } function validateBigTIFFHeader(input, isBigEndian) { const byteSize = readUInt(input, 16, 4, isBigEndian); const reserved = readUInt(input, 16, 6, isBigEndian); if (byteSize !== 8 || reserved !== 0) { throw new TypeError("Invalid BigTIFF header"); } } const signatures = /* @__PURE__ */ new Set([ "49492a00", // Little Endian "4d4d002a", // Big Endian "49492b00", // BigTIFF Little Endian "4d4d002b" // BigTIFF Big Endian ]); const TIFF = { validate: (input) => { const signature = toHexString(input, 0, 4); return signatures.has(signature); }, calculate(input) { const format = determineFormat(input); if (format.isBigTiff) { validateBigTIFFHeader(input, format.isBigEndian); } const ifdBuffer = readIFD(input, format); const tags = extractTags(ifdBuffer, format); const info = { height: tags[CONSTANTS.TAG.HEIGHT], width: tags[CONSTANTS.TAG.WIDTH], type: format.isBigTiff ? "bigtiff" : "tiff" }; if (tags[CONSTANTS.TAG.COMPRESSION]) { info.compression = tags[CONSTANTS.TAG.COMPRESSION]; } if (!info.width || !info.height) { throw new TypeError("Invalid Tiff. Missing tags"); } return info; } }; function calculateExtended(input) { return { height: 1 + readUInt24LE(input, 7), width: 1 + readUInt24LE(input, 4) }; } function calculateLossless(input) { return { height: 1 + ((input[4] & 15) << 10 | input[3] << 2 | (input[2] & 192) >> 6), width: 1 + ((input[2] & 63) << 8 | input[1]) }; } function calculateLossy(input) { return { height: readInt16LE(input, 8) & 16383, width: readInt16LE(input, 6) & 16383 }; } const WEBP = { validate(input) { const riffHeader = "RIFF" === toUTF8String(input, 0, 4); const webpHeader = "WEBP" === toUTF8String(input, 8, 12); const vp8Header = "VP8" === toUTF8String(input, 12, 15); return riffHeader && webpHeader && vp8Header; }, calculate(_input) { const chunkHeader = toUTF8String(_input, 12, 16); const input = _input.slice(20, 30); if (chunkHeader === "VP8X") { const extendedHeader = input[0]; const validStart = (extendedHeader & 192) === 0; const validEnd = (extendedHeader & 1) === 0; if (validStart && validEnd) { return calculateExtended(input); } throw new TypeError("Invalid WebP"); } if (chunkHeader === "VP8 " && input[0] !== 47) { return calculateLossy(input); } const signature = toHexString(input, 3, 6); if (chunkHeader === "VP8L" && signature !== "9d012a") { return calculateLossless(input); } throw new TypeError("Invalid WebP"); } }; const typeHandlers = /* @__PURE__ */ new Map([ ["bmp", BMP], ["cur", CUR], ["dds", DDS], ["gif", GIF], ["heif", HEIF], ["icns", ICNS], ["ico", ICO], ["j2c", J2C], ["jp2", JP2], ["jpg", JPG], ["jxl", JXL], ["jxl-stream", JXLStream], ["ktx", KTX], ["png", PNG], ["pnm", PNM], ["psd", PSD], ["svg", SVG], ["tga", TGA], ["tiff", TIFF], ["webp", WEBP] ]); const types = Array.from(typeHandlers.keys()); function appendForwardSlash(path) { return path.endsWith("/") ? path : path + "/"; } function prependForwardSlash(path) { return path[0] === "/" ? path : "/" + path; } const MANY_LEADING_SLASHES = /^\/{2,}/; function collapseDuplicateLeadingSlashes(path) { if (!path) { return path; } return path.replace(MANY_LEADING_SLASHES, "/"); } const MANY_SLASHES = /\/{2,}/g; function collapseDuplicateSlashes(path) { if (!path) { return path; } return path.replace(MANY_SLASHES, "/"); } const MANY_TRAILING_SLASHES = /\/{2,}$/g; function collapseDuplicateTrailingSlashes(path, trailingSlash) { if (!path) { return path; } return path.replace(MANY_TRAILING_SLASHES, trailingSlash ? "/" : "") || "/"; } function removeTrailingForwardSlash(path) { return path.endsWith("/") ? path.slice(0, path.length - 1) : path; } function removeLeadingForwardSlash(path) { return path.startsWith("/") ? path.substring(1) : path; } function trimSlashes(path) { return path.replace(/^\/|\/$/g, ""); } function isString(path) { return typeof path === "string" || path instanceof String; } const INTERNAL_PREFIXES = /* @__PURE__ */ new Set(["/_", "/@", "/.", "//"]); const JUST_SLASHES = /^\/{2,}$/; function isInternalPath(path) { return INTERNAL_PREFIXES.has(path.slice(0, 2)) && !JUST_SLASHES.test(path); } function joinPaths(...paths) { return paths.filter(isString).map((path, i) => { if (i === 0) { return removeTrailingForwardSlash(path); } else if (i === paths.length - 1) { return removeLeadingForwardSlash(path); } else { return trimSlashes(path); } }).join("/"); } function isRemotePath(src) { if (!src) return false; const trimmed = src.trim(); if (!trimmed) return false; let decoded = trimmed; let previousDecoded = ""; let maxIterations = 10; while (decoded !== previousDecoded && maxIterations > 0) { previousDecoded = decoded; try { decoded = decodeURIComponent(decoded); } catch { break; } maxIterations--; } if (/^[a-zA-Z]:/.test(decoded)) { return false; } if (decoded[0] === "/" && decoded[1] !== "/" && decoded[1] !== "\\") { return false; } if (decoded[0] === "\\") { return true; } if (decoded.startsWith("//")) { return true; } try { const url = new URL(decoded, "http://n"); if (url.username || url.password) { return true; } if (decoded.includes("@") && !url.pathname.includes("@") && !url.search.includes("@")) { return true; } if (url.origin !== "http://n") { const protocol = url.protocol.toLowerCase(); if (protocol === "file:") { return false; } return true; } if (URL.canParse(decoded)) { return true; } return false; } catch { return true; } } function slash(path) { return path.replace(/\\/g, "/"); } function fileExtension(path) { const ext = path.split(".").pop(); return ext !== path ? `.${ext}` : ""; } const WITH_FILE_EXT = /\/[^/]+\.\w+$/; function hasFileExtension(path) { return WITH_FILE_EXT.test(path); } nodePath.posix.join; const ASTRO_PATH_HEADER = "x-astro-path"; const ASTRO_PATH_PARAM = "x_astro_path"; const ASTRO_LOCALS_HEADER = "x-astro-locals"; const ASTRO_MIDDLEWARE_SECRET_HEADER = "x-astro-middleware-secret"; const middlewareSecret = "540c10bd-4b14-40ea-a067-00b109f1af2c"; function shouldAppendForwardSlash(trailingSlash, buildFormat) { switch (trailingSlash) { case "always": return true; case "never": return false; case "ignore": { switch (buildFormat) { case "directory": return true; case "preserve": case "file": return false; } } } } const ASTRO_VERSION = "6.1.10"; const ASTRO_GENERATOR = `Astro v${ASTRO_VERSION}`; const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute"; const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite"; const REWRITE_DIRECTIVE_HEADER_VALUE = "yes"; const NOOP_MIDDLEWARE_HEADER = "X-Astro-Noop"; const ROUTE_TYPE_HEADER = "X-Astro-Route-Type"; const DEFAULT_404_COMPONENT = "astro-default-404.astro"; const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308, 300, 304]; const REROUTABLE_STATUS_CODES = [404, 500]; const clientAddressSymbol = /* @__PURE__ */ Symbol.for("astro.clientAddress"); const originPathnameSymbol = /* @__PURE__ */ Symbol.for("astro.originPathname"); const pipelineSymbol = /* @__PURE__ */ Symbol.for("astro.pipeline"); const responseSentSymbol$1 = /* @__PURE__ */ Symbol.for("astro.responseSent"); function computeFallbackRoute(options) { const { pathname, responseStatus, fallback, fallbackType, locales, defaultLocale, strategy, base } = options; if (responseStatus !== 404) { return { type: "none" }; } if (!fallback || Object.keys(fallback).length === 0) { return { type: "none" }; } const segments = pathname.split("/"); const urlLocale = segments.find((segment) => { for (const locale of locales) { if (typeof locale === "string") { if (locale === segment) { return true; } } else if (locale.path === segment) { return true; } } return false; }); if (!urlLocale) { return { type: "none" }; } const fallbackKeys = Object.keys(fallback); if (!fallbackKeys.includes(urlLocale)) { return { type: "none" }; } const fallbackLocale = fallback[urlLocale]; const pathFallbackLocale = getPathByLocale(fallbackLocale, locales); let newPathname; if (pathFallbackLocale === defaultLocale && strategy === "pathname-prefix-other-locales") { if (pathname.includes(`${base}`)) { newPathname = pathname.replace(`/${urlLocale}`, ``); } else { newPathname = pathname.replace(`/${urlLocale}`, `/`); } } else { newPathname = pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`); } return { type: fallbackType, pathname: newPathname }; } class I18nRouter { #strategy; #defaultLocale; #locales; #base; #domains; constructor(options) { this.#strategy = options.strategy; this.#defaultLocale = options.defaultLocale; this.#locales = options.locales; this.#base = options.base === "/" ? "/" : removeTrailingForwardSlash(options.base || ""); this.#domains = options.domains; } /** * Evaluate routing strategy for a pathname. * Returns decision object (not HTTP Response). */ match(pathname, context) { if (this.shouldSkipProcessing(pathname, context)) { return { type: "continue" }; } switch (this.#strategy) { case "manual": return { type: "continue" }; case "pathname-prefix-always": return this.matchPrefixAlways(pathname, context); case "domains-prefix-always": if (this.localeHasntDomain(context.currentLocale, context.currentDomain)) { return { type: "continue" }; } return this.matchPrefixAlways(pathname, context); case "pathname-prefix-other-locales": return this.matchPrefixOtherLocales(pathname, context); case "domains-prefix-other-locales": if (this.localeHasntDomain(context.currentLocale, context.currentDomain)) { return { type: "continue" }; } return this.matchPrefixOtherLocales(pathname, context); case "pathname-prefix-always-no-redirect": return this.matchPrefixAlwaysNoRedirect(pathname, context); case "domains-prefix-always-no-redirect": if (this.localeHasntDomain(context.currentLocale, context.currentDomain)) { return { type: "continue" }; } return this.matchPrefixAlwaysNoRedirect(pathname, context); default: return { type: "continue" }; } } /** * Check if i18n processing should be skipped for this request */ shouldSkipProcessing(pathname, context) { if (pathname.includes("/404") || pathname.includes("/500")) { return true; } if (pathname.includes("/_server-islands/")) { return true; } if (context.isReroute) { return true; } if (context.routeType && context.routeType !== "page" && context.routeType !== "fallback") { return true; } return false; } /** * Strategy: pathname-prefix-always * All locales must have a prefix, including the default locale. */ matchPrefixAlways(pathname, _context) { const isRoot = pathname === this.#base + "/" || pathname === this.#base; if (isRoot) { const basePrefix = this.#base === "/" ? "" : this.#base; return { type: "redirect", location: `${basePrefix}/${this.#defaultLocale}` }; } if (!pathHasLocale(pathname, this.#locales)) { return { type: "notFound" }; } return { type: "continue" }; } /** * Strategy: pathname-prefix-other-locales * Default locale has no prefix, other locales must have a prefix. */ matchPrefixOtherLocales(pathname, _context) { let pathnameContainsDefaultLocale = false; for (const segment of pathname.split("/")) { if (normalizeTheLocale(segment) === normalizeTheLocale(this.#defaultLocale)) { pathnameContainsDefaultLocale = true; break; } } if (pathnameContainsDefaultLocale) { const newLocation = pathname.replace(`/${this.#defaultLocale}`, ""); return { type: "notFound", location: newLocation }; } return { type: "continue" }; } /** * Strategy: pathname-prefix-always-no-redirect * Like prefix-always but allows root to serve instead of redirecting */ matchPrefixAlwaysNoRedirect(pathname, _context) { const isRoot = pathname === this.#base + "/" || pathname === this.#base; if (isRoot) { return { type: "continue" }; } if (!pathHasLocale(pathname, this.#locales)) { return { type: "notFound" }; } return { type: "continue" }; } /** * Check if the current locale doesn't belong to the configured domain. * Used for domain-based routing strategies. */ localeHasntDomain(currentLocale, currentDomain) { if (!this.#domains || !currentDomain) { return false; } if (!currentLocale) { return false; } const localesForDomain = this.#domains[currentDomain]; if (!localesForDomain) { return true; } return !localesForDomain.includes(currentLocale); } } function createI18nMiddleware(i18n, base, trailingSlash, format) { if (!i18n) return (_, next) => next(); const i18nRouter = new I18nRouter({ strategy: i18n.strategy, defaultLocale: i18n.defaultLocale, locales: i18n.locales, base, domains: i18n.domainLookupTable ? Object.keys(i18n.domainLookupTable).reduce( (acc, domain) => { const locale = i18n.domainLookupTable[domain]; if (!acc[domain]) { acc[domain] = []; } acc[domain].push(locale); return acc; }, {} ) : void 0 }); return async (context, next) => { const response = await next(); const typeHeader = response.headers.get(ROUTE_TYPE_HEADER); const isReroute = response.headers.get(REROUTE_DIRECTIVE_HEADER); if (isReroute === "no" && typeof i18n.fallback === "undefined") { return response; } if (typeHeader !== "page" && typeHeader !== "fallback") { return response; } const routerContext = { currentLocale: context.currentLocale, currentDomain: context.url.hostname, routeType: typeHeader, isReroute: isReroute === "yes" }; const routeDecision = i18nRouter.match(context.url.pathname, routerContext); switch (routeDecision.type) { case "redirect": { let location = routeDecision.location; if (shouldAppendForwardSlash(trailingSlash, format)) { location = appendForwardSlash(location); } return context.redirect(location, routeDecision.status); } case "notFound": { if (context.isPrerendered) { const prerenderedRes = new Response(response.body, { status: 404, headers: response.headers }); prerenderedRes.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); if (routeDecision.location) { prerenderedRes.headers.set("Location", routeDecision.location); } return prerenderedRes; } const headers = new Headers(); if (routeDecision.location) { headers.set("Location", routeDecision.location); } return new Response(null, { status: 404, headers }); } } if (i18n.fallback && i18n.fallbackType) { const fallbackDecision = computeFallbackRoute({ pathname: context.url.pathname, responseStatus: response.status, currentLocale: context.currentLocale, fallback: i18n.fallback, fallbackType: i18n.fallbackType, locales: i18n.locales, defaultLocale: i18n.defaultLocale, strategy: i18n.strategy, base }); switch (fallbackDecision.type) { case "redirect": return context.redirect(fallbackDecision.pathname + context.url.search); case "rewrite": return await context.rewrite(fallbackDecision.pathname + context.url.search); } } return response; }; } function pathHasLocale(path, locales) { const segments = path.split("/").map(normalizeThePath); for (const segment of segments) { for (const locale of locales) { if (typeof locale === "string") { if (normalizeTheLocale(segment) === normalizeTheLocale(locale)) { return true; } } else if (segment === locale.path) { return true; } } } return false; } function getPathByLocale(locale, locales) { for (const loopLocale of locales) { if (typeof loopLocale === "string") { if (loopLocale === locale) { return loopLocale; } } else { for (const code of loopLocale.codes) { if (code === locale) { return loopLocale.path; } } } } throw new AstroError(i18nNoLocaleFoundInPath); } function normalizeTheLocale(locale) { return locale.replaceAll("_", "-").toLowerCase(); } function normalizeThePath(path) { return path.endsWith(".html") ? path.slice(0, -5) : path; } function getAllCodes(locales) { const result = []; for (const loopLocale of locales) { if (typeof loopLocale === "string") { result.push(loopLocale); } else { result.push(...loopLocale.codes); } } return result; } var dist = {}; var hasRequiredDist; function requireDist () { if (hasRequiredDist) return dist; hasRequiredDist = 1; Object.defineProperty(dist, "__esModule", { value: true }); dist.parseCookie = parseCookie; dist.parse = parseCookie; dist.stringifyCookie = stringifyCookie; dist.stringifySetCookie = stringifySetCookie; dist.serialize = stringifySetCookie; dist.parseSetCookie = parseSetCookie; dist.stringifySetCookie = stringifySetCookie; dist.serialize = stringifySetCookie; /** * RegExp to match cookie-name in RFC 6265 sec 4.1.1 * This refers out to the obsoleted definition of token in RFC 2616 sec 2.2 * which has been replaced by the token definition in RFC 7230 appendix B. * * cookie-name = token * token = 1*tchar * tchar = "!" / "#" / "$" / "%" / "&" / "'" / * "*" / "+" / "-" / "." / "^" / "_" / * "`" / "|" / "~" / DIGIT / ALPHA * * Note: Allowing more characters - https://github.com/jshttp/cookie/issues/191 * Allow same range as cookie value, except `=`, which delimits end of name. */ const cookieNameRegExp = /^[\u0021-\u003A\u003C\u003E-\u007E]+$/; /** * RegExp to match cookie-value in RFC 6265 sec 4.1.1 * * cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E * ; US-ASCII characters excluding CTLs, * ; whitespace DQUOTE, comma, semicolon, * ; and backslash * * Allowing more characters: https://github.com/jshttp/cookie/issues/191 * Comma, backslash, and DQUOTE are not part of the parsing algorithm. */ const cookieValueRegExp = /^[\u0021-\u003A\u003C-\u007E]*$/; /** * RegExp to match domain-value in RFC 6265 sec 4.1.1 * * domain-value = * ; defined in [RFC1034], Section 3.5, as * ; enhanced by [RFC1123], Section 2.1 * =