@@ -34,6 +34,11 @@ npm install @codefast/image-loader
34
34
yarn add @codefast/image-loader
35
35
```
36
36
37
+ ### Dependencies
38
+
39
+ This package has the following dependencies:
40
+ - ` query-string ` : ^7.1.3 (for URL parameter manipulation)
41
+
37
42
### Peer Dependencies
38
43
39
44
This package requires Next.js 15.4.1 or higher:
@@ -57,11 +62,7 @@ const imageLoaderFactory = createDefaultImageLoaderFactory();
57
62
58
63
// Export Next.js compatible loader function
59
64
export function imageLoader(params : ImageLoaderProps ): string {
60
- return imageLoaderFactory .load ({
61
- src: params .src ,
62
- width: params .width ,
63
- quality: params .quality ,
64
- });
65
+ return imageLoaderFactory .load (params );
65
66
}
66
67
67
68
export default imageLoader ;
@@ -129,25 +130,21 @@ export function MyComponent() {
129
130
### Core Types
130
131
131
132
``` typescript
132
- interface ImageLoaderProps {
133
- src: string ;
134
- width: number ;
135
- quality? : number ;
136
- }
137
-
138
- interface ImageLoaderConfig {
139
- src: string ;
140
- width: number ;
141
- quality? : number ;
142
- }
133
+ // Uses Next.js ImageLoaderProps directly
134
+ import type { ImageLoaderProps } from " next/image" ;
143
135
144
136
interface ImageLoader {
145
- load(config : ImageLoaderConfig ): string ;
146
-
147
- canHandle(src : string ): boolean ;
148
-
137
+ load(config : ImageLoaderProps ): string ;
138
+ canHandle(source : string ): boolean ;
149
139
getName(): string ;
150
140
}
141
+
142
+ interface ImageLoaderFactoryConfig {
143
+ defaultQuality? : number ;
144
+ domainMappings? : Record <string , string >;
145
+ }
146
+
147
+ type CDNProvider = " aws-cloudfront" | " cloudinary" | " imgix" | " supabase" | " unsplash" ;
151
148
```
152
149
153
150
### ImageLoaderFactory
@@ -170,12 +167,43 @@ const factory = new ImageLoaderFactory({
170
167
- ` registerLoader(loader: ImageLoader) ` - Register a new loader
171
168
- ` registerLoaders(loaders: ImageLoader[]) ` - Register multiple loaders
172
169
- ` unregisterLoader(name: string) ` - Remove a loader by name
170
+ - ` getLoaders() ` - Get all registered loaders
173
171
- ` findLoader(src: string) ` - Find appropriate loader for URL
174
- - ` load(config: ImageLoaderConfig ) ` - Transform image URL
172
+ - ` load(config: ImageLoaderProps ) ` - Transform image URL
175
173
- ` createNextImageLoader() ` - Create Next.js compatible function
176
174
- ` getStats() ` - Get factory statistics
177
175
- ` clear() ` - Remove all loaders
178
176
177
+ ### BaseImageLoader
178
+
179
+ Abstract base class for creating custom loaders:
180
+
181
+ ``` typescript
182
+ import { BaseImageLoader } from " @codefast/image-loader" ;
183
+ import type { ImageLoaderProps } from " next/image" ;
184
+
185
+ class MyCustomLoader extends BaseImageLoader {
186
+ constructor (config ? : { defaultQuality? : number }) {
187
+ super (config );
188
+ }
189
+
190
+ public getName(): string {
191
+ return " my-custom-loader" ;
192
+ }
193
+
194
+ public canHandle(source : string ): boolean {
195
+ return this .extractDomain (source ) === " cdn.example.com" ;
196
+ }
197
+
198
+ protected transformUrl(config : ImageLoaderProps ): string {
199
+ // Your transformation logic here
200
+ const { src, width, quality } = config ;
201
+ // Use utility methods like this.buildQueryParams() if needed
202
+ return src ; // Return transformed URL
203
+ }
204
+ }
205
+ ```
206
+
179
207
### Individual Loaders
180
208
181
209
Each CDN provider has its own loader class:
@@ -241,18 +269,18 @@ factory.registerLoaders([new UnsplashLoader({ defaultQuality: 85 }), new Cloudin
241
269
242
270
``` typescript
243
271
import { BaseImageLoader } from " @codefast/image-loader" ;
244
- import type { ImageLoaderConfig } from " @codefast /image-loader " ;
272
+ import type { ImageLoaderProps } from " next /image" ;
245
273
246
274
class MyCustomLoader extends BaseImageLoader {
247
275
public getName(): string {
248
276
return " my-custom-cdn" ;
249
277
}
250
278
251
- public canHandle(src : string ): boolean {
252
- return this .extractDomain (src ) === " cdn.mysite.com" ;
279
+ public canHandle(source : string ): boolean {
280
+ return this .extractDomain (source ) === " cdn.mysite.com" ;
253
281
}
254
282
255
- protected transformUrl(config : ImageLoaderConfig ): string {
283
+ protected transformUrl(config : ImageLoaderProps ): string {
256
284
const { src, width, quality } = config ;
257
285
258
286
try {
@@ -579,12 +607,24 @@ export class MyCDNLoader extends BaseImageLoader {
579
607
return MyCDNLoader .NAME ;
580
608
}
581
609
582
- public canHandle(src : string ): boolean {
583
- return this .extractDomain (src ) === MyCDNLoader .DOMAIN ;
610
+ public canHandle(source : string ): boolean {
611
+ return this .extractDomain (source ) === MyCDNLoader .DOMAIN ;
584
612
}
585
613
586
- protected transformUrl(config : ImageLoaderConfig ): string {
587
- // Implementation here
614
+ protected transformUrl(config : ImageLoaderProps ): string {
615
+ const { src, width, quality } = config ;
616
+
617
+ try {
618
+ const url = new URL (src );
619
+ url .searchParams .set (" w" , String (width ));
620
+ if (quality ) {
621
+ url .searchParams .set (" q" , String (quality ));
622
+ }
623
+ return url .toString ();
624
+ } catch (error ) {
625
+ console .warn (` Failed to transform URL: ${src } ` , error );
626
+ return src ;
627
+ }
588
628
}
589
629
}
590
630
```
0 commit comments