astro 6.0.7 → 6.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38,6 +38,8 @@ interface AstroActionContext {
38
38
  export declare function getActionContext(context: APIContext): AstroActionContext;
39
39
  export declare const ACTION_API_CONTEXT_SYMBOL: unique symbol;
40
40
  /** Transform form data to an object based on a Zod schema. */
41
- export declare function formDataToObject<T extends z.$ZodObject>(formData: FormData, schema: T): Record<string, unknown>;
41
+ export declare function formDataToObject<T extends z.$ZodObject>(formData: FormData, schema: T,
42
+ /** @internal */
43
+ prefix?: string): Record<string, unknown>;
42
44
  export declare function serializeActionResult(res: SafeResult<any, any>): SerializedActionResult;
43
45
  export {};
@@ -206,29 +206,60 @@ function isActionAPIContext(ctx) {
206
206
  const symbol = Reflect.get(ctx, ACTION_API_CONTEXT_SYMBOL);
207
207
  return symbol === true;
208
208
  }
209
- function formDataToObject(formData, schema) {
210
- const obj = schema._zod.def.catchall ? Object.fromEntries(formData.entries()) : {};
209
+ function formDataToObject(formData, schema, prefix = "") {
210
+ const formKeys = [...formData.keys()];
211
+ const obj = schema._zod.def.catchall ? Object.fromEntries(
212
+ [...formData.entries()].filter(([k]) => k.startsWith(prefix)).map(([k, v]) => [k.slice(prefix.length), v])
213
+ ) : {};
211
214
  for (const [key, baseValidator] of Object.entries(schema._zod.def.shape)) {
215
+ const prefixedKey = prefix + key;
212
216
  let validator = baseValidator;
213
217
  while (validator instanceof z.$ZodOptional || validator instanceof z.$ZodNullable || validator instanceof z.$ZodDefault) {
214
- if (validator instanceof z.$ZodDefault && !formData.has(key)) {
218
+ if (validator instanceof z.$ZodDefault && !formDataHasKeyOrPrefix(formKeys, prefixedKey)) {
215
219
  obj[key] = validator._zod.def.defaultValue instanceof Function ? validator._zod.def.defaultValue() : validator._zod.def.defaultValue;
216
220
  }
217
221
  validator = validator._zod.def.innerType;
218
222
  }
219
- if (!formData.has(key) && key in obj) {
223
+ while (validator instanceof z.$ZodPipe) {
224
+ validator = validator._zod.def.in;
225
+ }
226
+ if (validator instanceof z.$ZodDiscriminatedUnion) {
227
+ const typeKey = validator._zod.def.discriminator;
228
+ const typeValue = formData.get(prefixedKey + "." + typeKey);
229
+ if (typeof typeValue === "string") {
230
+ const match = validator._zod.def.options.find(
231
+ (option) => option.def.shape[typeKey].values.has(typeValue)
232
+ );
233
+ if (match) {
234
+ validator = match;
235
+ }
236
+ }
237
+ }
238
+ if (validator instanceof z.$ZodObject) {
239
+ const nestedPrefix = prefixedKey + ".";
240
+ const hasNestedKeys = formKeys.some((k) => k.startsWith(nestedPrefix));
241
+ if (hasNestedKeys) {
242
+ obj[key] = formDataToObject(formData, validator, nestedPrefix);
243
+ } else if (!(key in obj)) {
244
+ obj[key] = baseValidator instanceof z.$ZodNullable ? null : void 0;
245
+ }
246
+ } else if (!formData.has(prefixedKey) && key in obj) {
220
247
  continue;
221
248
  } else if (validator instanceof z.$ZodBoolean) {
222
- const val = formData.get(key);
223
- obj[key] = val === "true" ? true : val === "false" ? false : formData.has(key);
249
+ const val = formData.get(prefixedKey);
250
+ obj[key] = val === "true" ? true : val === "false" ? false : formData.has(prefixedKey);
224
251
  } else if (validator instanceof z.$ZodArray) {
225
- obj[key] = handleFormDataGetAll(key, formData, validator);
252
+ obj[key] = handleFormDataGetAll(prefixedKey, formData, validator);
226
253
  } else {
227
- obj[key] = handleFormDataGet(key, formData, validator, baseValidator);
254
+ obj[key] = handleFormDataGet(prefixedKey, formData, validator, baseValidator);
228
255
  }
229
256
  }
230
257
  return obj;
231
258
  }
259
+ function formDataHasKeyOrPrefix(formKeys, key) {
260
+ const prefix = key + ".";
261
+ return formKeys.some((k) => k === key || k.startsWith(prefix));
262
+ }
232
263
  function handleFormDataGetAll(key, formData, validator) {
233
264
  const entries = Array.from(formData.getAll(key));
234
265
  const elementValidator = validator._zod.def.element;
@@ -1,6 +1,6 @@
1
1
  class BuildTimeAstroVersionProvider {
2
2
  // Injected during the build through esbuild define
3
- version = "6.0.7";
3
+ version = "6.0.8";
4
4
  }
5
5
  export {
6
6
  BuildTimeAstroVersionProvider
@@ -192,7 +192,7 @@ ${contentConfig.error.message}`
192
192
  logger.info("Content config changed");
193
193
  shouldClear = true;
194
194
  }
195
- if (previousAstroVersion && previousAstroVersion !== "6.0.7") {
195
+ if (previousAstroVersion && previousAstroVersion !== "6.0.8") {
196
196
  logger.info("Astro version changed");
197
197
  shouldClear = true;
198
198
  }
@@ -200,8 +200,8 @@ ${contentConfig.error.message}`
200
200
  logger.info("Clearing content store");
201
201
  this.#store.clearAll();
202
202
  }
203
- if ("6.0.7") {
204
- this.#store.metaStore().set("astro-version", "6.0.7");
203
+ if ("6.0.8") {
204
+ this.#store.metaStore().set("astro-version", "6.0.8");
205
205
  }
206
206
  if (currentConfigDigest) {
207
207
  this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "6.0.7";
1
+ const ASTRO_VERSION = "6.0.8";
2
2
  const ASTRO_GENERATOR = `Astro v${ASTRO_VERSION}`;
3
3
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
4
4
  const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
@@ -26,7 +26,7 @@ async function dev(inlineConfig) {
26
26
  await telemetry.record([]);
27
27
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
28
28
  const logger = restart.container.logger;
29
- const currentVersion = "6.0.7";
29
+ const currentVersion = "6.0.8";
30
30
  const isPrerelease = currentVersion.includes("-");
31
31
  if (!isPrerelease) {
32
32
  try {
@@ -269,7 +269,7 @@ function printHelp({
269
269
  message.push(
270
270
  linebreak(),
271
271
  ` ${bgGreen(black(` ${commandName} `))} ${green(
272
- `v${"6.0.7"}`
272
+ `v${"6.0.8"}`
273
273
  )} ${headline}`
274
274
  );
275
275
  }
@@ -34,4 +34,13 @@ export declare function findRouteToRewrite({ payload, routes, request, trailingS
34
34
  export declare function copyRequest(newUrl: URL, oldRequest: Request, isPrerendered: boolean, logger: Logger, routePattern: string): Request;
35
35
  export declare function setOriginPathname(request: Request, pathname: string, trailingSlash: AstroConfig['trailingSlash'], buildFormat: AstroConfig['build']['format']): void;
36
36
  export declare function getOriginPathname(request: Request): string;
37
+ /**
38
+ * Pure function that normalizes a rewrite target pathname by stripping the base,
39
+ * handling trailing slashes, removing `.html` suffixes, and computing the final
40
+ * full URL pathname (with base re-prepended).
41
+ */
42
+ export declare function normalizeRewritePathname(urlPathname: string, base: AstroConfig['base'], trailingSlash: AstroConfig['trailingSlash'], buildFormat: AstroConfig['build']['format']): {
43
+ pathname: string;
44
+ resolvedUrlPathname: string;
45
+ };
37
46
  export {};
@@ -1,3 +1,4 @@
1
+ import { collapseDuplicateSlashes } from "@astrojs/internal-helpers/path";
1
2
  import { shouldAppendForwardSlash } from "../build/util.js";
2
3
  import { originPathnameSymbol } from "../constants.js";
3
4
  import { AstroError, AstroErrorData } from "../errors/index.js";
@@ -26,33 +27,15 @@ function findRouteToRewrite({
26
27
  } else if (payload instanceof Request) {
27
28
  newUrl = new URL(payload.url);
28
29
  } else {
29
- newUrl = new URL(payload, new URL(request.url).origin);
30
- }
31
- let pathname = newUrl.pathname;
32
- const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat);
33
- if (base !== "/") {
34
- const isBasePathRequest = newUrl.pathname === base || newUrl.pathname === removeTrailingForwardSlash(base);
35
- if (isBasePathRequest) {
36
- pathname = shouldAppendSlash ? "/" : "";
37
- } else if (newUrl.pathname.startsWith(base)) {
38
- pathname = shouldAppendSlash ? appendForwardSlash(newUrl.pathname) : removeTrailingForwardSlash(newUrl.pathname);
39
- pathname = pathname.slice(base.length);
40
- }
41
- }
42
- if (!pathname.startsWith("/") && shouldAppendSlash && newUrl.pathname.endsWith("/")) {
43
- pathname = prependForwardSlash(pathname);
44
- }
45
- if (pathname === "/" && base !== "/" && !shouldAppendSlash) {
46
- pathname = "";
47
- }
48
- if (buildFormat === "file") {
49
- pathname = pathname.replace(/\.html$/, "");
50
- }
51
- if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) {
52
- newUrl.pathname = removeTrailingForwardSlash(base);
53
- } else {
54
- newUrl.pathname = joinPaths(...[base, pathname].filter(Boolean));
30
+ newUrl = new URL(collapseDuplicateSlashes(payload), new URL(request.url).origin);
55
31
  }
32
+ const { pathname, resolvedUrlPathname } = normalizeRewritePathname(
33
+ newUrl.pathname,
34
+ base,
35
+ trailingSlash,
36
+ buildFormat
37
+ );
38
+ newUrl.pathname = resolvedUrlPathname;
56
39
  const decodedPathname = decodeURI(pathname);
57
40
  if (isRoute404(decodedPathname)) {
58
41
  const errorRoute = routes.find((route) => route.route === "/404");
@@ -145,9 +128,39 @@ function getOriginPathname(request) {
145
128
  }
146
129
  return new URL(request.url).pathname;
147
130
  }
131
+ function normalizeRewritePathname(urlPathname, base, trailingSlash, buildFormat) {
132
+ let pathname = collapseDuplicateSlashes(urlPathname);
133
+ const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat);
134
+ if (base !== "/") {
135
+ const isBasePathRequest = urlPathname === base || urlPathname === removeTrailingForwardSlash(base);
136
+ if (isBasePathRequest) {
137
+ pathname = shouldAppendSlash ? "/" : "";
138
+ } else if (urlPathname.startsWith(base)) {
139
+ pathname = shouldAppendSlash ? appendForwardSlash(urlPathname) : removeTrailingForwardSlash(urlPathname);
140
+ pathname = pathname.slice(base.length);
141
+ }
142
+ }
143
+ if (!pathname.startsWith("/") && shouldAppendSlash && urlPathname.endsWith("/")) {
144
+ pathname = prependForwardSlash(pathname);
145
+ }
146
+ if (pathname === "/" && base !== "/" && !shouldAppendSlash) {
147
+ pathname = "";
148
+ }
149
+ if (buildFormat === "file") {
150
+ pathname = pathname.replace(/\.html$/, "");
151
+ }
152
+ let resolvedUrlPathname;
153
+ if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) {
154
+ resolvedUrlPathname = removeTrailingForwardSlash(base);
155
+ } else {
156
+ resolvedUrlPathname = joinPaths(...[base, pathname].filter(Boolean));
157
+ }
158
+ return { pathname, resolvedUrlPathname };
159
+ }
148
160
  export {
149
161
  copyRequest,
150
162
  findRouteToRewrite,
151
163
  getOriginPathname,
164
+ normalizeRewritePathname,
152
165
  setOriginPathname
153
166
  };
@@ -26,6 +26,8 @@ async function ensureModulesLoaded(env, mod, seen = /* @__PURE__ */ new Set()) {
26
26
  if (!imp.id) continue;
27
27
  if (seen.has(imp.id)) continue;
28
28
  if (imp.id.includes(PROPAGATED_ASSET_QUERY_PARAM)) continue;
29
+ if (imp.id === RESOLVED_MODULE_DEV_CSS || imp.id === RESOLVED_MODULE_DEV_CSS_ALL || imp.id.startsWith(RESOLVED_MODULE_DEV_CSS_PREFIX))
30
+ continue;
29
31
  if (!imp.transformResult) {
30
32
  try {
31
33
  await env.fetchModule(imp.id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "6.0.7",
3
+ "version": "6.0.8",
4
4
  "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
5
5
  "type": "module",
6
6
  "author": "withastro",