Skip to content

Commit 7ba36a4

Browse files
committed
feat(image-loader): enhance typings and update dependencies
Refined type definitions by aligning `ImageLoaderProps` with Next.js types for consistency and reusability. Added a new `Dependencies` section in the README to document external dependencies. Improved loader implementation by simplifying parameter handling and updated the factory class with additional utility methods.
1 parent 33639d4 commit 7ba36a4

File tree

5 files changed

+85
-60
lines changed

5 files changed

+85
-60
lines changed

apps/docs/src/lib/image-loader.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ const imageLoaderFactory = createDefaultImageLoaderFactory();
1616
* @returns Transformed image URL optimized for the detected CDN
1717
*/
1818
export function imageLoader(params: ImageLoaderProps): string {
19-
return imageLoaderFactory.load({
20-
quality: params.quality,
21-
src: params.src,
22-
width: params.width,
23-
});
19+
return imageLoaderFactory.load(params);
2420
}
2521

2622
// Export the factory instance as default for convenience

packages/eslint-config/src/core/javascript.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,6 @@ export const baseJavaScriptRules: Linter.Config[] = [
3232
"no-useless-return": "error",
3333
"no-var": "error",
3434
"object-shorthand": "error",
35-
"prefer-arrow-callback": "error",
36-
"prefer-const": "error",
37-
"prefer-destructuring": ["error", { array: false, object: true }],
38-
"prefer-exponentiation-operator": "error",
39-
"prefer-numeric-literals": "error",
40-
"prefer-object-spread": "error",
41-
"prefer-rest-params": "error",
42-
"prefer-spread": "error",
43-
"prefer-template": "error",
44-
radix: "error",
45-
yoda: "error",
46-
47-
// Spacing rules
4835
"padding-line-between-statements": [
4936
"error",
5037

@@ -86,6 +73,17 @@ export const baseJavaScriptRules: Linter.Config[] = [
8673
prev: "*",
8774
},
8875
],
76+
"prefer-arrow-callback": "error",
77+
"prefer-const": "error",
78+
"prefer-destructuring": ["error", { array: false, object: true }],
79+
"prefer-exponentiation-operator": "error",
80+
"prefer-numeric-literals": "error",
81+
"prefer-object-spread": "error",
82+
"prefer-rest-params": "error",
83+
"prefer-spread": "error",
84+
"prefer-template": "error",
85+
radix: "error",
86+
yoda: "error",
8987
},
9088
},
9189
];

packages/image-loader/README.md

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ npm install @codefast/image-loader
3434
yarn add @codefast/image-loader
3535
```
3636

37+
### Dependencies
38+
39+
This package has the following dependencies:
40+
- `query-string`: ^7.1.3 (for URL parameter manipulation)
41+
3742
### Peer Dependencies
3843

3944
This package requires Next.js 15.4.1 or higher:
@@ -57,11 +62,7 @@ const imageLoaderFactory = createDefaultImageLoaderFactory();
5762

5863
// Export Next.js compatible loader function
5964
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);
6566
}
6667

6768
export default imageLoader;
@@ -129,25 +130,21 @@ export function MyComponent() {
129130
### Core Types
130131

131132
```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";
143135

144136
interface ImageLoader {
145-
load(config: ImageLoaderConfig): string;
146-
147-
canHandle(src: string): boolean;
148-
137+
load(config: ImageLoaderProps): string;
138+
canHandle(source: string): boolean;
149139
getName(): string;
150140
}
141+
142+
interface ImageLoaderFactoryConfig {
143+
defaultQuality?: number;
144+
domainMappings?: Record<string, string>;
145+
}
146+
147+
type CDNProvider = "aws-cloudfront" | "cloudinary" | "imgix" | "supabase" | "unsplash";
151148
```
152149

153150
### ImageLoaderFactory
@@ -170,12 +167,43 @@ const factory = new ImageLoaderFactory({
170167
- `registerLoader(loader: ImageLoader)` - Register a new loader
171168
- `registerLoaders(loaders: ImageLoader[])` - Register multiple loaders
172169
- `unregisterLoader(name: string)` - Remove a loader by name
170+
- `getLoaders()` - Get all registered loaders
173171
- `findLoader(src: string)` - Find appropriate loader for URL
174-
- `load(config: ImageLoaderConfig)` - Transform image URL
172+
- `load(config: ImageLoaderProps)` - Transform image URL
175173
- `createNextImageLoader()` - Create Next.js compatible function
176174
- `getStats()` - Get factory statistics
177175
- `clear()` - Remove all loaders
178176

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+
179207
### Individual Loaders
180208

181209
Each CDN provider has its own loader class:
@@ -241,18 +269,18 @@ factory.registerLoaders([new UnsplashLoader({ defaultQuality: 85 }), new Cloudin
241269

242270
```typescript
243271
import { BaseImageLoader } from "@codefast/image-loader";
244-
import type { ImageLoaderConfig } from "@codefast/image-loader";
272+
import type { ImageLoaderProps } from "next/image";
245273

246274
class MyCustomLoader extends BaseImageLoader {
247275
public getName(): string {
248276
return "my-custom-cdn";
249277
}
250278

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";
253281
}
254282

255-
protected transformUrl(config: ImageLoaderConfig): string {
283+
protected transformUrl(config: ImageLoaderProps): string {
256284
const { src, width, quality } = config;
257285

258286
try {
@@ -579,12 +607,24 @@ export class MyCDNLoader extends BaseImageLoader {
579607
return MyCDNLoader.NAME;
580608
}
581609

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;
584612
}
585613

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+
}
588628
}
589629
}
590630
```

packages/image-loader/src/loader-factory.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ export class ImageLoaderFactory {
3232
* Registers multiple image loaders at once
3333
*/
3434
public registerLoaders(loaders: ImageLoader[]): void {
35-
for (const loader of loaders) this.registerLoader(loader);
35+
for (const loader of loaders) {
36+
this.registerLoader(loader);
37+
}
3638
}
3739

3840
/**

packages/image-loader/src/types.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,11 @@ export interface ImageLoaderFactoryConfig {
3838

3939
/**
4040
* Supported CDN providers
41+
* These are the CDN providers that have actual loader implementations
4142
*/
4243
export type CDNProvider =
43-
| "akamai"
4444
| "aws-cloudfront"
45-
| "cloudflare"
4645
| "cloudinary"
47-
| "contentful"
48-
| "fastly"
49-
| "gumlet"
50-
| "imageengine"
51-
| "imagekit"
5246
| "imgix"
53-
| "nitrogen-aio"
54-
| "pixelbin"
55-
| "sanity"
56-
| "sirv"
5747
| "supabase"
58-
| "thumbor"
5948
| "unsplash";

0 commit comments

Comments
 (0)