feat(assets): Allow users to set a custom endpoint to use for image optimization (#8467)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
c92e0acd71
commit
ecc65abbf9
6 changed files with 75 additions and 1 deletions
5
.changeset/dirty-seahorses-move.md
Normal file
5
.changeset/dirty-seahorses-move.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Add a new `image.endpoint` setting to allow using a custom endpoint in dev and SSR
|
|
@ -974,6 +974,28 @@ export interface AstroUserConfig {
|
|||
* @name Image Options
|
||||
*/
|
||||
image?: {
|
||||
/**
|
||||
* @docs
|
||||
* @name image.endpoint
|
||||
* @type {string}
|
||||
* @default `undefined`
|
||||
* @version 3.1.0
|
||||
* @description
|
||||
* Set the endpoint to use for image optimization in dev and SSR. Set to `undefined` to use the default endpoint.
|
||||
*
|
||||
* The endpoint will always be injected at `/_image`.
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* image: {
|
||||
* // Example: Use a custom image endpoint
|
||||
* endpoint: './src/image-endpoint.ts',
|
||||
* },
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
endpoint?: string;
|
||||
|
||||
/**
|
||||
* @docs
|
||||
* @name image.service
|
||||
|
|
|
@ -11,10 +11,12 @@ import type {
|
|||
import { matchHostname, matchPattern } from './utils/remotePattern.js';
|
||||
|
||||
export function injectImageEndpoint(settings: AstroSettings) {
|
||||
const endpointEntrypoint = settings.config.image.endpoint ?? 'astro/assets/image-endpoint';
|
||||
|
||||
// TODO: Add a setting to disable the image endpoint
|
||||
settings.injectedRoutes.push({
|
||||
pattern: '/_image',
|
||||
entryPoint: 'astro/assets/image-endpoint',
|
||||
entryPoint: endpointEntrypoint,
|
||||
prerender: false,
|
||||
});
|
||||
|
||||
|
|
|
@ -183,6 +183,7 @@ export const AstroConfigSchema = z.object({
|
|||
.default(ASTRO_CONFIG_DEFAULTS.redirects),
|
||||
image: z
|
||||
.object({
|
||||
endpoint: z.string().optional(),
|
||||
service: z
|
||||
.object({
|
||||
entrypoint: z
|
||||
|
|
|
@ -462,6 +462,47 @@ describe('astro:image', () => {
|
|||
expect($('#local img').attr('data-service-config')).to.equal('bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('custom endpoint', async () => {
|
||||
/** @type {import('./test-utils').DevServer} */
|
||||
let customEndpointDevServer;
|
||||
|
||||
/** @type {import('./test-utils.js').Fixture} */
|
||||
let customEndpointFixture;
|
||||
|
||||
before(async () => {
|
||||
customEndpointFixture = await loadFixture({
|
||||
root: './fixtures/core-image/',
|
||||
image: {
|
||||
endpoint: './src/custom-endpoint.ts',
|
||||
service: testImageService({ foo: 'bar' }),
|
||||
domains: ['avatars.githubusercontent.com'],
|
||||
},
|
||||
});
|
||||
|
||||
customEndpointDevServer = await customEndpointFixture.startDevServer({
|
||||
server: { port: 4324 },
|
||||
});
|
||||
});
|
||||
|
||||
it('custom endpoint works', async () => {
|
||||
const response = await customEndpointFixture.fetch('/');
|
||||
const html = await response.text();
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
const src = $('#local img').attr('src');
|
||||
|
||||
let res = await customEndpointFixture.fetch(src);
|
||||
expect(res.status).to.equal(200);
|
||||
expect(await res.text()).to.equal(
|
||||
"You fool! I'm not a image endpoint at all, I just return this!"
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await customEndpointDevServer.stop();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('proper errors', () => {
|
||||
|
|
3
packages/astro/test/fixtures/core-image/src/custom-endpoint.ts
vendored
Normal file
3
packages/astro/test/fixtures/core-image/src/custom-endpoint.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const GET = async () => {
|
||||
return new Response("You fool! I'm not a image endpoint at all, I just return this!", { status: 200 });
|
||||
};
|
Loading…
Reference in a new issue