astro 4.16.0 → 4.16.1

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.
@@ -1,5 +1,7 @@
1
1
  import { yellow } from "kleur/colors";
2
+ import { ASTRO_ORIGIN_HEADER } from "../../core/constants.js";
2
3
  import { defineMiddleware } from "../../core/middleware/index.js";
4
+ import { getOriginHeader } from "../../core/routing/rewrite.js";
3
5
  import { ACTION_QUERY_PARAMS } from "../consts.js";
4
6
  import { formContentTypes, hasContentType } from "./utils.js";
5
7
  import { getAction } from "./virtual/get-action.js";
@@ -84,10 +86,14 @@ async function redirectWithResult({
84
86
  actionResult: serializeActionResult(actionResult)
85
87
  });
86
88
  if (actionResult.error) {
87
- const referer = context.request.headers.get("Referer");
88
- if (!referer) {
89
+ const referer2 = context.request.headers.get("Referer");
90
+ if (!referer2) {
89
91
  throw new Error("Internal: Referer unexpectedly missing from Action POST request.");
90
92
  }
93
+ return context.redirect(referer2);
94
+ }
95
+ const referer = getOriginHeader(context.request);
96
+ if (referer) {
91
97
  return context.redirect(referer);
92
98
  }
93
99
  return context.redirect(context.url.pathname);
@@ -1,5 +1,5 @@
1
1
  import { promises as fs, existsSync } from "node:fs";
2
- import * as fastq from "fastq";
2
+ import PQueue from "p-queue";
3
3
  import xxhash from "xxhash-wasm";
4
4
  import { AstroUserError } from "../core/errors/errors.js";
5
5
  import {
@@ -28,13 +28,13 @@ class ContentLayer {
28
28
  this.#store = store;
29
29
  this.#settings = settings;
30
30
  this.#watcher = watcher;
31
- this.#queue = fastq.promise(this.#doSync.bind(this), 1);
31
+ this.#queue = new PQueue({ concurrency: 1 });
32
32
  }
33
33
  /**
34
34
  * Whether the content layer is currently loading content
35
35
  */
36
36
  get loading() {
37
- return !this.#queue.idle();
37
+ return this.#queue.size > 0 || this.#queue.pending > 0;
38
38
  }
39
39
  /**
40
40
  * Watch for changes to the content config and trigger a sync when it changes.
@@ -90,7 +90,7 @@ class ContentLayer {
90
90
  * so that only one sync can run at a time. The function returns a promise that resolves when this sync job is complete.
91
91
  */
92
92
  sync(options = {}) {
93
- return this.#queue.push(options);
93
+ return this.#queue.add(() => this.#doSync(options));
94
94
  }
95
95
  async #doSync(options) {
96
96
  const contentConfig = globalContentConfigObserver.get();
@@ -121,7 +121,7 @@ class ContentLayer {
121
121
  logger.info("Content config changed");
122
122
  shouldClear = true;
123
123
  }
124
- if (previousAstroVersion !== "4.16.0") {
124
+ if (previousAstroVersion !== "4.16.1") {
125
125
  logger.info("Astro version changed");
126
126
  shouldClear = true;
127
127
  }
@@ -129,8 +129,8 @@ class ContentLayer {
129
129
  logger.info("Clearing content store");
130
130
  this.#store.clearAll();
131
131
  }
132
- if ("4.16.0") {
133
- await this.#store.metaStore().set("astro-version", "4.16.0");
132
+ if ("4.16.1") {
133
+ await this.#store.metaStore().set("astro-version", "4.16.1");
134
134
  }
135
135
  if (currentConfigDigest) {
136
136
  await this.#store.metaStore().set("config-digest", currentConfigDigest);
@@ -25,6 +25,10 @@ export declare const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
25
25
  * This metadata is used to determine the origin of a Response. If a rewrite has occurred, it should be prioritised over other logic.
26
26
  */
27
27
  export declare const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
28
+ /**
29
+ * Header used to track the original URL requested by the user. This information is useful rewrites are involved.
30
+ */
31
+ export declare const ASTRO_ORIGIN_HEADER = "X-Astro-Origin";
28
32
  export declare const REWRITE_DIRECTIVE_HEADER_VALUE = "yes";
29
33
  /**
30
34
  * The name for the header used to help i18n middleware, which only needs to act on "page" and "fallback" route types.
@@ -1,6 +1,7 @@
1
- const ASTRO_VERSION = "4.16.0";
1
+ const ASTRO_VERSION = "4.16.1";
2
2
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
3
3
  const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
4
+ const ASTRO_ORIGIN_HEADER = "X-Astro-Origin";
4
5
  const REWRITE_DIRECTIVE_HEADER_VALUE = "yes";
5
6
  const ROUTE_TYPE_HEADER = "X-Astro-Route-Type";
6
7
  const DEFAULT_404_COMPONENT = "astro-default-404.astro";
@@ -20,6 +21,7 @@ const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
20
21
  ];
21
22
  const MIDDLEWARE_PATH_SEGMENT_NAME = "middleware";
22
23
  export {
24
+ ASTRO_ORIGIN_HEADER,
23
25
  ASTRO_VERSION,
24
26
  DEFAULT_404_COMPONENT,
25
27
  DEFAULT_500_COMPONENT,
@@ -22,7 +22,7 @@ async function dev(inlineConfig) {
22
22
  await telemetry.record([]);
23
23
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
24
24
  const logger = restart.container.logger;
25
- const currentVersion = "4.16.0";
25
+ const currentVersion = "4.16.1";
26
26
  const isPrerelease = currentVersion.includes("-");
27
27
  if (!isPrerelease) {
28
28
  try {
@@ -29,8 +29,6 @@ export declare function info(opts: LogOptions, label: string | null, message: st
29
29
  export declare function warn(opts: LogOptions, label: string | null, message: string, newLine?: boolean): void;
30
30
  /** Emit a error message, Useful when Astro can't recover from some error. */
31
31
  export declare function error(opts: LogOptions, label: string | null, message: string, newLine?: boolean): void;
32
- type LogFn = typeof info | typeof warn | typeof error;
33
- export declare function table(opts: LogOptions, columns: number[]): (logFn: LogFn, ...input: Array<any>) => void;
34
32
  export declare function debug(...args: any[]): void;
35
33
  /**
36
34
  * Get the prefix for a log message.
@@ -63,4 +61,3 @@ export declare class AstroIntegrationLogger {
63
61
  error(message: string): void;
64
62
  debug(message: string): void;
65
63
  }
66
- export {};
@@ -1,5 +1,4 @@
1
1
  import { blue, bold, dim, red, yellow } from "kleur/colors";
2
- import stringWidth from "string-width";
3
2
  const dateTimeFormat = new Intl.DateTimeFormat([], {
4
3
  hour: "2-digit",
5
4
  minute: "2-digit",
@@ -39,25 +38,11 @@ function warn(opts, label, message, newLine = true) {
39
38
  function error(opts, label, message, newLine = true) {
40
39
  return log(opts, "error", label, message, newLine);
41
40
  }
42
- function table(opts, columns) {
43
- return function logTable(logFn, ...input) {
44
- const message = columns.map((len, i) => padStr(input[i].toString(), len)).join(" ");
45
- logFn(opts, null, message);
46
- };
47
- }
48
41
  function debug(...args) {
49
42
  if ("_astroGlobalDebug" in globalThis) {
50
43
  globalThis._astroGlobalDebug(...args);
51
44
  }
52
45
  }
53
- function padStr(str, len) {
54
- const strLen = stringWidth(str);
55
- if (strLen > len) {
56
- return str.substring(0, len - 3) + "...";
57
- }
58
- const spaces = Array.from({ length: len - strLen }, () => " ").join("");
59
- return str + spaces;
60
- }
61
46
  function getEventPrefix({ level, label }) {
62
47
  const timestamp = `${dateTimeFormat.format(/* @__PURE__ */ new Date())}`;
63
48
  const prefix = [];
@@ -147,7 +132,6 @@ export {
147
132
  isLogLevelEnabled,
148
133
  levels,
149
134
  log,
150
- table,
151
135
  timerMessage,
152
136
  warn
153
137
  };
@@ -38,7 +38,7 @@ function serverStart({
38
38
  host,
39
39
  base
40
40
  }) {
41
- const version = "4.16.0";
41
+ const version = "4.16.1";
42
42
  const localPrefix = `${dim("\u2503")} Local `;
43
43
  const networkPrefix = `${dim("\u2503")} Network `;
44
44
  const emptyPrefix = " ".repeat(11);
@@ -270,7 +270,7 @@ function printHelp({
270
270
  message.push(
271
271
  linebreak(),
272
272
  ` ${bgGreen(black(` ${commandName} `))} ${green(
273
- `v${"4.16.0"}`
273
+ `v${"4.16.1"}`
274
274
  )} ${headline}`
275
275
  );
276
276
  }
@@ -1,6 +1,7 @@
1
1
  import { AstroCookies } from "../cookies/cookies.js";
2
2
  import { apiContextRoutesSymbol } from "../render-context.js";
3
3
  import { getParams } from "../render/index.js";
4
+ import { copyRequest } from "../routing/rewrite.js";
4
5
  import { defineMiddleware } from "./index.js";
5
6
  function sequence(...handlers) {
6
7
  const filtered = handlers.filter((h) => !!h);
@@ -22,9 +23,9 @@ function sequence(...handlers) {
22
23
  if (payload instanceof Request) {
23
24
  newRequest = payload;
24
25
  } else if (payload instanceof URL) {
25
- newRequest = new Request(payload, handleContext.request);
26
+ newRequest = copyRequest(payload, handleContext.request);
26
27
  } else {
27
- newRequest = new Request(
28
+ newRequest = copyRequest(
28
29
  new URL(payload, handleContext.url.origin),
29
30
  handleContext.request
30
31
  );
@@ -8,6 +8,7 @@ import {
8
8
  import { renderEndpoint } from "../runtime/server/endpoint.js";
9
9
  import { renderPage } from "../runtime/server/index.js";
10
10
  import {
11
+ ASTRO_ORIGIN_HEADER,
11
12
  ASTRO_VERSION,
12
13
  REROUTE_DIRECTIVE_HEADER,
13
14
  REWRITE_DIRECTIVE_HEADER_KEY,
@@ -24,6 +25,7 @@ import { callMiddleware } from "./middleware/callMiddleware.js";
24
25
  import { sequence } from "./middleware/index.js";
25
26
  import { renderRedirect } from "./redirects/render.js";
26
27
  import { Slots, getParams, getProps } from "./render/index.js";
28
+ import { copyRequest, setOriginHeader } from "./routing/rewrite.js";
27
29
  const apiContextRoutesSymbol = Symbol.for("context.routes");
28
30
  class RenderContext {
29
31
  constructor(pipeline, locals, middleware, pathname, request, routeData, status, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}) {
@@ -58,6 +60,7 @@ class RenderContext {
58
60
  props
59
61
  }) {
60
62
  const pipelineMiddleware = await pipeline.getMiddleware();
63
+ setOriginHeader(request, pathname);
61
64
  return new RenderContext(
62
65
  pipeline,
63
66
  locals,
@@ -118,7 +121,7 @@ class RenderContext {
118
121
  if (payload instanceof Request) {
119
122
  this.request = payload;
120
123
  } else {
121
- this.request = this.#copyRequest(newUrl, this.request);
124
+ this.request = copyRequest(newUrl, this.request);
122
125
  }
123
126
  this.isRewriting = true;
124
127
  this.url = new URL(this.request.url);
@@ -202,7 +205,7 @@ class RenderContext {
202
205
  if (reroutePayload instanceof Request) {
203
206
  this.request = reroutePayload;
204
207
  } else {
205
- this.request = this.#copyRequest(newUrl, this.request);
208
+ this.request = copyRequest(newUrl, this.request);
206
209
  }
207
210
  this.url = new URL(this.request.url);
208
211
  this.cookies = new AstroCookies(this.request);
@@ -448,34 +451,6 @@ class RenderContext {
448
451
  if (!i18n) return;
449
452
  return this.#preferredLocaleList ??= computePreferredLocaleList(request, i18n.locales);
450
453
  }
451
- /**
452
- * Utility function that creates a new `Request` with a new URL from an old `Request`.
453
- *
454
- * @param newUrl The new `URL`
455
- * @param oldRequest The old `Request`
456
- */
457
- #copyRequest(newUrl, oldRequest) {
458
- if (oldRequest.bodyUsed) {
459
- throw new AstroError(AstroErrorData.RewriteWithBodyUsed);
460
- }
461
- return new Request(newUrl, {
462
- method: oldRequest.method,
463
- headers: oldRequest.headers,
464
- body: oldRequest.body,
465
- referrer: oldRequest.referrer,
466
- referrerPolicy: oldRequest.referrerPolicy,
467
- mode: oldRequest.mode,
468
- credentials: oldRequest.credentials,
469
- cache: oldRequest.cache,
470
- redirect: oldRequest.redirect,
471
- integrity: oldRequest.integrity,
472
- signal: oldRequest.signal,
473
- keepalive: oldRequest.keepalive,
474
- // https://fetch.spec.whatwg.org/#dom-request-duplex
475
- // @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
476
- duplex: "half"
477
- });
478
- }
479
454
  }
480
455
  export {
481
456
  RenderContext,
@@ -18,3 +18,12 @@ export interface FindRouteToRewriteResult {
18
18
  * 2.
19
19
  */
20
20
  export declare function findRouteToRewrite({ payload, routes, request, trailingSlash, buildFormat, base, }: FindRouteToRewrite): FindRouteToRewriteResult;
21
+ /**
22
+ * Utility function that creates a new `Request` with a new URL from an old `Request`.
23
+ *
24
+ * @param newUrl The new `URL`
25
+ * @param oldRequest The old `Request`
26
+ */
27
+ export declare function copyRequest(newUrl: URL, oldRequest: Request): Request;
28
+ export declare function setOriginHeader(request: Request, pathname: string): void;
29
+ export declare function getOriginHeader(request: Request): string | undefined;
@@ -1,4 +1,6 @@
1
1
  import { shouldAppendForwardSlash } from "../build/util.js";
2
+ import { ASTRO_ORIGIN_HEADER } from "../constants.js";
3
+ import { AstroError, AstroErrorData } from "../errors/index.js";
2
4
  import { appendForwardSlash, removeTrailingForwardSlash } from "../path.js";
3
5
  import { DEFAULT_404_ROUTE } from "./astro-designed-error-pages.js";
4
6
  function findRouteToRewrite({
@@ -44,6 +46,41 @@ function findRouteToRewrite({
44
46
  }
45
47
  }
46
48
  }
49
+ function copyRequest(newUrl, oldRequest) {
50
+ if (oldRequest.bodyUsed) {
51
+ throw new AstroError(AstroErrorData.RewriteWithBodyUsed);
52
+ }
53
+ return new Request(newUrl, {
54
+ method: oldRequest.method,
55
+ headers: oldRequest.headers,
56
+ body: oldRequest.body,
57
+ referrer: oldRequest.referrer,
58
+ referrerPolicy: oldRequest.referrerPolicy,
59
+ mode: oldRequest.mode,
60
+ credentials: oldRequest.credentials,
61
+ cache: oldRequest.cache,
62
+ redirect: oldRequest.redirect,
63
+ integrity: oldRequest.integrity,
64
+ signal: oldRequest.signal,
65
+ keepalive: oldRequest.keepalive,
66
+ // https://fetch.spec.whatwg.org/#dom-request-duplex
67
+ // @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
68
+ duplex: "half"
69
+ });
70
+ }
71
+ function setOriginHeader(request, pathname) {
72
+ request.headers.set(ASTRO_ORIGIN_HEADER, encodeURIComponent(pathname));
73
+ }
74
+ function getOriginHeader(request) {
75
+ const origin = request.headers.get(ASTRO_ORIGIN_HEADER);
76
+ if (origin) {
77
+ return decodeURIComponent(origin);
78
+ }
79
+ return void 0;
80
+ }
47
81
  export {
48
- findRouteToRewrite
82
+ copyRequest,
83
+ findRouteToRewrite,
84
+ getOriginHeader,
85
+ setOriginHeader
49
86
  };
@@ -75,7 +75,7 @@ function getFallback() {
75
75
  }
76
76
  function runScripts() {
77
77
  let wait = Promise.resolve();
78
- for (const script of Array.from(document.scripts)) {
78
+ for (const script of document.getElementsByTagName("script")) {
79
79
  if (script.dataset.astroExec === "") continue;
80
80
  const type = script.getAttribute("type");
81
81
  if (type && type !== "module" && type !== "text/javascript") continue;
@@ -416,7 +416,7 @@ if (inBrowser) {
416
416
  );
417
417
  }
418
418
  }
419
- for (const script of document.scripts) {
419
+ for (const script of document.getElementsByTagName("script")) {
420
420
  script.dataset.astroExec = "";
421
421
  }
422
422
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "4.16.0",
3
+ "version": "4.16.1",
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",
@@ -135,7 +135,6 @@
135
135
  "esbuild": "^0.21.5",
136
136
  "estree-walker": "^3.0.3",
137
137
  "fast-glob": "^3.3.2",
138
- "fastq": "^1.17.1",
139
138
  "flattie": "^1.1.1",
140
139
  "github-slugger": "^2.0.0",
141
140
  "gray-matter": "^4.0.3",
@@ -156,7 +155,6 @@
156
155
  "rehype": "^13.0.2",
157
156
  "semver": "^7.6.3",
158
157
  "shiki": "^1.22.0",
159
- "string-width": "^7.2.0",
160
158
  "tinyexec": "^0.3.0",
161
159
  "tsconfck": "^3.1.3",
162
160
  "unist-util-visit": "^5.0.0",
@@ -98,6 +98,7 @@ declare module 'astro:content' {
98
98
  /** Run `astro sync` to generate high fidelity types */
99
99
  export type CollectionKey = any;
100
100
  /** Run `astro sync` to generate high fidelity types */
101
+ // biome-ignore lint/correctness/noUnusedVariables: stub generic type to match generated type
101
102
  export type CollectionEntry<C> = any;
102
103
  /** Run `astro sync` to generate high fidelity types */
103
104
  export type ContentCollectionKey = any;