astro 7.2.2 → 7.2.4

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.
Files changed (158) hide show
  1. package/dist/actions/handler.d.ts +6 -12
  2. package/dist/actions/handler.js +30 -40
  3. package/dist/actions/load.d.ts +12 -0
  4. package/dist/actions/load.js +55 -0
  5. package/dist/actions/runtime/entrypoints/server.js +5 -4
  6. package/dist/actions/runtime/server.js +8 -6
  7. package/dist/assets/fonts/providers/index.d.ts +1 -1
  8. package/dist/assets/fonts/providers/index.js +2 -12
  9. package/dist/assets/utils/vendor/image-size/types/heif.js +8 -3
  10. package/dist/assets/utils/vendor/image-size/types/icns.js +10 -2
  11. package/dist/assets/utils/vendor/image-size/types/jp2.js +2 -2
  12. package/dist/assets/utils/vendor/image-size/types/jxl.js +5 -2
  13. package/dist/assets/utils/vendor/image-size/types/utils.d.ts +1 -1
  14. package/dist/assets/utils/vendor/image-size/types/utils.js +20 -6
  15. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  16. package/dist/container/environment.d.ts +20 -0
  17. package/dist/container/environment.js +106 -0
  18. package/dist/container/index.js +73 -37
  19. package/dist/content/content-layer.js +3 -3
  20. package/dist/content/data-store-writer.d.ts +7 -10
  21. package/dist/content/data-store-writer.js +62 -27
  22. package/dist/content/data-store.d.ts +20 -3
  23. package/dist/content/data-store.js +28 -7
  24. package/dist/content/mutable-data-store.js +15 -10
  25. package/dist/content/runtime.d.ts +3 -2
  26. package/dist/content/runtime.js +43 -26
  27. package/dist/core/app/app.d.ts +0 -2
  28. package/dist/core/app/app.js +0 -7
  29. package/dist/core/app/base.d.ts +32 -20
  30. package/dist/core/app/base.js +79 -73
  31. package/dist/core/app/dev-facade.d.ts +27 -0
  32. package/dist/core/app/dev-facade.js +51 -0
  33. package/dist/core/app/entrypoints/index.d.ts +0 -1
  34. package/dist/core/app/entrypoints/index.js +0 -2
  35. package/dist/core/app/entrypoints/virtual/dev.js +24 -19
  36. package/dist/core/app/node.js +13 -14
  37. package/dist/core/app/prepare-response.d.ts +1 -1
  38. package/dist/core/app/validate-headers.js +7 -3
  39. package/dist/core/build/app.d.ts +31 -6
  40. package/dist/core/build/app.js +31 -13
  41. package/dist/core/build/environment.d.ts +25 -0
  42. package/dist/core/build/environment.js +157 -0
  43. package/dist/core/cache/handler.d.ts +13 -7
  44. package/dist/core/cache/handler.js +55 -51
  45. package/dist/core/cache/provider.d.ts +4 -0
  46. package/dist/core/cache/provider.js +15 -0
  47. package/dist/core/constants.d.ts +0 -11
  48. package/dist/core/constants.js +1 -5
  49. package/dist/core/dev/dev.js +1 -1
  50. package/dist/core/environment/dev-nonrunnable.d.ts +6 -0
  51. package/dist/core/environment/dev-nonrunnable.js +170 -0
  52. package/dist/core/environment/index.d.ts +90 -0
  53. package/dist/core/environment/index.js +12 -0
  54. package/dist/core/environment/production.d.ts +6 -0
  55. package/dist/core/environment/production.js +117 -0
  56. package/dist/core/errors/build-handler.d.ts +5 -10
  57. package/dist/core/errors/build-handler.js +11 -17
  58. package/dist/core/errors/default-handler.d.ts +4 -9
  59. package/dist/core/errors/default-handler.js +92 -107
  60. package/dist/core/errors/dev-handler.d.ts +7 -11
  61. package/dist/core/errors/dev-handler.js +71 -69
  62. package/dist/core/errors/errors-data.d.ts +18 -0
  63. package/dist/core/errors/errors-data.js +7 -0
  64. package/dist/core/errors/handler.d.ts +22 -3
  65. package/dist/core/errors/handler.js +25 -0
  66. package/dist/core/fetch/default-handler.d.ts +15 -8
  67. package/dist/core/fetch/default-handler.js +12 -34
  68. package/dist/core/fetch/features.d.ts +23 -0
  69. package/dist/core/fetch/features.js +27 -0
  70. package/dist/core/fetch/fetch-state.d.ts +52 -7
  71. package/dist/core/fetch/fetch-state.js +99 -92
  72. package/dist/core/fetch/index.d.ts +9 -2
  73. package/dist/core/fetch/index.js +18 -79
  74. package/dist/core/fetch/vite-plugin.js +2 -1
  75. package/dist/core/i18n/domain.js +4 -11
  76. package/dist/core/i18n/handler.d.ts +28 -13
  77. package/dist/core/i18n/handler.js +100 -100
  78. package/dist/core/logger/manifest-logger.d.ts +31 -0
  79. package/dist/core/logger/manifest-logger.js +37 -0
  80. package/dist/core/manifest/ambient-source.d.ts +2 -0
  81. package/dist/core/manifest/ambient-source.js +4 -0
  82. package/dist/core/manifest/ambient.d.ts +16 -0
  83. package/dist/core/manifest/ambient.js +22 -0
  84. package/dist/core/manifest/derived.d.ts +3 -0
  85. package/dist/core/manifest/derived.js +10 -0
  86. package/dist/core/manifest/memo.d.ts +31 -0
  87. package/dist/core/manifest/memo.js +47 -0
  88. package/dist/core/messages/runtime.js +1 -1
  89. package/dist/core/middleware/astro-middleware.d.ts +25 -35
  90. package/dist/core/middleware/astro-middleware.js +61 -81
  91. package/dist/core/middleware/load.d.ts +19 -0
  92. package/dist/core/middleware/load.js +36 -0
  93. package/dist/core/middleware/sequence.js +15 -7
  94. package/dist/core/pages/handler.d.ts +18 -25
  95. package/dist/core/pages/handler.js +68 -84
  96. package/dist/core/redirects/render.js +3 -8
  97. package/dist/core/render/index.d.ts +0 -1
  98. package/dist/core/render/index.js +0 -2
  99. package/dist/core/render/route-cache.d.ts +6 -1
  100. package/dist/core/render/route-cache.js +11 -1
  101. package/dist/core/rewrites/handler.d.ts +4 -6
  102. package/dist/core/rewrites/handler.js +19 -20
  103. package/dist/core/routing/default.d.ts +2 -0
  104. package/dist/core/routing/default.js +7 -1
  105. package/dist/core/routing/dev.d.ts +1 -3
  106. package/dist/core/routing/dev.js +12 -5
  107. package/dist/core/routing/handler.d.ts +6 -16
  108. package/dist/core/routing/handler.js +126 -164
  109. package/dist/core/routing/helpers.d.ts +7 -1
  110. package/dist/core/routing/helpers.js +21 -0
  111. package/dist/core/routing/match-request.d.ts +10 -0
  112. package/dist/core/routing/match-request.js +46 -0
  113. package/dist/core/routing/route-table.d.ts +34 -0
  114. package/dist/core/routing/route-table.js +41 -0
  115. package/dist/core/routing/trailing-slash-handler.d.ts +4 -14
  116. package/dist/core/routing/trailing-slash-handler.js +39 -50
  117. package/dist/core/server-islands/mappings.d.ts +6 -0
  118. package/dist/core/server-islands/mappings.js +12 -0
  119. package/dist/core/session/driver.d.ts +4 -0
  120. package/dist/core/session/driver.js +14 -0
  121. package/dist/core/session/handler.d.ts +1 -1
  122. package/dist/core/session/handler.js +8 -8
  123. package/dist/core/session/provider-disabled.js +2 -2
  124. package/dist/entrypoints/prerender.js +5 -1
  125. package/dist/i18n/middleware.d.ts +4 -4
  126. package/dist/i18n/middleware.js +3 -3
  127. package/dist/manifest/serialized.d.ts +1 -0
  128. package/dist/manifest/serialized.js +9 -2
  129. package/dist/runtime/prerender/static-paths.d.ts +14 -2
  130. package/dist/runtime/prerender/static-paths.js +4 -3
  131. package/dist/types/public/config.d.ts +433 -241
  132. package/dist/vite-plugin-app/createAstroServerApp.js +22 -18
  133. package/dist/vite-plugin-app/environment.d.ts +18 -0
  134. package/dist/vite-plugin-app/environment.js +210 -0
  135. package/dist/vite-plugin-app/handle-request.d.ts +30 -0
  136. package/dist/vite-plugin-app/handle-request.js +129 -0
  137. package/dist/vite-plugin-app/index.d.ts +1 -1
  138. package/dist/vite-plugin-app/index.js +1 -1
  139. package/package.json +14 -7
  140. package/src/core/README.md +37 -0
  141. package/src/core/manifest/ambient-source.ts +9 -0
  142. package/src/types/README.md +5 -0
  143. package/dist/container/pipeline.d.ts +0 -14
  144. package/dist/container/pipeline.js +0 -78
  145. package/dist/core/app/dev/app.d.ts +0 -31
  146. package/dist/core/app/dev/app.js +0 -80
  147. package/dist/core/app/dev/pipeline.d.ts +0 -17
  148. package/dist/core/app/dev/pipeline.js +0 -133
  149. package/dist/core/app/pipeline.d.ts +0 -14
  150. package/dist/core/app/pipeline.js +0 -123
  151. package/dist/core/base-pipeline.d.ts +0 -183
  152. package/dist/core/base-pipeline.js +0 -293
  153. package/dist/core/build/pipeline.d.ts +0 -38
  154. package/dist/core/build/pipeline.js +0 -202
  155. package/dist/vite-plugin-app/app.d.ts +0 -62
  156. package/dist/vite-plugin-app/app.js +0 -237
  157. package/dist/vite-plugin-app/pipeline.d.ts +0 -25
  158. package/dist/vite-plugin-app/pipeline.js +0 -189
@@ -17,16 +17,10 @@ import type { FetchState } from '../core/fetch/fetch-state.js';
17
17
  * page dispatch. That placement preserves the existing behavior where
18
18
  * user middleware sees action requests and response finalization (cookies,
19
19
  * sessions, etc.) runs around the action response.
20
+ *
21
+ * Expects the APIContext that is already being used by the render pipeline.
22
+ * Returns a `Response` when the action fully handles the request (RPC),
23
+ * or `undefined` when the caller should continue processing the request
24
+ * (form actions or non-action requests).
20
25
  */
21
- export declare class ActionHandler {
22
- #private;
23
- /**
24
- * Run action handling for the current request. Expects the APIContext
25
- * that is already being used by the render pipeline.
26
- *
27
- * Returns a `Response` when the action fully handles the request (RPC),
28
- * or `undefined` when the caller should continue processing the
29
- * request (form actions or non-action requests).
30
- */
31
- handle(apiContext: APIContext, state: FetchState): Promise<Response | undefined> | undefined;
32
- }
26
+ export declare function handleAction(apiContext: APIContext, state: FetchState): Promise<Response | undefined> | undefined;
@@ -2,51 +2,41 @@ import {
2
2
  createCrossOriginForbiddenResponse,
3
3
  isForbiddenCrossOriginRequest
4
4
  } from "../core/app/origin-check.js";
5
- import { PipelineFeatures } from "../core/base-pipeline.js";
5
+ import { markFeatureUsed, FetchFeatures } from "../core/fetch/features.js";
6
6
  import { getActionContext, serializeActionResult } from "./runtime/server.js";
7
- class ActionHandler {
8
- /**
9
- * Run action handling for the current request. Expects the APIContext
10
- * that is already being used by the render pipeline.
11
- *
12
- * Returns a `Response` when the action fully handles the request (RPC),
13
- * or `undefined` when the caller should continue processing the
14
- * request (form actions or non-action requests).
15
- */
16
- handle(apiContext, state) {
17
- state.pipeline.usedFeatures |= PipelineFeatures.actions;
18
- if (apiContext.isPrerendered) {
19
- return void 0;
20
- }
21
- const { action, setActionResult } = getActionContext(apiContext);
22
- if (!action) {
23
- return void 0;
24
- }
25
- if (state.pipeline.manifest.checkOrigin && isForbiddenCrossOriginRequest(apiContext.request, apiContext.url, apiContext.isPrerendered)) {
26
- return Promise.resolve(createCrossOriginForbiddenResponse(apiContext.request));
27
- }
28
- return this.#executeAction(action, setActionResult);
7
+ function handleAction(apiContext, state) {
8
+ markFeatureUsed(state.manifest, FetchFeatures.actions);
9
+ if (apiContext.isPrerendered) {
10
+ return void 0;
29
11
  }
30
- async #executeAction(action, setActionResult) {
31
- const actionResult = await action.handler();
32
- const serialized = serializeActionResult(actionResult);
33
- if (action.calledFrom === "rpc") {
34
- if (serialized.type === "empty") {
35
- return new Response(null, {
36
- status: serialized.status
37
- });
38
- }
39
- return new Response(serialized.body, {
40
- status: serialized.status,
41
- headers: {
42
- "Content-Type": serialized.contentType
43
- }
12
+ const { action, setActionResult } = getActionContext(apiContext);
13
+ if (!action) {
14
+ return void 0;
15
+ }
16
+ if (state.manifest.checkOrigin && isForbiddenCrossOriginRequest(apiContext.request, apiContext.url, apiContext.isPrerendered)) {
17
+ return Promise.resolve(createCrossOriginForbiddenResponse(apiContext.request));
18
+ }
19
+ return executeAction(action, setActionResult);
20
+ }
21
+ async function executeAction(action, setActionResult) {
22
+ const actionResult = await action.handler();
23
+ const serialized = serializeActionResult(actionResult);
24
+ if (action.calledFrom === "rpc") {
25
+ if (serialized.type === "empty") {
26
+ return new Response(null, {
27
+ status: serialized.status
44
28
  });
45
29
  }
46
- setActionResult(action.name, serialized);
47
- return void 0;
30
+ return new Response(serialized.body, {
31
+ status: serialized.status,
32
+ headers: {
33
+ "Content-Type": serialized.contentType
34
+ }
35
+ });
48
36
  }
37
+ setActionResult(action.name, serialized);
38
+ return void 0;
49
39
  }
50
40
  export {
51
- ActionHandler
41
+ handleAction
52
42
  };
@@ -0,0 +1,12 @@
1
+ import type { $ZodType } from 'zod/v4/core';
2
+ import type { SSRActions, SSRManifest } from '../types/public/internal.js';
3
+ import type { ActionAccept, ActionClient } from './runtime/types.js';
4
+ /** Resolves the actions module from the manifest (a no-op module when none). */
5
+ export declare function getActions(manifest: SSRManifest): Promise<SSRActions>;
6
+ /**
7
+ * Clears the cached actions so they are re-resolved on the next request.
8
+ * Called via HMR when action files change during development.
9
+ */
10
+ export declare function clearActions(manifest: SSRManifest): void;
11
+ /** Looks up a single action handler by its dot-separated path. */
12
+ export declare function getAction(manifest: SSRManifest, path: string): Promise<ActionClient<unknown, ActionAccept, $ZodType>>;
@@ -0,0 +1,55 @@
1
+ import { FORBIDDEN_PATH_KEYS } from "@astrojs/internal-helpers/object";
2
+ import { ActionNotFoundError } from "../core/errors/errors-data.js";
3
+ import { AstroError } from "../core/errors/index.js";
4
+ import { createAsyncManifestMemo } from "../core/manifest/memo.js";
5
+ import { NOOP_ACTIONS_MOD } from "./noop-actions.js";
6
+ const actionsMemo = createAsyncManifestMemo(
7
+ async (manifest) => manifest.actions ? await manifest.actions() : NOOP_ACTIONS_MOD
8
+ );
9
+ function getActions(manifest) {
10
+ return actionsMemo.get(manifest);
11
+ }
12
+ function clearActions(manifest) {
13
+ actionsMemo.invalidate(manifest);
14
+ }
15
+ async function getAction(manifest, path) {
16
+ const pathKeys = path.split(".").map((key) => decodeURIComponent(key));
17
+ let { server } = await getActions(manifest);
18
+ if (!server || !(typeof server === "object")) {
19
+ throw new TypeError(
20
+ `Expected \`server\` export in actions file to be an object. Received ${typeof server}.`
21
+ );
22
+ }
23
+ for (const key of pathKeys) {
24
+ if (typeof server === "function") {
25
+ throw new AstroError({
26
+ ...ActionNotFoundError,
27
+ message: ActionNotFoundError.message(pathKeys.join("."))
28
+ });
29
+ }
30
+ if (FORBIDDEN_PATH_KEYS.has(key)) {
31
+ throw new AstroError({
32
+ ...ActionNotFoundError,
33
+ message: ActionNotFoundError.message(pathKeys.join("."))
34
+ });
35
+ }
36
+ if (!Object.hasOwn(server, key)) {
37
+ throw new AstroError({
38
+ ...ActionNotFoundError,
39
+ message: ActionNotFoundError.message(pathKeys.join("."))
40
+ });
41
+ }
42
+ server = server[key];
43
+ }
44
+ if (typeof server !== "function") {
45
+ throw new TypeError(
46
+ `Expected handler for action ${pathKeys.join(".")} to be a function. Received ${typeof server}.`
47
+ );
48
+ }
49
+ return server;
50
+ }
51
+ export {
52
+ clearActions,
53
+ getAction,
54
+ getActions
55
+ };
@@ -1,6 +1,7 @@
1
- import { pipelineSymbol } from "../../../core/constants.js";
1
+ import { fetchStateSymbol } from "../../../core/constants.js";
2
2
  import { ActionCalledFromServerError } from "../../../core/errors/errors-data.js";
3
3
  import { AstroError } from "../../../core/errors/errors.js";
4
+ import { getAction } from "../../load.js";
4
5
  import { createGetActionPath, createActionsProxy } from "../client.js";
5
6
  import { shouldAppendTrailingSlash } from "virtual:astro:actions/options";
6
7
  import { ACTION_QUERY_PARAMS } from "../../consts.js";
@@ -12,11 +13,11 @@ const getActionPath = createGetActionPath({
12
13
  });
13
14
  const actions = createActionsProxy({
14
15
  handleAction: async (param, path, context) => {
15
- const pipeline = context ? Reflect.get(context, pipelineSymbol) : void 0;
16
- if (!pipeline) {
16
+ const state = context ? Reflect.get(context, fetchStateSymbol) : void 0;
17
+ if (!state) {
17
18
  throw new AstroError(ActionCalledFromServerError);
18
19
  }
19
- const action = await pipeline.getAction(path);
20
+ const action = await getAction(state.manifest, path);
20
21
  if (!action) throw new Error(`Action not found: ${path}`);
21
22
  return action.bind(context)(param);
22
23
  }
@@ -1,7 +1,9 @@
1
1
  import { stringify as devalueStringify } from "devalue";
2
2
  import * as z from "zod/v4/core";
3
3
  import { shouldAppendForwardSlash } from "../../core/build/util.js";
4
- import { pipelineSymbol, REDIRECT_STATUS_CODES } from "../../core/constants.js";
4
+ import { REDIRECT_STATUS_CODES } from "../../core/constants.js";
5
+ import { getFetchStateFromAPIContext } from "../../core/fetch/fetch-state.js";
6
+ import { getAction } from "../load.js";
5
7
  import {
6
8
  ActionCalledFromServerError,
7
9
  ActionNotFoundError,
@@ -86,21 +88,21 @@ function getActionContext(context) {
86
88
  calledFrom: callerInfo.from,
87
89
  name: callerInfo.name,
88
90
  handler: async () => {
89
- const pipeline = Reflect.get(context, pipelineSymbol);
91
+ const { manifest } = getFetchStateFromAPIContext(context);
90
92
  const callerInfoName = shouldAppendForwardSlash(
91
- pipeline.manifest.trailingSlash,
92
- pipeline.manifest.buildFormat
93
+ manifest.trailingSlash,
94
+ manifest.buildFormat
93
95
  ) ? removeTrailingForwardSlash(callerInfo.name) : callerInfo.name;
94
96
  let baseAction;
95
97
  try {
96
- baseAction = await pipeline.getAction(callerInfoName);
98
+ baseAction = await getAction(manifest, callerInfoName);
97
99
  } catch (error) {
98
100
  if (error instanceof Error && "name" in error && typeof error.name === "string" && error.name === ActionNotFoundError.name) {
99
101
  return { data: void 0, error: new ActionError({ code: "NOT_FOUND" }) };
100
102
  }
101
103
  throw error;
102
104
  }
103
- const bodySizeLimit = pipeline.manifest.actionBodySizeLimit;
105
+ const bodySizeLimit = manifest.actionBodySizeLimit;
104
106
  let input;
105
107
  try {
106
108
  input = await parseRequestBody(context.request, bodySizeLimit);
@@ -26,7 +26,7 @@ declare function npm(options?: Omit<NpmProviderOptions, 'root' | 'readFile'>): F
26
26
  * - [Google](https://docs.astro.build/en/reference/font-provider-reference/#google)
27
27
  * - [Google Icons](https://docs.astro.build/en/reference/font-provider-reference/#google-icons)
28
28
  * - [Local](https://docs.astro.build/en/reference/font-provider-reference/#local)
29
- * - [NPM](TODO:)
29
+ * - [NPM](https://docs.astro.build/en/reference/font-provider-reference/#npm)
30
30
  */
31
31
  export declare const fontProviders: {
32
32
  adobe: typeof adobe;
@@ -94,18 +94,8 @@ function googleicons() {
94
94
  async init(context) {
95
95
  initializedProvider = await provider(context);
96
96
  },
97
- async resolveFont({ familyName, options, ...rest }) {
98
- const patchedOptions = options?.experimental?.glyphs && options.experimental.glyphs.length > 1 ? {
99
- ...options,
100
- experimental: {
101
- ...options.experimental,
102
- glyphs: [options.experimental.glyphs.join(",")]
103
- }
104
- } : options;
105
- return await initializedProvider?.resolveFont(familyName, {
106
- options: patchedOptions,
107
- ...rest
108
- });
97
+ async resolveFont({ familyName, ...rest }) {
98
+ return await initializedProvider?.resolveFont(familyName, rest);
109
99
  },
110
100
  async listFonts() {
111
101
  return await initializedProvider?.listFonts?.();
@@ -46,20 +46,25 @@ const HEIF = {
46
46
  const type = detectType(input, 8, metaBox.offset);
47
47
  const images = [];
48
48
  let currentOffset = ipcoBox.offset + 8;
49
- while (currentOffset < ipcoBox.offset + ipcoBox.size) {
49
+ const ipcoEnd = ipcoBox.offset + ipcoBox.size;
50
+ while (currentOffset < ipcoEnd) {
50
51
  const ispeBox = findBox(input, "ispe", currentOffset);
51
52
  if (!ispeBox) break;
53
+ if (ispeBox.size < 8) break;
54
+ if (ispeBox.offset + ispeBox.size > ipcoEnd) break;
52
55
  const rawWidth = readUInt32BE(input, ispeBox.offset + 12);
53
56
  const rawHeight = readUInt32BE(input, ispeBox.offset + 16);
54
57
  const clapBox = findBox(input, "clap", currentOffset);
55
58
  let width = rawWidth;
56
59
  let height = rawHeight;
57
- if (clapBox && clapBox.offset < ipcoBox.offset + ipcoBox.size) {
60
+ if (clapBox && clapBox.offset < ipcoEnd && clapBox.size >= 8) {
58
61
  const cropRight = readUInt32BE(input, clapBox.offset + 12);
59
62
  width = rawWidth - cropRight;
60
63
  }
61
64
  images.push({ height, width });
62
- currentOffset = ispeBox.offset + ispeBox.size;
65
+ const nextOffset = ispeBox.offset + ispeBox.size;
66
+ if (nextOffset <= currentOffset) break;
67
+ currentOffset = nextOffset;
63
68
  }
64
69
  if (images.length === 0) {
65
70
  throw new TypeError("Invalid HEIF, no sizes found");
@@ -1,6 +1,7 @@
1
1
  import { readUInt32BE, toUTF8String } from "./utils.js";
2
2
  const SIZE_HEADER = 4 + 4;
3
3
  const FILE_LENGTH_OFFSET = 4;
4
+ const MIN_ENTRY_LENGTH = 8;
4
5
  const ENTRY_LENGTH_OFFSET = 4;
5
6
  const ICON_TYPE_SIZE = {
6
7
  ICON: 32,
@@ -63,10 +64,17 @@ const ICNS = {
63
64
  let imageOffset = SIZE_HEADER;
64
65
  const images = [];
65
66
  while (imageOffset < fileLength && imageOffset < inputLength) {
67
+ if (inputLength - imageOffset < MIN_ENTRY_LENGTH) break;
66
68
  const imageHeader = readImageHeader(input, imageOffset);
69
+ const entryLength = imageHeader[1];
70
+ if (entryLength < MIN_ENTRY_LENGTH) break;
67
71
  const imageSize = getImageSize(imageHeader[0]);
68
- images.push(imageSize);
69
- imageOffset += imageHeader[1];
72
+ if (imageSize.width && imageSize.height) {
73
+ images.push(imageSize);
74
+ }
75
+ const nextOffset = imageOffset + entryLength;
76
+ if (nextOffset <= imageOffset) break;
77
+ imageOffset = nextOffset;
70
78
  }
71
79
  if (images.length === 0) {
72
80
  throw new TypeError("Invalid ICNS, no sizes found");
@@ -10,8 +10,8 @@ const JP2 = {
10
10
  },
11
11
  calculate(input) {
12
12
  const jp2hBox = findBox(input, "jp2h", 0);
13
- const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8);
14
- if (ihdrBox) {
13
+ const ihdrBox = jp2hBox && jp2hBox.size >= 8 && findBox(input, "ihdr", jp2hBox.offset + 8);
14
+ if (ihdrBox && ihdrBox.size >= 8) {
15
15
  return {
16
16
  height: readUInt32BE(input, ihdrBox.offset + 8),
17
17
  width: readUInt32BE(input, ihdrBox.offset + 12)
@@ -2,7 +2,7 @@ import { JXLStream } from "./jxl-stream.js";
2
2
  import { findBox, toUTF8String } from "./utils.js";
3
3
  function extractCodestream(input) {
4
4
  const jxlcBox = findBox(input, "jxlc", 0);
5
- if (jxlcBox) {
5
+ if (jxlcBox && jxlcBox.size >= 8) {
6
6
  return input.slice(jxlcBox.offset + 8, jxlcBox.offset + jxlcBox.size);
7
7
  }
8
8
  const partialStreams = extractPartialStreams(input);
@@ -17,10 +17,13 @@ function extractPartialStreams(input) {
17
17
  while (offset < input.length) {
18
18
  const jxlpBox = findBox(input, "jxlp", offset);
19
19
  if (!jxlpBox) break;
20
+ if (jxlpBox.size < 12) break;
20
21
  partialStreams.push(
21
22
  input.slice(jxlpBox.offset + 12, jxlpBox.offset + jxlpBox.size)
22
23
  );
23
- offset = jxlpBox.offset + jxlpBox.size;
24
+ const nextOffset = jxlpBox.offset + jxlpBox.size;
25
+ if (nextOffset <= offset) break;
26
+ offset = nextOffset;
24
27
  }
25
28
  return partialStreams;
26
29
  }
@@ -9,7 +9,7 @@ export declare const readUInt32BE: (input: Uint8Array, offset?: number) => numbe
9
9
  export declare const readUInt32LE: (input: Uint8Array, offset?: number) => number;
10
10
  export declare const readUInt64: (input: Uint8Array, offset: number, isBigEndian: boolean) => bigint;
11
11
  export declare function readUInt(input: Uint8Array, bits: 16 | 32, offset?: number, isBigEndian?: boolean): number;
12
- export declare function findBox(input: Uint8Array, boxName: string, currentOffset: number): {
12
+ export declare function findBox(input: Uint8Array, boxName: string, startOffset: number): {
13
13
  name: string;
14
14
  offset: number;
15
15
  size: number;
@@ -24,22 +24,36 @@ function readUInt(input, bits, offset = 0, isBigEndian = false) {
24
24
  const methodName = `readUInt${bits}${endian}`;
25
25
  return methods[methodName](input, offset);
26
26
  }
27
+ const MIN_BOX_HEADER = 8;
27
28
  function readBox(input, offset) {
28
- if (input.length - offset < 4) return;
29
+ if (input.length - offset < MIN_BOX_HEADER) return;
29
30
  const boxSize = readUInt32BE(input, offset);
31
+ if (boxSize === 0) {
32
+ return {
33
+ name: toUTF8String(input, offset + 4, offset + 8),
34
+ offset,
35
+ size: input.length - offset
36
+ };
37
+ }
38
+ if (boxSize === 1) return;
39
+ if (boxSize < MIN_BOX_HEADER) return;
30
40
  if (input.length - offset < boxSize) return;
31
41
  return {
32
- name: toUTF8String(input, 4 + offset, 8 + offset),
42
+ name: toUTF8String(input, offset + 4, offset + 8),
33
43
  offset,
34
44
  size: boxSize
35
45
  };
36
46
  }
37
- function findBox(input, boxName, currentOffset) {
38
- while (currentOffset < input.length) {
39
- const box = readBox(input, currentOffset);
47
+ function findBox(input, boxName, startOffset) {
48
+ let offset = startOffset;
49
+ while (offset < input.length) {
50
+ const box = readBox(input, offset);
40
51
  if (!box) break;
41
52
  if (box.name === boxName) return box;
42
- currentOffset += box.size > 0 ? box.size : 8;
53
+ if (box.size < MIN_BOX_HEADER) break;
54
+ const nextOffset = offset + box.size;
55
+ if (nextOffset <= offset) break;
56
+ offset = nextOffset;
43
57
  }
44
58
  }
45
59
  export {
@@ -1,6 +1,6 @@
1
1
  class BuildTimeAstroVersionProvider {
2
2
  // Injected during the build through esbuild define
3
- version = "7.2.2";
3
+ version = "7.2.4";
4
4
  }
5
5
  export {
6
6
  BuildTimeAstroVersionProvider
@@ -0,0 +1,20 @@
1
+ import type { RouteData, SSRLoadedRenderer, SSRResult } from '../types/public/internal.js';
2
+ import type { SinglePageBuiltModule } from '../core/build/types.js';
3
+ import type { RenderEnvironment } from '../core/environment/index.js';
4
+ export interface ContainerEnvironmentOptions {
5
+ /**
6
+ * The route → module interner. Created by `experimental_AstroContainer`'s
7
+ * constructor and shared with its `insertRoute` writes; this record owns
8
+ * the lookups.
9
+ */
10
+ interner: WeakMap<RouteData, SinglePageBuiltModule>;
11
+ resolve: SSRResult['resolve'];
12
+ renderers: SSRLoadedRenderer[];
13
+ streaming: boolean;
14
+ }
15
+ /**
16
+ * The container environment. Registered by `experimental_AstroContainer`'s
17
+ * constructor on its fabricated manifest — the container never touches the
18
+ * ambient manifest, so multiple containers in one process stay isolated.
19
+ */
20
+ export declare function createContainerEnvironment({ interner, resolve, renderers, streaming, }: ContainerEnvironmentOptions): RenderEnvironment;
@@ -0,0 +1,106 @@
1
+ import { RedirectSinglePageBuiltModule } from "../core/redirects/index.js";
2
+ import {
3
+ createModuleScriptElement,
4
+ createStylesheetElementSet
5
+ } from "../core/render/ssr-element.js";
6
+ import { getDefaultRoutes } from "../core/routing/default.js";
7
+ import { findRouteToRewrite } from "../core/routing/rewrite.js";
8
+ async function getModuleForRoute(manifest, route) {
9
+ for (const defaultRoute of getDefaultRoutes(manifest)) {
10
+ if (route.component === defaultRoute.component) {
11
+ return {
12
+ page: () => Promise.resolve(defaultRoute.instance)
13
+ };
14
+ }
15
+ }
16
+ if (route.type === "redirect") {
17
+ return RedirectSinglePageBuiltModule;
18
+ } else {
19
+ if (manifest.pageMap) {
20
+ const importComponentInstance = manifest.pageMap.get(route.component);
21
+ if (!importComponentInstance) {
22
+ throw new Error(
23
+ `Unexpectedly unable to find a component instance for route ${route.route}`
24
+ );
25
+ }
26
+ return await importComponentInstance();
27
+ } else if (manifest.pageModule) {
28
+ return manifest.pageModule;
29
+ }
30
+ throw new Error(
31
+ "Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error, please file an issue."
32
+ );
33
+ }
34
+ }
35
+ function createContainerEnvironment({
36
+ interner,
37
+ resolve,
38
+ renderers,
39
+ streaming
40
+ }) {
41
+ async function getComponentByRoute(_manifest, routeData) {
42
+ const page = interner.get(routeData);
43
+ if (page) {
44
+ return page.page();
45
+ }
46
+ throw new Error("Couldn't find component for route " + routeData.pathname);
47
+ }
48
+ return {
49
+ name: "container",
50
+ runtimeMode: "development",
51
+ defaultStreaming: () => streaming,
52
+ async resolve(_manifest, specifier) {
53
+ return resolve(specifier);
54
+ },
55
+ headElements(manifest, routeData) {
56
+ const routeInfo = manifest.routes.find((route) => route.routeData === routeData);
57
+ const links = /* @__PURE__ */ new Set();
58
+ const scripts = /* @__PURE__ */ new Set();
59
+ const styles = createStylesheetElementSet(routeInfo?.styles ?? []);
60
+ for (const script of routeInfo?.scripts ?? []) {
61
+ if ("stage" in script) {
62
+ if (script.stage === "head-inline") {
63
+ scripts.add({
64
+ props: {},
65
+ children: script.children
66
+ });
67
+ }
68
+ } else {
69
+ scripts.add(createModuleScriptElement(script));
70
+ }
71
+ }
72
+ return { links, styles, scripts };
73
+ },
74
+ componentMetadata() {
75
+ },
76
+ getComponentByRoute,
77
+ getModuleForRoute,
78
+ async tryRewrite(manifest, payload, request) {
79
+ const { newUrl, pathname, routeData } = findRouteToRewrite({
80
+ payload,
81
+ request,
82
+ // PER-CALL scan of the live manifest routes: the container inserts
83
+ // routes at runtime (`insertRoute` pushes into `manifest.routes`),
84
+ // and an uncompiled scan sees them immediately. Reading the derived
85
+ // route table here would miss them.
86
+ routes: manifest.routes.map((r) => r.routeData),
87
+ trailingSlash: manifest.trailingSlash,
88
+ buildFormat: manifest.buildFormat,
89
+ base: manifest.base,
90
+ outDir: manifest.outDir
91
+ });
92
+ const componentInstance = await getComponentByRoute(manifest, routeData);
93
+ return { componentInstance, routeData, newUrl, pathname };
94
+ },
95
+ getRenderers() {
96
+ return renderers;
97
+ },
98
+ errorStrategy: "default",
99
+ injectCspMetaTagsOnErrorPages: false,
100
+ logRequest() {
101
+ }
102
+ };
103
+ }
104
+ export {
105
+ createContainerEnvironment
106
+ };