summaryrefslogtreecommitdiff
path: root/packages/integrations/image/src
diff options
context:
space:
mode:
authorGravatar Tony Sullivan <tony.f.sullivan@outlook.com> 2022-07-27 15:39:05 +0000
committerGravatar GitHub <noreply@github.com> 2022-07-27 15:39:05 +0000
commita397b981f5f46dee85e6e00aa39633d018d4b9a2 (patch)
tree8622069c50ed93364d01d62f2aa9ac664429ed14 /packages/integrations/image/src
parent55c8aced44a60a664f28de9dabf03ca51897599e (diff)
downloadastro-a397b981f5f46dee85e6e00aa39633d018d4b9a2.tar.gz
astro-a397b981f5f46dee85e6e00aa39633d018d4b9a2.tar.zst
astro-a397b981f5f46dee85e6e00aa39633d018d4b9a2.zip
Fixes type definitions `@astrojs/image` and adds more documentation to the README (#4045)
* WIP: moving to a static .d.ts types file * fixing named exports for getImage and getPicture * removing the exports.astro map for now * WIP: adding readme docs for component attributes * Adding docs for getImage and getPicture * leaning fully on TSC to build .d.ts files * finally found the solution for proper ESM import types * adding a note to the README for tsconfig updates * chore: add changesets * typo * docs: removing the "Images in Markdown" example * removing the need for publishing src to NPM * fix: make type re-export explicit * updating image module defs to match InputFormat * using astro syntax highlighting for README code blocks * nit: missing backtick in README * make sure Astro component directives aren't recommended twice
Diffstat (limited to 'packages/integrations/image/src')
-rw-r--r--packages/integrations/image/src/build/ssg.ts2
-rw-r--r--packages/integrations/image/src/index.ts119
-rw-r--r--packages/integrations/image/src/integration.ts93
-rw-r--r--packages/integrations/image/src/lib/get-image.ts8
-rw-r--r--packages/integrations/image/src/lib/get-picture.ts6
-rw-r--r--packages/integrations/image/src/loaders/index.ts (renamed from packages/integrations/image/src/types.ts)44
-rw-r--r--packages/integrations/image/src/loaders/sharp.ts2
-rw-r--r--packages/integrations/image/src/utils/images.ts2
-rw-r--r--packages/integrations/image/src/utils/metadata.ts3
-rw-r--r--packages/integrations/image/src/utils/paths.ts2
-rw-r--r--packages/integrations/image/src/vite-plugin-astro-image.ts10
11 files changed, 141 insertions, 150 deletions
diff --git a/packages/integrations/image/src/build/ssg.ts b/packages/integrations/image/src/build/ssg.ts
index 78510889c..496905f92 100644
--- a/packages/integrations/image/src/build/ssg.ts
+++ b/packages/integrations/image/src/build/ssg.ts
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { OUTPUT_DIR } from '../constants.js';
-import type { SSRImageService, TransformOptions } from '../types.js';
+import type { SSRImageService, TransformOptions } from '../loaders/index.js';
import { isRemoteImage, loadLocalImage, loadRemoteImage } from '../utils/images.js';
import { ensureDir } from '../utils/paths.js';
diff --git a/packages/integrations/image/src/index.ts b/packages/integrations/image/src/index.ts
index 81ef8c6b9..234b1646d 100644
--- a/packages/integrations/image/src/index.ts
+++ b/packages/integrations/image/src/index.ts
@@ -1,5 +1,116 @@
-import integration from './integration.js';
-export * from './lib/get-image.js';
-export * from './lib/get-picture.js';
+import type { AstroConfig, AstroIntegration } from 'astro';
+import { ssgBuild } from './build/ssg.js';
+import { ssrBuild } from './build/ssr.js';
+import { PKG_NAME, ROUTE_PATTERN } from './constants.js';
+import { ImageService, TransformOptions } from './loaders/index.js';
+import { filenameFormat, propsToFilename } from './utils/paths.js';
+import { createPlugin } from './vite-plugin-astro-image.js';
-export default integration;
+export { getImage } from './lib/get-image.js';
+export { getPicture } from './lib/get-picture.js';
+export * from './loaders/index.js';
+export type { ImageMetadata} from './vite-plugin-astro-image.js';
+
+interface ImageIntegration {
+ loader?: ImageService;
+ addStaticImage?: (transform: TransformOptions) => void;
+ filenameFormat?: (transform: TransformOptions, searchParams: URLSearchParams) => string;
+}
+
+declare global {
+ // eslint-disable-next-line no-var
+ var astroImage: ImageIntegration | undefined;
+}
+
+export interface IntegrationOptions {
+ /**
+ * Entry point for the @type {HostedImageService} or @type {LocalImageService} to be used.
+ */
+ serviceEntryPoint?: string;
+}
+
+export default function integration(options: IntegrationOptions = {}): AstroIntegration {
+ const resolvedOptions = {
+ serviceEntryPoint: '@astrojs/image/sharp',
+ ...options,
+ };
+
+ // During SSG builds, this is used to track all transformed images required.
+ const staticImages = new Map<string, Map<string, TransformOptions>>();
+
+ let _config: AstroConfig;
+ let output: 'server' | 'static';
+
+ function getViteConfiguration() {
+ return {
+ plugins: [createPlugin(_config, resolvedOptions)],
+ optimizeDeps: {
+ include: ['image-size', 'sharp'],
+ },
+ ssr: {
+ noExternal: ['@astrojs/image', resolvedOptions.serviceEntryPoint],
+ },
+ };
+ }
+
+ return {
+ name: PKG_NAME,
+ hooks: {
+ 'astro:config:setup': ({ command, config, injectRoute, updateConfig }) => {
+ _config = config;
+
+ // Always treat `astro dev` as SSR mode, even without an adapter
+ output = command === 'dev' ? 'server' : config.output;
+
+ updateConfig({ vite: getViteConfiguration() });
+
+ if (output === 'server') {
+ injectRoute({
+ pattern: ROUTE_PATTERN,
+ entryPoint:
+ command === 'dev' ? '@astrojs/image/endpoints/dev' : '@astrojs/image/endpoints/prod',
+ });
+ }
+ },
+ 'astro:server:setup': async () => {
+ globalThis.astroImage = {};
+ },
+ 'astro:build:setup': () => {
+ // Used to cache all images rendered to HTML
+ // Added to globalThis to share the same map in Node and Vite
+ function addStaticImage(transform: TransformOptions) {
+ const srcTranforms = staticImages.has(transform.src)
+ ? staticImages.get(transform.src)!
+ : new Map<string, TransformOptions>();
+
+ srcTranforms.set(propsToFilename(transform), transform);
+
+ staticImages.set(transform.src, srcTranforms);
+ }
+
+ // Helpers for building static images should only be available for SSG
+ globalThis.astroImage =
+ output === 'static'
+ ? {
+ addStaticImage,
+ filenameFormat,
+ }
+ : {};
+ },
+ 'astro:build:done': async ({ dir }) => {
+ if (output === 'server') {
+ // for SSR builds, copy all image files from src to dist
+ // to make sure they are available for use in production
+ await ssrBuild({ srcDir: _config.srcDir, outDir: dir });
+ } else {
+ // for SSG builds, build all requested image transforms to dist
+ const loader = globalThis?.astroImage?.loader;
+
+ if (loader && 'transform' in loader && staticImages.size > 0) {
+ await ssgBuild({ loader, staticImages, srcDir: _config.srcDir, outDir: dir });
+ }
+ }
+ },
+ },
+ };
+}
diff --git a/packages/integrations/image/src/integration.ts b/packages/integrations/image/src/integration.ts
deleted file mode 100644
index 725276d03..000000000
--- a/packages/integrations/image/src/integration.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import type { AstroConfig, AstroIntegration } from 'astro';
-import { ssgBuild } from './build/ssg.js';
-import { ssrBuild } from './build/ssr.js';
-import { PKG_NAME, ROUTE_PATTERN } from './constants.js';
-import { IntegrationOptions, TransformOptions } from './types.js';
-import { filenameFormat, propsToFilename } from './utils/paths.js';
-import { createPlugin } from './vite-plugin-astro-image.js';
-
-export default function integration(options: IntegrationOptions = {}): AstroIntegration {
- const resolvedOptions = {
- serviceEntryPoint: '@astrojs/image/sharp',
- ...options,
- };
-
- // During SSG builds, this is used to track all transformed images required.
- const staticImages = new Map<string, Map<string, TransformOptions>>();
-
- let _config: AstroConfig;
- let output: 'server' | 'static';
-
- function getViteConfiguration() {
- return {
- plugins: [createPlugin(_config, resolvedOptions)],
- optimizeDeps: {
- include: ['image-size', 'sharp'],
- },
- ssr: {
- noExternal: ['@astrojs/image', resolvedOptions.serviceEntryPoint],
- },
- };
- }
-
- return {
- name: PKG_NAME,
- hooks: {
- 'astro:config:setup': ({ command, config, injectRoute, updateConfig }) => {
- _config = config;
-
- // Always treat `astro dev` as SSR mode, even without an adapter
- output = command === 'dev' ? 'server' : config.output;
-
- updateConfig({ vite: getViteConfiguration() });
-
- if (output === 'server') {
- injectRoute({
- pattern: ROUTE_PATTERN,
- entryPoint:
- command === 'dev' ? '@astrojs/image/endpoints/dev' : '@astrojs/image/endpoints/prod',
- });
- }
- },
- 'astro:server:setup': async () => {
- globalThis.astroImage = {};
- },
- 'astro:build:setup': () => {
- // Used to cache all images rendered to HTML
- // Added to globalThis to share the same map in Node and Vite
- function addStaticImage(transform: TransformOptions) {
- const srcTranforms = staticImages.has(transform.src)
- ? staticImages.get(transform.src)!
- : new Map<string, TransformOptions>();
-
- srcTranforms.set(propsToFilename(transform), transform);
-
- staticImages.set(transform.src, srcTranforms);
- }
-
- // Helpers for building static images should only be available for SSG
- globalThis.astroImage =
- output === 'static'
- ? {
- addStaticImage,
- filenameFormat,
- }
- : {};
- },
- 'astro:build:done': async ({ dir }) => {
- if (output === 'server') {
- // for SSR builds, copy all image files from src to dist
- // to make sure they are available for use in production
- await ssrBuild({ srcDir: _config.srcDir, outDir: dir });
- } else {
- // for SSG builds, build all requested image transforms to dist
- const loader = globalThis?.astroImage?.loader;
-
- if (loader && 'transform' in loader && staticImages.size > 0) {
- await ssgBuild({ loader, staticImages, srcDir: _config.srcDir, outDir: dir });
- }
- }
- },
- },
- };
-}
diff --git a/packages/integrations/image/src/lib/get-image.ts b/packages/integrations/image/src/lib/get-image.ts
index e0f57e873..0a28ff3ac 100644
--- a/packages/integrations/image/src/lib/get-image.ts
+++ b/packages/integrations/image/src/lib/get-image.ts
@@ -1,15 +1,15 @@
+/// <reference types="astro/astro-jsx" />
import slash from 'slash';
import { ROUTE_PATTERN } from '../constants.js';
import sharp from '../loaders/sharp.js';
import {
- ImageAttributes,
- ImageMetadata,
ImageService,
isSSRService,
OutputFormat,
TransformOptions,
-} from '../types.js';
+} from '../loaders/index.js';
import { isRemoteImage, parseAspectRatio } from '../utils/images.js';
+import { ImageMetadata } from '../vite-plugin-astro-image.js';
export interface GetImageTransform extends Omit<TransformOptions, 'src'> {
src: string | ImageMetadata | Promise<{ default: ImageMetadata }>;
@@ -101,7 +101,7 @@ async function resolveTransform(input: GetImageTransform): Promise<TransformOpti
* @param transform @type {TransformOptions} The transformations requested for the optimized image.
* @returns @type {ImageAttributes} The HTML attributes to be included on the built `<img />` element.
*/
-export async function getImage(transform: GetImageTransform): Promise<ImageAttributes> {
+export async function getImage(transform: GetImageTransform): Promise<astroHTML.JSX.ImgHTMLAttributes> {
if (!transform.src) {
throw new Error('[@astrojs/image] `src` is required');
}
diff --git a/packages/integrations/image/src/lib/get-picture.ts b/packages/integrations/image/src/lib/get-picture.ts
index 82bf9f7c5..0b9521853 100644
--- a/packages/integrations/image/src/lib/get-picture.ts
+++ b/packages/integrations/image/src/lib/get-picture.ts
@@ -1,7 +1,9 @@
+/// <reference types="astro/astro-jsx" />
import { lookup } from 'mrmime';
import { extname } from 'node:path';
-import { ImageAttributes, ImageMetadata, OutputFormat, TransformOptions } from '../types.js';
+import { OutputFormat, TransformOptions } from '../loaders/index.js';
import { parseAspectRatio } from '../utils/images.js';
+import { ImageMetadata } from '../vite-plugin-astro-image.js';
import { getImage } from './get-image.js';
export interface GetPictureParams {
@@ -12,7 +14,7 @@ export interface GetPictureParams {
}
export interface GetPictureResult {
- image: ImageAttributes;
+ image: astroHTML.JSX.HTMLAttributes;
sources: { type: string; srcset: string }[];
}
diff --git a/packages/integrations/image/src/types.ts b/packages/integrations/image/src/loaders/index.ts
index f7e0c0e5f..7681f25d4 100644
--- a/packages/integrations/image/src/types.ts
+++ b/packages/integrations/image/src/loaders/index.ts
@@ -1,17 +1,4 @@
/// <reference types="astro/astro-jsx" />
-export * from './index.js';
-
-interface ImageIntegration {
- loader?: ImageService;
- addStaticImage?: (transform: TransformOptions) => void;
- filenameFormat?: (transform: TransformOptions, searchParams: URLSearchParams) => string;
-}
-
-declare global {
- // eslint-disable-next-line no-var
- var astroImage: ImageIntegration | undefined;
-}
-
export type InputFormat =
| 'heic'
| 'heif'
@@ -26,21 +13,6 @@ export type InputFormat =
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.
- */
-export type FilenameFormatter = (transform: TransformOptions) => string;
-
-export interface IntegrationOptions {
- /**
- * Entry point for the @type {HostedImageService} or @type {LocalImageService} to be used.
- */
- serviceEntryPoint?: string;
-}
-
-/**
* Defines the original image and transforms that need to be applied to it.
*/
export interface TransformOptions {
@@ -83,22 +55,19 @@ export interface TransformOptions {
aspectRatio?: number | `${number}:${number}`;
}
-export type ImageAttributes = astroHTML.JSX.ImgHTMLAttributes;
-export type PictureAttributes = astroHTML.JSX.HTMLAttributes;
-
export interface HostedImageService<T extends TransformOptions = TransformOptions> {
/**
* Gets the HTML attributes needed for the server rendered `<img />` element.
*/
- getImageAttributes(transform: T): Promise<ImageAttributes>;
+ getImageAttributes(transform: T): Promise<astroHTML.JSX.ImgHTMLAttributes>;
}
export interface SSRImageService<T extends TransformOptions = TransformOptions>
extends HostedImageService<T> {
/**
- * Gets tthe HTML attributes needed for the server rendered `<img />` element.
+ * Gets the HTML attributes needed for the server rendered `<img />` element.
*/
- getImageAttributes(transform: T): Promise<Exclude<ImageAttributes, 'src'>>;
+ getImageAttributes(transform: T): Promise<Exclude<astroHTML.JSX.ImgHTMLAttributes, 'src'>>;
/**
* Serializes image transformation properties to URLSearchParams, used to build
* the final `src` that points to the self-hosted SSR endpoint.
@@ -134,10 +103,3 @@ export function isHostedService(service: ImageService): service is ImageService
export function isSSRService(service: ImageService): service is SSRImageService {
return 'transform' in service;
}
-
-export interface ImageMetadata {
- src: string;
- width: number;
- height: number;
- format: InputFormat;
-}
diff --git a/packages/integrations/image/src/loaders/sharp.ts b/packages/integrations/image/src/loaders/sharp.ts
index b4c5e18fd..f76a16d39 100644
--- a/packages/integrations/image/src/loaders/sharp.ts
+++ b/packages/integrations/image/src/loaders/sharp.ts
@@ -1,5 +1,5 @@
import sharp from 'sharp';
-import type { OutputFormat, SSRImageService, TransformOptions } from '../types.js';
+import type { OutputFormat, SSRImageService, TransformOptions } from './index.js';
import { isAspectRatioString, isOutputFormat } from '../utils/images.js';
class SharpService implements SSRImageService {
diff --git a/packages/integrations/image/src/utils/images.ts b/packages/integrations/image/src/utils/images.ts
index d36c64fc0..f3c519657 100644
--- a/packages/integrations/image/src/utils/images.ts
+++ b/packages/integrations/image/src/utils/images.ts
@@ -1,5 +1,5 @@
import fs from 'node:fs/promises';
-import type { OutputFormat, TransformOptions } from '../types.js';
+import type { OutputFormat, TransformOptions } from '../loaders/index.js';
export function isOutputFormat(value: string): value is OutputFormat {
return ['avif', 'jpeg', 'png', 'webp'].includes(value);
diff --git a/packages/integrations/image/src/utils/metadata.ts b/packages/integrations/image/src/utils/metadata.ts
index fa60281b6..349a37535 100644
--- a/packages/integrations/image/src/utils/metadata.ts
+++ b/packages/integrations/image/src/utils/metadata.ts
@@ -1,6 +1,7 @@
import sizeOf from 'image-size';
import fs from 'node:fs/promises';
-import { ImageMetadata, InputFormat } from '../types.js';
+import { InputFormat } from '../loaders/index.js';
+import { ImageMetadata } from '../vite-plugin-astro-image.js';
export async function metadata(src: string): Promise<ImageMetadata | undefined> {
const file = await fs.readFile(src);
diff --git a/packages/integrations/image/src/utils/paths.ts b/packages/integrations/image/src/utils/paths.ts
index a958d4911..6258d392d 100644
--- a/packages/integrations/image/src/utils/paths.ts
+++ b/packages/integrations/image/src/utils/paths.ts
@@ -1,7 +1,7 @@
import fs from 'node:fs';
import path from 'node:path';
import { OUTPUT_DIR } from '../constants.js';
-import type { TransformOptions } from '../types.js';
+import type { TransformOptions } from '../loaders/index.js';
import { isRemoteImage } from './images.js';
import { shorthash } from './shorthash.js';
diff --git a/packages/integrations/image/src/vite-plugin-astro-image.ts b/packages/integrations/image/src/vite-plugin-astro-image.ts
index 81593c142..aefc910bb 100644
--- a/packages/integrations/image/src/vite-plugin-astro-image.ts
+++ b/packages/integrations/image/src/vite-plugin-astro-image.ts
@@ -3,9 +3,17 @@ import { pathToFileURL } from 'node:url';
import type { PluginContext } from 'rollup';
import slash from 'slash';
import type { Plugin, ResolvedConfig } from 'vite';
-import type { IntegrationOptions } from './types.js';
+import type { IntegrationOptions } from './index.js';
+import type { InputFormat } from './loaders/index.js';
import { metadata } from './utils/metadata.js';
+export interface ImageMetadata {
+ src: string;
+ width: number;
+ height: number;
+ format: InputFormat;
+}
+
export function createPlugin(config: AstroConfig, options: Required<IntegrationOptions>): Plugin {
const filter = (id: string) =>
/^(?!\/_image?).*.(heic|heif|avif|jpeg|jpg|png|tiff|webp|gif)$/.test(id);