@netlify/dev 5.0.4 → 5.1.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/dist/main.cjs CHANGED
@@ -47,6 +47,7 @@ var import_functions_dev = require("@netlify/functions-dev");
47
47
  var import_headers = require("@netlify/headers");
48
48
  var import_images = require("@netlify/images");
49
49
  var import_redirects = require("@netlify/redirects");
50
+ var import_server_dev = require("@netlify/server-dev");
50
51
  var import_static = require("@netlify/static");
51
52
  var import_database_dev = require("@netlify/database-dev");
52
53
  var import_database_dev2 = require("@netlify/database-dev");
@@ -341,6 +342,7 @@ var NetlifyDev = class {
341
342
  #logger;
342
343
  #projectRoot;
343
344
  #redirectsHandler;
345
+ #serverHandler;
344
346
  #serverAddress;
345
347
  #siteID;
346
348
  #staticHandler;
@@ -367,6 +369,7 @@ var NetlifyDev = class {
367
369
  headers: options.headers?.enabled !== false,
368
370
  images: options.images?.enabled !== false,
369
371
  redirects: options.redirects?.enabled !== false,
372
+ server: options.server?.enabled === true,
370
373
  static: options.staticFiles?.enabled !== false
371
374
  };
372
375
  this.#functionsServePath = import_node_path2.default.join(projectRoot, ".netlify", "functions-serve");
@@ -400,17 +403,17 @@ var NetlifyDev = class {
400
403
  * @returns
401
404
  */
402
405
  async handleInEphemeralDirectory(readRequest, getWriteRequest, destPath, options = {}) {
403
- const serverAddress = this.getServerAddress(options.serverAddress);
406
+ const getServerAddress = () => this.getServerAddress(options.serverAddress);
404
407
  const edgeFunctionMatch = await this.#edgeFunctionsHandler?.match(readRequest);
405
408
  if (edgeFunctionMatch) {
406
409
  return {
407
- response: await edgeFunctionMatch.handle(getWriteRequest(), serverAddress),
410
+ response: await edgeFunctionMatch.handle(getWriteRequest(), getServerAddress()),
408
411
  type: "edge-function"
409
412
  };
410
413
  }
411
414
  const imageMatch = this.#imageHandler?.match(readRequest);
412
415
  if (imageMatch) {
413
- const response = await imageMatch.handle(serverAddress);
416
+ const response = await imageMatch.handle(getServerAddress());
414
417
  return { response, type: "image" };
415
418
  }
416
419
  const functionMatch = await this.#functionsHandler?.match(readRequest, destPath);
@@ -425,12 +428,22 @@ var NetlifyDev = class {
425
428
  }
426
429
  return { response: await functionMatch.handle(getWriteRequest()), type: "function" };
427
430
  }
431
+ const serverMatch = await this.#serverHandler?.match(readRequest);
432
+ if (serverMatch) {
433
+ const staticMatch2 = await this.#staticHandler?.match(readRequest);
434
+ if (staticMatch2) {
435
+ const response = await staticMatch2.handle();
436
+ await this.#headersHandler?.apply(readRequest, response, options.headersCollector);
437
+ return { response, type: "static" };
438
+ }
439
+ return { response: await serverMatch.handle(getWriteRequest()), type: "server" };
440
+ }
428
441
  const redirectMatch = await this.#redirectsHandler?.match(readRequest);
429
442
  if (redirectMatch) {
430
443
  const redirectRequest = new Request(redirectMatch.target);
431
444
  const imageMatch2 = this.#imageHandler?.match(redirectRequest);
432
445
  if (imageMatch2) {
433
- const response2 = await imageMatch2.handle(serverAddress);
446
+ const response2 = await imageMatch2.handle(getServerAddress());
434
447
  return { response: response2, type: "image" };
435
448
  }
436
449
  const functionMatch2 = await this.#functionsHandler?.match(redirectRequest, destPath);
@@ -700,6 +713,23 @@ var NetlifyDev = class {
700
713
  userFunctionsPath: userFunctionsPathExists ? userFunctionsPath : void 0
701
714
  });
702
715
  }
716
+ if (this.#features.server) {
717
+ geolocation ??= await (0, import_dev_utils.getGeoLocation)({
718
+ enabled: this.#features.geolocation,
719
+ cache: this.#geolocationConfig?.cache ?? true,
720
+ state
721
+ });
722
+ const serverHandler = new import_server_dev.ServerHandler({
723
+ accountID: config?.siteInfo?.account_id,
724
+ fileWatcher,
725
+ geolocation,
726
+ logger: this.#logger,
727
+ projectRoot: this.#projectRoot,
728
+ siteID
729
+ });
730
+ this.#serverHandler = serverHandler;
731
+ this.#cleanupJobs.push(() => serverHandler.stop());
732
+ }
703
733
  if (this.#features.headers) {
704
734
  this.#headersHandler = new import_headers.HeadersHandler({
705
735
  configPath: this.#config?.configPath,
@@ -740,6 +770,12 @@ var NetlifyDev = class {
740
770
  serverAddress
741
771
  };
742
772
  }
773
+ async handleUpgrade(request, socket, head) {
774
+ if (!this.#serverHandler) {
775
+ return false;
776
+ }
777
+ return await this.#serverHandler.handleUpgrade(request, socket, head);
778
+ }
743
779
  get db() {
744
780
  return this.#db;
745
781
  }
package/dist/main.d.cts CHANGED
@@ -1,4 +1,6 @@
1
+ import { Buffer } from 'node:buffer';
1
2
  import { IncomingMessage } from 'node:http';
3
+ import { Duplex } from 'node:stream';
2
4
  import { Logger } from '@netlify/dev-utils';
3
5
  import { HeadersCollector } from '@netlify/headers';
4
6
  import { NetlifyDB } from '@netlify/database-dev';
@@ -45,6 +47,12 @@ interface Features {
45
47
  functions?: {
46
48
  enabled?: boolean;
47
49
  };
50
+ /**
51
+ * [Experimental] Configuration options for Netlify Server.
52
+ */
53
+ server?: {
54
+ enabled?: boolean;
55
+ };
48
56
  /**
49
57
  * Configuration options for geolocation data used by Functions and Edge Functions.
50
58
  *
@@ -139,7 +147,7 @@ interface HandleOptions {
139
147
  */
140
148
  serverAddress?: string;
141
149
  }
142
- type ResponseType = 'edge-function' | 'function' | 'image' | 'redirect' | 'static';
150
+ type ResponseType = 'edge-function' | 'function' | 'image' | 'redirect' | 'server' | 'static';
143
151
  declare class NetlifyDev {
144
152
  #private;
145
153
  constructor(options: NetlifyDevOptions);
@@ -186,6 +194,7 @@ declare class NetlifyDev {
186
194
  start(): Promise<{
187
195
  serverAddress: string | undefined;
188
196
  }>;
197
+ handleUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer): Promise<boolean>;
189
198
  get db(): NetlifyDB | undefined;
190
199
  stop(): Promise<void>;
191
200
  getEnabledFeatures(): string[];
package/dist/main.d.ts CHANGED
@@ -1,4 +1,6 @@
1
+ import { Buffer } from 'node:buffer';
1
2
  import { IncomingMessage } from 'node:http';
3
+ import { Duplex } from 'node:stream';
2
4
  import { Logger } from '@netlify/dev-utils';
3
5
  import { HeadersCollector } from '@netlify/headers';
4
6
  import { NetlifyDB } from '@netlify/database-dev';
@@ -45,6 +47,12 @@ interface Features {
45
47
  functions?: {
46
48
  enabled?: boolean;
47
49
  };
50
+ /**
51
+ * [Experimental] Configuration options for Netlify Server.
52
+ */
53
+ server?: {
54
+ enabled?: boolean;
55
+ };
48
56
  /**
49
57
  * Configuration options for geolocation data used by Functions and Edge Functions.
50
58
  *
@@ -139,7 +147,7 @@ interface HandleOptions {
139
147
  */
140
148
  serverAddress?: string;
141
149
  }
142
- type ResponseType = 'edge-function' | 'function' | 'image' | 'redirect' | 'static';
150
+ type ResponseType = 'edge-function' | 'function' | 'image' | 'redirect' | 'server' | 'static';
143
151
  declare class NetlifyDev {
144
152
  #private;
145
153
  constructor(options: NetlifyDevOptions);
@@ -186,6 +194,7 @@ declare class NetlifyDev {
186
194
  start(): Promise<{
187
195
  serverAddress: string | undefined;
188
196
  }>;
197
+ handleUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer): Promise<boolean>;
189
198
  get db(): NetlifyDB | undefined;
190
199
  stop(): Promise<void>;
191
200
  getEnabledFeatures(): string[];
package/dist/main.js CHANGED
@@ -18,6 +18,7 @@ import { FunctionsHandler } from "@netlify/functions-dev";
18
18
  import { HeadersHandler } from "@netlify/headers";
19
19
  import { ImageHandler } from "@netlify/images";
20
20
  import { RedirectsHandler } from "@netlify/redirects";
21
+ import { ServerHandler } from "@netlify/server-dev";
21
22
  import { StaticHandler } from "@netlify/static";
22
23
  import { NetlifyDB } from "@netlify/database-dev";
23
24
  import { applyMigrations, initializeTrackingTable, resetDatabase } from "@netlify/database-dev";
@@ -312,6 +313,7 @@ var NetlifyDev = class {
312
313
  #logger;
313
314
  #projectRoot;
314
315
  #redirectsHandler;
316
+ #serverHandler;
315
317
  #serverAddress;
316
318
  #siteID;
317
319
  #staticHandler;
@@ -338,6 +340,7 @@ var NetlifyDev = class {
338
340
  headers: options.headers?.enabled !== false,
339
341
  images: options.images?.enabled !== false,
340
342
  redirects: options.redirects?.enabled !== false,
343
+ server: options.server?.enabled === true,
341
344
  static: options.staticFiles?.enabled !== false
342
345
  };
343
346
  this.#functionsServePath = path2.join(projectRoot, ".netlify", "functions-serve");
@@ -371,17 +374,17 @@ var NetlifyDev = class {
371
374
  * @returns
372
375
  */
373
376
  async handleInEphemeralDirectory(readRequest, getWriteRequest, destPath, options = {}) {
374
- const serverAddress = this.getServerAddress(options.serverAddress);
377
+ const getServerAddress = () => this.getServerAddress(options.serverAddress);
375
378
  const edgeFunctionMatch = await this.#edgeFunctionsHandler?.match(readRequest);
376
379
  if (edgeFunctionMatch) {
377
380
  return {
378
- response: await edgeFunctionMatch.handle(getWriteRequest(), serverAddress),
381
+ response: await edgeFunctionMatch.handle(getWriteRequest(), getServerAddress()),
379
382
  type: "edge-function"
380
383
  };
381
384
  }
382
385
  const imageMatch = this.#imageHandler?.match(readRequest);
383
386
  if (imageMatch) {
384
- const response = await imageMatch.handle(serverAddress);
387
+ const response = await imageMatch.handle(getServerAddress());
385
388
  return { response, type: "image" };
386
389
  }
387
390
  const functionMatch = await this.#functionsHandler?.match(readRequest, destPath);
@@ -396,12 +399,22 @@ var NetlifyDev = class {
396
399
  }
397
400
  return { response: await functionMatch.handle(getWriteRequest()), type: "function" };
398
401
  }
402
+ const serverMatch = await this.#serverHandler?.match(readRequest);
403
+ if (serverMatch) {
404
+ const staticMatch2 = await this.#staticHandler?.match(readRequest);
405
+ if (staticMatch2) {
406
+ const response = await staticMatch2.handle();
407
+ await this.#headersHandler?.apply(readRequest, response, options.headersCollector);
408
+ return { response, type: "static" };
409
+ }
410
+ return { response: await serverMatch.handle(getWriteRequest()), type: "server" };
411
+ }
399
412
  const redirectMatch = await this.#redirectsHandler?.match(readRequest);
400
413
  if (redirectMatch) {
401
414
  const redirectRequest = new Request(redirectMatch.target);
402
415
  const imageMatch2 = this.#imageHandler?.match(redirectRequest);
403
416
  if (imageMatch2) {
404
- const response2 = await imageMatch2.handle(serverAddress);
417
+ const response2 = await imageMatch2.handle(getServerAddress());
405
418
  return { response: response2, type: "image" };
406
419
  }
407
420
  const functionMatch2 = await this.#functionsHandler?.match(redirectRequest, destPath);
@@ -671,6 +684,23 @@ var NetlifyDev = class {
671
684
  userFunctionsPath: userFunctionsPathExists ? userFunctionsPath : void 0
672
685
  });
673
686
  }
687
+ if (this.#features.server) {
688
+ geolocation ??= await getGeoLocation({
689
+ enabled: this.#features.geolocation,
690
+ cache: this.#geolocationConfig?.cache ?? true,
691
+ state
692
+ });
693
+ const serverHandler = new ServerHandler({
694
+ accountID: config?.siteInfo?.account_id,
695
+ fileWatcher,
696
+ geolocation,
697
+ logger: this.#logger,
698
+ projectRoot: this.#projectRoot,
699
+ siteID
700
+ });
701
+ this.#serverHandler = serverHandler;
702
+ this.#cleanupJobs.push(() => serverHandler.stop());
703
+ }
674
704
  if (this.#features.headers) {
675
705
  this.#headersHandler = new HeadersHandler({
676
706
  configPath: this.#config?.configPath,
@@ -711,6 +741,12 @@ var NetlifyDev = class {
711
741
  serverAddress
712
742
  };
713
743
  }
744
+ async handleUpgrade(request, socket, head) {
745
+ if (!this.#serverHandler) {
746
+ return false;
747
+ }
748
+ return await this.#serverHandler.handleUpgrade(request, socket, head);
749
+ }
714
750
  get db() {
715
751
  return this.#db;
716
752
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/dev",
3
- "version": "5.0.4",
3
+ "version": "5.1.0",
4
4
  "description": "Emulation of the Netlify environment for local development",
5
5
  "type": "module",
6
6
  "engines": {
@@ -58,16 +58,17 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "@netlify/ai": "^1.0.1",
61
- "@netlify/blobs": "11.0.2",
61
+ "@netlify/blobs": "11.0.3",
62
62
  "@netlify/config": "^25.2.3",
63
63
  "@netlify/database-dev": "1.0.1",
64
64
  "@netlify/dev-utils": "6.0.1",
65
65
  "@netlify/edge-functions-dev": "2.0.1",
66
- "@netlify/functions-dev": "2.0.4",
66
+ "@netlify/functions-dev": "2.0.5",
67
67
  "@netlify/headers": "3.0.1",
68
68
  "@netlify/images": "2.0.1",
69
69
  "@netlify/redirects": "4.0.2",
70
- "@netlify/runtime": "5.0.2",
70
+ "@netlify/runtime": "5.0.3",
71
+ "@netlify/server-dev": "0.1.1",
71
72
  "@netlify/static": "4.0.0",
72
73
  "ulid": "^3.0.0"
73
74
  }