@netlify/dev 4.1.4 → 4.2.0
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/README.md +2 -2
- package/dist/main.cjs +23 -9
- package/dist/main.d.cts +9 -1
- package/dist/main.d.ts +9 -1
- package/dist/main.js +24 -17
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ users, it is primarily designed as a foundational library for higher-level tools
|
|
|
8
8
|
[Netlify Vite Plugin](https://docs.netlify.com/integrations/vite/overview/).
|
|
9
9
|
|
|
10
10
|
It provides a local request pipeline that mimics the Netlify platform’s request handling, including support for
|
|
11
|
-
Functions, Blobs, Static files, and
|
|
11
|
+
Functions, Blobs, Static files, Redirects, and Image CDN.
|
|
12
12
|
|
|
13
13
|
## 🚧 Feature Support
|
|
14
14
|
|
|
@@ -21,7 +21,7 @@ Functions, Blobs, Static files, and Redirects.
|
|
|
21
21
|
| Redirects and Rewrites | ✅ Yes |
|
|
22
22
|
| Headers | ✅ Yes |
|
|
23
23
|
| Environment Variables | ✅ Yes |
|
|
24
|
-
| Image CDN |
|
|
24
|
+
| Image CDN | ✅ Yes |
|
|
25
25
|
|
|
26
26
|
> Note: Missing features will be added incrementally. This module is **not** intended to be a full replacement for the
|
|
27
27
|
> Netlify CLI.
|
package/dist/main.cjs
CHANGED
|
@@ -41,6 +41,7 @@ var import_dev_utils = require("@netlify/dev-utils");
|
|
|
41
41
|
var import_dev = require("@netlify/edge-functions/dev");
|
|
42
42
|
var import_dev2 = require("@netlify/functions/dev");
|
|
43
43
|
var import_headers = require("@netlify/headers");
|
|
44
|
+
var import_images = require("@netlify/images");
|
|
44
45
|
var import_redirects = require("@netlify/redirects");
|
|
45
46
|
var import_static = require("@netlify/static");
|
|
46
47
|
|
|
@@ -314,6 +315,7 @@ var NetlifyDev = class {
|
|
|
314
315
|
#config;
|
|
315
316
|
#features;
|
|
316
317
|
#headersHandler;
|
|
318
|
+
#imageHandler;
|
|
317
319
|
#logger;
|
|
318
320
|
#projectRoot;
|
|
319
321
|
#redirectsHandler;
|
|
@@ -336,6 +338,7 @@ var NetlifyDev = class {
|
|
|
336
338
|
environmentVariables: options.environmentVariables?.enabled !== false,
|
|
337
339
|
functions: options.functions?.enabled !== false,
|
|
338
340
|
headers: options.headers?.enabled !== false,
|
|
341
|
+
images: options.images?.enabled !== false,
|
|
339
342
|
redirects: options.redirects?.enabled !== false,
|
|
340
343
|
static: options.staticFiles?.enabled !== false
|
|
341
344
|
};
|
|
@@ -366,6 +369,11 @@ var NetlifyDev = class {
|
|
|
366
369
|
type: "edge-function"
|
|
367
370
|
};
|
|
368
371
|
}
|
|
372
|
+
const imageMatch = this.#imageHandler?.match(readRequest);
|
|
373
|
+
if (imageMatch) {
|
|
374
|
+
const response = await imageMatch.handle();
|
|
375
|
+
return { response, type: "image" };
|
|
376
|
+
}
|
|
369
377
|
const functionMatch = await this.#functionsHandler?.match(readRequest, destPath);
|
|
370
378
|
if (functionMatch) {
|
|
371
379
|
if (functionMatch.preferStatic) {
|
|
@@ -380,7 +388,13 @@ var NetlifyDev = class {
|
|
|
380
388
|
}
|
|
381
389
|
const redirectMatch = await this.#redirectsHandler?.match(readRequest);
|
|
382
390
|
if (redirectMatch) {
|
|
383
|
-
const
|
|
391
|
+
const redirectRequest = new Request(redirectMatch.target);
|
|
392
|
+
const imageMatch2 = this.#imageHandler?.match(redirectRequest);
|
|
393
|
+
if (imageMatch2) {
|
|
394
|
+
const response2 = await imageMatch2.handle();
|
|
395
|
+
return { response: response2, type: "image" };
|
|
396
|
+
}
|
|
397
|
+
const functionMatch2 = await this.#functionsHandler?.match(redirectRequest, destPath);
|
|
384
398
|
if (functionMatch2 && !functionMatch2.preferStatic) {
|
|
385
399
|
return {
|
|
386
400
|
response: await functionMatch2.handle(getWriteRequest()),
|
|
@@ -406,13 +420,6 @@ var NetlifyDev = class {
|
|
|
406
420
|
return { response, type: "redirect" };
|
|
407
421
|
}
|
|
408
422
|
}
|
|
409
|
-
const { pathname } = new URL(readRequest.url);
|
|
410
|
-
if (pathname.startsWith("/.netlify/images")) {
|
|
411
|
-
this.#logger.error(
|
|
412
|
-
`The Netlify Image CDN is currently only supported in the Netlify CLI. Run ${(0, import_dev_utils.netlifyCommand)("npx netlify dev")} to get started.`
|
|
413
|
-
);
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
423
|
const staticMatch = await this.#staticHandler?.match(readRequest);
|
|
417
424
|
if (staticMatch) {
|
|
418
425
|
const response = await staticMatch.handle();
|
|
@@ -506,7 +513,7 @@ var NetlifyDev = class {
|
|
|
506
513
|
let serverAddress;
|
|
507
514
|
if (typeof this.#server === "string") {
|
|
508
515
|
serverAddress = this.#server;
|
|
509
|
-
} else if (this.#features.edgeFunctions) {
|
|
516
|
+
} else if (this.#features.edgeFunctions || this.#features.images) {
|
|
510
517
|
const passthroughServer = new import_dev_utils.HTTPServer(async (req) => {
|
|
511
518
|
const res = await this.handle(req);
|
|
512
519
|
return res ?? new Response(null, { status: 404 });
|
|
@@ -586,6 +593,13 @@ var NetlifyDev = class {
|
|
|
586
593
|
]
|
|
587
594
|
});
|
|
588
595
|
}
|
|
596
|
+
if (this.#features.images) {
|
|
597
|
+
this.#imageHandler = new import_images.ImageHandler({
|
|
598
|
+
imagesConfig: this.#config?.config.images,
|
|
599
|
+
logger: this.#logger,
|
|
600
|
+
originServerAddress: serverAddress
|
|
601
|
+
});
|
|
602
|
+
}
|
|
589
603
|
return {
|
|
590
604
|
serverAddress
|
|
591
605
|
};
|
package/dist/main.d.cts
CHANGED
|
@@ -43,6 +43,14 @@ interface Features {
|
|
|
43
43
|
headers?: {
|
|
44
44
|
enabled?: boolean;
|
|
45
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* Configuration options for Netlify Image CDN.
|
|
48
|
+
*
|
|
49
|
+
* {@link} https://docs.netlify.com/image-cdn/overview/
|
|
50
|
+
*/
|
|
51
|
+
images?: {
|
|
52
|
+
enabled?: boolean;
|
|
53
|
+
};
|
|
46
54
|
/**
|
|
47
55
|
* Configuration options for Netlify redirects and rewrites.
|
|
48
56
|
*
|
|
@@ -83,7 +91,7 @@ interface HandleOptions {
|
|
|
83
91
|
*/
|
|
84
92
|
headersCollector?: HeadersCollector;
|
|
85
93
|
}
|
|
86
|
-
type ResponseType = 'edge-function' | 'function' | 'redirect' | 'static';
|
|
94
|
+
type ResponseType = 'edge-function' | 'function' | 'image' | 'redirect' | 'static';
|
|
87
95
|
declare class NetlifyDev {
|
|
88
96
|
#private;
|
|
89
97
|
constructor(options: NetlifyDevOptions);
|
package/dist/main.d.ts
CHANGED
|
@@ -43,6 +43,14 @@ interface Features {
|
|
|
43
43
|
headers?: {
|
|
44
44
|
enabled?: boolean;
|
|
45
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* Configuration options for Netlify Image CDN.
|
|
48
|
+
*
|
|
49
|
+
* {@link} https://docs.netlify.com/image-cdn/overview/
|
|
50
|
+
*/
|
|
51
|
+
images?: {
|
|
52
|
+
enabled?: boolean;
|
|
53
|
+
};
|
|
46
54
|
/**
|
|
47
55
|
* Configuration options for Netlify redirects and rewrites.
|
|
48
56
|
*
|
|
@@ -83,7 +91,7 @@ interface HandleOptions {
|
|
|
83
91
|
*/
|
|
84
92
|
headersCollector?: HeadersCollector;
|
|
85
93
|
}
|
|
86
|
-
type ResponseType = 'edge-function' | 'function' | 'redirect' | 'static';
|
|
94
|
+
type ResponseType = 'edge-function' | 'function' | 'image' | 'redirect' | 'static';
|
|
87
95
|
declare class NetlifyDev {
|
|
88
96
|
#private;
|
|
89
97
|
constructor(options: NetlifyDevOptions);
|
package/dist/main.js
CHANGED
|
@@ -3,17 +3,11 @@ import { promises as fs2 } from "fs";
|
|
|
3
3
|
import path2 from "path";
|
|
4
4
|
import process2 from "process";
|
|
5
5
|
import { resolveConfig } from "@netlify/config";
|
|
6
|
-
import {
|
|
7
|
-
ensureNetlifyIgnore,
|
|
8
|
-
getAPIToken,
|
|
9
|
-
mockLocation,
|
|
10
|
-
LocalState,
|
|
11
|
-
HTTPServer,
|
|
12
|
-
netlifyCommand
|
|
13
|
-
} from "@netlify/dev-utils";
|
|
6
|
+
import { ensureNetlifyIgnore, getAPIToken, mockLocation, LocalState, HTTPServer } from "@netlify/dev-utils";
|
|
14
7
|
import { EdgeFunctionsHandler } from "@netlify/edge-functions/dev";
|
|
15
8
|
import { FunctionsHandler } from "@netlify/functions/dev";
|
|
16
9
|
import { HeadersHandler } from "@netlify/headers";
|
|
10
|
+
import { ImageHandler } from "@netlify/images";
|
|
17
11
|
import { RedirectsHandler } from "@netlify/redirects";
|
|
18
12
|
import { StaticHandler } from "@netlify/static";
|
|
19
13
|
|
|
@@ -287,6 +281,7 @@ var NetlifyDev = class {
|
|
|
287
281
|
#config;
|
|
288
282
|
#features;
|
|
289
283
|
#headersHandler;
|
|
284
|
+
#imageHandler;
|
|
290
285
|
#logger;
|
|
291
286
|
#projectRoot;
|
|
292
287
|
#redirectsHandler;
|
|
@@ -309,6 +304,7 @@ var NetlifyDev = class {
|
|
|
309
304
|
environmentVariables: options.environmentVariables?.enabled !== false,
|
|
310
305
|
functions: options.functions?.enabled !== false,
|
|
311
306
|
headers: options.headers?.enabled !== false,
|
|
307
|
+
images: options.images?.enabled !== false,
|
|
312
308
|
redirects: options.redirects?.enabled !== false,
|
|
313
309
|
static: options.staticFiles?.enabled !== false
|
|
314
310
|
};
|
|
@@ -339,6 +335,11 @@ var NetlifyDev = class {
|
|
|
339
335
|
type: "edge-function"
|
|
340
336
|
};
|
|
341
337
|
}
|
|
338
|
+
const imageMatch = this.#imageHandler?.match(readRequest);
|
|
339
|
+
if (imageMatch) {
|
|
340
|
+
const response = await imageMatch.handle();
|
|
341
|
+
return { response, type: "image" };
|
|
342
|
+
}
|
|
342
343
|
const functionMatch = await this.#functionsHandler?.match(readRequest, destPath);
|
|
343
344
|
if (functionMatch) {
|
|
344
345
|
if (functionMatch.preferStatic) {
|
|
@@ -353,7 +354,13 @@ var NetlifyDev = class {
|
|
|
353
354
|
}
|
|
354
355
|
const redirectMatch = await this.#redirectsHandler?.match(readRequest);
|
|
355
356
|
if (redirectMatch) {
|
|
356
|
-
const
|
|
357
|
+
const redirectRequest = new Request(redirectMatch.target);
|
|
358
|
+
const imageMatch2 = this.#imageHandler?.match(redirectRequest);
|
|
359
|
+
if (imageMatch2) {
|
|
360
|
+
const response2 = await imageMatch2.handle();
|
|
361
|
+
return { response: response2, type: "image" };
|
|
362
|
+
}
|
|
363
|
+
const functionMatch2 = await this.#functionsHandler?.match(redirectRequest, destPath);
|
|
357
364
|
if (functionMatch2 && !functionMatch2.preferStatic) {
|
|
358
365
|
return {
|
|
359
366
|
response: await functionMatch2.handle(getWriteRequest()),
|
|
@@ -379,13 +386,6 @@ var NetlifyDev = class {
|
|
|
379
386
|
return { response, type: "redirect" };
|
|
380
387
|
}
|
|
381
388
|
}
|
|
382
|
-
const { pathname } = new URL(readRequest.url);
|
|
383
|
-
if (pathname.startsWith("/.netlify/images")) {
|
|
384
|
-
this.#logger.error(
|
|
385
|
-
`The Netlify Image CDN is currently only supported in the Netlify CLI. Run ${netlifyCommand("npx netlify dev")} to get started.`
|
|
386
|
-
);
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
389
|
const staticMatch = await this.#staticHandler?.match(readRequest);
|
|
390
390
|
if (staticMatch) {
|
|
391
391
|
const response = await staticMatch.handle();
|
|
@@ -479,7 +479,7 @@ var NetlifyDev = class {
|
|
|
479
479
|
let serverAddress;
|
|
480
480
|
if (typeof this.#server === "string") {
|
|
481
481
|
serverAddress = this.#server;
|
|
482
|
-
} else if (this.#features.edgeFunctions) {
|
|
482
|
+
} else if (this.#features.edgeFunctions || this.#features.images) {
|
|
483
483
|
const passthroughServer = new HTTPServer(async (req) => {
|
|
484
484
|
const res = await this.handle(req);
|
|
485
485
|
return res ?? new Response(null, { status: 404 });
|
|
@@ -559,6 +559,13 @@ var NetlifyDev = class {
|
|
|
559
559
|
]
|
|
560
560
|
});
|
|
561
561
|
}
|
|
562
|
+
if (this.#features.images) {
|
|
563
|
+
this.#imageHandler = new ImageHandler({
|
|
564
|
+
imagesConfig: this.#config?.config.images,
|
|
565
|
+
logger: this.#logger,
|
|
566
|
+
originServerAddress: serverAddress
|
|
567
|
+
});
|
|
568
|
+
}
|
|
562
569
|
return {
|
|
563
570
|
serverAddress
|
|
564
571
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/dev",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Emulation of the Netlify environment for local development",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -52,15 +52,16 @@
|
|
|
52
52
|
"vitest": "^3.0.0"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@netlify/blobs": "9.1.
|
|
55
|
+
"@netlify/blobs": "9.1.6",
|
|
56
56
|
"@netlify/config": "^23.0.10",
|
|
57
|
-
"@netlify/dev-utils": "3.
|
|
58
|
-
"@netlify/edge-functions": "2.14.
|
|
59
|
-
"@netlify/functions": "4.1.
|
|
60
|
-
"@netlify/headers": "2.0.
|
|
61
|
-
"@netlify/
|
|
62
|
-
"@netlify/
|
|
63
|
-
"@netlify/
|
|
57
|
+
"@netlify/dev-utils": "3.2.0",
|
|
58
|
+
"@netlify/edge-functions": "2.14.4",
|
|
59
|
+
"@netlify/functions": "4.1.4",
|
|
60
|
+
"@netlify/headers": "2.0.2",
|
|
61
|
+
"@netlify/images": "1.0.0",
|
|
62
|
+
"@netlify/redirects": "3.0.2",
|
|
63
|
+
"@netlify/runtime": "4.0.3",
|
|
64
|
+
"@netlify/static": "3.0.2",
|
|
64
65
|
"ulid": "^3.0.0"
|
|
65
66
|
}
|
|
66
67
|
}
|