@netlify/dev 2.3.1 → 3.0.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 CHANGED
@@ -1,7 +1,6 @@
1
1
  # @netlify/dev
2
2
 
3
- > [!WARNING]
4
- > This module is under active development and does **not** yet support all Netlify platform features.
3
+ > [!WARNING] This module is under active development and does **not** yet support all Netlify platform features.
5
4
 
6
5
  `@netlify/dev` is a local emulator for the Netlify production environment. While it can be used directly by advanced
7
6
  users, it is primarily designed as a foundational library for higher-level tools like the
package/dist/main.cjs CHANGED
@@ -39,6 +39,7 @@ var import_node_process2 = __toESM(require("process"), 1);
39
39
  var import_config = require("@netlify/config");
40
40
  var import_dev_utils = require("@netlify/dev-utils");
41
41
  var import_dev = require("@netlify/functions/dev");
42
+ var import_headers = require("@netlify/headers");
42
43
  var import_redirects = require("@netlify/redirects");
43
44
  var import_static = require("@netlify/static");
44
45
 
@@ -277,6 +278,7 @@ var NetlifyDev = class {
277
278
  blobs: options.blobs?.enabled !== false,
278
279
  environmentVariables: options.environmentVariables?.enabled !== false,
279
280
  functions: options.functions?.enabled !== false,
281
+ headers: options.headers?.enabled !== false,
280
282
  redirects: options.redirects?.enabled !== false,
281
283
  static: options.staticFiles?.enabled !== false
282
284
  };
@@ -295,6 +297,13 @@ var NetlifyDev = class {
295
297
  timeouts: {},
296
298
  userFunctionsPath: userFunctionsPathExists ? userFunctionsPath : void 0
297
299
  }) : null;
300
+ const headers = this.#features.headers ? new import_headers.HeadersHandler({
301
+ configPath: this.#config?.configPath,
302
+ configHeaders: this.#config?.config.headers,
303
+ projectDir: this.#projectRoot,
304
+ publishDir: this.#config?.config.build.publish ?? void 0,
305
+ logger: this.#logger
306
+ }) : { handle: async (_request, response) => response };
298
307
  const redirects = this.#features.redirects ? new import_redirects.RedirectsHandler({
299
308
  configPath: this.#config?.configPath,
300
309
  configRedirects: this.#config?.config.redirects,
@@ -311,7 +320,8 @@ var NetlifyDev = class {
311
320
  if (functionMatch.preferStatic) {
312
321
  const staticMatch2 = await staticFiles?.match(request);
313
322
  if (staticMatch2) {
314
- return staticMatch2.handle();
323
+ const response = await staticMatch2.handle();
324
+ return headers.handle(request, response);
315
325
  }
316
326
  }
317
327
  return functionMatch.handle(request);
@@ -324,7 +334,11 @@ var NetlifyDev = class {
324
334
  }
325
335
  const response = await redirects?.handle(request, redirectMatch, async (maybeStaticFile) => {
326
336
  const staticMatch2 = await staticFiles?.match(maybeStaticFile);
327
- return staticMatch2?.handle;
337
+ if (!staticMatch2) return;
338
+ return async () => {
339
+ const response2 = await staticMatch2.handle();
340
+ return headers.handle(new Request(redirectMatch.target), response2);
341
+ };
328
342
  });
329
343
  if (response) {
330
344
  return response;
@@ -332,7 +346,8 @@ var NetlifyDev = class {
332
346
  }
333
347
  const staticMatch = await staticFiles?.match(request);
334
348
  if (staticMatch) {
335
- return staticMatch.handle();
349
+ const response = await staticMatch.handle();
350
+ return headers.handle(request, response);
336
351
  }
337
352
  }
338
353
  async getConfig() {
package/dist/main.d.cts CHANGED
@@ -25,6 +25,14 @@ interface Features {
25
25
  functions?: {
26
26
  enabled: boolean;
27
27
  };
28
+ /**
29
+ * Configuration options for Netlify response headers.
30
+ *
31
+ * {@link} https://docs.netlify.com/routing/headers/
32
+ */
33
+ headers?: {
34
+ enabled: boolean;
35
+ };
28
36
  /**
29
37
  * Configuration options for Netlify redirects and rewrites.
30
38
  *
package/dist/main.d.ts CHANGED
@@ -25,6 +25,14 @@ interface Features {
25
25
  functions?: {
26
26
  enabled: boolean;
27
27
  };
28
+ /**
29
+ * Configuration options for Netlify response headers.
30
+ *
31
+ * {@link} https://docs.netlify.com/routing/headers/
32
+ */
33
+ headers?: {
34
+ enabled: boolean;
35
+ };
28
36
  /**
29
37
  * Configuration options for Netlify redirects and rewrites.
30
38
  *
package/dist/main.js CHANGED
@@ -1,10 +1,11 @@
1
1
  // src/main.ts
2
- import { promises as fs2 } from "node:fs";
3
- import path2 from "node:path";
4
- import process2 from "node:process";
2
+ import { promises as fs2 } from "fs";
3
+ import path2 from "path";
4
+ import process2 from "process";
5
5
  import { resolveConfig } from "@netlify/config";
6
6
  import { ensureNetlifyIgnore, getAPIToken, LocalState } from "@netlify/dev-utils";
7
7
  import { FunctionsHandler } from "@netlify/functions/dev";
8
+ import { HeadersHandler } from "@netlify/headers";
8
9
  import { RedirectsHandler } from "@netlify/redirects";
9
10
  import { StaticHandler } from "@netlify/static";
10
11
 
@@ -142,7 +143,7 @@ var getEnvelopeEnv = async ({
142
143
  };
143
144
 
144
145
  // src/lib/fs.ts
145
- import { promises as fs } from "node:fs";
146
+ import { promises as fs } from "fs";
146
147
  var isDirectory = async (path3) => {
147
148
  try {
148
149
  const stat = await fs.stat(path3);
@@ -161,8 +162,8 @@ var isFile = async (path3) => {
161
162
  };
162
163
 
163
164
  // src/lib/runtime.ts
164
- import path from "node:path";
165
- import process from "node:process";
165
+ import path from "path";
166
+ import process from "process";
166
167
  import { BlobsServer } from "@netlify/blobs/server";
167
168
  import { startRuntime } from "@netlify/runtime";
168
169
  var restoreEnvironment = (snapshot) => {
@@ -243,6 +244,7 @@ var NetlifyDev = class {
243
244
  blobs: options.blobs?.enabled !== false,
244
245
  environmentVariables: options.environmentVariables?.enabled !== false,
245
246
  functions: options.functions?.enabled !== false,
247
+ headers: options.headers?.enabled !== false,
246
248
  redirects: options.redirects?.enabled !== false,
247
249
  static: options.staticFiles?.enabled !== false
248
250
  };
@@ -261,6 +263,13 @@ var NetlifyDev = class {
261
263
  timeouts: {},
262
264
  userFunctionsPath: userFunctionsPathExists ? userFunctionsPath : void 0
263
265
  }) : null;
266
+ const headers = this.#features.headers ? new HeadersHandler({
267
+ configPath: this.#config?.configPath,
268
+ configHeaders: this.#config?.config.headers,
269
+ projectDir: this.#projectRoot,
270
+ publishDir: this.#config?.config.build.publish ?? void 0,
271
+ logger: this.#logger
272
+ }) : { handle: async (_request, response) => response };
264
273
  const redirects = this.#features.redirects ? new RedirectsHandler({
265
274
  configPath: this.#config?.configPath,
266
275
  configRedirects: this.#config?.config.redirects,
@@ -277,7 +286,8 @@ var NetlifyDev = class {
277
286
  if (functionMatch.preferStatic) {
278
287
  const staticMatch2 = await staticFiles?.match(request);
279
288
  if (staticMatch2) {
280
- return staticMatch2.handle();
289
+ const response = await staticMatch2.handle();
290
+ return headers.handle(request, response);
281
291
  }
282
292
  }
283
293
  return functionMatch.handle(request);
@@ -290,7 +300,11 @@ var NetlifyDev = class {
290
300
  }
291
301
  const response = await redirects?.handle(request, redirectMatch, async (maybeStaticFile) => {
292
302
  const staticMatch2 = await staticFiles?.match(maybeStaticFile);
293
- return staticMatch2?.handle;
303
+ if (!staticMatch2) return;
304
+ return async () => {
305
+ const response2 = await staticMatch2.handle();
306
+ return headers.handle(new Request(redirectMatch.target), response2);
307
+ };
294
308
  });
295
309
  if (response) {
296
310
  return response;
@@ -298,7 +312,8 @@ var NetlifyDev = class {
298
312
  }
299
313
  const staticMatch = await staticFiles?.match(request);
300
314
  if (staticMatch) {
301
- return staticMatch.handle();
315
+ const response = await staticMatch.handle();
316
+ return headers.handle(request, response);
302
317
  }
303
318
  }
304
319
  async getConfig() {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@netlify/dev",
3
- "version": "2.3.1",
3
+ "version": "3.0.0",
4
4
  "description": "Emulation of the Netlify environment for local development",
5
5
  "type": "module",
6
6
  "engines": {
7
- "node": "^14.16.0 || >=16.0.0"
7
+ "node": "^18.14.0 || >=20"
8
8
  },
9
9
  "main": "./dist/main.cjs",
10
10
  "module": "./dist/main.js",
@@ -47,18 +47,18 @@
47
47
  "author": "Netlify Inc.",
48
48
  "devDependencies": {
49
49
  "@netlify/api": "^14.0.2",
50
- "@netlify/types": "1.2.0",
51
- "tmp-promise": "^3.0.3",
50
+ "@netlify/types": "2.0.0",
52
51
  "tsup": "^8.0.0",
53
52
  "vitest": "^3.0.0"
54
53
  },
55
54
  "dependencies": {
56
- "@netlify/blobs": "9.1.2",
55
+ "@netlify/blobs": "9.1.3",
57
56
  "@netlify/config": "^23.0.7",
58
- "@netlify/dev-utils": "2.2.0",
59
- "@netlify/functions": "3.1.10",
60
- "@netlify/redirects": "1.1.4",
61
- "@netlify/runtime": "2.2.2",
62
- "@netlify/static": "1.1.4"
57
+ "@netlify/dev-utils": "3.0.0",
58
+ "@netlify/functions": "4.0.0",
59
+ "@netlify/headers": "1.0.0",
60
+ "@netlify/redirects": "2.0.0",
61
+ "@netlify/runtime": "3.0.0",
62
+ "@netlify/static": "2.0.0"
63
63
  }
64
64
  }