diff --git a/.changeset/neat-wolves-kick.md b/.changeset/neat-wolves-kick.md deleted file mode 100644 index 8cd7ce070..000000000 --- a/.changeset/neat-wolves-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Adds support for the new `astrojs/image` integration diff --git a/.changeset/tough-buses-compare.md b/.changeset/tough-buses-compare.md deleted file mode 100644 index 843001daf..000000000 --- a/.changeset/tough-buses-compare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/image': patch ---- - -Initial release! 🎉 diff --git a/examples/basics/package.json b/examples/basics/package.json index 8f29994b1..9586d929b 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/blog-multiple-authors/package.json b/examples/blog-multiple-authors/package.json index ae06dc85b..2d46a1743 100644 --- a/examples/blog-multiple-authors/package.json +++ b/examples/blog-multiple-authors/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/preact": "^0.3.1", - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "sass": "^1.52.2" }, "dependencies": { diff --git a/examples/blog/package.json b/examples/blog/package.json index 14197689a..68837621e 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/preact": "^0.3.1", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "preact": "^10.7.3" diff --git a/examples/component/demo/package.json b/examples/component/demo/package.json index 2002a3ef0..6c935ce70 100644 --- a/examples/component/demo/package.json +++ b/examples/component/demo/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "@example/my-component": "workspace:*", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/component/package.json b/examples/component/package.json index e9128c591..c63522f40 100644 --- a/examples/component/package.json +++ b/examples/component/package.json @@ -8,6 +8,6 @@ "serve": "astro --root demo preview" }, "devDependencies": { - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/docs/package.json b/examples/docs/package.json index b38c36c90..c0fc46cb4 100644 --- a/examples/docs/package.json +++ b/examples/docs/package.json @@ -20,6 +20,6 @@ "devDependencies": { "@astrojs/preact": "^0.3.1", "@astrojs/react": "^0.2.0", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/env-vars/package.json b/examples/env-vars/package.json index a48e49a74..6c26e8d48 100644 --- a/examples/env-vars/package.json +++ b/examples/env-vars/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/framework-alpine/package.json b/examples/framework-alpine/package.json index c91f6961a..dbccf159a 100644 --- a/examples/framework-alpine/package.json +++ b/examples/framework-alpine/package.json @@ -9,7 +9,7 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "alpinejs": "^3.10.2" diff --git a/examples/framework-lit/package.json b/examples/framework-lit/package.json index a4c01c099..e6eb5dbae 100644 --- a/examples/framework-lit/package.json +++ b/examples/framework-lit/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/lit": "^0.3.0", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "@webcomponents/template-shadowroot": "^0.1.0", diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index f09b07159..1004c0cda 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -15,7 +15,7 @@ "@astrojs/solid-js": "^0.2.0", "@astrojs/svelte": "^0.2.0", "@astrojs/vue": "^0.2.0", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "@webcomponents/template-shadowroot": "^0.1.0", diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index b0ac3338c..b9968806c 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/preact": "^0.3.1", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "preact": "^10.7.3" diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index ac0873f60..4105059a4 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -12,7 +12,7 @@ "@astrojs/react": "^0.2.0", "@types/react": "^18.0.10", "@types/react-dom": "^18.0.5", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "react": "^18.1.0", diff --git a/examples/framework-solid/package.json b/examples/framework-solid/package.json index 79e0591af..93318c61d 100644 --- a/examples/framework-solid/package.json +++ b/examples/framework-solid/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/solid-js": "^0.2.0", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "solid-js": "^1.4.3" diff --git a/examples/framework-svelte/package.json b/examples/framework-svelte/package.json index 45bcea2d2..df508fe22 100644 --- a/examples/framework-svelte/package.json +++ b/examples/framework-svelte/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/svelte": "^0.2.0", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "svelte": "^3.48.0" diff --git a/examples/framework-vue/package.json b/examples/framework-vue/package.json index f2ba9bddb..952147434 100644 --- a/examples/framework-vue/package.json +++ b/examples/framework-vue/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/vue": "^0.2.0", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "vue": "^3.2.37" diff --git a/examples/integrations-playground/package.json b/examples/integrations-playground/package.json index a20208a34..e7488ecf0 100644 --- a/examples/integrations-playground/package.json +++ b/examples/integrations-playground/package.json @@ -16,7 +16,7 @@ "@astrojs/solid-js": "0.2.0", "@astrojs/tailwind": "^0.2.2", "@astrojs/turbolinks": "^0.1.3", - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "solid-js": "^1.4.3" }, "dependencies": { diff --git a/examples/minimal/package.json b/examples/minimal/package.json index addbc34b5..5b80a13a5 100644 --- a/examples/minimal/package.json +++ b/examples/minimal/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/non-html-pages/package.json b/examples/non-html-pages/package.json index cd5c422ff..c913965c6 100644 --- a/examples/non-html-pages/package.json +++ b/examples/non-html-pages/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/portfolio/package.json b/examples/portfolio/package.json index 9307deeeb..0a4572315 100644 --- a/examples/portfolio/package.json +++ b/examples/portfolio/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/preact": "^0.3.1", - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "sass": "^1.52.2" }, "dependencies": { diff --git a/examples/ssr/package.json b/examples/ssr/package.json index f526703c0..15de90559 100644 --- a/examples/ssr/package.json +++ b/examples/ssr/package.json @@ -11,7 +11,7 @@ "devDependencies": { "@astrojs/node": "^0.1.3", "@astrojs/svelte": "^0.2.0", - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "concurrently": "^7.2.1", "lightcookie": "^1.0.25", "unocss": "^0.15.6", diff --git a/examples/starter/package.json b/examples/starter/package.json index 48b2568a4..f526b4a1f 100644 --- a/examples/starter/package.json +++ b/examples/starter/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/subpath/package.json b/examples/subpath/package.json index 371a105ca..c0a4bcf0d 100644 --- a/examples/subpath/package.json +++ b/examples/subpath/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/react": "^0.2.0", - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "sass": "^1.52.2" }, "dependencies": { diff --git a/examples/with-markdown-plugins/package.json b/examples/with-markdown-plugins/package.json index ed88fe42e..e828f51b1 100644 --- a/examples/with-markdown-plugins/package.json +++ b/examples/with-markdown-plugins/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/markdown-remark": "^0.11.3", - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "hast-util-select": "5.0.1", "rehype-autolink-headings": "^6.1.1", "rehype-slug": "^5.0.1", diff --git a/examples/with-markdown-shiki/package.json b/examples/with-markdown-shiki/package.json index 2291b1e99..824a4ba66 100644 --- a/examples/with-markdown-shiki/package.json +++ b/examples/with-markdown-shiki/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "@astrojs/markdown-remark": "^0.11.3", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/with-markdown/package.json b/examples/with-markdown/package.json index 7f9d5f659..2fc90664b 100644 --- a/examples/with-markdown/package.json +++ b/examples/with-markdown/package.json @@ -14,7 +14,7 @@ "@astrojs/react": "^0.2.0", "@astrojs/svelte": "^0.2.0", "@astrojs/vue": "^0.2.0", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" }, "dependencies": { "preact": "^10.7.3", diff --git a/examples/with-mdx/package.json b/examples/with-mdx/package.json index cd0903ee0..84ad2b3e2 100644 --- a/examples/with-mdx/package.json +++ b/examples/with-mdx/package.json @@ -11,7 +11,7 @@ "devDependencies": { "@astrojs/mdx": "^0.0.2", "@astrojs/preact": "^0.3.1", - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "preact": "^10.6.5" } } diff --git a/examples/with-nanostores/package.json b/examples/with-nanostores/package.json index a38e3b81e..6a47db852 100644 --- a/examples/with-nanostores/package.json +++ b/examples/with-nanostores/package.json @@ -25,6 +25,6 @@ "@astrojs/solid-js": "^0.2.0", "@astrojs/svelte": "^0.2.0", "@astrojs/vue": "^0.2.0", - "astro": "^1.0.0-beta.61" + "astro": "^1.0.0-beta.62" } } diff --git a/examples/with-tailwindcss/package.json b/examples/with-tailwindcss/package.json index 411c31b48..c34742050 100644 --- a/examples/with-tailwindcss/package.json +++ b/examples/with-tailwindcss/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/tailwind": "^0.2.2", - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "autoprefixer": "^10.4.7", "canvas-confetti": "^1.5.1", "postcss": "^8.4.14", diff --git a/examples/with-vite-plugin-pwa/package.json b/examples/with-vite-plugin-pwa/package.json index f3c9141d3..7bf432589 100644 --- a/examples/with-vite-plugin-pwa/package.json +++ b/examples/with-vite-plugin-pwa/package.json @@ -9,7 +9,7 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^1.0.0-beta.61", + "astro": "^1.0.0-beta.62", "vite-plugin-pwa": "0.11.11", "workbox-window": "^6.5.3" } diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index 944ff28fd..d573ec18f 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,11 @@ # astro +## 1.0.0-beta.62 + +### Patch Changes + +- [#3788](https://github.com/withastro/astro/pull/3788) [`f4943e0f`](https://github.com/withastro/astro/commit/f4943e0fbced044f0ba4435cb41d77b67c98e69f) Thanks [@tony-sull](https://github.com/tony-sull)! - Adds support for the new `astrojs/image` integration + ## 1.0.0-beta.61 ### Patch Changes diff --git a/packages/astro/package.json b/packages/astro/package.json index 49e7666a7..6351e2e7b 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "astro", - "version": "1.0.0-beta.61", + "version": "1.0.0-beta.62", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "type": "module", "author": "withastro", diff --git a/packages/integrations/image/CHANGELOG.md b/packages/integrations/image/CHANGELOG.md new file mode 100644 index 000000000..ce9fc333f --- /dev/null +++ b/packages/integrations/image/CHANGELOG.md @@ -0,0 +1,7 @@ +# @astrojs/image + +## 0.0.2 + +### Patch Changes + +- [#3788](https://github.com/withastro/astro/pull/3788) [`f4943e0f`](https://github.com/withastro/astro/commit/f4943e0fbced044f0ba4435cb41d77b67c98e69f) Thanks [@tony-sull](https://github.com/tony-sull)! - Initial release! 🎉 diff --git a/packages/integrations/image/package.json b/packages/integrations/image/package.json index 2626f951d..adf4f9e1c 100644 --- a/packages/integrations/image/package.json +++ b/packages/integrations/image/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/image", "description": "Load and transform images in your Astro site.", - "version": "0.0.1", + "version": "0.0.2", "type": "module", "types": "./dist/types.d.ts", "author": "withastro", diff --git a/packages/integrations/image/src/endpoints/dev.ts b/packages/integrations/image/src/endpoints/dev.ts index 9b1c2eff2..4d0ed365a 100644 --- a/packages/integrations/image/src/endpoints/dev.ts +++ b/packages/integrations/image/src/endpoints/dev.ts @@ -24,10 +24,10 @@ export const get: APIRoute = async ({ request }) => { return new Response(data, { status: 200, headers: { - 'Content-Type': lookup(format) || '' - } + 'Content-Type': lookup(format) || '', + }, }); } catch (err: unknown) { return new Response(`Server Error: ${err}`, { status: 500 }); } -} +}; diff --git a/packages/integrations/image/src/endpoints/prod.ts b/packages/integrations/image/src/endpoints/prod.ts index 65a8202a0..1ff56df48 100644 --- a/packages/integrations/image/src/endpoints/prod.ts +++ b/packages/integrations/image/src/endpoints/prod.ts @@ -15,7 +15,9 @@ export const get: APIRoute = async ({ request }) => { } // TODO: Can we lean on fs to load local images in SSR prod builds? - const href = isRemoteImage(transform.src) ? new URL(transform.src) : new URL(transform.src, url.origin); + const href = isRemoteImage(transform.src) + ? new URL(transform.src) + : new URL(transform.src, url.origin); const inputBuffer = await loadRemoteImage(href.toString()); @@ -30,11 +32,11 @@ export const get: APIRoute = async ({ request }) => { headers: { 'Content-Type': lookup(format) || '', 'Cache-Control': 'public, max-age=31536000', - 'ETag': etag(inputBuffer), - 'Date': (new Date()).toUTCString(), - } + ETag: etag(inputBuffer), + Date: new Date().toUTCString(), + }, }); } catch (err: unknown) { return new Response(`Server Error: ${err}`, { status: 500 }); } -} +}; diff --git a/packages/integrations/image/src/index.ts b/packages/integrations/image/src/index.ts index 7f1e1b456..43cf8fd1e 100644 --- a/packages/integrations/image/src/index.ts +++ b/packages/integrations/image/src/index.ts @@ -2,10 +2,21 @@ import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; import slash from 'slash'; -import { ensureDir, isRemoteImage, loadLocalImage, loadRemoteImage, propsToFilename } from './utils.js'; +import { + ensureDir, + isRemoteImage, + loadLocalImage, + loadRemoteImage, + propsToFilename, +} from './utils.js'; import { createPlugin } from './vite-plugin-astro-image.js'; import type { AstroConfig, AstroIntegration } from 'astro'; -import type { ImageAttributes, IntegrationOptions, SSRImageService, TransformOptions } from './types'; +import type { + ImageAttributes, + IntegrationOptions, + SSRImageService, + TransformOptions, +} from './types'; const PKG_NAME = '@astrojs/image'; const ROUTE_PATTERN = '/_image'; @@ -13,15 +24,18 @@ const OUTPUT_DIR = '/_image'; /** * Gets the HTML attributes required to build an `` for the transformed image. - * + * * @param loader @type {ImageService} The image service used for transforming images. * @param transform @type {TransformOptions} The transformations requested for the optimized image. * @returns @type {ImageAttributes} The HTML attributes to be included on the built `` element. */ -export async function getImage(loader: SSRImageService, transform: TransformOptions): Promise { +export async function getImage( + loader: SSRImageService, + transform: TransformOptions +): Promise { (globalThis as any).loader = loader; - const attributes = await loader.getImageAttributes(transform); + const attributes = await loader.getImageAttributes(transform); // For SSR services, build URLs for the injected route if (typeof loader.transform === 'function') { @@ -32,14 +46,15 @@ export async function getImage(loader: SSRImageService, transform: TransformOpti (globalThis as any)?.addStaticImage(transform); } - const src = globalThis && (globalThis as any).filenameFormat - ? (globalThis as any).filenameFormat(transform, searchParams) - : `${ROUTE_PATTERN}?${searchParams.toString()}`; + const src = + globalThis && (globalThis as any).filenameFormat + ? (globalThis as any).filenameFormat(transform, searchParams) + : `${ROUTE_PATTERN}?${searchParams.toString()}`; - return { - ...attributes, - src: slash(src), // Windows compat - } + return { + ...attributes, + src: slash(src), // Windows compat + }; } // For hosted services, return the attributes as-is @@ -49,7 +64,7 @@ export async function getImage(loader: SSRImageService, transform: TransformOpti const createIntegration = (options: IntegrationOptions = {}): AstroIntegration => { const resolvedOptions = { serviceEntryPoint: '@astrojs/image/sharp', - ...options + ...options, }; // During SSG builds, this is used to track all transformed images required. @@ -59,10 +74,8 @@ const createIntegration = (options: IntegrationOptions = {}): AstroIntegration = function getViteConfiguration() { return { - plugins: [ - createPlugin(_config, resolvedOptions) - ] - } + plugins: [createPlugin(_config, resolvedOptions)], + }; } return { @@ -80,23 +93,31 @@ const createIntegration = (options: IntegrationOptions = {}): AstroIntegration = // Added to globalThis to share the same map in Node and Vite (globalThis as any).addStaticImage = (transform: TransformOptions) => { staticImages.set(propsToFilename(transform), transform); - } + }; // TODO: Add support for custom, user-provided filename format functions - (globalThis as any).filenameFormat = (transform: TransformOptions, searchParams: URLSearchParams) => { + (globalThis as any).filenameFormat = ( + transform: TransformOptions, + searchParams: URLSearchParams + ) => { if (mode === 'ssg') { return isRemoteImage(transform.src) ? path.join(OUTPUT_DIR, path.basename(propsToFilename(transform))) - : path.join(OUTPUT_DIR, path.dirname(transform.src), path.basename(propsToFilename(transform))); + : path.join( + OUTPUT_DIR, + path.dirname(transform.src), + path.basename(propsToFilename(transform)) + ); } else { return `${ROUTE_PATTERN}?${searchParams.toString()}`; } - } + }; if (mode === 'ssr') { injectRoute({ pattern: ROUTE_PATTERN, - entryPoint: command === 'dev' ? '@astrojs/image/endpoints/dev' : '@astrojs/image/endpoints/prod' + entryPoint: + command === 'dev' ? '@astrojs/image/endpoints/dev' : '@astrojs/image/endpoints/prod', }); } }, @@ -111,7 +132,10 @@ const createIntegration = (options: IntegrationOptions = {}): AstroIntegration = // try to load the remote image inputBuffer = await loadRemoteImage(transform.src); - const outputFileURL = new URL(path.join('./', OUTPUT_DIR, path.basename(filename)), dir); + const outputFileURL = new URL( + path.join('./', OUTPUT_DIR, path.basename(filename)), + dir + ); outputFile = fileURLToPath(outputFileURL); } else { const inputFileURL = new URL(`.${transform.src}`, _config.srcDir); @@ -131,9 +155,9 @@ const createIntegration = (options: IntegrationOptions = {}): AstroIntegration = ensureDir(path.dirname(outputFile)); await fs.writeFile(outputFile, data); } - } - } - } -} + }, + }, + }; +}; export default createIntegration; diff --git a/packages/integrations/image/src/loaders/sharp.ts b/packages/integrations/image/src/loaders/sharp.ts index 5c79c7338..d5d3da8f0 100644 --- a/packages/integrations/image/src/loaders/sharp.ts +++ b/packages/integrations/image/src/loaders/sharp.ts @@ -2,42 +2,42 @@ import sharp from 'sharp'; import { isAspectRatioString, isOutputFormat } from '../utils.js'; import type { TransformOptions, OutputFormat, SSRImageService } from '../types'; -class SharpService implements SSRImageService { +class SharpService implements SSRImageService { async getImageAttributes(transform: TransformOptions) { const { width, height, src, format, quality, aspectRatio, ...rest } = transform; - + return { ...rest, width: width, - height: height - } + height: height, + }; } serializeTransform(transform: TransformOptions) { const searchParams = new URLSearchParams(); - + if (transform.quality) { searchParams.append('q', transform.quality.toString()); } - + if (transform.format) { searchParams.append('f', transform.format); } - + if (transform.width) { searchParams.append('w', transform.width.toString()); } - + if (transform.height) { searchParams.append('h', transform.height.toString()); } - + if (transform.aspectRatio) { searchParams.append('ar', transform.aspectRatio.toString()); } - + searchParams.append('href', transform.src); - + return { searchParams }; } @@ -45,54 +45,54 @@ class SharpService implements SSRImageService { if (!searchParams.has('href')) { return undefined; } - + let transform: TransformOptions = { src: searchParams.get('href')! }; if (searchParams.has('q')) { transform.quality = parseInt(searchParams.get('q')!); } - + if (searchParams.has('f')) { const format = searchParams.get('f')!; if (isOutputFormat(format)) { transform.format = format; } } - + if (searchParams.has('w')) { transform.width = parseInt(searchParams.get('w')!); } - + if (searchParams.has('h')) { transform.height = parseInt(searchParams.get('h')!); } - + if (searchParams.has('ar')) { const ratio = searchParams.get('ar')!; - + if (isAspectRatioString(ratio)) { transform.aspectRatio = ratio; } else { transform.aspectRatio = parseFloat(ratio); } } - + return transform; } async transform(inputBuffer: Buffer, transform: TransformOptions) { const sharpImage = sharp(inputBuffer, { failOnError: false }); - + if (transform.width || transform.height) { sharpImage.resize(transform.width, transform.height); } - + if (transform.format) { sharpImage.toFormat(transform.format, { quality: transform.quality }); } - + const { data, info } = await sharpImage.toBuffer({ resolveWithObject: true }); - + return { data, format: info.format as OutputFormat, diff --git a/packages/integrations/image/src/metadata.ts b/packages/integrations/image/src/metadata.ts index 3d344ad96..020d9461f 100644 --- a/packages/integrations/image/src/metadata.ts +++ b/packages/integrations/image/src/metadata.ts @@ -15,6 +15,6 @@ export async function metadata(src: string): Promise src, width, height, - format: type as InputFormat - } + format: type as InputFormat, + }; } diff --git a/packages/integrations/image/src/types.ts b/packages/integrations/image/src/types.ts index b161c15ed..1292169b2 100644 --- a/packages/integrations/image/src/types.ts +++ b/packages/integrations/image/src/types.ts @@ -1,7 +1,7 @@ export * from './index'; export type InputFormat = - | 'heic' + | 'heic' | 'heif' | 'avif' | 'jpeg' @@ -11,15 +11,11 @@ export type InputFormat = | 'webp' | 'gif'; -export type OutputFormat = - | 'avif' - | 'jpeg' - | 'png' - | 'webp'; +export type OutputFormat = 'avif' | 'jpeg' | 'png' | 'webp'; /** * Converts a set of image transforms to the filename to use when building for static. - * + * * This is only used for static production builds and ignored when an SSR adapter is used, * or in `astro dev` for static builds. */ @@ -38,20 +34,20 @@ export interface IntegrationOptions { export interface TransformOptions { /** * Source for the original image file. - * + * * For images in your project's repository, use the `src` relative to the `public` directory. * For remote images, provide the full URL. */ src: string; /** * The output format to be used in the optimized image. - * + * * @default undefined The original image format will be used. - */ + */ format?: OutputFormat; /** * The compression quality used during optimization. - * + * * @default undefined Allows the image service to determine defaults. */ quality?: number; @@ -68,7 +64,7 @@ export interface TransformOptions { /** * The desired aspect ratio of the output image. Combine with either `width` or `height` * to automatically calculate and crop the other dimension. - * + * * @example 1.777 - numbers can be used for computed ratios, useful for doing `{width/height}` * @example "16:9" - strings can be used in the format of `{ratioWidth}:{ratioHeight}`. */ @@ -84,21 +80,22 @@ export interface HostedImageService; } -export interface SSRImageService extends HostedImageService { +export interface SSRImageService + extends HostedImageService { /** * Gets the HTML attributes needed for the server rendered `` element. */ - getImageAttributes(transform: T): Promise>; + getImageAttributes(transform: T): Promise>; /** * Serializes image transformation properties to URLSearchParams, used to build * the final `src` that points to the self-hosted SSR endpoint. - * + * * @param transform @type {TransformOptions} defining the requested image transformation. */ serializeTransform(transform: T): { searchParams: URLSearchParams }; /** * The reverse of `serializeTransform(transform)`, this parsed the @type {TransformOptions} back out of a given URL. - * + * * @param searchParams @type {URLSearchParams} * @returns @type {TransformOptions} used to generate the URL, or undefined if the URL isn't valid. */ @@ -106,14 +103,16 @@ export interface SSRImageService /** * Performs the image transformations on the input image and returns both the binary data and * final image format of the optimized image. - * + * * @param inputBuffer Binary buffer containing the original image. * @param transform @type {TransformOptions} defining the requested transformations. */ - transform(inputBuffer: Buffer, transform: T): Promise<{ data: Buffer, format: OutputFormat }>; + transform(inputBuffer: Buffer, transform: T): Promise<{ data: Buffer; format: OutputFormat }>; } -export type ImageService = HostedImageService | SSRImageService; +export type ImageService = + | HostedImageService + | SSRImageService; export interface ImageMetadata { src: string; diff --git a/packages/integrations/image/src/utils.ts b/packages/integrations/image/src/utils.ts index 48249aff1..95e0fb2a1 100644 --- a/packages/integrations/image/src/utils.ts +++ b/packages/integrations/image/src/utils.ts @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; import type { OutputFormat, TransformOptions } from './types'; - export function isOutputFormat(value: string): value is OutputFormat { +export function isOutputFormat(value: string): value is OutputFormat { return ['avif', 'jpeg', 'png', 'webp'].includes(value); } @@ -41,9 +41,7 @@ export async function loadRemoteImage(src: string) { } export async function loadImage(src: string) { - return isRemoteImage(src) - ? await loadRemoteImage(src) - : await loadLocalImage(src); + return isRemoteImage(src) ? await loadRemoteImage(src) : await loadLocalImage(src); } export function propsToFilename({ src, width, height, format }: TransformOptions) { diff --git a/packages/integrations/image/src/vite-plugin-astro-image.ts b/packages/integrations/image/src/vite-plugin-astro-image.ts index 852e9c58f..e2fcfffcb 100644 --- a/packages/integrations/image/src/vite-plugin-astro-image.ts +++ b/packages/integrations/image/src/vite-plugin-astro-image.ts @@ -8,7 +8,8 @@ import type { AstroConfig } from 'astro'; import type { IntegrationOptions } from './types'; export function createPlugin(config: AstroConfig, options: Required): Plugin { - const filter = (id: string) => /^(?!\/_image?).*.(heic|heif|avif|jpeg|jpg|png|tiff|webp|gif)$/.test(id); + const filter = (id: string) => + /^(?!\/_image?).*.(heic|heif|avif|jpeg|jpg|png|tiff|webp|gif)$/.test(id); const virtualModuleId = 'virtual:image-loader'; @@ -43,10 +44,12 @@ export function createPlugin(config: AstroConfig, options: Required { - verifyImage('_image/googlelogo_color_272x92dp_544x184.webp', { width: 544, height: 184, type: 'webp' }); + verifyImage('_image/googlelogo_color_272x92dp_544x184.webp', { + width: 544, + height: 184, + type: 'webp', + }); }); }); }); @@ -95,9 +99,9 @@ describe('SSG images', function () { it('returns the optimized image', async () => { const image = $('#social-jpg'); - + const res = await fixture.fetch(image.attr('src')); - + expect(res.status).to.equal(200); expect(res.headers.get('Content-Type')).to.equal('image/jpeg'); @@ -119,7 +123,9 @@ describe('SSG images', function () { expect(searchParams.get('f')).to.equal('webp'); expect(searchParams.get('w')).to.equal('544'); expect(searchParams.get('h')).to.equal('184'); - expect(searchParams.get('href')).to.equal('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'); + expect(searchParams.get('href')).to.equal( + 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png' + ); }); }); }); diff --git a/packages/integrations/image/test/sharp.test.js b/packages/integrations/image/test/sharp.test.js index 04b63ed7b..82e332e3d 100644 --- a/packages/integrations/image/test/sharp.test.js +++ b/packages/integrations/image/test/sharp.test.js @@ -13,7 +13,7 @@ describe('Sharp service', () => { ['height', { src, height: 414 }], ['width & height', { src, height: 400, width: 200 }], ['aspect ratio string', { src, aspectRatio: '16:9' }], - ['aspect ratio float', { src, aspectRatio: 1.7 }] + ['aspect ratio float', { src, aspectRatio: 1.7 }], ].forEach(([description, props]) => { it(description, async () => { const { searchParams } = await sharp.serializeTransform(props); @@ -48,7 +48,7 @@ describe('Sharp service', () => { ['height', `h=414&href=${href}`, { src, height: 414 }], ['width & height', `w=200&h=400&href=${href}`, { src, height: 400, width: 200 }], ['aspect ratio string', `ar=16:9&href=${href}`, { src, aspectRatio: '16:9' }], - ['aspect ratio float', `ar=1.7&href=${href}`, { src, aspectRatio: 1.7 }] + ['aspect ratio float', `ar=1.7&href=${href}`, { src, aspectRatio: 1.7 }], ].forEach(([description, params, expected]) => { it(description, async () => { const searchParams = new URLSearchParams(params); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bfd6d5a9d..e083b479c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,14 +49,14 @@ importers: examples/basics: specifiers: - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 devDependencies: astro: link:../../packages/astro examples/blog: specifiers: '@astrojs/preact': ^0.3.1 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 preact: ^10.7.3 dependencies: preact: 10.8.2 @@ -67,7 +67,7 @@ importers: examples/blog-multiple-authors: specifiers: '@astrojs/preact': ^0.3.1 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 preact: ^10.7.3 sass: ^1.52.2 dependencies: @@ -79,14 +79,14 @@ importers: examples/component: specifiers: - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 devDependencies: astro: link:../../packages/astro examples/component/demo: specifiers: '@example/my-component': workspace:* - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 devDependencies: '@example/my-component': link:../packages/my-component astro: link:../../../packages/astro @@ -102,7 +102,7 @@ importers: '@docsearch/css': ^3.1.0 '@docsearch/react': ^3.1.0 '@types/react': ^17.0.45 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 preact: ^10.7.3 react: ^18.1.0 react-dom: ^18.1.0 @@ -121,14 +121,14 @@ importers: examples/env-vars: specifiers: - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 devDependencies: astro: link:../../packages/astro examples/framework-alpine: specifiers: alpinejs: ^3.10.2 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 dependencies: alpinejs: 3.10.2 devDependencies: @@ -138,7 +138,7 @@ importers: specifiers: '@astrojs/lit': ^0.3.0 '@webcomponents/template-shadowroot': ^0.1.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 lit: ^2.2.5 dependencies: '@webcomponents/template-shadowroot': 0.1.0 @@ -156,7 +156,7 @@ importers: '@astrojs/svelte': ^0.2.0 '@astrojs/vue': ^0.2.0 '@webcomponents/template-shadowroot': ^0.1.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 lit: ^2.2.5 preact: ^10.7.3 react: ^18.1.0 @@ -185,7 +185,7 @@ importers: examples/framework-preact: specifiers: '@astrojs/preact': ^0.3.1 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 preact: ^10.7.3 dependencies: preact: 10.8.2 @@ -198,7 +198,7 @@ importers: '@astrojs/react': ^0.2.0 '@types/react': ^18.0.10 '@types/react-dom': ^18.0.5 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 react: ^18.1.0 react-dom: ^18.1.0 dependencies: @@ -213,7 +213,7 @@ importers: examples/framework-solid: specifiers: '@astrojs/solid-js': ^0.2.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 solid-js: ^1.4.3 dependencies: solid-js: 1.4.5 @@ -224,7 +224,7 @@ importers: examples/framework-svelte: specifiers: '@astrojs/svelte': ^0.2.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 svelte: ^3.48.0 dependencies: svelte: 3.48.0 @@ -235,7 +235,7 @@ importers: examples/framework-vue: specifiers: '@astrojs/vue': ^0.2.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 vue: ^3.2.37 dependencies: vue: 3.2.37 @@ -253,7 +253,7 @@ importers: '@astrojs/tailwind': ^0.2.2 '@astrojs/turbolinks': ^0.1.3 '@webcomponents/template-shadowroot': ^0.1.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 lit: ^2.2.5 preact: ^10.7.3 react: ^18.1.0 @@ -282,20 +282,20 @@ importers: examples/minimal: specifiers: - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 devDependencies: astro: link:../../packages/astro examples/non-html-pages: specifiers: - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 devDependencies: astro: link:../../packages/astro examples/portfolio: specifiers: '@astrojs/preact': ^0.3.1 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 preact: ^10.7.3 sass: ^1.52.2 dependencies: @@ -309,7 +309,7 @@ importers: specifiers: '@astrojs/node': ^0.1.3 '@astrojs/svelte': ^0.2.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 concurrently: ^7.2.1 lightcookie: ^1.0.25 svelte: ^3.48.0 @@ -328,14 +328,14 @@ importers: examples/starter: specifiers: - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 devDependencies: astro: link:../../packages/astro examples/subpath: specifiers: '@astrojs/react': ^0.2.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 react: ^18.1.0 react-dom: ^18.1.0 sass: ^1.52.2 @@ -354,7 +354,7 @@ importers: '@astrojs/react': ^0.2.0 '@astrojs/svelte': ^0.2.0 '@astrojs/vue': ^0.2.0 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 preact: ^10.7.3 react: ^18.1.0 react-dom: ^18.1.0 @@ -377,7 +377,7 @@ importers: examples/with-markdown-plugins: specifiers: '@astrojs/markdown-remark': ^0.11.3 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 hast-util-select: 5.0.1 rehype-autolink-headings: ^6.1.1 rehype-slug: ^5.0.1 @@ -395,7 +395,7 @@ importers: examples/with-markdown-shiki: specifiers: '@astrojs/markdown-remark': ^0.11.3 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 devDependencies: '@astrojs/markdown-remark': link:../../packages/markdown/remark astro: link:../../packages/astro @@ -404,7 +404,7 @@ importers: specifiers: '@astrojs/mdx': ^0.0.2 '@astrojs/preact': ^0.3.1 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 preact: ^10.6.5 devDependencies: '@astrojs/mdx': link:../../packages/integrations/mdx @@ -422,7 +422,7 @@ importers: '@nanostores/preact': ^0.1.3 '@nanostores/react': ^0.1.5 '@nanostores/vue': ^0.4.1 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 nanostores: ^0.5.12 preact: ^10.7.3 react: ^18.1.0 @@ -450,7 +450,7 @@ importers: examples/with-tailwindcss: specifiers: '@astrojs/tailwind': ^0.2.2 - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 autoprefixer: ^10.4.7 canvas-confetti: ^1.5.1 postcss: ^8.4.14 @@ -465,7 +465,7 @@ importers: examples/with-vite-plugin-pwa: specifiers: - astro: ^1.0.0-beta.61 + astro: ^1.0.0-beta.62 vite-plugin-pwa: 0.11.11 workbox-window: ^6.5.3 devDependencies: @@ -8960,11 +8960,6 @@ packages: /debug/3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true dependencies: ms: 2.1.3 dev: false @@ -12033,8 +12028,6 @@ packages: debug: 3.2.7 iconv-lite: 0.4.24 sax: 1.2.4 - transitivePeerDependencies: - - supports-color dev: false /netmask/2.0.2: @@ -12116,8 +12109,6 @@ packages: rimraf: 2.7.1 semver: 5.7.1 tar: 4.4.19 - transitivePeerDependencies: - - supports-color dev: false /node-releases/2.0.5: