@@ -41,4 +41,6 @@ import * as z from 'zod/v4/core'; | ||
| /** Transform form data to an object based on a Zod schema. */ | ||
| export declare function formDataToObject<T extends z.$ZodObject>(formData: FormData, schema: T): Record<string, unknown>; | ||
| export declare function formDataToObject<T extends z.$ZodObject>(formData: FormData, schema: T, | ||
| /** @internal */ | ||
| prefix?: string): Record<string, unknown>; | ||
| export declare function serializeActionResult(res: SafeResult<any, any>): SerializedActionResult; | ||
| export {}; |
@@ -209,8 +209,12 @@ import { stringify as devalueStringify } from "devalue"; | ||
| } | ||
| function formDataToObject(formData, schema) { | ||
| const obj = schema._zod.def.catchall ? Object.fromEntries(formData.entries()) : {}; | ||
| function formDataToObject(formData, schema, prefix = "") { | ||
| const formKeys = [...formData.keys()]; | ||
| const obj = schema._zod.def.catchall ? Object.fromEntries( | ||
| [...formData.entries()].filter(([k]) => k.startsWith(prefix)).map(([k, v]) => [k.slice(prefix.length), v]) | ||
| ) : {}; | ||
| for (const [key, baseValidator] of Object.entries(schema._zod.def.shape)) { | ||
| const prefixedKey = prefix + key; | ||
| let validator = baseValidator; | ||
| while (validator instanceof z.$ZodOptional || validator instanceof z.$ZodNullable || validator instanceof z.$ZodDefault) { | ||
| if (validator instanceof z.$ZodDefault && !formData.has(key)) { | ||
| if (validator instanceof z.$ZodDefault && !formDataHasKeyOrPrefix(formKeys, prefixedKey)) { | ||
| obj[key] = validator._zod.def.defaultValue instanceof Function ? validator._zod.def.defaultValue() : validator._zod.def.defaultValue; | ||
@@ -220,11 +224,34 @@ } | ||
| } | ||
| if (!formData.has(key) && key in obj) { | ||
| while (validator instanceof z.$ZodPipe) { | ||
| validator = validator._zod.def.in; | ||
| } | ||
| if (validator instanceof z.$ZodDiscriminatedUnion) { | ||
| const typeKey = validator._zod.def.discriminator; | ||
| const typeValue = formData.get(prefixedKey + "." + typeKey); | ||
| if (typeof typeValue === "string") { | ||
| const match = validator._zod.def.options.find( | ||
| (option) => option.def.shape[typeKey].values.has(typeValue) | ||
| ); | ||
| if (match) { | ||
| validator = match; | ||
| } | ||
| } | ||
| } | ||
| if (validator instanceof z.$ZodObject) { | ||
| const nestedPrefix = prefixedKey + "."; | ||
| const hasNestedKeys = formKeys.some((k) => k.startsWith(nestedPrefix)); | ||
| if (hasNestedKeys) { | ||
| obj[key] = formDataToObject(formData, validator, nestedPrefix); | ||
| } else if (!(key in obj)) { | ||
| obj[key] = baseValidator instanceof z.$ZodNullable ? null : void 0; | ||
| } | ||
| } else if (!formData.has(prefixedKey) && key in obj) { | ||
| continue; | ||
| } else if (validator instanceof z.$ZodBoolean) { | ||
| const val = formData.get(key); | ||
| obj[key] = val === "true" ? true : val === "false" ? false : formData.has(key); | ||
| const val = formData.get(prefixedKey); | ||
| obj[key] = val === "true" ? true : val === "false" ? false : formData.has(prefixedKey); | ||
| } else if (validator instanceof z.$ZodArray) { | ||
| obj[key] = handleFormDataGetAll(key, formData, validator); | ||
| obj[key] = handleFormDataGetAll(prefixedKey, formData, validator); | ||
| } else { | ||
| obj[key] = handleFormDataGet(key, formData, validator, baseValidator); | ||
| obj[key] = handleFormDataGet(prefixedKey, formData, validator, baseValidator); | ||
| } | ||
@@ -234,2 +261,6 @@ } | ||
| } | ||
| function formDataHasKeyOrPrefix(formKeys, key) { | ||
| const prefix = key + "."; | ||
| return formKeys.some((k) => k === key || k.startsWith(prefix)); | ||
| } | ||
| function handleFormDataGetAll(key, formData, validator) { | ||
@@ -236,0 +267,0 @@ const entries = Array.from(formData.getAll(key)); |
| class BuildTimeAstroVersionProvider { | ||
| // Injected during the build through esbuild define | ||
| version = "6.0.7"; | ||
| version = "6.0.8"; | ||
| } | ||
@@ -5,0 +5,0 @@ export { |
@@ -195,3 +195,3 @@ import { existsSync, promises as fs } from "node:fs"; | ||
| } | ||
| if (previousAstroVersion && previousAstroVersion !== "6.0.7") { | ||
| if (previousAstroVersion && previousAstroVersion !== "6.0.8") { | ||
| logger.info("Astro version changed"); | ||
@@ -204,4 +204,4 @@ shouldClear = true; | ||
| } | ||
| if ("6.0.7") { | ||
| this.#store.metaStore().set("astro-version", "6.0.7"); | ||
| if ("6.0.8") { | ||
| this.#store.metaStore().set("astro-version", "6.0.8"); | ||
| } | ||
@@ -208,0 +208,0 @@ if (currentConfigDigest) { |
@@ -1,2 +0,2 @@ | ||
| const ASTRO_VERSION = "6.0.7"; | ||
| const ASTRO_VERSION = "6.0.8"; | ||
| const ASTRO_GENERATOR = `Astro v${ASTRO_VERSION}`; | ||
@@ -3,0 +3,0 @@ const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute"; |
@@ -29,3 +29,3 @@ import fs from "node:fs"; | ||
| const logger = restart.container.logger; | ||
| const currentVersion = "6.0.7"; | ||
| const currentVersion = "6.0.8"; | ||
| const isPrerelease = currentVersion.includes("-"); | ||
@@ -32,0 +32,0 @@ if (!isPrerelease) { |
@@ -272,3 +272,3 @@ import colors from "piccolore"; | ||
| ` ${bgGreen(black(` ${commandName} `))} ${green( | ||
| `v${"6.0.7"}` | ||
| `v${"6.0.8"}` | ||
| )} ${headline}` | ||
@@ -275,0 +275,0 @@ ); |
@@ -37,2 +37,11 @@ import type { RewritePayload } from '../../types/public/common.js'; | ||
| export declare function getOriginPathname(request: Request): string; | ||
| /** | ||
| * Pure function that normalizes a rewrite target pathname by stripping the base, | ||
| * handling trailing slashes, removing `.html` suffixes, and computing the final | ||
| * full URL pathname (with base re-prepended). | ||
| */ | ||
| export declare function normalizeRewritePathname(urlPathname: string, base: AstroConfig['base'], trailingSlash: AstroConfig['trailingSlash'], buildFormat: AstroConfig['build']['format']): { | ||
| pathname: string; | ||
| resolvedUrlPathname: string; | ||
| }; | ||
| export {}; |
@@ -0,1 +1,2 @@ | ||
| import { collapseDuplicateSlashes } from "@astrojs/internal-helpers/path"; | ||
| import { shouldAppendForwardSlash } from "../build/util.js"; | ||
@@ -29,29 +30,11 @@ import { originPathnameSymbol } from "../constants.js"; | ||
| } else { | ||
| newUrl = new URL(payload, new URL(request.url).origin); | ||
| newUrl = new URL(collapseDuplicateSlashes(payload), new URL(request.url).origin); | ||
| } | ||
| let pathname = newUrl.pathname; | ||
| const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat); | ||
| if (base !== "/") { | ||
| const isBasePathRequest = newUrl.pathname === base || newUrl.pathname === removeTrailingForwardSlash(base); | ||
| if (isBasePathRequest) { | ||
| pathname = shouldAppendSlash ? "/" : ""; | ||
| } else if (newUrl.pathname.startsWith(base)) { | ||
| pathname = shouldAppendSlash ? appendForwardSlash(newUrl.pathname) : removeTrailingForwardSlash(newUrl.pathname); | ||
| pathname = pathname.slice(base.length); | ||
| } | ||
| } | ||
| if (!pathname.startsWith("/") && shouldAppendSlash && newUrl.pathname.endsWith("/")) { | ||
| pathname = prependForwardSlash(pathname); | ||
| } | ||
| if (pathname === "/" && base !== "/" && !shouldAppendSlash) { | ||
| pathname = ""; | ||
| } | ||
| if (buildFormat === "file") { | ||
| pathname = pathname.replace(/\.html$/, ""); | ||
| } | ||
| if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) { | ||
| newUrl.pathname = removeTrailingForwardSlash(base); | ||
| } else { | ||
| newUrl.pathname = joinPaths(...[base, pathname].filter(Boolean)); | ||
| } | ||
| const { pathname, resolvedUrlPathname } = normalizeRewritePathname( | ||
| newUrl.pathname, | ||
| base, | ||
| trailingSlash, | ||
| buildFormat | ||
| ); | ||
| newUrl.pathname = resolvedUrlPathname; | ||
| const decodedPathname = decodeURI(pathname); | ||
@@ -149,2 +132,31 @@ if (isRoute404(decodedPathname)) { | ||
| } | ||
| function normalizeRewritePathname(urlPathname, base, trailingSlash, buildFormat) { | ||
| let pathname = collapseDuplicateSlashes(urlPathname); | ||
| const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat); | ||
| if (base !== "/") { | ||
| const isBasePathRequest = urlPathname === base || urlPathname === removeTrailingForwardSlash(base); | ||
| if (isBasePathRequest) { | ||
| pathname = shouldAppendSlash ? "/" : ""; | ||
| } else if (urlPathname.startsWith(base)) { | ||
| pathname = shouldAppendSlash ? appendForwardSlash(urlPathname) : removeTrailingForwardSlash(urlPathname); | ||
| pathname = pathname.slice(base.length); | ||
| } | ||
| } | ||
| if (!pathname.startsWith("/") && shouldAppendSlash && urlPathname.endsWith("/")) { | ||
| pathname = prependForwardSlash(pathname); | ||
| } | ||
| if (pathname === "/" && base !== "/" && !shouldAppendSlash) { | ||
| pathname = ""; | ||
| } | ||
| if (buildFormat === "file") { | ||
| pathname = pathname.replace(/\.html$/, ""); | ||
| } | ||
| let resolvedUrlPathname; | ||
| if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) { | ||
| resolvedUrlPathname = removeTrailingForwardSlash(base); | ||
| } else { | ||
| resolvedUrlPathname = joinPaths(...[base, pathname].filter(Boolean)); | ||
| } | ||
| return { pathname, resolvedUrlPathname }; | ||
| } | ||
| export { | ||
@@ -154,3 +166,4 @@ copyRequest, | ||
| getOriginPathname, | ||
| normalizeRewritePathname, | ||
| setOriginPathname | ||
| }; |
@@ -29,2 +29,4 @@ import { prependForwardSlash } from "@astrojs/internal-helpers/path"; | ||
| if (imp.id.includes(PROPAGATED_ASSET_QUERY_PARAM)) continue; | ||
| if (imp.id === RESOLVED_MODULE_DEV_CSS || imp.id === RESOLVED_MODULE_DEV_CSS_ALL || imp.id.startsWith(RESOLVED_MODULE_DEV_CSS_PREFIX)) | ||
| continue; | ||
| if (!imp.transformResult) { | ||
@@ -31,0 +33,0 @@ try { |
+1
-1
| { | ||
| "name": "astro", | ||
| "version": "6.0.7", | ||
| "version": "6.0.8", | ||
| "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 7 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 7 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
2613138
0.09%69001
0.08%