astro 5.13.10 → 5.13.11
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.
- package/dist/assets/fonts/definitions.d.ts +8 -0
- package/dist/assets/fonts/implementations/data-collector.d.ts +1 -1
- package/dist/assets/fonts/implementations/url-proxy-hash-resolver.d.ts +8 -0
- package/dist/assets/fonts/implementations/url-proxy-hash-resolver.js +24 -0
- package/dist/assets/fonts/implementations/url-proxy.d.ts +4 -4
- package/dist/assets/fonts/implementations/url-proxy.js +4 -4
- package/dist/assets/fonts/orchestrate.js +2 -1
- package/dist/assets/fonts/types.d.ts +1 -0
- package/dist/assets/fonts/vite-plugin-fonts.js +16 -7
- package/dist/assets/services/sharp.js +2 -1
- package/dist/cli/info/index.js +1 -2
- package/dist/cli/preview/index.d.ts +1 -1
- package/dist/container/index.d.ts +0 -1
- package/dist/container/index.js +7 -3
- package/dist/content/content-layer.js +3 -3
- package/dist/core/app/node.js +70 -2
- package/dist/core/build/pipeline.d.ts +1 -1
- package/dist/core/config/schemas/base.d.ts +70 -70
- package/dist/core/config/schemas/relative.d.ts +125 -125
- package/dist/core/constants.d.ts +4 -0
- package/dist/core/constants.js +5 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/env/schema.d.ts +22 -22
- package/dist/i18n/index.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/types/public/config.d.ts +12 -12
- package/dist/vite-plugin-astro-server/pipeline.d.ts +1 -1
- package/{zod.d.ts → dist/zod.d.ts} +0 -1
- package/dist/zod.js +7 -0
- package/package.json +5 -15
- package/index.d.ts +0 -2
- package/zod.mjs +0 -3
|
@@ -86,4 +86,12 @@ export interface FontFileReader {
|
|
|
86
86
|
style: Style;
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
|
+
export interface UrlProxyHashResolver {
|
|
90
|
+
resolve: (input: {
|
|
91
|
+
originalUrl: string;
|
|
92
|
+
type: FontType;
|
|
93
|
+
cssVariable: string;
|
|
94
|
+
data: Partial<unifont.FontFaceData>;
|
|
95
|
+
}) => string;
|
|
96
|
+
}
|
|
89
97
|
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { DataCollector } from '../definitions.js';
|
|
2
2
|
import type { CreateUrlProxyParams } from '../types.js';
|
|
3
|
-
export declare function createDataCollector({ hasUrl, saveUrl, savePreload, saveFontData, }:
|
|
3
|
+
export declare function createDataCollector({ hasUrl, saveUrl, savePreload, saveFontData, }: Pick<CreateUrlProxyParams, 'hasUrl' | 'saveUrl' | 'savePreload' | 'saveFontData'>): DataCollector;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Hasher, UrlProxyContentResolver, UrlProxyHashResolver } from '../definitions.js';
|
|
2
|
+
export declare function createBuildUrlProxyHashResolver({ hasher, contentResolver, }: {
|
|
3
|
+
hasher: Hasher;
|
|
4
|
+
contentResolver: UrlProxyContentResolver;
|
|
5
|
+
}): UrlProxyHashResolver;
|
|
6
|
+
export declare function createDevUrlProxyHashResolver({ baseHashResolver, }: {
|
|
7
|
+
baseHashResolver: UrlProxyHashResolver;
|
|
8
|
+
}): UrlProxyHashResolver;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
function createBuildUrlProxyHashResolver({
|
|
2
|
+
hasher,
|
|
3
|
+
contentResolver
|
|
4
|
+
}) {
|
|
5
|
+
return {
|
|
6
|
+
resolve({ originalUrl, type }) {
|
|
7
|
+
return `${hasher.hashString(contentResolver.resolve(originalUrl))}.${type}`;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function createDevUrlProxyHashResolver({
|
|
12
|
+
baseHashResolver
|
|
13
|
+
}) {
|
|
14
|
+
return {
|
|
15
|
+
resolve(input) {
|
|
16
|
+
const { cssVariable, data } = input;
|
|
17
|
+
return [cssVariable.slice(2), data.weight, data.style, baseHashResolver.resolve(input)].filter(Boolean).join("-");
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
createBuildUrlProxyHashResolver,
|
|
23
|
+
createDevUrlProxyHashResolver
|
|
24
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { DataCollector,
|
|
2
|
-
export declare function createUrlProxy({
|
|
3
|
-
|
|
4
|
-
hasher: Hasher;
|
|
1
|
+
import type { DataCollector, UrlProxy, UrlProxyHashResolver, UrlResolver } from '../definitions.js';
|
|
2
|
+
export declare function createUrlProxy({ hashResolver, dataCollector, urlResolver, cssVariable, }: {
|
|
3
|
+
hashResolver: UrlProxyHashResolver;
|
|
5
4
|
dataCollector: DataCollector;
|
|
6
5
|
urlResolver: UrlResolver;
|
|
6
|
+
cssVariable: string;
|
|
7
7
|
}): UrlProxy;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
function createUrlProxy({
|
|
2
|
-
|
|
3
|
-
hasher,
|
|
2
|
+
hashResolver,
|
|
4
3
|
dataCollector,
|
|
5
|
-
urlResolver
|
|
4
|
+
urlResolver,
|
|
5
|
+
cssVariable
|
|
6
6
|
}) {
|
|
7
7
|
return {
|
|
8
8
|
proxy({ url: originalUrl, type, data, collectPreload, init }) {
|
|
9
|
-
const hash =
|
|
9
|
+
const hash = hashResolver.resolve({ cssVariable, data, originalUrl, type });
|
|
10
10
|
const url = urlResolver.resolve(hash);
|
|
11
11
|
dataCollector.collect({
|
|
12
12
|
url: originalUrl,
|
|
@@ -59,7 +59,8 @@ async function orchestrate({
|
|
|
59
59
|
!collectedFonts.some((f) => JSON.stringify(f.data) === JSON.stringify(collected.data))) {
|
|
60
60
|
collectedFonts.push(collected);
|
|
61
61
|
}
|
|
62
|
-
}
|
|
62
|
+
},
|
|
63
|
+
cssVariable: family.cssVariable
|
|
63
64
|
});
|
|
64
65
|
let fonts;
|
|
65
66
|
if (family.provider === LOCAL_PROVIDER_NAME) {
|
|
@@ -59,6 +59,7 @@ export interface CreateUrlProxyParams {
|
|
|
59
59
|
saveUrl: (input: FontFileData) => void;
|
|
60
60
|
savePreload: (preload: PreloadData) => void;
|
|
61
61
|
saveFontData: (collected: CollectedFontForMetrics) => void;
|
|
62
|
+
cssVariable: string;
|
|
62
63
|
}
|
|
63
64
|
/**
|
|
64
65
|
* Holds associations of hash and original font file URLs, so they can be
|
|
@@ -37,6 +37,10 @@ import {
|
|
|
37
37
|
createLocalUrlProxyContentResolver,
|
|
38
38
|
createRemoteUrlProxyContentResolver
|
|
39
39
|
} from "./implementations/url-proxy-content-resolver.js";
|
|
40
|
+
import {
|
|
41
|
+
createBuildUrlProxyHashResolver,
|
|
42
|
+
createDevUrlProxyHashResolver
|
|
43
|
+
} from "./implementations/url-proxy-hash-resolver.js";
|
|
40
44
|
import { createBuildUrlResolver, createDevUrlResolver } from "./implementations/url-resolver.js";
|
|
41
45
|
import { orchestrate } from "./orchestrate.js";
|
|
42
46
|
function fontsPlugin({ settings, sync, logger }) {
|
|
@@ -75,7 +79,8 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
75
79
|
cacheDir,
|
|
76
80
|
modResolver,
|
|
77
81
|
cssRenderer,
|
|
78
|
-
urlResolver
|
|
82
|
+
urlResolver,
|
|
83
|
+
createHashResolver
|
|
79
84
|
}) {
|
|
80
85
|
const { root } = settings.config;
|
|
81
86
|
const hasher = await createXxHasher();
|
|
@@ -119,14 +124,14 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
119
124
|
fontTypeExtractor,
|
|
120
125
|
fontFileReader,
|
|
121
126
|
logger,
|
|
122
|
-
createUrlProxy: ({ local, ...params }) => {
|
|
127
|
+
createUrlProxy: ({ local, cssVariable, ...params }) => {
|
|
123
128
|
const dataCollector = createDataCollector(params);
|
|
124
129
|
const contentResolver = local ? createLocalUrlProxyContentResolver({ errorHandler }) : createRemoteUrlProxyContentResolver();
|
|
125
130
|
return createUrlProxy({
|
|
126
131
|
urlResolver,
|
|
127
|
-
contentResolver,
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
hashResolver: createHashResolver({ hasher, contentResolver }),
|
|
133
|
+
dataCollector,
|
|
134
|
+
cssVariable
|
|
130
135
|
});
|
|
131
136
|
},
|
|
132
137
|
defaults: DEFAULTS
|
|
@@ -158,7 +163,8 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
158
163
|
urlResolver: createBuildUrlResolver({
|
|
159
164
|
base: baseUrl,
|
|
160
165
|
assetsPrefix: settings.config.build.assetsPrefix
|
|
161
|
-
})
|
|
166
|
+
}),
|
|
167
|
+
createHashResolver: (dependencies) => createBuildUrlProxyHashResolver(dependencies)
|
|
162
168
|
});
|
|
163
169
|
}
|
|
164
170
|
},
|
|
@@ -168,7 +174,10 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
168
174
|
cacheDir: new URL(CACHE_DIR, settings.dotAstroDir),
|
|
169
175
|
modResolver: createDevServerRemoteFontProviderModResolver({ server }),
|
|
170
176
|
cssRenderer: createMinifiableCssRenderer({ minify: false }),
|
|
171
|
-
urlResolver: createDevUrlResolver({ base: baseUrl })
|
|
177
|
+
urlResolver: createDevUrlResolver({ base: baseUrl }),
|
|
178
|
+
createHashResolver: (dependencies) => createDevUrlProxyHashResolver({
|
|
179
|
+
baseHashResolver: createBuildUrlProxyHashResolver(dependencies)
|
|
180
|
+
})
|
|
172
181
|
});
|
|
173
182
|
const localPaths = [...fontFileDataMap.values()].filter(({ url }) => isAbsolute(url)).map((v) => v.url);
|
|
174
183
|
server.watcher.on("change", (path) => {
|
|
@@ -89,8 +89,9 @@ const sharpService = {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
const { data, info } = await result.toBuffer({ resolveWithObject: true });
|
|
92
|
+
const needsCopy = "buffer" in data && data.buffer instanceof SharedArrayBuffer;
|
|
92
93
|
return {
|
|
93
|
-
data,
|
|
94
|
+
data: needsCopy ? new Uint8Array(data) : data,
|
|
94
95
|
format: info.format
|
|
95
96
|
};
|
|
96
97
|
}
|
package/dist/cli/info/index.js
CHANGED
|
@@ -2,5 +2,5 @@ import { type Flags } from '../flags.js';
|
|
|
2
2
|
interface PreviewOptions {
|
|
3
3
|
flags: Flags;
|
|
4
4
|
}
|
|
5
|
-
export declare function preview({ flags }: PreviewOptions): Promise<import("../../
|
|
5
|
+
export declare function preview({ flags }: PreviewOptions): Promise<import("../../index.js").PreviewServer | undefined>;
|
|
6
6
|
export {};
|
package/dist/container/index.js
CHANGED
|
@@ -129,7 +129,7 @@ class experimental_AstroContainer {
|
|
|
129
129
|
* @param options.renderer The server renderer exported by integration.
|
|
130
130
|
*/
|
|
131
131
|
addServerRenderer(options) {
|
|
132
|
-
const { renderer
|
|
132
|
+
const { renderer } = options;
|
|
133
133
|
if (!renderer.check || !renderer.renderToStaticMarkup) {
|
|
134
134
|
throw new Error(
|
|
135
135
|
"The renderer you passed isn't valid. A renderer is usually an object that exposes the `check` and `renderToStaticMarkup` functions.\nUsually, the renderer is exported by a /server.js entrypoint e.g. `import renderer from '@astrojs/react/server.js'`"
|
|
@@ -140,11 +140,15 @@ class experimental_AstroContainer {
|
|
|
140
140
|
name: renderer.name,
|
|
141
141
|
ssr: renderer
|
|
142
142
|
});
|
|
143
|
-
} else {
|
|
143
|
+
} else if ("name" in options) {
|
|
144
144
|
this.#pipeline.manifest.renderers.push({
|
|
145
|
-
name,
|
|
145
|
+
name: options.name,
|
|
146
146
|
ssr: renderer
|
|
147
147
|
});
|
|
148
|
+
} else {
|
|
149
|
+
throw new Error(
|
|
150
|
+
"The renderer name must be provided when adding a server renderer that is not a named renderer."
|
|
151
|
+
);
|
|
148
152
|
}
|
|
149
153
|
}
|
|
150
154
|
/**
|
|
@@ -164,7 +164,7 @@ ${contentConfig.error.message}`);
|
|
|
164
164
|
logger.info("Content config changed");
|
|
165
165
|
shouldClear = true;
|
|
166
166
|
}
|
|
167
|
-
if (previousAstroVersion && previousAstroVersion !== "5.13.
|
|
167
|
+
if (previousAstroVersion && previousAstroVersion !== "5.13.11") {
|
|
168
168
|
logger.info("Astro version changed");
|
|
169
169
|
shouldClear = true;
|
|
170
170
|
}
|
|
@@ -172,8 +172,8 @@ ${contentConfig.error.message}`);
|
|
|
172
172
|
logger.info("Clearing content store");
|
|
173
173
|
this.#store.clearAll();
|
|
174
174
|
}
|
|
175
|
-
if ("5.13.
|
|
176
|
-
await this.#store.metaStore().set("astro-version", "5.13.
|
|
175
|
+
if ("5.13.11") {
|
|
176
|
+
await this.#store.metaStore().set("astro-version", "5.13.11");
|
|
177
177
|
}
|
|
178
178
|
if (currentConfigDigest) {
|
|
179
179
|
await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
package/dist/core/app/node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { Http2ServerResponse } from "node:http2";
|
|
3
|
-
import { clientAddressSymbol } from "../constants.js";
|
|
3
|
+
import { clientAddressSymbol, nodeRequestAbortControllerCleanupSymbol } from "../constants.js";
|
|
4
4
|
import { deserializeManifest } from "./common.js";
|
|
5
5
|
import { createOutgoingHttpHeaders } from "./createOutgoingHttpHeaders.js";
|
|
6
6
|
import { App } from "./index.js";
|
|
@@ -38,6 +38,7 @@ class NodeApp extends App {
|
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
40
|
static createRequest(req, { skipBody = false } = {}) {
|
|
41
|
+
const controller = new AbortController();
|
|
41
42
|
const isEncrypted = "encrypted" in req.socket && req.socket.encrypted;
|
|
42
43
|
const getFirstForwardedValue = (multiValueHeader) => {
|
|
43
44
|
return multiValueHeader?.toString()?.split(",").map((e) => e.trim())?.[0];
|
|
@@ -59,13 +60,48 @@ class NodeApp extends App {
|
|
|
59
60
|
}
|
|
60
61
|
const options = {
|
|
61
62
|
method: req.method || "GET",
|
|
62
|
-
headers: makeRequestHeaders(req)
|
|
63
|
+
headers: makeRequestHeaders(req),
|
|
64
|
+
signal: controller.signal
|
|
63
65
|
};
|
|
64
66
|
const bodyAllowed = options.method !== "HEAD" && options.method !== "GET" && skipBody === false;
|
|
65
67
|
if (bodyAllowed) {
|
|
66
68
|
Object.assign(options, makeRequestBody(req));
|
|
67
69
|
}
|
|
68
70
|
const request = new Request(url, options);
|
|
71
|
+
const socket = getRequestSocket(req);
|
|
72
|
+
if (socket && typeof socket.on === "function") {
|
|
73
|
+
const existingCleanup = getAbortControllerCleanup(req);
|
|
74
|
+
if (existingCleanup) {
|
|
75
|
+
existingCleanup();
|
|
76
|
+
}
|
|
77
|
+
let cleanedUp = false;
|
|
78
|
+
const removeSocketListener = () => {
|
|
79
|
+
if (typeof socket.off === "function") {
|
|
80
|
+
socket.off("close", onSocketClose);
|
|
81
|
+
} else if (typeof socket.removeListener === "function") {
|
|
82
|
+
socket.removeListener("close", onSocketClose);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const cleanup = () => {
|
|
86
|
+
if (cleanedUp) return;
|
|
87
|
+
cleanedUp = true;
|
|
88
|
+
removeSocketListener();
|
|
89
|
+
controller.signal.removeEventListener("abort", cleanup);
|
|
90
|
+
Reflect.deleteProperty(req, nodeRequestAbortControllerCleanupSymbol);
|
|
91
|
+
};
|
|
92
|
+
const onSocketClose = () => {
|
|
93
|
+
cleanup();
|
|
94
|
+
if (!controller.signal.aborted) {
|
|
95
|
+
controller.abort();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
socket.on("close", onSocketClose);
|
|
99
|
+
controller.signal.addEventListener("abort", cleanup, { once: true });
|
|
100
|
+
Reflect.set(req, nodeRequestAbortControllerCleanupSymbol, cleanup);
|
|
101
|
+
if (socket.destroyed) {
|
|
102
|
+
onSocketClose();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
69
105
|
const forwardedClientIp = getFirstForwardedValue(req.headers["x-forwarded-for"]);
|
|
70
106
|
const clientIp = forwardedClientIp || req.socket?.remoteAddress;
|
|
71
107
|
if (clientIp) {
|
|
@@ -94,6 +130,23 @@ class NodeApp extends App {
|
|
|
94
130
|
destination.statusMessage = statusText;
|
|
95
131
|
}
|
|
96
132
|
destination.writeHead(status, createOutgoingHttpHeaders(headers));
|
|
133
|
+
const cleanupAbortFromDestination = getAbortControllerCleanup(
|
|
134
|
+
destination.req ?? void 0
|
|
135
|
+
);
|
|
136
|
+
if (cleanupAbortFromDestination) {
|
|
137
|
+
const runCleanup = () => {
|
|
138
|
+
cleanupAbortFromDestination();
|
|
139
|
+
if (typeof destination.off === "function") {
|
|
140
|
+
destination.off("finish", runCleanup);
|
|
141
|
+
destination.off("close", runCleanup);
|
|
142
|
+
} else {
|
|
143
|
+
destination.removeListener?.("finish", runCleanup);
|
|
144
|
+
destination.removeListener?.("close", runCleanup);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
destination.on("finish", runCleanup);
|
|
148
|
+
destination.on("close", runCleanup);
|
|
149
|
+
}
|
|
97
150
|
if (!body) return destination.end();
|
|
98
151
|
try {
|
|
99
152
|
const reader = body.getReader();
|
|
@@ -165,6 +218,21 @@ function asyncIterableToBodyProps(iterable) {
|
|
|
165
218
|
duplex: "half"
|
|
166
219
|
};
|
|
167
220
|
}
|
|
221
|
+
function getAbortControllerCleanup(req) {
|
|
222
|
+
if (!req) return void 0;
|
|
223
|
+
const cleanup = Reflect.get(req, nodeRequestAbortControllerCleanupSymbol);
|
|
224
|
+
return typeof cleanup === "function" ? cleanup : void 0;
|
|
225
|
+
}
|
|
226
|
+
function getRequestSocket(req) {
|
|
227
|
+
if (req.socket && typeof req.socket.on === "function") {
|
|
228
|
+
return req.socket;
|
|
229
|
+
}
|
|
230
|
+
const http2Socket = req.stream?.session?.socket;
|
|
231
|
+
if (http2Socket && typeof http2Socket.on === "function") {
|
|
232
|
+
return http2Socket;
|
|
233
|
+
}
|
|
234
|
+
return void 0;
|
|
235
|
+
}
|
|
168
236
|
async function loadManifest(rootFolder) {
|
|
169
237
|
const manifestFile = new URL("./manifest.json", rootFolder);
|
|
170
238
|
const rawManifest = await fs.promises.readFile(manifestFile, "utf-8");
|
|
@@ -14,7 +14,7 @@ export declare class BuildPipeline extends Pipeline {
|
|
|
14
14
|
readonly internals: BuildInternals;
|
|
15
15
|
readonly manifest: SSRManifest;
|
|
16
16
|
readonly options: StaticBuildOptions;
|
|
17
|
-
readonly config: import("../../
|
|
17
|
+
readonly config: import("../../index.js").AstroConfig;
|
|
18
18
|
readonly settings: AstroSettings;
|
|
19
19
|
readonly defaultRoutes: {
|
|
20
20
|
instance: ComponentInstance;
|