Skip to content

Commit b063a2d

Browse files
authored
fix(assets): Fix endpoint not being injected when an integration would enable experimental.assets (#7829)
1 parent 05ee09f commit b063a2d

12 files changed

Lines changed: 48 additions & 24 deletions

File tree

.changeset/neat-balloons-doubt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Fix `astro:assets` endpoint not working in dev and SSR if `experimental.assets` was enabled by an integration (such as Starlight)

packages/astro/src/assets/internal.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1+
import type { AstroSettings } from '../@types/astro.js';
12
import { AstroError, AstroErrorData } from '../core/errors/index.js';
23
import { isLocalService, type ImageService } from './services/service.js';
34
import type { GetImageResult, ImageMetadata, ImageTransform } from './types.js';
45

6+
export function injectImageEndpoint(settings: AstroSettings) {
7+
settings.injectedRoutes.push({
8+
pattern: '/_image',
9+
entryPoint: 'astro/assets/image-endpoint',
10+
prerender: false,
11+
});
12+
13+
return settings;
14+
}
15+
516
export function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata {
617
return typeof src === 'object';
718
}

packages/astro/src/cli/load-settings.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ export async function loadSettings({ cmd, flags, logging }: LoadSettingsOptions)
2727
return {} as any;
2828
});
2929

30-
const mode = cmd === 'build' ? 'build' : 'dev';
3130
if (!initialAstroConfig) return;
3231
telemetry.record(event.eventCliSession(cmd, initialUserConfig, flags));
33-
return createSettings(initialAstroConfig, mode, root);
32+
return createSettings(initialAstroConfig, root);
3433
}
3534

3635
export async function handleConfigError(

packages/astro/src/config/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function getViteConfig(inlineConfig: UserConfig) {
3535
level: 'info',
3636
};
3737
const { astroConfig: config } = await openConfig({ cmd });
38-
const settings = createSettings(config, cmd, inlineConfig.root);
38+
const settings = createSettings(config, inlineConfig.root);
3939
await runHookConfigSetup({ settings, command: cmd, logging });
4040
const viteConfig = await createVite(
4141
{

packages/astro/src/core/build/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import { performance } from 'node:perf_hooks';
44
import type * as vite from 'vite';
55
import type yargs from 'yargs-parser';
66
import type { AstroConfig, AstroSettings, ManifestData, RuntimeMode } from '../../@types/astro';
7+
import { injectImageEndpoint } from '../../assets/internal.js';
78
import {
89
runHookBuildDone,
910
runHookBuildStart,
1011
runHookConfigDone,
1112
runHookConfigSetup,
1213
} from '../../integrations/index.js';
14+
import { isServerLikeOutput } from '../../prerender/utils.js';
1315
import { createVite } from '../create-vite.js';
1416
import { debug, info, levels, timerMessage, warn, type LogOptions } from '../logger/core.js';
1517
import { printHelp } from '../messages.js';
@@ -89,6 +91,13 @@ class AstroBuilder {
8991
command: 'build',
9092
logging,
9193
});
94+
95+
// HACK: Since we only inject the endpoint if `experimental.assets` is on and it's possible for an integration to
96+
// add that flag, we need to only check and inject the endpoint after running the config setup hook.
97+
if (this.settings.config.experimental.assets && isServerLikeOutput(this.settings.config)) {
98+
this.settings = injectImageEndpoint(this.settings);
99+
}
100+
92101
this.manifest = createRouteManifest({ settings: this.settings }, this.logging);
93102

94103
const viteConfig = await createVite(

packages/astro/src/core/config/settings.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
44
import type { AstroConfig, AstroSettings, AstroUserConfig } from '../../@types/astro';
55
import { getContentPaths } from '../../content/index.js';
66
import jsxRenderer from '../../jsx/renderer.js';
7-
import { isServerLikeOutput } from '../../prerender/utils.js';
87
import { markdownContentEntryType } from '../../vite-plugin-markdown/content-entry-type.js';
98
import { getDefaultClientDirectives } from '../client-directive/index.js';
109
import { AstroError, AstroErrorData } from '../errors/index.js';
@@ -14,18 +13,15 @@ import { createDefaultDevConfig } from './config.js';
1413
import { AstroTimer } from './timer.js';
1514
import { loadTSConfig } from './tsconfig.js';
1615

17-
export function createBaseSettings(config: AstroConfig, mode: 'build' | 'dev'): AstroSettings {
16+
export function createBaseSettings(config: AstroConfig): AstroSettings {
1817
const { contentDir } = getContentPaths(config);
1918
return {
2019
config,
2120
tsConfig: undefined,
2221
tsConfigPath: undefined,
2322

2423
adapter: undefined,
25-
injectedRoutes:
26-
config.experimental.assets && (isServerLikeOutput(config) || mode === 'dev')
27-
? [{ pattern: '/_image', entryPoint: 'astro/assets/image-endpoint', prerender: false }]
28-
: [],
24+
injectedRoutes: [],
2925
pageExtensions: ['.astro', '.html', ...SUPPORTED_MARKDOWN_FILE_EXTENSIONS],
3026
contentEntryTypes: [markdownContentEntryType],
3127
dataEntryTypes: [
@@ -108,13 +104,9 @@ export function createBaseSettings(config: AstroConfig, mode: 'build' | 'dev'):
108104
};
109105
}
110106

111-
export function createSettings(
112-
config: AstroConfig,
113-
mode: 'build' | 'dev',
114-
cwd?: string
115-
): AstroSettings {
107+
export function createSettings(config: AstroConfig, cwd?: string): AstroSettings {
116108
const tsconfig = loadTSConfig(cwd);
117-
const settings = createBaseSettings(config, mode);
109+
const settings = createBaseSettings(config);
118110

119111
const watchFiles = tsconfig?.exists ? [tsconfig.path, ...tsconfig.extendedPaths] : [];
120112

@@ -136,5 +128,5 @@ export async function createDefaultDevSettings(
136128
root = fileURLToPath(root);
137129
}
138130
const config = await createDefaultDevConfig(userConfig, root);
139-
return createBaseSettings(config, 'dev');
131+
return createBaseSettings(config);
140132
}

packages/astro/src/core/dev/container.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { AstroSettings, AstroUserConfig } from '../../@types/astro';
44

55
import nodeFs from 'node:fs';
66
import * as vite from 'vite';
7+
import { injectImageEndpoint } from '../../assets/internal.js';
78
import {
89
runHookConfigDone,
910
runHookConfigSetup,
@@ -64,6 +65,13 @@ export async function createContainer(params: CreateContainerParams = {}): Promi
6465
logging,
6566
isRestart,
6667
});
68+
69+
// HACK: Since we only inject the endpoint if `experimental.assets` is on and it's possible for an integration to
70+
// add that flag, we need to only check and inject the endpoint after running the config setup hook.
71+
if (settings.config.experimental.assets) {
72+
settings = injectImageEndpoint(settings);
73+
}
74+
6775
const { host, headers, open } = settings.config.server;
6876

6977
// The client entrypoint for renderers. Since these are imported dynamically

packages/astro/src/core/dev/restart.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export async function restartContainer({
9292
});
9393
info(logging, 'astro', logMsg + '\n');
9494
let astroConfig = newConfig.astroConfig;
95-
const settings = createSettings(astroConfig, 'dev', resolvedRoot);
95+
const settings = createSettings(astroConfig, resolvedRoot);
9696
await close();
9797
return {
9898
container: await createRestartedContainer(container, settings, needsStart),

packages/astro/test/test-utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ export async function loadFixture(inlineConfig) {
138138
* the `AstroSettings`. This function helps to create a fresh settings object that is used by the
139139
* command functions below to prevent tests from polluting each other.
140140
*/
141-
const getSettings = async (mode) => {
142-
let settings = createSettings(config, mode, fileURLToPath(cwd));
141+
const getSettings = async () => {
142+
let settings = createSettings(config, fileURLToPath(cwd));
143143
if (config.integrations.find((integration) => integration.name === '@astrojs/mdx')) {
144144
// Enable default JSX integration. It needs to come first, so unshift rather than push!
145145
const { default: jsxRenderer } = await import('astro/jsx/renderer.js');

packages/astro/test/units/config/format.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe('Astro config formats', () => {
2727
logging: defaultLogging,
2828
fsMod: fs,
2929
});
30-
const settings = createSettings(astroConfig, 'dev');
30+
const settings = createSettings(astroConfig);
3131

3232
await runInContainer({ fs, root, settings }, () => {
3333
expect(true).to.equal(

0 commit comments

Comments
 (0)