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
|
* @name Image Options
|
||||||
*/
|
*/
|
||||||
image?: {
|
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
|
* @docs
|
||||||
* @name image.service
|
* @name image.service
|
||||||
|
|
|
@ -11,10 +11,12 @@ import type {
|
||||||
import { matchHostname, matchPattern } from './utils/remotePattern.js';
|
import { matchHostname, matchPattern } from './utils/remotePattern.js';
|
||||||
|
|
||||||
export function injectImageEndpoint(settings: AstroSettings) {
|
export function injectImageEndpoint(settings: AstroSettings) {
|
||||||
|
const endpointEntrypoint = settings.config.image.endpoint ?? 'astro/assets/image-endpoint';
|
||||||
|
|
||||||
// TODO: Add a setting to disable the image endpoint
|
// TODO: Add a setting to disable the image endpoint
|
||||||
settings.injectedRoutes.push({
|
settings.injectedRoutes.push({
|
||||||
pattern: '/_image',
|
pattern: '/_image',
|
||||||
entryPoint: 'astro/assets/image-endpoint',
|
entryPoint: endpointEntrypoint,
|
||||||
prerender: false,
|
prerender: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,7 @@ export const AstroConfigSchema = z.object({
|
||||||
.default(ASTRO_CONFIG_DEFAULTS.redirects),
|
.default(ASTRO_CONFIG_DEFAULTS.redirects),
|
||||||
image: z
|
image: z
|
||||||
.object({
|
.object({
|
||||||
|
endpoint: z.string().optional(),
|
||||||
service: z
|
service: z
|
||||||
.object({
|
.object({
|
||||||
entrypoint: z
|
entrypoint: z
|
||||||
|
|
|
@ -462,6 +462,47 @@ describe('astro:image', () => {
|
||||||
expect($('#local img').attr('data-service-config')).to.equal('bar');
|
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', () => {
|
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