astro 5.0.2 → 5.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/components/Image.astro +2 -2
  2. package/components/Picture.astro +2 -2
  3. package/dist/assets/utils/resolveImports.js +1 -1
  4. package/dist/cli/info/index.d.ts +2 -0
  5. package/dist/cli/info/index.js +71 -26
  6. package/dist/container/index.js +2 -2
  7. package/dist/content/content-layer.js +3 -3
  8. package/dist/content/vite-plugin-content-assets.js +1 -1
  9. package/dist/content/vite-plugin-content-virtual-mod.js +2 -4
  10. package/dist/core/app/index.d.ts +1 -0
  11. package/dist/core/app/index.js +23 -17
  12. package/dist/core/app/types.d.ts +0 -1
  13. package/dist/core/base-pipeline.js +0 -3
  14. package/dist/core/build/generate.js +5 -4
  15. package/dist/core/build/index.js +2 -2
  16. package/dist/core/build/plugins/plugin-manifest.js +1 -2
  17. package/dist/core/build/plugins/plugin-renderers.js +1 -1
  18. package/dist/core/build/plugins/plugin-ssr.js +1 -1
  19. package/dist/core/build/static-build.d.ts +2 -1
  20. package/dist/core/build/static-build.js +13 -15
  21. package/dist/core/config/schema.d.ts +18 -20
  22. package/dist/core/config/schema.js +14 -8
  23. package/dist/core/config/validate.js +2 -1
  24. package/dist/core/constants.js +1 -1
  25. package/dist/core/create-vite.js +4 -2
  26. package/dist/core/dev/container.js +2 -1
  27. package/dist/core/dev/dev.js +2 -2
  28. package/dist/core/errors/errors-data.d.ts +16 -16
  29. package/dist/core/errors/errors-data.js +8 -8
  30. package/dist/core/errors/zod-error-map.js +46 -26
  31. package/dist/core/messages.js +6 -4
  32. package/dist/core/middleware/index.d.ts +5 -1
  33. package/dist/core/middleware/index.js +6 -6
  34. package/dist/core/render-context.d.ts +3 -2
  35. package/dist/core/render-context.js +14 -8
  36. package/dist/core/request.d.ts +2 -1
  37. package/dist/core/request.js +3 -9
  38. package/dist/core/sync/index.d.ts +1 -0
  39. package/dist/core/sync/index.js +3 -0
  40. package/dist/env/env-loader.d.ts +6 -0
  41. package/dist/env/env-loader.js +45 -0
  42. package/dist/env/runtime.d.ts +2 -2
  43. package/dist/env/runtime.js +2 -2
  44. package/dist/env/vite-plugin-env.d.ts +4 -2
  45. package/dist/env/vite-plugin-env.js +19 -10
  46. package/dist/i18n/index.js +2 -2
  47. package/dist/runtime/server/render/component.js +0 -6
  48. package/dist/types/public/config.d.ts +3 -3
  49. package/dist/vite-plugin-astro-server/plugin.js +0 -1
  50. package/dist/vite-plugin-astro-server/route.js +7 -5
  51. package/dist/vite-plugin-env/index.d.ts +3 -3
  52. package/dist/vite-plugin-env/index.js +2 -36
  53. package/package.json +2 -2
  54. package/templates/env.mjs +11 -5
@@ -47,7 +47,7 @@ if (import.meta.env.DEV) {
47
47
  additionalAttributes['data-image-component'] = 'true';
48
48
  }
49
49
 
50
- const attributes = useResponsive
50
+ const { class: className, ...attributes } = useResponsive
51
51
  ? applyResponsiveAttributes({
52
52
  layout,
53
53
  image,
@@ -58,4 +58,4 @@ const attributes = useResponsive
58
58
  ---
59
59
 
60
60
  {/* Applying class outside of the spread prevents it from applying unnecessary astro-* classes */}
61
- <img src={image.src} {...attributes} class={attributes.class} />
61
+ <img src={image.src} {...attributes} class={className} />
@@ -102,7 +102,7 @@ if (fallbackImage.srcSet.values.length > 0) {
102
102
  imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute;
103
103
  }
104
104
 
105
- const attributes = useResponsive
105
+ const { class: className, ...attributes } = useResponsive
106
106
  ? applyResponsiveAttributes({
107
107
  layout,
108
108
  image: fallbackImage,
@@ -133,5 +133,5 @@ if (import.meta.env.DEV) {
133
133
  })
134
134
  }
135
135
  {/* Applying class outside of the spread prevents it from applying unnecessary astro-* classes */}
136
- <img src={fallbackImage.src} {...attributes} class={attributes.class} />
136
+ <img src={fallbackImage.src} {...attributes} class={className} />
137
137
  </picture>
@@ -7,7 +7,7 @@ function imageSrcToImportId(imageSrc, filePath) {
7
7
  if (isRemotePath(imageSrc)) {
8
8
  return;
9
9
  }
10
- const ext = imageSrc.split(".").at(-1);
10
+ const ext = imageSrc.split(".").at(-1)?.toLowerCase();
11
11
  if (!ext || !VALID_INPUT_FORMATS.includes(ext)) {
12
12
  return;
13
13
  }
@@ -8,4 +8,6 @@ export declare function getInfoOutput({ userConfig, print, }: {
8
8
  print: boolean;
9
9
  }): Promise<string>;
10
10
  export declare function printInfo({ flags }: InfoOptions): Promise<void>;
11
+ export declare function copyToClipboard(text: string, force?: boolean): Promise<void>;
12
+ export declare function readFromClipboard(): string;
11
13
  export {};
@@ -1,4 +1,4 @@
1
- import { execSync } from "node:child_process";
1
+ import { spawnSync } from "node:child_process";
2
2
  import { arch, platform } from "node:os";
3
3
  import * as colors from "kleur/colors";
4
4
  import prompts from "prompts";
@@ -33,48 +33,55 @@ async function printInfo({ flags }) {
33
33
  applyPolyfill();
34
34
  const { userConfig } = await resolveConfig(flagsToAstroInlineConfig(flags), "info");
35
35
  const output = await getInfoOutput({ userConfig, print: true });
36
- await copyToClipboard(output);
36
+ await copyToClipboard(output, flags.copy);
37
37
  }
38
- async function copyToClipboard(text) {
38
+ async function copyToClipboard(text, force) {
39
39
  text = text.trim();
40
40
  const system = platform();
41
41
  let command = "";
42
+ let args = [];
42
43
  if (system === "darwin") {
43
44
  command = "pbcopy";
44
45
  } else if (system === "win32") {
45
46
  command = "clip";
46
47
  } else {
47
48
  const unixCommands = [
48
- ["xclip", "-sel clipboard -l 1"],
49
- ["wl-copy", '"$0"']
49
+ ["xclip", ["-sel", "clipboard", "-l", "1"]],
50
+ ["wl-copy", []]
50
51
  ];
51
- for (const [unixCommand, args] of unixCommands) {
52
+ for (const [unixCommand, unixArgs] of unixCommands) {
52
53
  try {
53
- const output = execSync(`which ${unixCommand}`, { encoding: "utf8", stdio: "pipe" });
54
- if (output[0] !== "/") {
55
- continue;
54
+ const output = spawnSync("which", [unixCommand], { encoding: "utf8" });
55
+ if (output.stdout.trim()) {
56
+ command = unixCommand;
57
+ args = unixArgs;
58
+ break;
56
59
  }
57
- command = `${unixCommand} ${args}`;
58
60
  } catch {
59
61
  continue;
60
62
  }
61
63
  }
62
- if (!command) return;
63
64
  }
64
- console.log();
65
- const { shouldCopy } = await prompts({
66
- type: "confirm",
67
- name: "shouldCopy",
68
- message: "Copy to clipboard?",
69
- initial: true
70
- });
71
- if (!shouldCopy) return;
72
- try {
73
- execSync(command.replaceAll("$0", text), {
74
- stdio: "ignore",
75
- input: text,
76
- encoding: "utf8"
65
+ if (!command) {
66
+ console.error(colors.red("\nClipboard command not found!"));
67
+ console.info("Please manually copy the text above.");
68
+ return;
69
+ }
70
+ if (!force) {
71
+ const { shouldCopy } = await prompts({
72
+ type: "confirm",
73
+ name: "shouldCopy",
74
+ message: "Copy to clipboard?",
75
+ initial: true
77
76
  });
77
+ if (!shouldCopy) return;
78
+ }
79
+ try {
80
+ const result = spawnSync(command, args, { input: text });
81
+ if (result.error) {
82
+ throw result.error;
83
+ }
84
+ console.info(colors.green("Copied to clipboard!"));
78
85
  } catch {
79
86
  console.error(
80
87
  colors.red(`
@@ -82,6 +89,42 @@ Sorry, something went wrong!`) + ` Please copy the text above manually.`
82
89
  );
83
90
  }
84
91
  }
92
+ function readFromClipboard() {
93
+ const system = platform();
94
+ let command = "";
95
+ let args = [];
96
+ if (system === "darwin") {
97
+ command = "pbpaste";
98
+ } else if (system === "win32") {
99
+ command = "powershell";
100
+ args = ["-command", "Get-Clipboard"];
101
+ } else {
102
+ const unixCommands = [
103
+ ["xclip", ["-sel", "clipboard", "-o"]],
104
+ ["wl-paste", []]
105
+ ];
106
+ for (const [unixCommand, unixArgs] of unixCommands) {
107
+ try {
108
+ const output = spawnSync("which", [unixCommand], { encoding: "utf8" });
109
+ if (output.stdout.trim()) {
110
+ command = unixCommand;
111
+ args = unixArgs;
112
+ break;
113
+ }
114
+ } catch {
115
+ continue;
116
+ }
117
+ }
118
+ }
119
+ if (!command) {
120
+ throw new Error("Clipboard read command not found!");
121
+ }
122
+ const result = spawnSync(command, args, { encoding: "utf8" });
123
+ if (result.error) {
124
+ throw result.error;
125
+ }
126
+ return result.stdout.trim();
127
+ }
85
128
  const PLATFORM_TO_OS = {
86
129
  darwin: "macOS",
87
130
  win32: "Windows",
@@ -115,11 +158,13 @@ ${" ".repeat(MAX_PADDING)}${colors.green(entry)}`;
115
158
  }
116
159
  plaintext += "\n";
117
160
  if (print) {
118
- console.log(richtext);
161
+ console.info(richtext);
119
162
  }
120
163
  return plaintext;
121
164
  }
122
165
  export {
166
+ copyToClipboard,
123
167
  getInfoOutput,
124
- printInfo
168
+ printInfo,
169
+ readFromClipboard
125
170
  };
@@ -36,7 +36,6 @@ function createManifest(manifest, renderers, middleware) {
36
36
  i18n: manifest?.i18n,
37
37
  checkOrigin: false,
38
38
  middleware: manifest?.middleware ?? middlewareInstance,
39
- envGetSecretEnabled: false,
40
39
  key: createKey()
41
40
  };
42
41
  }
@@ -267,7 +266,8 @@ class experimental_AstroContainer {
267
266
  request,
268
267
  pathname: url.pathname,
269
268
  locals: options?.locals ?? {},
270
- partial: options?.partial ?? true
269
+ partial: options?.partial ?? true,
270
+ clientAddress: ""
271
271
  });
272
272
  if (options.params) {
273
273
  renderContext.params = options.params;
@@ -114,7 +114,7 @@ class ContentLayer {
114
114
  logger.info("Content config changed");
115
115
  shouldClear = true;
116
116
  }
117
- if (previousAstroVersion !== "5.0.2") {
117
+ if (previousAstroVersion !== "5.0.4") {
118
118
  logger.info("Astro version changed");
119
119
  shouldClear = true;
120
120
  }
@@ -122,8 +122,8 @@ class ContentLayer {
122
122
  logger.info("Clearing content store");
123
123
  this.#store.clearAll();
124
124
  }
125
- if ("5.0.2") {
126
- await this.#store.metaStore().set("astro-version", "5.0.2");
125
+ if ("5.0.4") {
126
+ await this.#store.metaStore().set("astro-version", "5.0.4");
127
127
  }
128
128
  if (currentConfigDigest) {
129
129
  await this.#store.metaStore().set("config-digest", currentConfigDigest);
@@ -26,7 +26,7 @@ function astroContentAssetPropagationPlugin({
26
26
  const params = new URLSearchParams(query);
27
27
  const importerParam = params.get("importer");
28
28
  const importerPath = importerParam ? fileURLToPath(new URL(importerParam, settings.config.root)) : importer;
29
- const resolved = this.resolve(base, importerPath, { skipSelf: true, ...opts });
29
+ const resolved = await this.resolve(base, importerPath, { skipSelf: true, ...opts });
30
30
  if (!resolved) {
31
31
  throw new AstroError({
32
32
  ...AstroErrorData.ImageNotFound,
@@ -40,14 +40,12 @@ function astroContentVirtualModPlugin({
40
40
  settings,
41
41
  fs
42
42
  }) {
43
- let IS_DEV = false;
44
43
  let dataStoreFile;
45
44
  return {
46
45
  name: "astro-content-virtual-mod-plugin",
47
46
  enforce: "pre",
48
- configResolved(config) {
49
- IS_DEV = !config.isProduction;
50
- dataStoreFile = getDataStoreFile(settings, IS_DEV);
47
+ config(_, env) {
48
+ dataStoreFile = getDataStoreFile(settings, env.command === "serve");
51
49
  },
52
50
  async resolveId(id) {
53
51
  if (id === VIRTUAL_MODULE_ID) {
@@ -44,6 +44,7 @@ export interface RenderErrorOptions {
44
44
  * Allows passing an error to 500.astro. It will be available through `Astro.props.error`.
45
45
  */
46
46
  error?: unknown;
47
+ clientAddress: string | undefined;
47
48
  }
48
49
  export declare class App {
49
50
  #private;
@@ -156,7 +156,7 @@ class App {
156
156
  let clientAddress;
157
157
  let addCookieHeader;
158
158
  addCookieHeader = renderOptions?.addCookieHeader;
159
- clientAddress = renderOptions?.clientAddress;
159
+ clientAddress = renderOptions?.clientAddress ?? Reflect.get(request, clientAddressSymbol);
160
160
  routeData = renderOptions?.routeData;
161
161
  locals = renderOptions?.locals;
162
162
  if (routeData) {
@@ -171,12 +171,8 @@ class App {
171
171
  if (typeof locals !== "object") {
172
172
  const error = new AstroError(AstroErrorData.LocalsNotAnObject);
173
173
  this.#logger.error(null, error.stack);
174
- return this.#renderError(request, { status: 500, error });
174
+ return this.#renderError(request, { status: 500, error, clientAddress });
175
175
  }
176
- Reflect.set(request, clientLocalsSymbol, locals);
177
- }
178
- if (clientAddress) {
179
- Reflect.set(request, clientAddressSymbol, clientAddress);
180
176
  }
181
177
  if (!routeData) {
182
178
  routeData = this.match(request);
@@ -186,7 +182,7 @@ class App {
186
182
  if (!routeData) {
187
183
  this.#logger.debug("router", "Astro hasn't found routes that match " + request.url);
188
184
  this.#logger.debug("router", "Here's the available routes:\n", this.#manifestData);
189
- return this.#renderError(request, { locals, status: 404 });
185
+ return this.#renderError(request, { locals, status: 404, clientAddress });
190
186
  }
191
187
  const pathname = this.#getPathnameFromRequest(request);
192
188
  const defaultStatus = this.#getDefaultStatusCode(routeData, pathname);
@@ -199,12 +195,13 @@ class App {
199
195
  pathname,
200
196
  request,
201
197
  routeData,
202
- status: defaultStatus
198
+ status: defaultStatus,
199
+ clientAddress
203
200
  });
204
201
  response = await renderContext.render(await mod.page());
205
202
  } catch (err) {
206
203
  this.#logger.error(null, err.stack || err.message || String(err));
207
- return this.#renderError(request, { locals, status: 500, error: err });
204
+ return this.#renderError(request, { locals, status: 500, error: err, clientAddress });
208
205
  }
209
206
  if (REROUTABLE_STATUS_CODES.includes(response.status) && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
210
207
  return this.#renderError(request, {
@@ -213,7 +210,8 @@ class App {
213
210
  status: response.status,
214
211
  // We don't have an error to report here. Passing null means we pass nothing intentionally
215
212
  // while undefined means there's no error
216
- error: response.status === 500 ? null : void 0
213
+ error: response.status === 500 ? null : void 0,
214
+ clientAddress
217
215
  });
218
216
  }
219
217
  if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) {
@@ -251,7 +249,8 @@ class App {
251
249
  status,
252
250
  response: originalResponse,
253
251
  skipMiddleware = false,
254
- error
252
+ error,
253
+ clientAddress
255
254
  }) {
256
255
  const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? "/" : ""}`;
257
256
  const errorRouteData = matchRoute(errorRoutePath, this.#manifestData);
@@ -279,7 +278,8 @@ class App {
279
278
  request,
280
279
  routeData: errorRouteData,
281
280
  status,
282
- props: { error }
281
+ props: { error },
282
+ clientAddress
283
283
  });
284
284
  const response2 = await renderContext.render(await mod.page());
285
285
  return this.#mergeResponses(response2, originalResponse);
@@ -289,7 +289,8 @@ class App {
289
289
  locals,
290
290
  status,
291
291
  response: originalResponse,
292
- skipMiddleware: true
292
+ skipMiddleware: true,
293
+ clientAddress
293
294
  });
294
295
  }
295
296
  }
@@ -314,6 +315,14 @@ class App {
314
315
  originalResponse.headers.delete("Content-type");
315
316
  } catch {
316
317
  }
318
+ const mergedHeaders = new Map([
319
+ ...Array.from(newResponse.headers),
320
+ ...Array.from(originalResponse.headers)
321
+ ]);
322
+ const newHeaders = new Headers();
323
+ for (const [name, value] of mergedHeaders) {
324
+ newHeaders.set(name, value);
325
+ }
317
326
  return new Response(newResponse.body, {
318
327
  status,
319
328
  statusText: status === 200 ? newResponse.statusText : originalResponse.statusText,
@@ -322,10 +331,7 @@ class App {
322
331
  // If users see something weird, it's because they are setting some headers they should not.
323
332
  //
324
333
  // Although, we don't want it to replace the content-type, because the error page must return `text/html`
325
- headers: new Headers([
326
- ...Array.from(newResponse.headers),
327
- ...Array.from(originalResponse.headers)
328
- ])
334
+ headers: newHeaders
329
335
  });
330
336
  }
331
337
  #getDefaultStatusCode(routeData, pathname) {
@@ -59,7 +59,6 @@ export type SSRManifest = {
59
59
  i18n: SSRManifestI18n | undefined;
60
60
  middleware?: () => Promise<AstroMiddlewareInstance> | AstroMiddlewareInstance;
61
61
  checkOrigin: boolean;
62
- envGetSecretEnabled: boolean;
63
62
  };
64
63
  export type SSRManifestI18n = {
65
64
  fallback: Record<string, string> | undefined;
@@ -1,8 +1,5 @@
1
- import { setGetEnv } from "../env/runtime.js";
2
1
  import { createI18nMiddleware } from "../i18n/middleware.js";
3
2
  import { createOriginCheckMiddleware } from "./app/middlewares.js";
4
- import { AstroError } from "./errors/errors.js";
5
- import { AstroErrorData } from "./errors/index.js";
6
3
  import { NOOP_MIDDLEWARE_FN } from "./middleware/noop-middleware.js";
7
4
  import { sequence } from "./middleware/sequence.js";
8
5
  import { RouteCache } from "./render/route-cache.js";
@@ -295,13 +295,15 @@ async function generatePath(pathname, pipeline, gopts, route) {
295
295
  url,
296
296
  headers: new Headers(),
297
297
  logger,
298
- isPrerendered: true
298
+ isPrerendered: true,
299
+ routePattern: route.component
299
300
  });
300
301
  const renderContext = await RenderContext.create({
301
302
  pipeline,
302
303
  pathname,
303
304
  request,
304
- routeData: route
305
+ routeData: route,
306
+ clientAddress: void 0
305
307
  });
306
308
  let body;
307
309
  let response;
@@ -387,8 +389,7 @@ function createBuildManifest(settings, internals, renderers, middleware, key) {
387
389
  };
388
390
  },
389
391
  checkOrigin: (settings.config.security?.checkOrigin && settings.buildOutput === "server") ?? false,
390
- key,
391
- envGetSecretEnabled: false
392
+ key
392
393
  };
393
394
  }
394
395
  export {
@@ -144,12 +144,12 @@ class AstroBuilder {
144
144
  viteConfig,
145
145
  key: keyPromise
146
146
  };
147
- const { internals, ssrOutputChunkNames, contentFileNames } = await viteBuild(opts);
147
+ const { internals, ssrOutputChunkNames, ssrOutputAssetNames, contentFileNames } = await viteBuild(opts);
148
148
  const hasServerIslands = this.settings.serverIslandNameMap.size > 0;
149
149
  if (hasServerIslands && this.settings.buildOutput !== "server") {
150
150
  throw new AstroError(AstroErrorData.NoAdapterInstalledServerIslands);
151
151
  }
152
- await staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames);
152
+ await staticBuild(opts, internals, ssrOutputChunkNames, ssrOutputAssetNames, contentFileNames);
153
153
  this.timer.assetsStart = performance.now();
154
154
  Object.keys(assets).map((k) => {
155
155
  if (!assets[k]) return;
@@ -208,8 +208,7 @@ function buildManifest(opts, internals, staticFiles, encodedKey) {
208
208
  buildFormat: settings.config.build.format,
209
209
  checkOrigin: (settings.config.security?.checkOrigin && settings.buildOutput === "server") ?? false,
210
210
  serverIslandNameMap: Array.from(settings.serverIslandNameMap),
211
- key: encodedKey,
212
- envGetSecretEnabled: (unwrapSupportKind(settings.adapter?.supportedAstroFeatures.envGetSecret) ?? "unsupported") !== "unsupported"
211
+ key: encodedKey
213
212
  };
214
213
  }
215
214
  export {
@@ -21,7 +21,7 @@ function vitePluginRenderers(opts) {
21
21
  let rendererItems = "";
22
22
  for (const renderer of opts.settings.renderers) {
23
23
  const variable = `_renderer${i}`;
24
- imports.push(`import ${variable} from '${renderer.serverEntrypoint}';`);
24
+ imports.push(`import ${variable} from ${JSON.stringify(renderer.serverEntrypoint)};`);
25
25
  rendererItems += `Object.assign(${JSON.stringify(renderer)}, { ssr: ${variable} }),`;
26
26
  i++;
27
27
  }
@@ -21,7 +21,7 @@ function vitePluginAdapter(adapter) {
21
21
  },
22
22
  async load(id) {
23
23
  if (id === RESOLVED_ADAPTER_VIRTUAL_MODULE_ID) {
24
- return `export * from '${adapter.serverEntrypoint}';`;
24
+ return `export * from ${JSON.stringify(adapter.serverEntrypoint)};`;
25
25
  }
26
26
  }
27
27
  };
@@ -4,9 +4,10 @@ import type { StaticBuildOptions } from './types.js';
4
4
  export declare function viteBuild(opts: StaticBuildOptions): Promise<{
5
5
  internals: BuildInternals;
6
6
  ssrOutputChunkNames: string[];
7
+ ssrOutputAssetNames: string[];
7
8
  contentFileNames: undefined;
8
9
  }>;
9
- export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals, ssrOutputChunkNames: string[], contentFileNames?: string[]): Promise<void>;
10
+ export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals, ssrOutputChunkNames: string[], ssrOutputAssetNames: string[], contentFileNames?: string[]): Promise<void>;
10
11
  export declare function copyFiles(fromFolder: URL, toFolder: URL, includeDotfiles?: boolean): Promise<void[] | undefined>;
11
12
  /**
12
13
  * This function takes the virtual module name of any page entrypoint and
@@ -69,16 +69,20 @@ async function viteBuild(opts) {
69
69
  teardown();
70
70
  }
71
71
  const ssrOutputChunkNames = [];
72
+ const ssrOutputAssetNames = [];
72
73
  for (const output of ssrOutputs) {
73
74
  for (const chunk of output.output) {
74
75
  if (chunk.type === "chunk") {
75
76
  ssrOutputChunkNames.push(chunk.fileName);
76
77
  }
78
+ if (chunk.type === "asset") {
79
+ ssrOutputAssetNames.push(chunk.fileName);
80
+ }
77
81
  }
78
82
  }
79
- return { internals, ssrOutputChunkNames, contentFileNames };
83
+ return { internals, ssrOutputChunkNames, ssrOutputAssetNames, contentFileNames };
80
84
  }
81
- async function staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames) {
85
+ async function staticBuild(opts, internals, ssrOutputChunkNames, ssrOutputAssetNames, contentFileNames) {
82
86
  const { settings } = opts;
83
87
  if (settings.buildOutput === "static") {
84
88
  settings.timer.start("Static generate");
@@ -89,7 +93,7 @@ async function staticBuild(opts, internals, ssrOutputChunkNames, contentFileName
89
93
  settings.timer.start("Server generate");
90
94
  await generatePages(opts, internals);
91
95
  await cleanStaticOutput(opts, internals);
92
- await ssrMoveAssets(opts);
96
+ await ssrMoveAssets(opts, ssrOutputAssetNames);
93
97
  settings.timer.end("Server generate");
94
98
  }
95
99
  }
@@ -305,27 +309,21 @@ async function copyFiles(fromFolder, toFolder, includeDotfiles = false) {
305
309
  })
306
310
  );
307
311
  }
308
- async function ssrMoveAssets(opts) {
312
+ async function ssrMoveAssets(opts, ssrOutputAssetNames) {
309
313
  opts.logger.info("build", "Rearranging server assets...");
310
314
  const serverRoot = opts.settings.buildOutput === "static" ? opts.settings.config.build.client : opts.settings.config.build.server;
311
315
  const clientRoot = opts.settings.config.build.client;
312
- const assets = opts.settings.config.build.assets;
313
- const serverAssets = new URL(`./${assets}/`, appendForwardSlash(serverRoot.toString()));
314
- const clientAssets = new URL(`./${assets}/`, appendForwardSlash(clientRoot.toString()));
315
- const files = await glob(`**/*`, {
316
- cwd: fileURLToPath(serverAssets)
317
- });
318
- if (files.length > 0) {
316
+ if (ssrOutputAssetNames.length > 0) {
319
317
  await Promise.all(
320
- files.map(async function moveAsset(filename) {
321
- const currentUrl = new URL(filename, appendForwardSlash(serverAssets.toString()));
322
- const clientUrl = new URL(filename, appendForwardSlash(clientAssets.toString()));
318
+ ssrOutputAssetNames.map(async function moveAsset(filename) {
319
+ const currentUrl = new URL(filename, appendForwardSlash(serverRoot.toString()));
320
+ const clientUrl = new URL(filename, appendForwardSlash(clientRoot.toString()));
323
321
  const dir = new URL(path.parse(clientUrl.href).dir);
324
322
  if (!fs.existsSync(dir)) await fs.promises.mkdir(dir, { recursive: true });
325
323
  return fs.promises.rename(currentUrl, clientUrl);
326
324
  })
327
325
  );
328
- removeEmptyDirs(fileURLToPath(serverAssets));
326
+ removeEmptyDirs(fileURLToPath(serverRoot));
329
327
  }
330
328
  }
331
329
  function makeAstroPageEntryPointFileName(prefix, facadeModuleId, routes) {