astro 4.8.6 → 4.9.0
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/astro-jsx.d.ts +1 -1
- package/dist/@types/astro.d.ts +43 -96
- package/dist/actions/runtime/middleware.d.ts +1 -0
- package/dist/actions/runtime/middleware.js +44 -12
- package/dist/actions/runtime/route.js +1 -2
- package/dist/actions/runtime/utils.d.ts +6 -1
- package/dist/actions/runtime/utils.js +2 -1
- package/dist/actions/runtime/virtual/server.d.ts +4 -2
- package/dist/actions/runtime/virtual/server.js +9 -11
- package/dist/actions/utils.d.ts +2 -0
- package/dist/actions/utils.js +2 -1
- package/dist/container/index.d.ts +162 -0
- package/dist/container/index.js +234 -0
- package/dist/container/pipeline.d.ts +11 -0
- package/dist/container/pipeline.js +96 -0
- package/dist/core/app/node.js +4 -1
- package/dist/core/build/consts.d.ts +1 -0
- package/dist/core/build/consts.js +3 -1
- package/dist/core/build/generate.js +3 -3
- package/dist/core/build/index.js +2 -2
- package/dist/core/build/plugins/plugin-content.d.ts +1 -1
- package/dist/core/build/plugins/plugin-content.js +13 -2
- package/dist/core/build/plugins/plugin-manifest.js +2 -2
- package/dist/core/build/static-build.d.ts +2 -1
- package/dist/core/build/static-build.js +7 -6
- package/dist/core/config/schema.d.ts +92 -120
- package/dist/core/config/schema.js +18 -23
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.d.ts +1 -1
- package/dist/core/render-context.js +6 -3
- package/dist/core/routing/manifest/create.d.ts +4 -1
- package/dist/core/routing/manifest/create.js +10 -8
- package/dist/i18n/utils.d.ts +1 -1
- package/dist/integrations/features-validation.js +1 -1
- package/dist/runtime/client/dev-toolbar/apps/utils/highlight.js +2 -0
- package/dist/runtime/server/jsx.js +1 -0
- package/dist/vite-plugin-astro-server/plugin.d.ts +0 -1
- package/dist/vite-plugin-astro-server/plugin.js +1 -1
- package/package.json +7 -3
- package/templates/actions.mjs +37 -12
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { posix } from "node:path";
|
|
2
|
+
import { validateConfig } from "../core/config/config.js";
|
|
3
|
+
import { ASTRO_CONFIG_DEFAULTS } from "../core/config/schema.js";
|
|
4
|
+
import { Logger } from "../core/logger/core.js";
|
|
5
|
+
import { nodeLogDestination } from "../core/logger/node.js";
|
|
6
|
+
import { removeLeadingForwardSlash } from "../core/path.js";
|
|
7
|
+
import { RenderContext } from "../core/render-context.js";
|
|
8
|
+
import { getParts, getPattern, validateSegment } from "../core/routing/manifest/create.js";
|
|
9
|
+
import { ContainerPipeline } from "./pipeline.js";
|
|
10
|
+
function createManifest(renderers, manifest, middleware) {
|
|
11
|
+
const defaultMiddleware = (_, next) => {
|
|
12
|
+
return next();
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
rewritingEnabled: false,
|
|
16
|
+
trailingSlash: manifest?.trailingSlash ?? ASTRO_CONFIG_DEFAULTS.trailingSlash,
|
|
17
|
+
buildFormat: manifest?.buildFormat ?? ASTRO_CONFIG_DEFAULTS.build.format,
|
|
18
|
+
compressHTML: manifest?.compressHTML ?? ASTRO_CONFIG_DEFAULTS.compressHTML,
|
|
19
|
+
assets: manifest?.assets ?? /* @__PURE__ */ new Set(),
|
|
20
|
+
assetsPrefix: manifest?.assetsPrefix ?? void 0,
|
|
21
|
+
entryModules: manifest?.entryModules ?? {},
|
|
22
|
+
routes: manifest?.routes ?? [],
|
|
23
|
+
adapterName: "",
|
|
24
|
+
clientDirectives: manifest?.clientDirectives ?? /* @__PURE__ */ new Map(),
|
|
25
|
+
renderers: manifest?.renderers ?? renderers,
|
|
26
|
+
base: manifest?.base ?? ASTRO_CONFIG_DEFAULTS.base,
|
|
27
|
+
componentMetadata: manifest?.componentMetadata ?? /* @__PURE__ */ new Map(),
|
|
28
|
+
inlinedScripts: manifest?.inlinedScripts ?? /* @__PURE__ */ new Map(),
|
|
29
|
+
i18n: manifest?.i18n,
|
|
30
|
+
checkOrigin: false,
|
|
31
|
+
middleware: manifest?.middleware ?? middleware ?? defaultMiddleware
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
class experimental_AstroContainer {
|
|
35
|
+
#pipeline;
|
|
36
|
+
/**
|
|
37
|
+
* Internally used to check if the container was created with a manifest.
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
#withManifest = false;
|
|
41
|
+
constructor({
|
|
42
|
+
streaming = false,
|
|
43
|
+
renderers = [],
|
|
44
|
+
manifest,
|
|
45
|
+
resolve
|
|
46
|
+
}) {
|
|
47
|
+
this.#pipeline = ContainerPipeline.create({
|
|
48
|
+
logger: new Logger({
|
|
49
|
+
level: "info",
|
|
50
|
+
dest: nodeLogDestination
|
|
51
|
+
}),
|
|
52
|
+
manifest: createManifest(renderers, manifest),
|
|
53
|
+
streaming,
|
|
54
|
+
serverLike: true,
|
|
55
|
+
renderers,
|
|
56
|
+
resolve: async (specifier) => {
|
|
57
|
+
if (this.#withManifest) {
|
|
58
|
+
return this.#containerResolve(specifier);
|
|
59
|
+
} else if (resolve) {
|
|
60
|
+
return resolve(specifier);
|
|
61
|
+
}
|
|
62
|
+
return specifier;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
async #containerResolve(specifier) {
|
|
67
|
+
const found = this.#pipeline.manifest.entryModules[specifier];
|
|
68
|
+
if (found) {
|
|
69
|
+
return new URL(found, ASTRO_CONFIG_DEFAULTS.build.client).toString();
|
|
70
|
+
}
|
|
71
|
+
return found;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Creates a new instance of a container.
|
|
75
|
+
*
|
|
76
|
+
* @param {AstroContainerOptions=} containerOptions
|
|
77
|
+
*/
|
|
78
|
+
static async create(containerOptions = {}) {
|
|
79
|
+
const { streaming = false, renderers = [] } = containerOptions;
|
|
80
|
+
const loadedRenderers = await Promise.all(
|
|
81
|
+
renderers.map(async (renderer) => {
|
|
82
|
+
const mod = await import(renderer.serverEntrypoint);
|
|
83
|
+
if (typeof mod.default !== "undefined") {
|
|
84
|
+
return {
|
|
85
|
+
...renderer,
|
|
86
|
+
ssr: mod.default
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return void 0;
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
const finalRenderers = loadedRenderers.filter((r) => Boolean(r));
|
|
93
|
+
return new experimental_AstroContainer({ streaming, renderers: finalRenderers });
|
|
94
|
+
}
|
|
95
|
+
// NOTE: we keep this private via TS instead via `#` so it's still available on the surface, so we can play with it.
|
|
96
|
+
// @ematipico: I plan to use it for a possible integration that could help people
|
|
97
|
+
static async createFromManifest(manifest) {
|
|
98
|
+
const config = await validateConfig(ASTRO_CONFIG_DEFAULTS, process.cwd(), "container");
|
|
99
|
+
const container = new experimental_AstroContainer({
|
|
100
|
+
manifest
|
|
101
|
+
});
|
|
102
|
+
container.#withManifest = true;
|
|
103
|
+
return container;
|
|
104
|
+
}
|
|
105
|
+
#insertRoute({
|
|
106
|
+
path,
|
|
107
|
+
componentInstance,
|
|
108
|
+
params = {},
|
|
109
|
+
type = "page"
|
|
110
|
+
}) {
|
|
111
|
+
const pathUrl = new URL(path, "https://example.com");
|
|
112
|
+
const routeData = this.#createRoute(pathUrl, params, type);
|
|
113
|
+
this.#pipeline.manifest.routes.push({
|
|
114
|
+
routeData,
|
|
115
|
+
file: "",
|
|
116
|
+
links: [],
|
|
117
|
+
styles: [],
|
|
118
|
+
scripts: []
|
|
119
|
+
});
|
|
120
|
+
this.#pipeline.insertRoute(routeData, componentInstance);
|
|
121
|
+
return routeData;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* @description
|
|
125
|
+
* It renders a component and returns the result as a string.
|
|
126
|
+
*
|
|
127
|
+
* ## Example
|
|
128
|
+
*
|
|
129
|
+
* ```js
|
|
130
|
+
* import Card from "../src/components/Card.astro";
|
|
131
|
+
*
|
|
132
|
+
* const container = await AstroContainer.create();
|
|
133
|
+
* const result = await container.renderToString(Card);
|
|
134
|
+
*
|
|
135
|
+
* console.log(result); // it's a string
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
*
|
|
139
|
+
* @param {AstroComponentFactory} component The instance of the component.
|
|
140
|
+
* @param {ContainerRenderOptions=} options Possible options to pass when rendering the component.
|
|
141
|
+
*/
|
|
142
|
+
async renderToString(component, options = {}) {
|
|
143
|
+
const response = await this.renderToResponse(component, options);
|
|
144
|
+
return await response.text();
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* @description
|
|
148
|
+
* It renders a component and returns the `Response` as result of the rendering phase.
|
|
149
|
+
*
|
|
150
|
+
* ## Example
|
|
151
|
+
*
|
|
152
|
+
* ```js
|
|
153
|
+
* import Card from "../src/components/Card.astro";
|
|
154
|
+
*
|
|
155
|
+
* const container = await AstroContainer.create();
|
|
156
|
+
* const response = await container.renderToResponse(Card);
|
|
157
|
+
*
|
|
158
|
+
* console.log(response.status); // it's a number
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
161
|
+
*
|
|
162
|
+
* @param {AstroComponentFactory} component The instance of the component.
|
|
163
|
+
* @param {ContainerRenderOptions=} options Possible options to pass when rendering the component.
|
|
164
|
+
*/
|
|
165
|
+
async renderToResponse(component, options = {}) {
|
|
166
|
+
const { routeType = "page", slots } = options;
|
|
167
|
+
const request = options?.request ?? new Request("https://example.com/");
|
|
168
|
+
const url = new URL(request.url);
|
|
169
|
+
const componentInstance = routeType === "endpoint" ? component : this.#wrapComponent(component, options.params);
|
|
170
|
+
const routeData = this.#insertRoute({
|
|
171
|
+
path: request.url,
|
|
172
|
+
componentInstance,
|
|
173
|
+
params: options.params,
|
|
174
|
+
type: routeType
|
|
175
|
+
});
|
|
176
|
+
const renderContext = RenderContext.create({
|
|
177
|
+
pipeline: this.#pipeline,
|
|
178
|
+
routeData,
|
|
179
|
+
status: 200,
|
|
180
|
+
middleware: this.#pipeline.middleware,
|
|
181
|
+
request,
|
|
182
|
+
pathname: url.pathname,
|
|
183
|
+
locals: options?.locals ?? {}
|
|
184
|
+
});
|
|
185
|
+
if (options.params) {
|
|
186
|
+
renderContext.params = options.params;
|
|
187
|
+
}
|
|
188
|
+
return renderContext.render(componentInstance, slots);
|
|
189
|
+
}
|
|
190
|
+
#createRoute(url, params, type) {
|
|
191
|
+
const segments = removeLeadingForwardSlash(url.pathname).split(posix.sep).filter(Boolean).map((s) => {
|
|
192
|
+
validateSegment(s);
|
|
193
|
+
return getParts(s, url.pathname);
|
|
194
|
+
});
|
|
195
|
+
return {
|
|
196
|
+
route: url.pathname,
|
|
197
|
+
component: "",
|
|
198
|
+
generate(_data) {
|
|
199
|
+
return "";
|
|
200
|
+
},
|
|
201
|
+
params: Object.keys(params),
|
|
202
|
+
pattern: getPattern(
|
|
203
|
+
segments,
|
|
204
|
+
ASTRO_CONFIG_DEFAULTS.base,
|
|
205
|
+
ASTRO_CONFIG_DEFAULTS.trailingSlash
|
|
206
|
+
),
|
|
207
|
+
prerender: false,
|
|
208
|
+
segments,
|
|
209
|
+
type,
|
|
210
|
+
fallbackRoutes: [],
|
|
211
|
+
isIndex: false
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* If the provided component isn't a default export, the function wraps it in an object `{default: Component }` to mimic the default export.
|
|
216
|
+
* @param componentFactory
|
|
217
|
+
* @param params
|
|
218
|
+
* @private
|
|
219
|
+
*/
|
|
220
|
+
#wrapComponent(componentFactory, params) {
|
|
221
|
+
if (params) {
|
|
222
|
+
return {
|
|
223
|
+
default: componentFactory,
|
|
224
|
+
getStaticPaths() {
|
|
225
|
+
return [{ params }];
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
return { default: componentFactory };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
export {
|
|
233
|
+
experimental_AstroContainer
|
|
234
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ComponentInstance, RewritePayload, RouteData, SSRResult } from '../@types/astro.js';
|
|
2
|
+
import { type HeadElements, Pipeline } from '../core/base-pipeline.js';
|
|
3
|
+
export declare class ContainerPipeline extends Pipeline {
|
|
4
|
+
#private;
|
|
5
|
+
static create({ logger, manifest, renderers, resolve, serverLike, streaming, }: Pick<ContainerPipeline, 'logger' | 'manifest' | 'renderers' | 'resolve' | 'serverLike' | 'streaming'>): ContainerPipeline;
|
|
6
|
+
componentMetadata(_routeData: RouteData): Promise<SSRResult['componentMetadata']> | void;
|
|
7
|
+
headElements(routeData: RouteData): Promise<HeadElements> | HeadElements;
|
|
8
|
+
tryRewrite(rewritePayload: RewritePayload): Promise<[RouteData, ComponentInstance]>;
|
|
9
|
+
insertRoute(route: RouteData, componentInstance: ComponentInstance): void;
|
|
10
|
+
getComponentByRoute(_routeData: RouteData): Promise<ComponentInstance>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Pipeline } from "../core/base-pipeline.js";
|
|
2
|
+
import { RouteNotFound } from "../core/errors/errors-data.js";
|
|
3
|
+
import { AstroError } from "../core/errors/index.js";
|
|
4
|
+
import {
|
|
5
|
+
createModuleScriptElement,
|
|
6
|
+
createStylesheetElementSet
|
|
7
|
+
} from "../core/render/ssr-element.js";
|
|
8
|
+
class ContainerPipeline extends Pipeline {
|
|
9
|
+
/**
|
|
10
|
+
* Internal cache to store components instances by `RouteData`.
|
|
11
|
+
* @private
|
|
12
|
+
*/
|
|
13
|
+
#componentsInterner = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
static create({
|
|
15
|
+
logger,
|
|
16
|
+
manifest,
|
|
17
|
+
renderers,
|
|
18
|
+
resolve,
|
|
19
|
+
serverLike,
|
|
20
|
+
streaming
|
|
21
|
+
}) {
|
|
22
|
+
return new ContainerPipeline(
|
|
23
|
+
logger,
|
|
24
|
+
manifest,
|
|
25
|
+
"development",
|
|
26
|
+
renderers,
|
|
27
|
+
resolve,
|
|
28
|
+
serverLike,
|
|
29
|
+
streaming
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
componentMetadata(_routeData) {
|
|
33
|
+
}
|
|
34
|
+
headElements(routeData) {
|
|
35
|
+
const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData);
|
|
36
|
+
const links = /* @__PURE__ */ new Set();
|
|
37
|
+
const scripts = /* @__PURE__ */ new Set();
|
|
38
|
+
const styles = createStylesheetElementSet(routeInfo?.styles ?? []);
|
|
39
|
+
for (const script of routeInfo?.scripts ?? []) {
|
|
40
|
+
if ("stage" in script) {
|
|
41
|
+
if (script.stage === "head-inline") {
|
|
42
|
+
scripts.add({
|
|
43
|
+
props: {},
|
|
44
|
+
children: script.children
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
scripts.add(createModuleScriptElement(script));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { links, styles, scripts };
|
|
52
|
+
}
|
|
53
|
+
async tryRewrite(rewritePayload) {
|
|
54
|
+
let foundRoute;
|
|
55
|
+
for (const route of this.manifest.routes) {
|
|
56
|
+
const routeData = route.routeData;
|
|
57
|
+
if (rewritePayload instanceof URL) {
|
|
58
|
+
if (routeData.pattern.test(rewritePayload.pathname)) {
|
|
59
|
+
foundRoute = routeData;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
} else if (rewritePayload instanceof Request) {
|
|
63
|
+
const url = new URL(rewritePayload.url);
|
|
64
|
+
if (routeData.pattern.test(url.pathname)) {
|
|
65
|
+
foundRoute = routeData;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
} else if (routeData.pattern.test(decodeURI(rewritePayload))) {
|
|
69
|
+
foundRoute = routeData;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (foundRoute) {
|
|
74
|
+
const componentInstance = await this.getComponentByRoute(foundRoute);
|
|
75
|
+
return [foundRoute, componentInstance];
|
|
76
|
+
} else {
|
|
77
|
+
throw new AstroError(RouteNotFound);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
insertRoute(route, componentInstance) {
|
|
81
|
+
this.#componentsInterner.set(route, {
|
|
82
|
+
page() {
|
|
83
|
+
return Promise.resolve(componentInstance);
|
|
84
|
+
},
|
|
85
|
+
renderers: this.manifest.renderers,
|
|
86
|
+
onRequest: this.manifest.middleware
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// At the moment it's not used by the container via any public API
|
|
90
|
+
// @ts-expect-error It needs to be implemented.
|
|
91
|
+
async getComponentByRoute(_routeData) {
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
ContainerPipeline
|
|
96
|
+
};
|
package/dist/core/app/node.js
CHANGED
|
@@ -48,7 +48,10 @@ class NodeApp extends App {
|
|
|
48
48
|
Object.assign(options, makeRequestBody(req));
|
|
49
49
|
}
|
|
50
50
|
const request = new Request(url, options);
|
|
51
|
-
|
|
51
|
+
const clientIp = req.headers["x-forwarded-for"];
|
|
52
|
+
if (clientIp) {
|
|
53
|
+
Reflect.set(request, clientAddressSymbol, clientIp);
|
|
54
|
+
} else if (req.socket?.remoteAddress) {
|
|
52
55
|
Reflect.set(request, clientAddressSymbol, req.socket.remoteAddress);
|
|
53
56
|
}
|
|
54
57
|
return request;
|
|
@@ -91,7 +91,7 @@ ${bgGreen(black(` ${verb} static routes `))}`);
|
|
|
91
91
|
if (ssr) {
|
|
92
92
|
for (const [pageData, filePath] of pagesToGenerate) {
|
|
93
93
|
if (pageData.route.prerender) {
|
|
94
|
-
if (config.
|
|
94
|
+
if (config.i18n?.domains && Object.keys(config.i18n.domains).length > 0) {
|
|
95
95
|
throw new AstroError({
|
|
96
96
|
...NoPrerenderedRoutesWithDomains,
|
|
97
97
|
message: NoPrerenderedRoutesWithDomains.message(pageData.component)
|
|
@@ -210,7 +210,7 @@ async function getPathsForRoute(route, mod, pipeline, builtPaths) {
|
|
|
210
210
|
const label = staticPaths.length === 1 ? "page" : "pages";
|
|
211
211
|
logger.debug(
|
|
212
212
|
"build",
|
|
213
|
-
`\u251C\u2500\u2500 ${bold(green("\
|
|
213
|
+
`\u251C\u2500\u2500 ${bold(green("\u221A"))} ${route.component} \u2192 ${magenta(`[${staticPaths.length} ${label}]`)}`
|
|
214
214
|
);
|
|
215
215
|
paths = staticPaths.map((staticPath) => {
|
|
216
216
|
try {
|
|
@@ -388,7 +388,7 @@ function createBuildManifest(settings, internals, renderers, middleware) {
|
|
|
388
388
|
buildFormat: settings.config.build.format,
|
|
389
389
|
middleware,
|
|
390
390
|
rewritingEnabled: settings.config.experimental.rewriting,
|
|
391
|
-
checkOrigin: settings.config.
|
|
391
|
+
checkOrigin: settings.config.security?.checkOrigin ?? false
|
|
392
392
|
};
|
|
393
393
|
}
|
|
394
394
|
export {
|
package/dist/core/build/index.js
CHANGED
|
@@ -129,8 +129,8 @@ class AstroBuilder {
|
|
|
129
129
|
teardownCompiler: this.teardownCompiler,
|
|
130
130
|
viteConfig
|
|
131
131
|
};
|
|
132
|
-
const { internals, ssrOutputChunkNames } = await viteBuild(opts);
|
|
133
|
-
await staticBuild(opts, internals, ssrOutputChunkNames);
|
|
132
|
+
const { internals, ssrOutputChunkNames, contentFileNames } = await viteBuild(opts);
|
|
133
|
+
await staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames);
|
|
134
134
|
this.timer.assetsStart = performance.now();
|
|
135
135
|
Object.keys(assets).map((k) => {
|
|
136
136
|
if (!assets[k]) return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type BuildInternals } from '../internal.js';
|
|
2
2
|
import type { AstroBuildPlugin } from '../plugin.js';
|
|
3
3
|
import type { StaticBuildOptions } from '../types.js';
|
|
4
|
-
export declare function copyContentToCache(opts: StaticBuildOptions): Promise<
|
|
4
|
+
export declare function copyContentToCache(opts: StaticBuildOptions): Promise<string[]>;
|
|
5
5
|
export declare function pluginContent(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import fsMod from "node:fs";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import glob from "fast-glob";
|
|
4
5
|
import pLimit from "p-limit";
|
|
5
6
|
import { normalizePath } from "vite";
|
|
6
7
|
import { CONTENT_RENDER_FLAG, PROPAGATED_ASSET_FLAG } from "../../../content/consts.js";
|
|
@@ -19,12 +20,12 @@ import {
|
|
|
19
20
|
} from "../../path.js";
|
|
20
21
|
import { isContentCollectionsCacheEnabled } from "../../util.js";
|
|
21
22
|
import { addRollupInput } from "../add-rollup-input.js";
|
|
22
|
-
import { CHUNKS_PATH } from "../consts.js";
|
|
23
|
+
import { CHUNKS_PATH, CONTENT_PATH } from "../consts.js";
|
|
23
24
|
import {} from "../internal.js";
|
|
24
25
|
import { copyFiles } from "../static-build.js";
|
|
25
26
|
import { encodeName } from "../util.js";
|
|
26
27
|
import { extendManualChunks } from "./util.js";
|
|
27
|
-
const CONTENT_CACHE_DIR = "./
|
|
28
|
+
const CONTENT_CACHE_DIR = "./" + CONTENT_PATH;
|
|
28
29
|
const CONTENT_MANIFEST_FILE = "./manifest.json";
|
|
29
30
|
const CONTENT_MANIFEST_VERSION = 1;
|
|
30
31
|
const virtualEmptyModuleId = `virtual:empty-content`;
|
|
@@ -340,7 +341,17 @@ async function copyContentToCache(opts) {
|
|
|
340
341
|
await fsMod.promises.mkdir(cacheTmp, { recursive: true });
|
|
341
342
|
await copyFiles(distContentRoot, cacheTmp, true);
|
|
342
343
|
await copyFiles(cacheTmp, contentCacheDir);
|
|
344
|
+
let files = [];
|
|
345
|
+
await Promise.all([
|
|
346
|
+
glob(`**/*.{mjs,json}`, {
|
|
347
|
+
cwd: fileURLToPath(cacheTmp)
|
|
348
|
+
}).then((f) => files.push(...f.map((file) => CONTENT_PATH + file))),
|
|
349
|
+
glob(`**/*.{mjs,json}`, {
|
|
350
|
+
cwd: fileURLToPath(new URL("./" + CHUNKS_PATH, config.outDir))
|
|
351
|
+
}).then((f) => files.push(...f.map((file) => CHUNKS_PATH + file)))
|
|
352
|
+
]);
|
|
343
353
|
await fsMod.promises.rm(cacheTmp, { recursive: true, force: true });
|
|
354
|
+
return files;
|
|
344
355
|
}
|
|
345
356
|
function pluginContent(opts, internals) {
|
|
346
357
|
const { cacheDir, outDir } = opts.settings.config;
|
|
@@ -178,7 +178,7 @@ function buildManifest(opts, internals, staticFiles) {
|
|
|
178
178
|
});
|
|
179
179
|
}
|
|
180
180
|
const i18n = settings.config.i18n;
|
|
181
|
-
if (
|
|
181
|
+
if (i18n && i18n.domains) {
|
|
182
182
|
for (const [locale, domainValue] of Object.entries(i18n.domains)) {
|
|
183
183
|
domainLookupTable[domainValue] = normalizeTheLocale(locale);
|
|
184
184
|
}
|
|
@@ -212,7 +212,7 @@ function buildManifest(opts, internals, staticFiles) {
|
|
|
212
212
|
assets: staticFiles.map(prefixAssetPath),
|
|
213
213
|
i18n: i18nManifest,
|
|
214
214
|
buildFormat: settings.config.build.format,
|
|
215
|
-
checkOrigin: settings.config.
|
|
215
|
+
checkOrigin: settings.config.security?.checkOrigin ?? false,
|
|
216
216
|
rewritingEnabled: settings.config.experimental.rewriting
|
|
217
217
|
};
|
|
218
218
|
}
|
|
@@ -4,8 +4,9 @@ import type { StaticBuildOptions } from './types.js';
|
|
|
4
4
|
export declare function viteBuild(opts: StaticBuildOptions): Promise<{
|
|
5
5
|
internals: BuildInternals;
|
|
6
6
|
ssrOutputChunkNames: string[];
|
|
7
|
+
contentFileNames: string[] | undefined;
|
|
7
8
|
}>;
|
|
8
|
-
export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals, ssrOutputChunkNames: string[]): Promise<void>;
|
|
9
|
+
export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals, ssrOutputChunkNames: string[], contentFileNames?: string[]): Promise<void>;
|
|
9
10
|
export declare function copyFiles(fromFolder: URL, toFolder: URL, includeDotfiles?: boolean): Promise<void[] | undefined>;
|
|
10
11
|
/**
|
|
11
12
|
* This function takes the virtual module name of any page entrypoint and
|
|
@@ -75,8 +75,9 @@ async function viteBuild(opts) {
|
|
|
75
75
|
const ssrOutputs = viteBuildReturnToRollupOutputs(ssrOutput);
|
|
76
76
|
const clientOutputs = viteBuildReturnToRollupOutputs(clientOutput ?? []);
|
|
77
77
|
await runPostBuildHooks(container, ssrOutputs, clientOutputs);
|
|
78
|
+
let contentFileNames = void 0;
|
|
78
79
|
if (opts.settings.config.experimental.contentCollectionCache) {
|
|
79
|
-
await copyContentToCache(opts);
|
|
80
|
+
contentFileNames = await copyContentToCache(opts);
|
|
80
81
|
}
|
|
81
82
|
settings.timer.end("Client build");
|
|
82
83
|
internals.ssrEntryChunk = void 0;
|
|
@@ -91,15 +92,15 @@ async function viteBuild(opts) {
|
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
|
-
return { internals, ssrOutputChunkNames };
|
|
95
|
+
return { internals, ssrOutputChunkNames, contentFileNames };
|
|
95
96
|
}
|
|
96
|
-
async function staticBuild(opts, internals, ssrOutputChunkNames) {
|
|
97
|
+
async function staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames) {
|
|
97
98
|
const { settings } = opts;
|
|
98
99
|
switch (true) {
|
|
99
100
|
case settings.config.output === "static": {
|
|
100
101
|
settings.timer.start("Static generate");
|
|
101
102
|
await generatePages(opts, internals);
|
|
102
|
-
await cleanServerOutput(opts, ssrOutputChunkNames, internals);
|
|
103
|
+
await cleanServerOutput(opts, ssrOutputChunkNames, contentFileNames, internals);
|
|
103
104
|
settings.timer.end("Static generate");
|
|
104
105
|
return;
|
|
105
106
|
}
|
|
@@ -325,9 +326,9 @@ export const ${e.n} = noop;`;
|
|
|
325
326
|
removeEmptyDirs(out);
|
|
326
327
|
}
|
|
327
328
|
}
|
|
328
|
-
async function cleanServerOutput(opts, ssrOutputChunkNames, internals) {
|
|
329
|
+
async function cleanServerOutput(opts, ssrOutputChunkNames, contentFileNames, internals) {
|
|
329
330
|
const out = getOutDirWithinCwd(opts.settings.config.outDir);
|
|
330
|
-
const files = ssrOutputChunkNames.filter((f) => f.endsWith(".mjs"));
|
|
331
|
+
const files = ssrOutputChunkNames.filter((f) => f.endsWith(".mjs")).concat(contentFileNames ?? []);
|
|
331
332
|
if (internals.manifestFileName) {
|
|
332
333
|
files.push(internals.manifestFileName);
|
|
333
334
|
}
|