astro 6.1.3 → 6.1.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/assets/utils/index.d.ts +1 -1
- package/dist/assets/utils/index.js +1 -9
- package/dist/assets/utils/vendor/image-size/utils/bit-reader.d.ts +2 -2
- package/dist/assets/utils/vendor/image-size/utils/bit-reader.js +5 -3
- package/dist/cli/add/index.js +37 -44
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/content/loaders/errors.d.ts +2 -2
- package/dist/content/loaders/errors.js +3 -0
- package/dist/core/app/base.js +1 -1
- package/dist/core/base-pipeline.d.ts +22 -35
- package/dist/core/base-pipeline.js +41 -8
- package/dist/core/build/generate.js +9 -1
- package/dist/core/build/pipeline.d.ts +3 -7
- package/dist/core/build/pipeline.js +30 -28
- package/dist/core/config/schemas/refined-validators.d.ts +44 -0
- package/dist/core/config/schemas/refined-validators.js +168 -0
- package/dist/core/config/schemas/refined.js +28 -141
- package/dist/core/constants.js +1 -1
- package/dist/core/cookies/cookies.js +1 -0
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/restart.js +63 -68
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/render-context.d.ts +2 -2
- package/dist/core/render-context.js +20 -0
- package/dist/core/routing/create-manifest.js +12 -4
- package/dist/core/routing/default.d.ts +2 -3
- package/dist/integrations/features-validation.d.ts +3 -1
- package/dist/integrations/features-validation.js +2 -0
- package/dist/preferences/store.js +2 -1
- package/dist/runtime/server/transition.d.ts +2 -2
- package/dist/runtime/server/transition.js +4 -2
- package/dist/vite-plugin-app/pipeline.d.ts +4 -13
- package/dist/vite-plugin-app/pipeline.js +27 -12
- package/dist/vite-plugin-astro-server/base.d.ts +52 -0
- package/dist/vite-plugin-astro-server/base.js +66 -36
- package/dist/vite-plugin-astro-server/trailing-slash.d.ts +34 -0
- package/dist/vite-plugin-astro-server/trailing-slash.js +24 -11
- package/package.json +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AstroConfig } from '../../../types/public/config.js';
|
|
2
|
+
export interface ConfigValidationIssue {
|
|
3
|
+
message: string;
|
|
4
|
+
path: (string | number)[];
|
|
5
|
+
}
|
|
6
|
+
type I18nConfig = NonNullable<AstroConfig['i18n']>;
|
|
7
|
+
/**
|
|
8
|
+
* Validates that `build.assetsPrefix`, when specified as an object, includes a `fallback` key.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateAssetsPrefix(config: Pick<AstroConfig, 'build'>): ConfigValidationIssue[];
|
|
11
|
+
/**
|
|
12
|
+
* Validates that remote pattern wildcards are only at the start of hostnames
|
|
13
|
+
* and at the end of pathnames.
|
|
14
|
+
*/
|
|
15
|
+
export declare function validateRemotePatterns(remotePatterns: AstroConfig['image']['remotePatterns']): ConfigValidationIssue[];
|
|
16
|
+
/**
|
|
17
|
+
* Validates that `redirectToDefaultLocale` is not `true` when
|
|
18
|
+
* `prefixDefaultLocale` is `false`, which would cause infinite redirects.
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateI18nRedirectToDefaultLocale(i18n: AstroConfig['i18n']): ConfigValidationIssue[];
|
|
21
|
+
/**
|
|
22
|
+
* Validates that `outDir` is not inside `publicDir`, which would cause an infinite loop.
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateOutDirNotInPublicDir(outDir: AstroConfig['outDir'], publicDir: AstroConfig['publicDir']): ConfigValidationIssue[];
|
|
25
|
+
/**
|
|
26
|
+
* Validates that the default locale is present in the locales array.
|
|
27
|
+
*/
|
|
28
|
+
export declare function validateI18nDefaultLocale(i18n: Pick<I18nConfig, 'defaultLocale' | 'locales'>): ConfigValidationIssue[];
|
|
29
|
+
/**
|
|
30
|
+
* Validates i18n fallback entries: keys and values must exist in locales,
|
|
31
|
+
* and the default locale cannot be used as a key.
|
|
32
|
+
*/
|
|
33
|
+
export declare function validateI18nFallback(i18n: Pick<I18nConfig, 'defaultLocale' | 'locales' | 'fallback'>): ConfigValidationIssue[];
|
|
34
|
+
/**
|
|
35
|
+
* Validates i18n domain entries: locale keys must exist, domain values must be
|
|
36
|
+
* valid origin URLs, site must be set, and output must be 'server'.
|
|
37
|
+
*/
|
|
38
|
+
export declare function validateI18nDomains(config: Pick<AstroConfig, 'site' | 'output' | 'i18n'>): ConfigValidationIssue[];
|
|
39
|
+
/**
|
|
40
|
+
* Validates that font `cssVariable` values start with `--` and don't contain
|
|
41
|
+
* spaces or colons.
|
|
42
|
+
*/
|
|
43
|
+
export declare function validateFontsCssVariables(fonts: NonNullable<AstroConfig['fonts']>): ConfigValidationIssue[];
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
function validateAssetsPrefix(config) {
|
|
2
|
+
if (config.build.assetsPrefix && typeof config.build.assetsPrefix !== "string" && !config.build.assetsPrefix.fallback) {
|
|
3
|
+
return [
|
|
4
|
+
{
|
|
5
|
+
message: "The `fallback` is mandatory when defining the option as an object.",
|
|
6
|
+
path: ["build", "assetsPrefix"]
|
|
7
|
+
}
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
function validateRemotePatterns(remotePatterns) {
|
|
13
|
+
const issues = [];
|
|
14
|
+
for (let i = 0; i < remotePatterns.length; i++) {
|
|
15
|
+
const { hostname, pathname } = remotePatterns[i];
|
|
16
|
+
if (hostname && hostname.includes("*") && !(hostname.startsWith("*.") || hostname.startsWith("**."))) {
|
|
17
|
+
issues.push({
|
|
18
|
+
message: "wildcards can only be placed at the beginning of the hostname",
|
|
19
|
+
path: ["image", "remotePatterns", i, "hostname"]
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
if (pathname && pathname.includes("*") && !(pathname.endsWith("/*") || pathname.endsWith("/**"))) {
|
|
23
|
+
issues.push({
|
|
24
|
+
message: "wildcards can only be placed at the end of a pathname",
|
|
25
|
+
path: ["image", "remotePatterns", i, "pathname"]
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return issues;
|
|
30
|
+
}
|
|
31
|
+
function validateI18nRedirectToDefaultLocale(i18n) {
|
|
32
|
+
if (i18n && typeof i18n.routing !== "string" && i18n.routing.prefixDefaultLocale === false && i18n.routing.redirectToDefaultLocale === true) {
|
|
33
|
+
return [
|
|
34
|
+
{
|
|
35
|
+
message: "The option `i18n.routing.redirectToDefaultLocale` can be used only when `i18n.routing.prefixDefaultLocale` is set to `true`; otherwise, redirects might cause infinite loops. Remove the option `i18n.routing.redirectToDefaultLocale`, or change its value to `false`.",
|
|
36
|
+
path: ["i18n", "routing", "redirectToDefaultLocale"]
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
function validateOutDirNotInPublicDir(outDir, publicDir) {
|
|
43
|
+
if (outDir.toString().startsWith(publicDir.toString())) {
|
|
44
|
+
return [
|
|
45
|
+
{
|
|
46
|
+
message: "The value of `outDir` must not point to a path within the folder set as `publicDir`, this will cause an infinite loop",
|
|
47
|
+
path: ["outDir"]
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
function validateI18nDefaultLocale(i18n) {
|
|
54
|
+
const locales = i18n.locales.map((locale) => typeof locale === "string" ? locale : locale.path);
|
|
55
|
+
if (!locales.includes(i18n.defaultLocale)) {
|
|
56
|
+
return [
|
|
57
|
+
{
|
|
58
|
+
message: `The default locale \`${i18n.defaultLocale}\` is not present in the \`i18n.locales\` array.`,
|
|
59
|
+
path: ["i18n", "locales"]
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
function validateI18nFallback(i18n) {
|
|
66
|
+
const issues = [];
|
|
67
|
+
const { defaultLocale, fallback } = i18n;
|
|
68
|
+
if (!fallback) return [];
|
|
69
|
+
const locales = i18n.locales.map((locale) => typeof locale === "string" ? locale : locale.path);
|
|
70
|
+
for (const [fallbackFrom, fallbackTo] of Object.entries(fallback)) {
|
|
71
|
+
if (!locales.includes(fallbackFrom)) {
|
|
72
|
+
issues.push({
|
|
73
|
+
message: `The locale \`${fallbackFrom}\` key in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`,
|
|
74
|
+
path: ["i18n", "fallbacks"]
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (fallbackFrom === defaultLocale) {
|
|
78
|
+
issues.push({
|
|
79
|
+
message: `You can't use the default locale as a key. The default locale can only be used as value.`,
|
|
80
|
+
path: ["i18n", "fallbacks"]
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (!locales.includes(fallbackTo)) {
|
|
84
|
+
issues.push({
|
|
85
|
+
message: `The locale \`${fallbackTo}\` value in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`,
|
|
86
|
+
path: ["i18n", "fallbacks"]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return issues;
|
|
91
|
+
}
|
|
92
|
+
function validateI18nDomains(config) {
|
|
93
|
+
const issues = [];
|
|
94
|
+
const i18n = config.i18n;
|
|
95
|
+
if (!i18n?.domains) return [];
|
|
96
|
+
const entries = Object.entries(i18n.domains);
|
|
97
|
+
const hasDomains = Object.keys(i18n.domains).length > 0;
|
|
98
|
+
if (entries.length > 0 && !hasDomains) {
|
|
99
|
+
issues.push({
|
|
100
|
+
message: `When specifying some domains, the property \`i18n.routing.strategy\` must be set to \`"domains"\`.`,
|
|
101
|
+
path: ["i18n", "routing", "strategy"]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (hasDomains) {
|
|
105
|
+
if (!config.site) {
|
|
106
|
+
issues.push({
|
|
107
|
+
message: "The option `site` isn't set. When using the 'domains' strategy for `i18n`, `site` is required to create absolute URLs for locales that aren't mapped to a domain.",
|
|
108
|
+
path: ["site"]
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (config.output !== "server") {
|
|
112
|
+
issues.push({
|
|
113
|
+
message: 'Domain support is only available when `output` is `"server"`.',
|
|
114
|
+
path: ["output"]
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const locales = i18n.locales.map((locale) => typeof locale === "string" ? locale : locale.path);
|
|
119
|
+
for (const [domainKey, domainValue] of entries) {
|
|
120
|
+
if (!locales.includes(domainKey)) {
|
|
121
|
+
issues.push({
|
|
122
|
+
message: `The locale \`${domainKey}\` key in the \`i18n.domains\` record doesn't exist in the \`i18n.locales\` array.`,
|
|
123
|
+
path: ["i18n", "domains"]
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (!domainValue.startsWith("https") && !domainValue.startsWith("http")) {
|
|
127
|
+
issues.push({
|
|
128
|
+
message: "The domain value must be a valid URL, and it has to start with 'https' or 'http'.",
|
|
129
|
+
path: ["i18n", "domains"]
|
|
130
|
+
});
|
|
131
|
+
} else {
|
|
132
|
+
try {
|
|
133
|
+
const domainUrl = new URL(domainValue);
|
|
134
|
+
if (domainUrl.pathname !== "/") {
|
|
135
|
+
issues.push({
|
|
136
|
+
message: `The URL \`${domainValue}\` must contain only the origin. A subsequent pathname isn't allowed here. Remove \`${domainUrl.pathname}\`.`,
|
|
137
|
+
path: ["i18n", "domains"]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
} catch {
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return issues;
|
|
145
|
+
}
|
|
146
|
+
function validateFontsCssVariables(fonts) {
|
|
147
|
+
const issues = [];
|
|
148
|
+
for (let i = 0; i < fonts.length; i++) {
|
|
149
|
+
const { cssVariable } = fonts[i];
|
|
150
|
+
if (!cssVariable.startsWith("--") || cssVariable.includes(" ") || cssVariable.includes(":")) {
|
|
151
|
+
issues.push({
|
|
152
|
+
message: `**cssVariable** property "${cssVariable}" contains invalid characters for CSS variable generation. It must start with -- and be a valid indent: https://developer.mozilla.org/en-US/docs/Web/CSS/ident.`,
|
|
153
|
+
path: ["fonts", i, "cssVariable"]
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return issues;
|
|
158
|
+
}
|
|
159
|
+
export {
|
|
160
|
+
validateAssetsPrefix,
|
|
161
|
+
validateFontsCssVariables,
|
|
162
|
+
validateI18nDefaultLocale,
|
|
163
|
+
validateI18nDomains,
|
|
164
|
+
validateI18nFallback,
|
|
165
|
+
validateI18nRedirectToDefaultLocale,
|
|
166
|
+
validateOutDirNotInPublicDir,
|
|
167
|
+
validateRemotePatterns
|
|
168
|
+
};
|
|
@@ -1,152 +1,39 @@
|
|
|
1
1
|
import * as z from "zod/v4";
|
|
2
|
+
import {
|
|
3
|
+
validateAssetsPrefix,
|
|
4
|
+
validateFontsCssVariables,
|
|
5
|
+
validateI18nDefaultLocale,
|
|
6
|
+
validateI18nDomains,
|
|
7
|
+
validateI18nFallback,
|
|
8
|
+
validateI18nRedirectToDefaultLocale,
|
|
9
|
+
validateOutDirNotInPublicDir,
|
|
10
|
+
validateRemotePatterns
|
|
11
|
+
} from "./refined-validators.js";
|
|
2
12
|
const AstroConfigRefinedSchema = z.custom().superRefine((config, ctx) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
path: ["image", "remotePatterns", i, "hostname"]
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
if (pathname && pathname.includes("*") && !(pathname.endsWith("/*") || pathname.endsWith("/**"))) {
|
|
20
|
-
ctx.addIssue({
|
|
21
|
-
code: z.ZodIssueCode.custom,
|
|
22
|
-
message: "wildcards can only be placed at the end of a pathname",
|
|
23
|
-
path: ["image", "remotePatterns", i, "pathname"]
|
|
24
|
-
});
|
|
25
|
-
}
|
|
13
|
+
let issues = [];
|
|
14
|
+
issues = issues.concat(
|
|
15
|
+
validateAssetsPrefix(config),
|
|
16
|
+
validateRemotePatterns(config.image.remotePatterns),
|
|
17
|
+
validateI18nRedirectToDefaultLocale(config.i18n),
|
|
18
|
+
validateOutDirNotInPublicDir(config.outDir, config.publicDir)
|
|
19
|
+
);
|
|
20
|
+
if (config.i18n) {
|
|
21
|
+
issues = issues.concat(
|
|
22
|
+
validateI18nDefaultLocale(config.i18n),
|
|
23
|
+
validateI18nFallback(config.i18n),
|
|
24
|
+
validateI18nDomains(config)
|
|
25
|
+
);
|
|
26
26
|
}
|
|
27
|
-
if (config.
|
|
28
|
-
|
|
29
|
-
code: z.ZodIssueCode.custom,
|
|
30
|
-
message: "The option `i18n.routing.redirectToDefaultLocale` can be used only when `i18n.routing.prefixDefaultLocale` is set to `true`; otherwise, redirects might cause infinite loops. Remove the option `i18n.routing.redirectToDefaultLocale`, or change its value to `false`.",
|
|
31
|
-
path: ["i18n", "routing", "redirectToDefaultLocale"]
|
|
32
|
-
});
|
|
27
|
+
if (config.fonts && config.fonts.length > 0) {
|
|
28
|
+
issues = issues.concat(validateFontsCssVariables(config.fonts));
|
|
33
29
|
}
|
|
34
|
-
|
|
30
|
+
for (const issue of issues) {
|
|
35
31
|
ctx.addIssue({
|
|
36
32
|
code: z.ZodIssueCode.custom,
|
|
37
|
-
message:
|
|
38
|
-
path:
|
|
33
|
+
message: issue.message,
|
|
34
|
+
path: issue.path
|
|
39
35
|
});
|
|
40
36
|
}
|
|
41
|
-
if (config.i18n) {
|
|
42
|
-
const { defaultLocale, locales: _locales, fallback, domains } = config.i18n;
|
|
43
|
-
const locales = _locales.map((locale) => {
|
|
44
|
-
if (typeof locale === "string") {
|
|
45
|
-
return locale;
|
|
46
|
-
} else {
|
|
47
|
-
return locale.path;
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
if (!locales.includes(defaultLocale)) {
|
|
51
|
-
ctx.addIssue({
|
|
52
|
-
code: z.ZodIssueCode.custom,
|
|
53
|
-
message: `The default locale \`${defaultLocale}\` is not present in the \`i18n.locales\` array.`,
|
|
54
|
-
path: ["i18n", "locales"]
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
if (fallback) {
|
|
58
|
-
for (const [fallbackFrom, fallbackTo] of Object.entries(fallback)) {
|
|
59
|
-
if (!locales.includes(fallbackFrom)) {
|
|
60
|
-
ctx.addIssue({
|
|
61
|
-
code: z.ZodIssueCode.custom,
|
|
62
|
-
message: `The locale \`${fallbackFrom}\` key in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`,
|
|
63
|
-
path: ["i18n", "fallbacks"]
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
if (fallbackFrom === defaultLocale) {
|
|
67
|
-
ctx.addIssue({
|
|
68
|
-
code: z.ZodIssueCode.custom,
|
|
69
|
-
message: `You can't use the default locale as a key. The default locale can only be used as value.`,
|
|
70
|
-
path: ["i18n", "fallbacks"]
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
if (!locales.includes(fallbackTo)) {
|
|
74
|
-
ctx.addIssue({
|
|
75
|
-
code: z.ZodIssueCode.custom,
|
|
76
|
-
message: `The locale \`${fallbackTo}\` value in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`,
|
|
77
|
-
path: ["i18n", "fallbacks"]
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
if (domains) {
|
|
83
|
-
const entries = Object.entries(domains);
|
|
84
|
-
const hasDomains = domains ? Object.keys(domains).length > 0 : false;
|
|
85
|
-
if (entries.length > 0 && !hasDomains) {
|
|
86
|
-
ctx.addIssue({
|
|
87
|
-
code: z.ZodIssueCode.custom,
|
|
88
|
-
message: `When specifying some domains, the property \`i18n.routing.strategy\` must be set to \`"domains"\`.`,
|
|
89
|
-
path: ["i18n", "routing", "strategy"]
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
if (hasDomains) {
|
|
93
|
-
if (!config.site) {
|
|
94
|
-
ctx.addIssue({
|
|
95
|
-
code: z.ZodIssueCode.custom,
|
|
96
|
-
message: "The option `site` isn't set. When using the 'domains' strategy for `i18n`, `site` is required to create absolute URLs for locales that aren't mapped to a domain.",
|
|
97
|
-
path: ["site"]
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
if (config.output !== "server") {
|
|
101
|
-
ctx.addIssue({
|
|
102
|
-
code: z.ZodIssueCode.custom,
|
|
103
|
-
message: 'Domain support is only available when `output` is `"server"`.',
|
|
104
|
-
path: ["output"]
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
for (const [domainKey, domainValue] of entries) {
|
|
109
|
-
if (!locales.includes(domainKey)) {
|
|
110
|
-
ctx.addIssue({
|
|
111
|
-
code: z.ZodIssueCode.custom,
|
|
112
|
-
message: `The locale \`${domainKey}\` key in the \`i18n.domains\` record doesn't exist in the \`i18n.locales\` array.`,
|
|
113
|
-
path: ["i18n", "domains"]
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
if (!domainValue.startsWith("https") && !domainValue.startsWith("http")) {
|
|
117
|
-
ctx.addIssue({
|
|
118
|
-
code: z.ZodIssueCode.custom,
|
|
119
|
-
message: "The domain value must be a valid URL, and it has to start with 'https' or 'http'.",
|
|
120
|
-
path: ["i18n", "domains"]
|
|
121
|
-
});
|
|
122
|
-
} else {
|
|
123
|
-
try {
|
|
124
|
-
const domainUrl = new URL(domainValue);
|
|
125
|
-
if (domainUrl.pathname !== "/") {
|
|
126
|
-
ctx.addIssue({
|
|
127
|
-
code: z.ZodIssueCode.custom,
|
|
128
|
-
message: `The URL \`${domainValue}\` must contain only the origin. A subsequent pathname isn't allowed here. Remove \`${domainUrl.pathname}\`.`,
|
|
129
|
-
path: ["i18n", "domains"]
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
} catch {
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
if (config.fonts && config.fonts.length > 0) {
|
|
139
|
-
for (let i = 0; i < config.fonts.length; i++) {
|
|
140
|
-
const { cssVariable } = config.fonts[i];
|
|
141
|
-
if (!cssVariable.startsWith("--") || cssVariable.includes(" ") || cssVariable.includes(":")) {
|
|
142
|
-
ctx.addIssue({
|
|
143
|
-
code: "custom",
|
|
144
|
-
message: `**cssVariable** property "${cssVariable}" contains invalid characters for CSS variable generation. It must start with -- and be a valid indent: https://developer.mozilla.org/en-US/docs/Web/CSS/ident.`,
|
|
145
|
-
path: ["fonts", i, "cssVariable"]
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
37
|
});
|
|
151
38
|
export {
|
|
152
39
|
AstroConfigRefinedSchema
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -37,7 +37,7 @@ async function dev(inlineConfig) {
|
|
|
37
37
|
await telemetry.record([]);
|
|
38
38
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
39
39
|
const logger = restart.container.logger;
|
|
40
|
-
const currentVersion = "6.1.
|
|
40
|
+
const currentVersion = "6.1.4";
|
|
41
41
|
const isPrerelease = currentVersion.includes("-");
|
|
42
42
|
if (!isPrerelease) {
|
|
43
43
|
try {
|
package/dist/core/dev/restart.js
CHANGED
|
@@ -3,26 +3,18 @@ import * as vite from "vite";
|
|
|
3
3
|
import { globalContentLayer } from "../../content/instance.js";
|
|
4
4
|
import { attachContentServerListeners } from "../../content/server-listeners.js";
|
|
5
5
|
import { eventCliSession, telemetry } from "../../events/index.js";
|
|
6
|
+
import { runHookConfigDone, runHookConfigSetup } from "../../integrations/hooks.js";
|
|
6
7
|
import { SETTINGS_FILE } from "../../preferences/constants.js";
|
|
8
|
+
import { getPrerenderDefault } from "../../prerender/utils.js";
|
|
7
9
|
import { createSettings, resolveConfig } from "../config/index.js";
|
|
8
|
-
import {
|
|
10
|
+
import { createVite } from "../create-vite.js";
|
|
9
11
|
import { collectErrorMetadata } from "../errors/dev/utils.js";
|
|
10
12
|
import { isAstroConfigZodError } from "../errors/errors.js";
|
|
11
13
|
import { createSafeError } from "../errors/index.js";
|
|
14
|
+
import { createNodeLogger } from "../logger/node.js";
|
|
12
15
|
import { formatErrorMessage, warnIfCspWithShiki } from "../messages/runtime.js";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
const { logger, fs, inlineConfig } = container;
|
|
16
|
-
const newContainer = await createContainer({
|
|
17
|
-
isRestart: true,
|
|
18
|
-
logger,
|
|
19
|
-
settings,
|
|
20
|
-
inlineConfig,
|
|
21
|
-
fs
|
|
22
|
-
});
|
|
23
|
-
await startContainer(newContainer);
|
|
24
|
-
return newContainer;
|
|
25
|
-
}
|
|
16
|
+
import { createRoutesList } from "../routing/create-manifest.js";
|
|
17
|
+
import { createContainer } from "./container.js";
|
|
26
18
|
const configRE = /.*astro.config.(?:mjs|mts|cjs|cts|js|ts)$/;
|
|
27
19
|
function shouldRestartContainer({ settings, inlineConfig, restartInFlight }, changedFile) {
|
|
28
20
|
if (restartInFlight) return false;
|
|
@@ -47,25 +39,41 @@ function shouldRestartContainer({ settings, inlineConfig, restartInFlight }, cha
|
|
|
47
39
|
}
|
|
48
40
|
return shouldRestart;
|
|
49
41
|
}
|
|
50
|
-
async function
|
|
51
|
-
const { logger,
|
|
42
|
+
async function restartContainerInPlace(container) {
|
|
43
|
+
const { logger, settings: existingSettings, inlineConfig, fs } = container;
|
|
52
44
|
container.restartInFlight = true;
|
|
53
45
|
try {
|
|
54
|
-
const { astroConfig } = await resolveConfig(
|
|
55
|
-
if (astroConfig.security.csp) {
|
|
56
|
-
logger.warn(
|
|
57
|
-
"config",
|
|
58
|
-
"Astro's Content Security Policy (CSP) does not work in development mode. To verify your CSP implementation, build the project and run the preview server."
|
|
59
|
-
);
|
|
60
|
-
}
|
|
46
|
+
const { astroConfig } = await resolveConfig(inlineConfig, "dev", fs);
|
|
61
47
|
warnIfCspWithShiki(astroConfig, logger);
|
|
62
|
-
|
|
48
|
+
let settings = await createSettings(
|
|
63
49
|
astroConfig,
|
|
64
|
-
|
|
50
|
+
inlineConfig.logLevel,
|
|
65
51
|
fileURLToPath(existingSettings.config.root)
|
|
66
52
|
);
|
|
67
|
-
await
|
|
68
|
-
|
|
53
|
+
settings = await runHookConfigSetup({ settings, command: "dev", logger, isRestart: true });
|
|
54
|
+
if (!settings.adapter?.adapterFeatures?.buildOutput) {
|
|
55
|
+
settings.buildOutput = getPrerenderDefault(settings.config) ? "static" : "server";
|
|
56
|
+
}
|
|
57
|
+
await runHookConfigDone({ settings, logger, command: "dev" });
|
|
58
|
+
const mode = inlineConfig?.mode ?? "development";
|
|
59
|
+
const {
|
|
60
|
+
server: { host, headers, allowedHosts }
|
|
61
|
+
} = settings.config;
|
|
62
|
+
const rendererClientEntries = settings.renderers.map((r) => r.clientEntrypoint).filter(Boolean);
|
|
63
|
+
const routesList = await createRoutesList({ settings, fsMod: fs }, logger, { dev: true });
|
|
64
|
+
const address = container.viteServer.httpServer?.address();
|
|
65
|
+
const port = address !== null && typeof address === "object" ? address.port : void 0;
|
|
66
|
+
const newViteConfig = await createVite(
|
|
67
|
+
{
|
|
68
|
+
server: { host, headers, allowedHosts, port },
|
|
69
|
+
optimizeDeps: { include: rendererClientEntries }
|
|
70
|
+
},
|
|
71
|
+
{ settings, logger, mode, command: "dev", fs, sync: false, routesList }
|
|
72
|
+
);
|
|
73
|
+
container.viteServer.config = await vite.resolveConfig(newViteConfig, "serve");
|
|
74
|
+
await container.viteServer.restart();
|
|
75
|
+
container.settings = settings;
|
|
76
|
+
return settings;
|
|
69
77
|
} catch (_err) {
|
|
70
78
|
const error = createSafeError(_err);
|
|
71
79
|
if (!isAstroConfigZodError(_err)) {
|
|
@@ -74,16 +82,14 @@ async function restartContainer(container) {
|
|
|
74
82
|
formatErrorMessage(collectErrorMetadata(error), logger.level() === "debug") + "\n"
|
|
75
83
|
);
|
|
76
84
|
}
|
|
77
|
-
container.viteServer.environments
|
|
85
|
+
container.viteServer.environments?.client?.hot?.send({
|
|
78
86
|
type: "error",
|
|
79
|
-
err: {
|
|
80
|
-
message: error.message,
|
|
81
|
-
stack: error.stack || ""
|
|
82
|
-
}
|
|
87
|
+
err: { message: error.message, stack: error.stack || "" }
|
|
83
88
|
});
|
|
84
|
-
container.restartInFlight = false;
|
|
85
89
|
logger.error(null, "Continuing with previous valid configuration\n");
|
|
86
90
|
return error;
|
|
91
|
+
} finally {
|
|
92
|
+
container.restartInFlight = false;
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
async function createContainerWithAutomaticRestart({
|
|
@@ -92,12 +98,6 @@ async function createContainerWithAutomaticRestart({
|
|
|
92
98
|
}) {
|
|
93
99
|
const logger = createNodeLogger(inlineConfig ?? {});
|
|
94
100
|
const { userConfig, astroConfig } = await resolveConfig(inlineConfig ?? {}, "dev", fs);
|
|
95
|
-
if (astroConfig.security.csp) {
|
|
96
|
-
logger.warn(
|
|
97
|
-
"config",
|
|
98
|
-
"Astro's Content Security Policy (CSP) does not work in development mode. To verify your CSP implementation, build the project and run the preview server."
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
101
|
warnIfCspWithShiki(astroConfig, logger);
|
|
102
102
|
telemetry.record(eventCliSession("dev", userConfig));
|
|
103
103
|
const settings = await createSettings(
|
|
@@ -119,7 +119,6 @@ async function createContainerWithAutomaticRestart({
|
|
|
119
119
|
container: initialContainer,
|
|
120
120
|
bindCLIShortcuts() {
|
|
121
121
|
const customShortcuts = [
|
|
122
|
-
// Disable default Vite shortcuts that don't work well with Astro
|
|
123
122
|
{ key: "r", description: "" },
|
|
124
123
|
{ key: "u", description: "" },
|
|
125
124
|
{ key: "c", description: "" }
|
|
@@ -139,42 +138,38 @@ async function createContainerWithAutomaticRestart({
|
|
|
139
138
|
return restartComplete;
|
|
140
139
|
}
|
|
141
140
|
};
|
|
142
|
-
async function handleServerRestart(logMsg = "", server) {
|
|
143
|
-
logger.info(null, (logMsg + " Restarting...").trim());
|
|
144
|
-
const container = restart.container;
|
|
145
|
-
const result = await restartContainer(container);
|
|
146
|
-
if (result instanceof Error) {
|
|
147
|
-
resolveRestart(result);
|
|
148
|
-
} else {
|
|
149
|
-
restart.container = result;
|
|
150
|
-
setupContainer();
|
|
151
|
-
await attachContentServerListeners(restart.container);
|
|
152
|
-
if (server) {
|
|
153
|
-
server.resolvedUrls = result.viteServer.resolvedUrls;
|
|
154
|
-
}
|
|
155
|
-
resolveRestart(null);
|
|
156
|
-
}
|
|
157
|
-
restartComplete = new Promise((resolve) => {
|
|
158
|
-
resolveRestart = resolve;
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
141
|
function handleChangeRestart(logMsg) {
|
|
162
142
|
return async function(changedFile) {
|
|
163
143
|
if (shouldRestartContainer(restart.container, changedFile)) {
|
|
164
|
-
|
|
144
|
+
logger.info(null, (logMsg + " Restarting...").trim());
|
|
145
|
+
const result = await restartContainerInPlace(restart.container);
|
|
146
|
+
if (result instanceof Error) {
|
|
147
|
+
resolveRestart(result);
|
|
148
|
+
} else {
|
|
149
|
+
setupContainer();
|
|
150
|
+
await attachContentServerListeners(restart.container);
|
|
151
|
+
resolveRestart(null);
|
|
152
|
+
}
|
|
153
|
+
restartComplete = new Promise((resolve) => {
|
|
154
|
+
resolveRestart = resolve;
|
|
155
|
+
});
|
|
165
156
|
}
|
|
166
157
|
};
|
|
167
158
|
}
|
|
159
|
+
let changeHandler;
|
|
160
|
+
let unlinkHandler;
|
|
161
|
+
let addHandler;
|
|
168
162
|
function setupContainer() {
|
|
169
163
|
const watcher = restart.container.viteServer.watcher;
|
|
170
|
-
watcher.
|
|
171
|
-
watcher.
|
|
172
|
-
watcher.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
164
|
+
if (changeHandler) watcher.off("change", changeHandler);
|
|
165
|
+
if (unlinkHandler) watcher.off("unlink", unlinkHandler);
|
|
166
|
+
if (addHandler) watcher.off("add", addHandler);
|
|
167
|
+
changeHandler = handleChangeRestart("Configuration file updated.");
|
|
168
|
+
unlinkHandler = handleChangeRestart("Configuration file removed.");
|
|
169
|
+
addHandler = handleChangeRestart("Configuration file added.");
|
|
170
|
+
watcher.on("change", changeHandler);
|
|
171
|
+
watcher.on("unlink", unlinkHandler);
|
|
172
|
+
watcher.on("add", addHandler);
|
|
178
173
|
}
|
|
179
174
|
setupContainer();
|
|
180
175
|
return restart;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ActionAPIContext } from '../actions/runtime/types.js';
|
|
2
2
|
import type { ComponentInstance } from '../types/astro.js';
|
|
3
|
-
import type { MiddlewareHandler, Props } from '../types/public/common.js';
|
|
3
|
+
import type { MiddlewareHandler, Params, Props } from '../types/public/common.js';
|
|
4
4
|
import type { APIContext, AstroGlobal } from '../types/public/context.js';
|
|
5
5
|
import type { RouteData, SSRResult } from '../types/public/internal.js';
|
|
6
6
|
import type { ServerIslandMappings, SSRActions } from './app/types.js';
|
|
@@ -26,7 +26,7 @@ export declare class RenderContext {
|
|
|
26
26
|
status: number;
|
|
27
27
|
clientAddress: string | undefined;
|
|
28
28
|
protected cookies: AstroCookies;
|
|
29
|
-
params:
|
|
29
|
+
params: Params;
|
|
30
30
|
protected url: URL;
|
|
31
31
|
props: Props;
|
|
32
32
|
partial: undefined | boolean;
|
|
@@ -38,6 +38,26 @@ import { AstroSession } from "./session/runtime.js";
|
|
|
38
38
|
import { collapseDuplicateSlashes } from "@astrojs/internal-helpers/path";
|
|
39
39
|
import { validateAndDecodePathname } from "./util/pathname.js";
|
|
40
40
|
class RenderContext {
|
|
41
|
+
pipeline;
|
|
42
|
+
locals;
|
|
43
|
+
middleware;
|
|
44
|
+
actions;
|
|
45
|
+
serverIslands;
|
|
46
|
+
// It must be a DECODED pathname
|
|
47
|
+
pathname;
|
|
48
|
+
request;
|
|
49
|
+
routeData;
|
|
50
|
+
status;
|
|
51
|
+
clientAddress;
|
|
52
|
+
cookies;
|
|
53
|
+
params;
|
|
54
|
+
url;
|
|
55
|
+
props;
|
|
56
|
+
partial;
|
|
57
|
+
shouldInjectCspMetaTags;
|
|
58
|
+
session;
|
|
59
|
+
cache;
|
|
60
|
+
skipMiddleware;
|
|
41
61
|
constructor(pipeline, locals, middleware, actions, serverIslands, 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.shouldInjectCspMetaTags, session = void 0, cache, skipMiddleware = false) {
|
|
42
62
|
this.pipeline = pipeline;
|
|
43
63
|
this.locals = locals;
|