astro 5.16.2 → 5.16.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.
- package/dist/actions/runtime/server.d.ts +5 -4
- package/dist/actions/runtime/server.js +0 -1
- package/dist/assets/fonts/definitions.d.ts +8 -3
- package/dist/assets/fonts/infra/build-remote-font-provider-mod-resolver.d.ts +3 -1
- package/dist/assets/fonts/infra/build-remote-font-provider-mod-resolver.js +5 -7
- package/dist/assets/fonts/infra/build-url-proxy-hash-resolver.d.ts +15 -5
- package/dist/assets/fonts/infra/build-url-proxy-hash-resolver.js +17 -10
- package/dist/assets/fonts/infra/build-url-resolver.d.ts +10 -5
- package/dist/assets/fonts/infra/build-url-resolver.js +33 -27
- package/dist/assets/fonts/infra/cached-font-fetcher.d.ts +11 -7
- package/dist/assets/fonts/infra/cached-font-fetcher.js +35 -29
- package/dist/assets/fonts/infra/capsize-font-metrics-resolver.d.ts +18 -5
- package/dist/assets/fonts/infra/capsize-font-metrics-resolver.js +45 -40
- package/dist/assets/fonts/infra/data-collector.d.ts +10 -3
- package/dist/assets/fonts/infra/data-collector.js +30 -16
- package/dist/assets/fonts/infra/dev-remote-font-provider-mod-resolver.d.ts +7 -3
- package/dist/assets/fonts/infra/dev-remote-font-provider-mod-resolver.js +11 -9
- package/dist/assets/fonts/infra/dev-url-proxy-hash-resolver.d.ts +15 -5
- package/dist/assets/fonts/infra/dev-url-proxy-hash-resolver.js +31 -22
- package/dist/assets/fonts/infra/dev-url-resolver.d.ts +9 -4
- package/dist/assets/fonts/infra/dev-url-resolver.js +24 -20
- package/dist/assets/fonts/infra/font-type-extractor.d.ts +4 -1
- package/dist/assets/fonts/infra/font-type-extractor.js +14 -16
- package/dist/assets/fonts/infra/fontace-font-file-reader.d.ts +10 -1
- package/dist/assets/fonts/infra/fontace-font-file-reader.js +18 -20
- package/dist/assets/fonts/infra/levenshtein-string-matcher.d.ts +4 -1
- package/dist/assets/fonts/infra/levenshtein-string-matcher.js +119 -121
- package/dist/assets/fonts/infra/local-url-proxy-content-resolver.d.ts +4 -0
- package/dist/assets/fonts/infra/local-url-proxy-content-resolver.js +14 -0
- package/dist/assets/fonts/infra/minifiable-css-renderer.d.ts +8 -3
- package/dist/assets/fonts/infra/minifiable-css-renderer.js +12 -10
- package/dist/assets/fonts/infra/remote-font-provider-resolver.d.ts +9 -4
- package/dist/assets/fonts/infra/remote-font-provider-resolver.js +42 -38
- package/dist/assets/fonts/infra/remote-url-proxy-content-resolver.d.ts +4 -0
- package/dist/assets/fonts/infra/remote-url-proxy-content-resolver.js +9 -0
- package/dist/assets/fonts/infra/require-local-provider-url-resolver.d.ts +8 -4
- package/dist/assets/fonts/infra/require-local-provider-url-resolver.js +17 -12
- package/dist/assets/fonts/infra/system-fallbacks-provider.d.ts +5 -10
- package/dist/assets/fonts/infra/system-fallbacks-provider.js +8 -11
- package/dist/assets/fonts/infra/unstorage-fs-storage.d.ts +11 -0
- package/dist/assets/fonts/infra/unstorage-fs-storage.js +26 -0
- package/dist/assets/fonts/infra/url-proxy.d.ts +16 -7
- package/dist/assets/fonts/infra/url-proxy.js +46 -27
- package/dist/assets/fonts/infra/xxhash-hasher.d.ts +6 -1
- package/dist/assets/fonts/infra/xxhash-hasher.js +13 -9
- package/dist/assets/fonts/orchestrate.d.ts +1 -2
- package/dist/assets/fonts/utils.d.ts +1 -2
- package/dist/assets/fonts/vite-plugin-fonts.js +43 -46
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/core/app/index.js +8 -2
- package/dist/core/constants.js +1 -1
- package/dist/core/csp/runtime.d.ts +11 -0
- package/dist/core/csp/runtime.js +35 -0
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.js +25 -5
- package/dist/core/util/pathname.d.ts +10 -0
- package/dist/core/util/pathname.js +17 -0
- package/dist/vite-plugin-astro-server/request.js +9 -2
- package/package.json +2 -2
- package/dist/assets/fonts/infra/fs-storage.d.ts +0 -4
- package/dist/assets/fonts/infra/fs-storage.js +0 -14
- package/dist/assets/fonts/infra/url-proxy-content-resolver.d.ts +0 -3
- package/dist/assets/fonts/infra/url-proxy-content-resolver.js +0 -23
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
2
|
import { resolveEntrypoint } from "../utils.js";
|
|
3
|
-
|
|
4
|
-
root
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
3
|
+
class RequireLocalProviderUrlResolver {
|
|
4
|
+
#root;
|
|
5
|
+
// TODO: remove when stabilizing
|
|
6
|
+
#intercept;
|
|
7
|
+
constructor({
|
|
8
|
+
root,
|
|
9
|
+
intercept
|
|
10
|
+
}) {
|
|
11
|
+
this.#root = root;
|
|
12
|
+
this.#intercept = intercept;
|
|
13
|
+
}
|
|
14
|
+
resolve(input) {
|
|
15
|
+
const path = fileURLToPath(resolveEntrypoint(this.#root, input));
|
|
16
|
+
this.#intercept?.(path);
|
|
17
|
+
return path;
|
|
18
|
+
}
|
|
14
19
|
}
|
|
15
20
|
export {
|
|
16
|
-
|
|
21
|
+
RequireLocalProviderUrlResolver
|
|
17
22
|
};
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { SystemFallbacksProvider } from '../definitions.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
'ui-serif': "Times New Roman"[];
|
|
8
|
-
'ui-sans-serif': "Arial"[];
|
|
9
|
-
'ui-monospace': "Courier New"[];
|
|
10
|
-
};
|
|
11
|
-
export declare function createSystemFallbacksProvider(): SystemFallbacksProvider;
|
|
2
|
+
import type { FontFaceMetrics, GenericFallbackName } from '../types.js';
|
|
3
|
+
export declare class RealSystemFallbacksProvider implements SystemFallbacksProvider {
|
|
4
|
+
getLocalFonts(fallback: GenericFallbackName): Array<string> | null;
|
|
5
|
+
getMetricsForLocalFont(family: string): FontFaceMetrics;
|
|
6
|
+
}
|
|
@@ -58,17 +58,14 @@ const DEFAULT_FALLBACKS = {
|
|
|
58
58
|
"ui-sans-serif": ["Arial"],
|
|
59
59
|
"ui-monospace": ["Courier New"]
|
|
60
60
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
};
|
|
61
|
+
class RealSystemFallbacksProvider {
|
|
62
|
+
getLocalFonts(fallback) {
|
|
63
|
+
return DEFAULT_FALLBACKS[fallback] ?? null;
|
|
64
|
+
}
|
|
65
|
+
getMetricsForLocalFont(family) {
|
|
66
|
+
return SYSTEM_METRICS[family];
|
|
67
|
+
}
|
|
70
68
|
}
|
|
71
69
|
export {
|
|
72
|
-
|
|
73
|
-
createSystemFallbacksProvider
|
|
70
|
+
RealSystemFallbacksProvider
|
|
74
71
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Storage } from '../definitions.js';
|
|
2
|
+
export declare class UnstorageFsStorage implements Storage {
|
|
3
|
+
#private;
|
|
4
|
+
constructor({ base }: {
|
|
5
|
+
base: URL;
|
|
6
|
+
});
|
|
7
|
+
getItem(key: string): Promise<any | null>;
|
|
8
|
+
getItemRaw(key: string): Promise<Buffer | null>;
|
|
9
|
+
setItem(key: string, value: any): Promise<void>;
|
|
10
|
+
setItemRaw(key: string, value: any): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import * as unstorage from "unstorage";
|
|
3
|
+
import fsLiteDriver from "unstorage/drivers/fs-lite";
|
|
4
|
+
class UnstorageFsStorage {
|
|
5
|
+
#unstorage;
|
|
6
|
+
constructor({ base }) {
|
|
7
|
+
this.#unstorage = unstorage.createStorage({
|
|
8
|
+
driver: fsLiteDriver({ base: fileURLToPath(base) })
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
async getItem(key) {
|
|
12
|
+
return await this.#unstorage.getItem(key);
|
|
13
|
+
}
|
|
14
|
+
async getItemRaw(key) {
|
|
15
|
+
return await this.#unstorage.getItemRaw(key);
|
|
16
|
+
}
|
|
17
|
+
async setItem(key, value) {
|
|
18
|
+
return await this.#unstorage.setItem(key, value);
|
|
19
|
+
}
|
|
20
|
+
async setItemRaw(key, value) {
|
|
21
|
+
return await this.#unstorage.setItemRaw(key, value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
UnstorageFsStorage
|
|
26
|
+
};
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import type { DataCollector, UrlProxy, UrlProxyHashResolver, UrlResolver } from '../definitions.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
urlResolver:
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import type { DataCollector, ProxyData, UrlProxy, UrlProxyHashResolver, UrlResolver } from '../definitions.js';
|
|
2
|
+
import type { FontFileData, FontType } from '../types.js';
|
|
3
|
+
export declare class RealUrlProxy implements UrlProxy {
|
|
4
|
+
#private;
|
|
5
|
+
constructor({ hashResolver, dataCollector, urlResolver, cssVariable, }: {
|
|
6
|
+
hashResolver: UrlProxyHashResolver;
|
|
7
|
+
dataCollector: DataCollector;
|
|
8
|
+
urlResolver: UrlResolver;
|
|
9
|
+
cssVariable: string;
|
|
10
|
+
});
|
|
11
|
+
proxy({ url: originalUrl, type, data, collectPreload, init, }: Pick<FontFileData, 'url' | 'init'> & {
|
|
12
|
+
type: FontType;
|
|
13
|
+
collectPreload: boolean;
|
|
14
|
+
data: ProxyData;
|
|
15
|
+
}): string;
|
|
16
|
+
}
|
|
@@ -1,31 +1,50 @@
|
|
|
1
1
|
import { renderFontWeight } from "../utils.js";
|
|
2
|
-
|
|
3
|
-
hashResolver
|
|
4
|
-
dataCollector
|
|
5
|
-
urlResolver
|
|
6
|
-
cssVariable
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
2
|
+
class RealUrlProxy {
|
|
3
|
+
#hashResolver;
|
|
4
|
+
#dataCollector;
|
|
5
|
+
#urlResolver;
|
|
6
|
+
#cssVariable;
|
|
7
|
+
constructor({
|
|
8
|
+
hashResolver,
|
|
9
|
+
dataCollector,
|
|
10
|
+
urlResolver,
|
|
11
|
+
cssVariable
|
|
12
|
+
}) {
|
|
13
|
+
this.#hashResolver = hashResolver;
|
|
14
|
+
this.#dataCollector = dataCollector;
|
|
15
|
+
this.#urlResolver = urlResolver;
|
|
16
|
+
this.#cssVariable = cssVariable;
|
|
17
|
+
}
|
|
18
|
+
proxy({
|
|
19
|
+
url: originalUrl,
|
|
20
|
+
type,
|
|
21
|
+
data,
|
|
22
|
+
collectPreload,
|
|
23
|
+
init
|
|
24
|
+
}) {
|
|
25
|
+
const hash = this.#hashResolver.resolve({
|
|
26
|
+
cssVariable: this.#cssVariable,
|
|
27
|
+
data,
|
|
28
|
+
originalUrl,
|
|
29
|
+
type
|
|
30
|
+
});
|
|
31
|
+
const url = this.#urlResolver.resolve(hash);
|
|
32
|
+
this.#dataCollector.collect({
|
|
33
|
+
url: originalUrl,
|
|
34
|
+
hash,
|
|
35
|
+
preload: collectPreload ? {
|
|
36
|
+
url,
|
|
37
|
+
type,
|
|
38
|
+
weight: renderFontWeight(data.weight),
|
|
39
|
+
style: data.style,
|
|
40
|
+
subset: data.subset
|
|
41
|
+
} : null,
|
|
42
|
+
data,
|
|
43
|
+
init
|
|
44
|
+
});
|
|
45
|
+
return url;
|
|
46
|
+
}
|
|
28
47
|
}
|
|
29
48
|
export {
|
|
30
|
-
|
|
49
|
+
RealUrlProxy
|
|
31
50
|
};
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { Hasher } from '../definitions.js';
|
|
2
|
-
export declare
|
|
2
|
+
export declare class XxhashHasher implements Hasher {
|
|
3
|
+
hashString: (input: string) => string;
|
|
4
|
+
private constructor();
|
|
5
|
+
static create(): Promise<XxhashHasher>;
|
|
6
|
+
hashObject(input: Record<string, any>): string;
|
|
7
|
+
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import xxhash from "xxhash-wasm";
|
|
2
2
|
import { sortObjectByKey } from "../utils.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
hashString
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
3
|
+
class XxhashHasher {
|
|
4
|
+
hashString;
|
|
5
|
+
constructor(hashString) {
|
|
6
|
+
this.hashString = hashString;
|
|
7
|
+
}
|
|
8
|
+
static async create() {
|
|
9
|
+
const { h64ToString } = await xxhash();
|
|
10
|
+
return new XxhashHasher(h64ToString);
|
|
11
|
+
}
|
|
12
|
+
hashObject(input) {
|
|
13
|
+
return this.hashString(JSON.stringify(sortObjectByKey(input)));
|
|
14
|
+
}
|
|
11
15
|
}
|
|
12
16
|
export {
|
|
13
|
-
|
|
17
|
+
XxhashHasher
|
|
14
18
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { Storage } from 'unstorage';
|
|
2
1
|
import type { Logger } from '../../core/logger/core.js';
|
|
3
|
-
import type { CssRenderer, FontFileReader, FontMetricsResolver, FontTypeExtractor, Hasher, LocalProviderUrlResolver, RemoteFontProviderResolver, StringMatcher, SystemFallbacksProvider, UrlProxy } from './definitions.js';
|
|
2
|
+
import type { CssRenderer, FontFileReader, FontMetricsResolver, FontTypeExtractor, Hasher, LocalProviderUrlResolver, RemoteFontProviderResolver, Storage, StringMatcher, SystemFallbacksProvider, UrlProxy } from './definitions.js';
|
|
4
3
|
import type { ConsumableMap, CreateUrlProxyParams, Defaults, FontFamily, FontFileDataMap, InternalConsumableMap } from './types.js';
|
|
5
4
|
/**
|
|
6
5
|
* Manages how fonts are resolved:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type * as unifont from 'unifont';
|
|
2
|
-
import type { Storage } from '
|
|
3
|
-
import type { CssProperties } from './definitions.js';
|
|
2
|
+
import type { CssProperties, Storage } from './definitions.js';
|
|
4
3
|
import type { FontType, GenericFallbackName, ResolvedFontFamily } from './types.js';
|
|
5
4
|
/**
|
|
6
5
|
* Turns unifont font face data into generic CSS properties, to be consumed by the CSS renderer.
|
|
@@ -17,29 +17,27 @@ import {
|
|
|
17
17
|
RESOLVED_VIRTUAL_MODULE_ID,
|
|
18
18
|
VIRTUAL_MODULE_ID
|
|
19
19
|
} from "./constants.js";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
} from "./infra/url-proxy-content-resolver.js";
|
|
42
|
-
import { createXxhashHasher } from "./infra/xxhash-hasher.js";
|
|
20
|
+
import { BuildRemoteFontProviderModResolver } from "./infra/build-remote-font-provider-mod-resolver.js";
|
|
21
|
+
import { BuildUrlProxyHashResolver } from "./infra/build-url-proxy-hash-resolver.js";
|
|
22
|
+
import { BuildUrlResolver } from "./infra/build-url-resolver.js";
|
|
23
|
+
import { CachedFontFetcher } from "./infra/cached-font-fetcher.js";
|
|
24
|
+
import { CapsizeFontMetricsResolver } from "./infra/capsize-font-metrics-resolver.js";
|
|
25
|
+
import { RealDataCollector } from "./infra/data-collector.js";
|
|
26
|
+
import { DevServerRemoteFontProviderModResolver } from "./infra/dev-remote-font-provider-mod-resolver.js";
|
|
27
|
+
import { DevUrlProxyHashResolver } from "./infra/dev-url-proxy-hash-resolver.js";
|
|
28
|
+
import { DevUrlResolver } from "./infra/dev-url-resolver.js";
|
|
29
|
+
import { RealFontTypeExtractor } from "./infra/font-type-extractor.js";
|
|
30
|
+
import { FontaceFontFileReader } from "./infra/fontace-font-file-reader.js";
|
|
31
|
+
import { LevenshteinStringMatcher } from "./infra/levenshtein-string-matcher.js";
|
|
32
|
+
import { LocalUrlProxyContentResolver } from "./infra/local-url-proxy-content-resolver.js";
|
|
33
|
+
import { MinifiableCssRenderer } from "./infra/minifiable-css-renderer.js";
|
|
34
|
+
import { RealRemoteFontProviderResolver } from "./infra/remote-font-provider-resolver.js";
|
|
35
|
+
import { RemoteUrlProxyContentResolver } from "./infra/remote-url-proxy-content-resolver.js";
|
|
36
|
+
import { RequireLocalProviderUrlResolver } from "./infra/require-local-provider-url-resolver.js";
|
|
37
|
+
import { RealSystemFallbacksProvider } from "./infra/system-fallbacks-provider.js";
|
|
38
|
+
import { UnstorageFsStorage } from "./infra/unstorage-fs-storage.js";
|
|
39
|
+
import { RealUrlProxy } from "./infra/url-proxy.js";
|
|
40
|
+
import { XxhashHasher } from "./infra/xxhash-hasher.js";
|
|
43
41
|
import { orchestrate } from "./orchestrate.js";
|
|
44
42
|
function fontsPlugin({ settings, sync, logger }) {
|
|
45
43
|
if (!settings.config.experimental.fonts) {
|
|
@@ -83,13 +81,13 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
83
81
|
createHashResolver
|
|
84
82
|
}) {
|
|
85
83
|
const { root } = settings.config;
|
|
86
|
-
const hasher = await
|
|
87
|
-
const remoteFontProviderResolver =
|
|
84
|
+
const hasher = await XxhashHasher.create();
|
|
85
|
+
const remoteFontProviderResolver = new RealRemoteFontProviderResolver({
|
|
88
86
|
root,
|
|
89
87
|
modResolver
|
|
90
88
|
});
|
|
91
89
|
const pathsToWarn = /* @__PURE__ */ new Set();
|
|
92
|
-
const localProviderUrlResolver =
|
|
90
|
+
const localProviderUrlResolver = new RequireLocalProviderUrlResolver({
|
|
93
91
|
root,
|
|
94
92
|
intercept: (path) => {
|
|
95
93
|
if (path.startsWith(fileURLToPath(settings.config.publicDir))) {
|
|
@@ -104,13 +102,13 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
104
102
|
}
|
|
105
103
|
}
|
|
106
104
|
});
|
|
107
|
-
const storage =
|
|
108
|
-
const systemFallbacksProvider =
|
|
109
|
-
fontFetcher =
|
|
110
|
-
const fontMetricsResolver =
|
|
111
|
-
fontTypeExtractor =
|
|
112
|
-
const fontFileReader =
|
|
113
|
-
const stringMatcher =
|
|
105
|
+
const storage = new UnstorageFsStorage({ base: cacheDir });
|
|
106
|
+
const systemFallbacksProvider = new RealSystemFallbacksProvider();
|
|
107
|
+
fontFetcher = new CachedFontFetcher({ storage, fetch, readFile });
|
|
108
|
+
const fontMetricsResolver = new CapsizeFontMetricsResolver({ fontFetcher, cssRenderer });
|
|
109
|
+
fontTypeExtractor = new RealFontTypeExtractor();
|
|
110
|
+
const fontFileReader = new FontaceFontFileReader();
|
|
111
|
+
const stringMatcher = new LevenshteinStringMatcher();
|
|
114
112
|
const res = await orchestrate({
|
|
115
113
|
families: settings.config.experimental.fonts,
|
|
116
114
|
hasher,
|
|
@@ -124,9 +122,9 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
124
122
|
fontFileReader,
|
|
125
123
|
logger,
|
|
126
124
|
createUrlProxy: ({ local, cssVariable, ...params }) => {
|
|
127
|
-
const dataCollector =
|
|
128
|
-
const contentResolver = local ?
|
|
129
|
-
return
|
|
125
|
+
const dataCollector = new RealDataCollector(params);
|
|
126
|
+
const contentResolver = local ? new LocalUrlProxyContentResolver() : new RemoteUrlProxyContentResolver();
|
|
127
|
+
return new RealUrlProxy({
|
|
130
128
|
urlResolver,
|
|
131
129
|
hashResolver: createHashResolver({ hasher, contentResolver }),
|
|
132
130
|
dataCollector,
|
|
@@ -145,8 +143,7 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
145
143
|
for (const { css } of internalConsumableMap.values()) {
|
|
146
144
|
settings.injectedCsp.styleHashes.push(await generateCspDigest(css, algorithm));
|
|
147
145
|
}
|
|
148
|
-
const
|
|
149
|
-
for (const resource of resources) {
|
|
146
|
+
for (const resource of urlResolver.cspResources) {
|
|
150
147
|
settings.injectedCsp.fontResources.add(resource);
|
|
151
148
|
}
|
|
152
149
|
}
|
|
@@ -160,14 +157,14 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
160
157
|
if (isBuild) {
|
|
161
158
|
await initialize({
|
|
162
159
|
cacheDir: new URL(CACHE_DIR, settings.config.cacheDir),
|
|
163
|
-
modResolver:
|
|
164
|
-
cssRenderer:
|
|
165
|
-
urlResolver:
|
|
160
|
+
modResolver: new BuildRemoteFontProviderModResolver(),
|
|
161
|
+
cssRenderer: new MinifiableCssRenderer({ minify: true }),
|
|
162
|
+
urlResolver: new BuildUrlResolver({
|
|
166
163
|
base: baseUrl,
|
|
167
164
|
assetsPrefix: settings.config.build.assetsPrefix,
|
|
168
165
|
searchParams: settings.adapter?.client?.assetQueryParams ?? new URLSearchParams()
|
|
169
166
|
}),
|
|
170
|
-
createHashResolver:
|
|
167
|
+
createHashResolver: (dependencies) => new BuildUrlProxyHashResolver(dependencies)
|
|
171
168
|
});
|
|
172
169
|
}
|
|
173
170
|
},
|
|
@@ -175,13 +172,13 @@ function fontsPlugin({ settings, sync, logger }) {
|
|
|
175
172
|
await initialize({
|
|
176
173
|
// In dev, we cache fonts data in .astro so it can be easily inspected and cleared
|
|
177
174
|
cacheDir: new URL(CACHE_DIR, settings.dotAstroDir),
|
|
178
|
-
modResolver:
|
|
179
|
-
cssRenderer:
|
|
180
|
-
urlResolver:
|
|
175
|
+
modResolver: new DevServerRemoteFontProviderModResolver({ server }),
|
|
176
|
+
cssRenderer: new MinifiableCssRenderer({ minify: false }),
|
|
177
|
+
urlResolver: new DevUrlResolver({
|
|
181
178
|
base: baseUrl,
|
|
182
179
|
searchParams: settings.adapter?.client?.assetQueryParams ?? new URLSearchParams()
|
|
183
180
|
}),
|
|
184
|
-
createHashResolver:
|
|
181
|
+
createHashResolver: (dependencies) => new DevUrlProxyHashResolver(dependencies)
|
|
185
182
|
});
|
|
186
183
|
const localPaths = [...fontFileDataMap.values()].filter(({ url }) => isAbsolute(url)).map((v) => v.url);
|
|
187
184
|
server.watcher.on("change", (path) => {
|
|
@@ -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.16.
|
|
167
|
+
if (previousAstroVersion && previousAstroVersion !== "5.16.4") {
|
|
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.16.
|
|
176
|
-
await this.#store.metaStore().set("astro-version", "5.16.
|
|
175
|
+
if ("5.16.4") {
|
|
176
|
+
await this.#store.metaStore().set("astro-version", "5.16.4");
|
|
177
177
|
}
|
|
178
178
|
if (currentConfigDigest) {
|
|
179
179
|
await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
package/dist/core/app/index.js
CHANGED
|
@@ -30,6 +30,7 @@ import { ensure404Route } from "../routing/astro-designed-error-pages.js";
|
|
|
30
30
|
import { createDefaultRoutes } from "../routing/default.js";
|
|
31
31
|
import { matchRoute } from "../routing/match.js";
|
|
32
32
|
import { PERSIST_SYMBOL } from "../session.js";
|
|
33
|
+
import { validateAndDecodePathname } from "../util/pathname.js";
|
|
33
34
|
import { AppPipeline } from "./pipeline.js";
|
|
34
35
|
import { deserializeManifest } from "./common.js";
|
|
35
36
|
class App {
|
|
@@ -197,7 +198,7 @@ class App {
|
|
|
197
198
|
const url = new URL(request.url);
|
|
198
199
|
const pathname = prependForwardSlash(this.removeBase(url.pathname));
|
|
199
200
|
try {
|
|
200
|
-
return
|
|
201
|
+
return validateAndDecodePathname(pathname);
|
|
201
202
|
} catch (e) {
|
|
202
203
|
this.getAdapterLogger().error(e.toString());
|
|
203
204
|
return pathname;
|
|
@@ -218,7 +219,12 @@ class App {
|
|
|
218
219
|
if (!pathname) {
|
|
219
220
|
pathname = prependForwardSlash(this.removeBase(url.pathname));
|
|
220
221
|
}
|
|
221
|
-
|
|
222
|
+
try {
|
|
223
|
+
pathname = validateAndDecodePathname(pathname);
|
|
224
|
+
} catch {
|
|
225
|
+
return void 0;
|
|
226
|
+
}
|
|
227
|
+
let routeData = matchRoute(pathname, this.#manifestData);
|
|
222
228
|
if (!routeData) return void 0;
|
|
223
229
|
if (allowPrerenderedRoutes) {
|
|
224
230
|
return routeData;
|
package/dist/core/constants.js
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SSRManifestCSP } from '../app/types.js';
|
|
2
|
+
import type { CspDirective } from './config.js';
|
|
3
|
+
/**
|
|
4
|
+
* `existingDirective` is something like `img-src 'self'`. Same as `newDirective`.
|
|
5
|
+
*
|
|
6
|
+
* Returns `undefined` if no directive has been deduped
|
|
7
|
+
* @param existingDirective
|
|
8
|
+
* @param newDirective
|
|
9
|
+
*/
|
|
10
|
+
export declare function deduplicateDirectiveValues(existingDirective: CspDirective, newDirective: CspDirective): CspDirective | undefined;
|
|
11
|
+
export declare function pushDirective(directives: SSRManifestCSP['directives'], newDirective: CspDirective): SSRManifestCSP['directives'];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
function deduplicateDirectiveValues(existingDirective, newDirective) {
|
|
2
|
+
const [directiveName, ...existingValues] = existingDirective.split(/\s+/).filter(Boolean);
|
|
3
|
+
const [newDirectiveName, ...newValues] = newDirective.split(/\s+/).filter(Boolean);
|
|
4
|
+
if (directiveName !== newDirectiveName) {
|
|
5
|
+
return void 0;
|
|
6
|
+
}
|
|
7
|
+
const finalDirectives = Array.from(/* @__PURE__ */ new Set([...existingValues, ...newValues]));
|
|
8
|
+
return `${directiveName} ${finalDirectives.join(" ")}`;
|
|
9
|
+
}
|
|
10
|
+
function pushDirective(directives, newDirective) {
|
|
11
|
+
let deduplicated = false;
|
|
12
|
+
if (directives.length === 0) {
|
|
13
|
+
return [newDirective];
|
|
14
|
+
}
|
|
15
|
+
const finalDirectives = [];
|
|
16
|
+
for (const directive of directives) {
|
|
17
|
+
if (deduplicated) {
|
|
18
|
+
finalDirectives.push(directive);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const result = deduplicateDirectiveValues(directive, newDirective);
|
|
22
|
+
if (result) {
|
|
23
|
+
finalDirectives.push(result);
|
|
24
|
+
deduplicated = true;
|
|
25
|
+
} else {
|
|
26
|
+
finalDirectives.push(directive);
|
|
27
|
+
finalDirectives.push(newDirective);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return finalDirectives;
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
deduplicateDirectiveValues,
|
|
34
|
+
pushDirective
|
|
35
|
+
};
|
package/dist/core/dev/dev.js
CHANGED
|
@@ -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 = "5.16.
|
|
25
|
+
const currentVersion = "5.16.4";
|
|
26
26
|
const isPrerelease = currentVersion.includes("-");
|
|
27
27
|
if (!isPrerelease) {
|
|
28
28
|
try {
|
package/dist/core/messages.js
CHANGED
|
@@ -38,7 +38,7 @@ function serverStart({
|
|
|
38
38
|
host,
|
|
39
39
|
base
|
|
40
40
|
}) {
|
|
41
|
-
const version = "5.16.
|
|
41
|
+
const version = "5.16.4";
|
|
42
42
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
43
43
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
44
44
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -275,7 +275,7 @@ function printHelp({
|
|
|
275
275
|
message.push(
|
|
276
276
|
linebreak(),
|
|
277
277
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
278
|
-
`v${"5.16.
|
|
278
|
+
`v${"5.16.4"}`
|
|
279
279
|
)} ${headline}`
|
|
280
280
|
);
|
|
281
281
|
}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from "./constants.js";
|
|
21
21
|
import { AstroCookies, attachCookiesToResponse } from "./cookies/index.js";
|
|
22
22
|
import { getCookiesFromResponse } from "./cookies/response.js";
|
|
23
|
+
import { pushDirective } from "./csp/runtime.js";
|
|
23
24
|
import { generateCspDigest } from "./encryption.js";
|
|
24
25
|
import { CspNotEnabled, ForbiddenRewrite } from "./errors/errors-data.js";
|
|
25
26
|
import { AstroError, AstroErrorData } from "./errors/index.js";
|
|
@@ -30,6 +31,7 @@ import { getParams, getProps, Slots } from "./render/index.js";
|
|
|
30
31
|
import { isRoute404or500, isRouteExternalRedirect, isRouteServerIsland } from "./routing/match.js";
|
|
31
32
|
import { copyRequest, getOriginPathname, setOriginPathname } from "./routing/rewrite.js";
|
|
32
33
|
import { AstroSession } from "./session.js";
|
|
34
|
+
import { validateAndDecodePathname } from "./util/pathname.js";
|
|
33
35
|
const apiContextRoutesSymbol = Symbol.for("context.routes");
|
|
34
36
|
class RenderContext {
|
|
35
37
|
constructor(pipeline, locals, middleware, actions, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = RenderContext.#createNormalizedUrl(request.url), props = {}, partial = void 0, shouldInjectCspMetaTags = !!pipeline.manifest.csp, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig, pipeline.runtimeMode) : void 0) {
|
|
@@ -53,10 +55,14 @@ class RenderContext {
|
|
|
53
55
|
static #createNormalizedUrl(requestUrl) {
|
|
54
56
|
const url = new URL(requestUrl);
|
|
55
57
|
try {
|
|
56
|
-
url.pathname =
|
|
57
|
-
}
|
|
58
|
-
|
|
58
|
+
url.pathname = validateAndDecodePathname(url.pathname);
|
|
59
|
+
} catch {
|
|
60
|
+
try {
|
|
61
|
+
url.pathname = decodeURI(url.pathname);
|
|
62
|
+
} catch {
|
|
63
|
+
}
|
|
59
64
|
}
|
|
65
|
+
return url;
|
|
60
66
|
}
|
|
61
67
|
/**
|
|
62
68
|
* A flag that tells the render content if the rewriting was triggered
|
|
@@ -367,7 +373,14 @@ class RenderContext {
|
|
|
367
373
|
if (!pipeline.manifest.csp) {
|
|
368
374
|
throw new AstroError(CspNotEnabled);
|
|
369
375
|
}
|
|
370
|
-
renderContext
|
|
376
|
+
if (renderContext?.result?.directives) {
|
|
377
|
+
renderContext.result.directives = pushDirective(
|
|
378
|
+
renderContext.result.directives,
|
|
379
|
+
payload
|
|
380
|
+
);
|
|
381
|
+
} else {
|
|
382
|
+
renderContext?.result?.directives.push(payload);
|
|
383
|
+
}
|
|
371
384
|
},
|
|
372
385
|
insertScriptResource(resource) {
|
|
373
386
|
if (!pipeline.manifest.csp) {
|
|
@@ -596,7 +609,14 @@ class RenderContext {
|
|
|
596
609
|
if (!pipeline.manifest.csp) {
|
|
597
610
|
throw new AstroError(CspNotEnabled);
|
|
598
611
|
}
|
|
599
|
-
renderContext
|
|
612
|
+
if (renderContext?.result?.directives) {
|
|
613
|
+
renderContext.result.directives = pushDirective(
|
|
614
|
+
renderContext.result.directives,
|
|
615
|
+
payload
|
|
616
|
+
);
|
|
617
|
+
} else {
|
|
618
|
+
renderContext?.result?.directives.push(payload);
|
|
619
|
+
}
|
|
600
620
|
},
|
|
601
621
|
insertScriptResource(resource) {
|
|
602
622
|
if (!pipeline.manifest.csp) {
|