@ecopages/image-processor 0.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@ecopages/image-processor` are documented here.
4
+
5
+ > **Note:** Changelog tracking begins at version `0.2.0`. Changes prior to this release are not recorded here but are available in the git history.
6
+
7
+ ## [UNRELEASED] — TBD
8
+
9
+ ### Features
10
+
11
+ - **`image-plugins.ts`** — New file extracting image processing plugin logic for reuse across build adapters (`image-plugins.ts`).
12
+ - Bun-specific plugin helpers moved to `bun-plugins.ts`, separating runtime concerns from the image processing core.
13
+
14
+ ### Refactoring
15
+
16
+ - `plugin.ts` updated to use the new `image-plugins.ts` abstraction.
17
+ - `image-processor.ts` minor updates.
18
+ - README updated with usage clarification.
19
+
20
+ ### Tests
21
+
22
+ - `image-renderer.test.ts` expanded (68 lines added).
23
+ - `image-processor.test.ts` and `image-utils.test.ts` updated.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Andrea Zanenghi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,218 @@
1
+ # @ecopages/image-processor
2
+
3
+ A powerful and flexible image processing library designed to optimize and manage responsive images in ecopages applications.
4
+
5
+ ## Features
6
+
7
+ - **Automatic Image Optimization**: Converts and compresses images to modern formats
8
+ - **Responsive Image Generation**: Creates multiple image variants for different screen sizes
9
+ - **Virtual Module Integration**: Direct import of optimized images through `ecopages:images`
10
+ - **TypeScript Support**: Full type definitions and auto-generated types
11
+ - **Multiple Layout Options**: Supports fixed, constrained, and full-width layouts
12
+ - **Ecopages Integration**: Seamlessly integrated with the ecopages framework
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @ecopages/image-processor
18
+ ```
19
+
20
+ ## Configuration
21
+
22
+ ```typescript
23
+ import path from 'node:path';
24
+ import { ConfigBuilder } from '@ecopages/core';
25
+ import { ImageProcessorPlugin } from '@ecopages/image-processor';
26
+
27
+ const imageProcessor = new ImageProcessorPlugin({
28
+ name: 'ecopages-image-processor',
29
+ type: 'image',
30
+ options: {
31
+ sourceDir: path.resolve(import.meta.dir, 'src/images'),
32
+ outputDir: path.resolve(import.meta.dir, '.eco/images'),
33
+ publicPath: '/images',
34
+ acceptedFormats: ['jpg', 'jpeg', 'png', 'webp'],
35
+ quality: 80,
36
+ format: 'webp',
37
+ sizes: [
38
+ { width: 320, label: 'sm' },
39
+ { width: 768, label: 'md' },
40
+ { width: 1024, label: 'lg' },
41
+ { width: 1920, label: 'xl' },
42
+ ],
43
+ },
44
+ });
45
+
46
+ export default await new ConfigBuilder()
47
+ .setRootDir(import.meta.dir)
48
+ .setBaseUrl(import.meta.env.ECOPAGES_BASE_URL)
49
+ .setProcessors([imageProcessor])
50
+ .build();
51
+ ```
52
+
53
+ ### Configuration Options
54
+
55
+ #### ImageProcessorConfig
56
+
57
+ | Option | Type | Default | Description |
58
+ | ----------------- | --------------------------------------- | ----------------------------- | ------------------------------------- |
59
+ | `sourceDir` | `string` | `'/src/public/assets/images'` | Source directory for images |
60
+ | `outputDir` | `string` | `'/dist/assets/optimized'` | Output directory for processed images |
61
+ | `publicPath` | `string` | `'/assets/optimized'` | Public URL path for images |
62
+ | `sizes` | `Array<{width: number, label: string}>` | `[]` | Image variants configuration |
63
+ | `quality` | `number` | `80` | Output image quality (0-100) |
64
+ | `format` | `'webp' \| 'jpeg' \| 'png' \| 'avif'` | `'webp'` | Output image format |
65
+ | `acceptedFormats` | `string[]` | `['jpg','jpeg','png','webp']` | Accepted input formats |
66
+
67
+ ## Usage
68
+
69
+ ### Virtual Module System
70
+
71
+ The `ecopages:images` virtual module provides a unified, type-safe way to handle images across your project:
72
+
73
+ ```typescript
74
+ // All images from your source directory are available as named exports
75
+ import { heroImage, profilePicture, blogThumbnail } from 'ecopages:images';
76
+
77
+ // Names are automatically converted to camelCase
78
+ // example:
79
+ // src/images/hero-image.jpg -> heroImage
80
+ // src/images/profile_picture.png -> profilePicture
81
+ ```
82
+
83
+ No manual `dependencies.modules` declaration is required for `ecopages:images`; imports are automatically detected and included in the client bundle.
84
+
85
+ #### Benefits:
86
+
87
+ - **TypeScript Integration**: Full autocompletion support for image names
88
+ - **Automatic Processing**: Images are processed at build time
89
+ - **Tree Shaking**: Only imported images and their required metadata are included in the final bundle
90
+ - **Type Safety**: Prevents imports of non-existent images
91
+ - **Unified API**: Consistent way to handle images across your project
92
+
93
+ ### Importing Images
94
+
95
+ Images are available through the virtual module `ecopages:images`:
96
+
97
+ ```typescript
98
+ import { myImage } from 'ecopages:images';
99
+
100
+ // myImage contains:
101
+ // {
102
+ // attributes: {
103
+ // src: string,
104
+ // width: number, // original image width
105
+ // height: number, // original image height
106
+ // sizes: string,
107
+ // srcset: string
108
+ // },
109
+ // variants: Array<{ width, height, src, label }>
110
+ // }
111
+ ```
112
+
113
+ ### HTML Component
114
+
115
+ ```typescript
116
+ import { EcoImage } from '@ecopages/image-processor/component/html';
117
+
118
+ // Basic usage
119
+ EcoImage({
120
+ ...myImage,
121
+ width: 800,
122
+ height: 600,
123
+ alt: 'My image',
124
+ });
125
+
126
+ // Advanced usage
127
+ EcoImage({
128
+ ...myImage,
129
+ alt: 'My image',
130
+ layout: 'constrained',
131
+ priority: true,
132
+ aspectRatio: '16/9',
133
+ staticVariant: 'xl',
134
+ });
135
+ ```
136
+
137
+ ### React Component
138
+
139
+ ```jsx
140
+ import { EcoImage } from "@ecopages/image-processor/component/react";
141
+
142
+ // Basic usage
143
+ <EcoImage
144
+ {...myImage}
145
+ alt="My image"
146
+ />
147
+
148
+ // Advanced usage
149
+ <EcoImage
150
+ {...myImage}
151
+ alt="My image"
152
+ layout="constrained"
153
+ priority
154
+ aspectRatio="16/9"
155
+ staticVariant="xl"
156
+ />
157
+ ```
158
+
159
+ ### Component Props
160
+
161
+ The component accepts all standard HTML/React image attributes (`src`, `alt`, `data-*`, `crossOrigin`, etc.) in addition to the following specific props:
162
+
163
+ | Prop | Type | Default | Description |
164
+ | --------------- | ------------------------------------------ | ------------------- | -------------------------------------------- |
165
+ | `width` | `number` | From image metadata | Original width, can be overridden if needed |
166
+ | `height` | `number` | From image metadata | Original height, can be overridden if needed |
167
+ | `priority` | `boolean` | `false` | Prioritize loading |
168
+ | `layout` | `'fixed' \| 'constrained' \| 'full-width'` | `'constrained'` | Layout behavior |
169
+ | `staticVariant` | `string` | - | Force specific size variant |
170
+ | `aspectRatio` | `string` | From width/height | Override the natural aspect ratio |
171
+ | `unstyled` | `boolean` | `false` | Disable default styling |
172
+
173
+ Note: Images imported through `ecopages:images` automatically include their width and height metadata, preventing layout shifts by default. These values can be overridden when needed, for example when using a different aspect ratio or specific layout requirements.
174
+
175
+ ## Layout Modes
176
+
177
+ ### Fixed Layout
178
+
179
+ ```typescript
180
+ EcoImage({
181
+ ...myImage,
182
+ layout: 'fixed',
183
+ width: 400,
184
+ height: 300,
185
+ alt: 'Fixed image',
186
+ });
187
+ ```
188
+
189
+ ### Constrained Layout
190
+
191
+ ```typescript
192
+ EcoImage({
193
+ ...myImage,
194
+ layout: 'constrained',
195
+ width: 800,
196
+ alt: 'Constrained image',
197
+ });
198
+ ```
199
+
200
+ ### Full-Width Layout
201
+
202
+ ```typescript
203
+ EcoImage({
204
+ ...myImage,
205
+ layout: 'full-width',
206
+ alt: 'Full-width image',
207
+ });
208
+ ```
209
+
210
+ ## Best Practices
211
+
212
+ 1. Always provide `alt` text for accessibility
213
+ 2. Use `priority` for above-the-fold images
214
+ 3. Always specify both `width` and `height` to prevent layout shifts
215
+ 4. Use `aspectRatio` only when you need to force a different aspect ratio than width/height
216
+ 5. Choose appropriate `layout` modes based on your needs
217
+ 6. Utilize the virtual module for type-safe image imports
218
+ 7. Configure size variants that match your breakpoints
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@ecopages/image-processor",
3
+ "version": "0.2.0-alpha.1",
4
+ "description": "Image processor, transform and optimize images for web",
5
+ "keywords": [
6
+ "image",
7
+ "processor"
8
+ ],
9
+ "license": "MIT",
10
+ "main": "./src/image-processor.js",
11
+ "type": "module",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/ecopages/ecopages.git",
15
+ "directory": "packages/processors/image-processor"
16
+ },
17
+ "peerDependencies": {
18
+ "@ecopages/core": "0.2.0-alpha.1"
19
+ },
20
+ "dependencies": {
21
+ "@ecopages/file-system": "0.2.0-alpha.1",
22
+ "@ecopages/logger": "latest",
23
+ "react": "^19",
24
+ "react-dom": "^19",
25
+ "sharp": "^0.33.5"
26
+ },
27
+ "exports": {
28
+ ".": {
29
+ "default": "./src/index.js",
30
+ "types": "./src/index.d.ts"
31
+ },
32
+ "./types": {
33
+ "types": "./src/types.d.ts"
34
+ },
35
+ "./component/html": {
36
+ "default": "./src/component/html.js",
37
+ "types": "./src/component/html.d.ts"
38
+ },
39
+ "./component/react": {
40
+ "default": "./src/component/react.js",
41
+ "types": "./src/component/react.d.ts"
42
+ },
43
+ "./types.ts": {
44
+ "types": "./src/types.d.ts"
45
+ },
46
+ "./component/html.ts": {
47
+ "default": "./src/component/html.js",
48
+ "types": "./src/component/html.d.ts"
49
+ },
50
+ "./component/react.ts": {
51
+ "default": "./src/component/react.js",
52
+ "types": "./src/component/react.d.ts"
53
+ }
54
+ },
55
+ "typesVersions": {
56
+ "*": {
57
+ "ecopages:images": [
58
+ "./virtual-module.d.ts"
59
+ ]
60
+ }
61
+ },
62
+ "types": "./src/index.d.ts"
63
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * This file contains the plugins for bundling the image specifications.
3
+ * @module @ecopages/image-processor/bun-plugins
4
+ */
5
+ import type { EcoBuildPlugin } from '@ecopages/core/build/build-types';
6
+ import type { ImageMap } from './plugin';
7
+ /**
8
+ * This function creates a plugin for bundling the image specifications.
9
+ * https://bun.sh/docs/runtime/plugins#virtual-modules
10
+ * @param exports
11
+ * @returns
12
+ */
13
+ export declare function createImagePlugin(exports: ImageMap): EcoBuildPlugin;
14
+ /**
15
+ * This function creates a plugin for bundling the image specifications.
16
+ * Due to some limitations in the bundler, we need to use a different approach.
17
+ * https://bun.sh/docs/runtime/plugins#virtual-modules > bun-v1.2.5
18
+ * (This feature is currently only available at runtime with Bun.plugin and not yet supported in the bundler, but you can mimic the behavior using onResolve and onLoad.)
19
+ * @param exports
20
+ * @returns
21
+ */
22
+ export declare function createImagePluginBundler(exports: ImageMap): EcoBuildPlugin;
@@ -0,0 +1,33 @@
1
+ import { anyCaseToCamelCase } from "./utils";
2
+ function createPluginResult(exports) {
3
+ return {
4
+ contents: `${Object.entries(exports).map(([key, value]) => `export const ${anyCaseToCamelCase(key)} = ${JSON.stringify(value)};`).join("\n")}`,
5
+ loader: "ts"
6
+ };
7
+ }
8
+ function createImagePlugin(exports) {
9
+ return {
10
+ name: "ecopages:images",
11
+ setup(build) {
12
+ build.module("ecopages:images", () => createPluginResult(exports));
13
+ }
14
+ };
15
+ }
16
+ function createImagePluginBundler(exports) {
17
+ return {
18
+ name: "ecopages:images",
19
+ setup(build) {
20
+ build.onResolve({ filter: /^ecopages:images$/ }, () => {
21
+ return {
22
+ namespace: "ecopages-images",
23
+ path: "ecopages:images"
24
+ };
25
+ });
26
+ build.onLoad({ filter: /.*/, namespace: "ecopages-images" }, () => createPluginResult(exports));
27
+ }
28
+ };
29
+ }
30
+ export {
31
+ createImagePlugin,
32
+ createImagePluginBundler
33
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * This file contains the plugins for bundling the image specifications.
3
+ * @module @ecopages/image-processor/bun-plugins
4
+ */
5
+
6
+ import type { EcoBuildOnLoadResult, EcoBuildPlugin } from '@ecopages/core/build/build-types';
7
+ import type { ImageMap } from './plugin';
8
+ import { anyCaseToCamelCase } from './utils';
9
+
10
+ /**
11
+ * This function creates the plugin result for the image specifications.
12
+ */
13
+ function createPluginResult(exports: ImageMap): EcoBuildOnLoadResult {
14
+ return {
15
+ contents: `${Object.entries(exports)
16
+ .map(([key, value]) => `export const ${anyCaseToCamelCase(key)} = ${JSON.stringify(value)};`)
17
+ .join('\n')}`,
18
+ loader: 'ts',
19
+ };
20
+ }
21
+
22
+ /**
23
+ * This function creates a plugin for bundling the image specifications.
24
+ * https://bun.sh/docs/runtime/plugins#virtual-modules
25
+ * @param exports
26
+ * @returns
27
+ */
28
+ export function createImagePlugin(exports: ImageMap): EcoBuildPlugin {
29
+ return {
30
+ name: 'ecopages:images',
31
+ setup(build) {
32
+ build.module('ecopages:images', () => createPluginResult(exports));
33
+ },
34
+ };
35
+ }
36
+
37
+ /**
38
+ * This function creates a plugin for bundling the image specifications.
39
+ * Due to some limitations in the bundler, we need to use a different approach.
40
+ * https://bun.sh/docs/runtime/plugins#virtual-modules > bun-v1.2.5
41
+ * (This feature is currently only available at runtime with Bun.plugin and not yet supported in the bundler, but you can mimic the behavior using onResolve and onLoad.)
42
+ * @param exports
43
+ * @returns
44
+ */
45
+ export function createImagePluginBundler(exports: ImageMap): EcoBuildPlugin {
46
+ return {
47
+ name: 'ecopages:images',
48
+ setup(build) {
49
+ build.onResolve({ filter: /^ecopages:images$/ }, () => {
50
+ return {
51
+ namespace: 'ecopages-images',
52
+ path: 'ecopages:images',
53
+ };
54
+ });
55
+
56
+ build.onLoad({ filter: /.*/, namespace: 'ecopages-images' }, () => createPluginResult(exports));
57
+ },
58
+ };
59
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Image component that renders the image as a string.
3
+ * @module @ecopages/image-processor/component/html
4
+ */
5
+ import { type EcoImageProps } from '../image-renderer';
6
+ /**
7
+ * EcoImage
8
+ * This component generates the image element based on the provided props as a string
9
+ * @param props {@link EcoImageProps}
10
+ */
11
+ export declare const EcoImage: (props: EcoImageProps) => string;
@@ -0,0 +1,7 @@
1
+ import { renderer } from "../image-renderer";
2
+ const EcoImage = (props) => {
3
+ return renderer.renderToString(props);
4
+ };
5
+ export {
6
+ EcoImage
7
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Image component that renders the image as a string.
3
+ * @module @ecopages/image-processor/component/html
4
+ */
5
+
6
+ import { type EcoImageProps, renderer } from '../image-renderer';
7
+
8
+ /**
9
+ * EcoImage
10
+ * This component generates the image element based on the provided props as a string
11
+ * @param props {@link EcoImageProps}
12
+ */
13
+ export const EcoImage = (props: EcoImageProps): string => {
14
+ return renderer.renderToString(props);
15
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Image component that renders the image as a string.
3
+ * @module @ecopages/image-processor/component/react
4
+ */
5
+ import { type JSX } from 'react';
6
+ import { type EcoImageProps } from '../image-renderer';
7
+ /**
8
+ * EcoImage
9
+ * This component generates the image element based on the provided props as JSX
10
+ * @param props {@link EcoImageProps}
11
+ * @returns
12
+ */
13
+ export declare const EcoImage: (props: EcoImageProps) => JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { createElement } from "react";
2
+ import { renderer } from "../image-renderer";
3
+ const EcoImage = (props) => {
4
+ return createElement("img", {
5
+ ...renderer.generateAttributesJsx(props),
6
+ suppressHydrationWarning: true
7
+ });
8
+ };
9
+ export {
10
+ EcoImage
11
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Image component that renders the image as a string.
3
+ * @module @ecopages/image-processor/component/react
4
+ */
5
+
6
+ import { createElement, type JSX } from 'react';
7
+ import { type EcoImageProps, renderer } from '../image-renderer';
8
+
9
+ /**
10
+ * EcoImage
11
+ * This component generates the image element based on the provided props as JSX
12
+ * @param props {@link EcoImageProps}
13
+ * @returns
14
+ */
15
+ export const EcoImage = (props: EcoImageProps): JSX.Element => {
16
+ return createElement('img', {
17
+ ...renderer.generateAttributesJsx(props),
18
+ suppressHydrationWarning: true,
19
+ });
20
+ };
@@ -0,0 +1,6 @@
1
+ import type { ImageLayout } from './image-renderer';
2
+ /**
3
+ * Default image layout
4
+ * @constant "constrained"
5
+ */
6
+ export declare const DEFAULT_LAYOUT: ImageLayout;
@@ -0,0 +1,4 @@
1
+ const DEFAULT_LAYOUT = "constrained";
2
+ export {
3
+ DEFAULT_LAYOUT
4
+ };
@@ -0,0 +1,7 @@
1
+ import type { ImageLayout } from './image-renderer';
2
+
3
+ /**
4
+ * Default image layout
5
+ * @constant "constrained"
6
+ */
7
+ export const DEFAULT_LAYOUT: ImageLayout = 'constrained';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * This file contains the plugins for bundling the image specifications.
3
+ * @module @ecopages/image-processor/image-plugins
4
+ */
5
+ import type { EcoBuildPlugin } from '@ecopages/core/build/build-types';
6
+ import type { ImageMap } from './plugin';
7
+ /**
8
+ * This function creates a plugin for bundling the image specifications.
9
+ * https://bun.sh/docs/runtime/plugins#virtual-modules
10
+ * @param exports
11
+ * @returns
12
+ */
13
+ export declare function createImagePlugin(exports: ImageMap): EcoBuildPlugin;
14
+ /**
15
+ * This function creates a plugin for bundling the image specifications.
16
+ * Due to some limitations in the bundler, we need to use a different approach.
17
+ * https://bun.sh/docs/runtime/plugins#virtual-modules > bun-v1.2.5
18
+ * (This feature is currently only available at runtime with Bun.plugin and not yet supported in the bundler, but you can mimic the behavior using onResolve and onLoad.)
19
+ * @param exports
20
+ * @returns
21
+ */
22
+ export declare function createImagePluginBundler(exports: ImageMap): EcoBuildPlugin;
@@ -0,0 +1,33 @@
1
+ import { anyCaseToCamelCase } from "./utils";
2
+ function createPluginResult(exports) {
3
+ return {
4
+ contents: `${Object.entries(exports).map(([key, value]) => `export const ${anyCaseToCamelCase(key)} = ${JSON.stringify(value)};`).join("\n")}`,
5
+ loader: "ts"
6
+ };
7
+ }
8
+ function createImagePlugin(exports) {
9
+ return {
10
+ name: "ecopages:images",
11
+ setup(build) {
12
+ build.module("ecopages:images", () => createPluginResult(exports));
13
+ }
14
+ };
15
+ }
16
+ function createImagePluginBundler(exports) {
17
+ return {
18
+ name: "ecopages:images",
19
+ setup(build) {
20
+ build.onResolve({ filter: /^ecopages:images$/ }, () => {
21
+ return {
22
+ namespace: "ecopages-images",
23
+ path: "ecopages:images"
24
+ };
25
+ });
26
+ build.onLoad({ filter: /.*/, namespace: "ecopages-images" }, () => createPluginResult(exports));
27
+ }
28
+ };
29
+ }
30
+ export {
31
+ createImagePlugin,
32
+ createImagePluginBundler
33
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * This file contains the plugins for bundling the image specifications.
3
+ * @module @ecopages/image-processor/image-plugins
4
+ */
5
+
6
+ import type { EcoBuildOnLoadResult, EcoBuildPlugin } from '@ecopages/core/build/build-types';
7
+ import type { ImageMap } from './plugin';
8
+ import { anyCaseToCamelCase } from './utils';
9
+
10
+ /**
11
+ * This function creates the plugin result for the image specifications.
12
+ */
13
+ function createPluginResult(exports: ImageMap): EcoBuildOnLoadResult {
14
+ return {
15
+ contents: `${Object.entries(exports)
16
+ .map(([key, value]) => `export const ${anyCaseToCamelCase(key)} = ${JSON.stringify(value)};`)
17
+ .join('\n')}`,
18
+ loader: 'ts',
19
+ };
20
+ }
21
+
22
+ /**
23
+ * This function creates a plugin for bundling the image specifications.
24
+ * https://bun.sh/docs/runtime/plugins#virtual-modules
25
+ * @param exports
26
+ * @returns
27
+ */
28
+ export function createImagePlugin(exports: ImageMap): EcoBuildPlugin {
29
+ return {
30
+ name: 'ecopages:images',
31
+ setup(build) {
32
+ build.module('ecopages:images', () => createPluginResult(exports));
33
+ },
34
+ };
35
+ }
36
+
37
+ /**
38
+ * This function creates a plugin for bundling the image specifications.
39
+ * Due to some limitations in the bundler, we need to use a different approach.
40
+ * https://bun.sh/docs/runtime/plugins#virtual-modules > bun-v1.2.5
41
+ * (This feature is currently only available at runtime with Bun.plugin and not yet supported in the bundler, but you can mimic the behavior using onResolve and onLoad.)
42
+ * @param exports
43
+ * @returns
44
+ */
45
+ export function createImagePluginBundler(exports: ImageMap): EcoBuildPlugin {
46
+ return {
47
+ name: 'ecopages:images',
48
+ setup(build) {
49
+ build.onResolve({ filter: /^ecopages:images$/ }, () => {
50
+ return {
51
+ namespace: 'ecopages-images',
52
+ path: 'ecopages:images',
53
+ };
54
+ });
55
+
56
+ build.onLoad({ filter: /.*/, namespace: 'ecopages-images' }, () => createPluginResult(exports));
57
+ },
58
+ };
59
+ }