@jsenv/server 16.0.1 → 16.0.2

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.
@@ -232,7 +232,7 @@
232
232
  // AsyncIterator objects; they just return a Promise for the value of
233
233
  // the final result produced by the iterator.
234
234
  exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {
235
- if (PromiseImpl === undefined) PromiseImpl = Promise;
235
+ if (PromiseImpl === void 0) PromiseImpl = Promise;
236
236
 
237
237
  var iter = new AsyncIterator(
238
238
  wrap(innerFn, outerFn, self, tryLocsList),
@@ -1,10 +1,10 @@
1
- import { PassThrough, Transform, Stream } from "node:stream";
2
1
  import os from "node:os";
3
2
  import path from "node:path";
4
3
  import fsPromises from "node:fs/promises";
5
4
  import { EventEmitter } from "node:events";
6
5
  import { StringDecoder } from "node:string_decoder";
7
6
  import require$$0 from "node:domain";
7
+ import { PassThrough, Transform, Stream } from "node:stream";
8
8
  import fs from "node:fs";
9
9
  import require$$1, { createHash } from "node:crypto";
10
10
 
package/dist/js/ws.js CHANGED
@@ -12,6 +12,175 @@ function getDefaultExportFromCjs (x) {
12
12
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
13
13
  }
14
14
 
15
+ var stream$1;
16
+ var hasRequiredStream;
17
+
18
+ function requireStream () {
19
+ if (hasRequiredStream) return stream$1;
20
+ hasRequiredStream = 1;
21
+
22
+ const { Duplex } = require$$0;
23
+
24
+ /**
25
+ * Emits the `'close'` event on a stream.
26
+ *
27
+ * @param {Duplex} stream The stream.
28
+ * @private
29
+ */
30
+ function emitClose(stream) {
31
+ stream.emit('close');
32
+ }
33
+
34
+ /**
35
+ * The listener of the `'end'` event.
36
+ *
37
+ * @private
38
+ */
39
+ function duplexOnEnd() {
40
+ if (!this.destroyed && this._writableState.finished) {
41
+ this.destroy();
42
+ }
43
+ }
44
+
45
+ /**
46
+ * The listener of the `'error'` event.
47
+ *
48
+ * @param {Error} err The error
49
+ * @private
50
+ */
51
+ function duplexOnError(err) {
52
+ this.removeListener('error', duplexOnError);
53
+ this.destroy();
54
+ if (this.listenerCount('error') === 0) {
55
+ // Do not suppress the throwing behavior.
56
+ this.emit('error', err);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Wraps a `WebSocket` in a duplex stream.
62
+ *
63
+ * @param {WebSocket} ws The `WebSocket` to wrap
64
+ * @param {Object} [options] The options for the `Duplex` constructor
65
+ * @return {Duplex} The duplex stream
66
+ * @public
67
+ */
68
+ function createWebSocketStream(ws, options) {
69
+ let terminateOnDestroy = true;
70
+
71
+ const duplex = new Duplex({
72
+ ...options,
73
+ autoDestroy: false,
74
+ emitClose: false,
75
+ objectMode: false,
76
+ writableObjectMode: false
77
+ });
78
+
79
+ ws.on('message', function message(msg, isBinary) {
80
+ const data =
81
+ !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;
82
+
83
+ if (!duplex.push(data)) ws.pause();
84
+ });
85
+
86
+ ws.once('error', function error(err) {
87
+ if (duplex.destroyed) return;
88
+
89
+ // Prevent `ws.terminate()` from being called by `duplex._destroy()`.
90
+ //
91
+ // - If the `'error'` event is emitted before the `'open'` event, then
92
+ // `ws.terminate()` is a noop as no socket is assigned.
93
+ // - Otherwise, the error is re-emitted by the listener of the `'error'`
94
+ // event of the `Receiver` object. The listener already closes the
95
+ // connection by calling `ws.close()`. This allows a close frame to be
96
+ // sent to the other peer. If `ws.terminate()` is called right after this,
97
+ // then the close frame might not be sent.
98
+ terminateOnDestroy = false;
99
+ duplex.destroy(err);
100
+ });
101
+
102
+ ws.once('close', function close() {
103
+ if (duplex.destroyed) return;
104
+
105
+ duplex.push(null);
106
+ });
107
+
108
+ duplex._destroy = function (err, callback) {
109
+ if (ws.readyState === ws.CLOSED) {
110
+ callback(err);
111
+ process.nextTick(emitClose, duplex);
112
+ return;
113
+ }
114
+
115
+ let called = false;
116
+
117
+ ws.once('error', function error(err) {
118
+ called = true;
119
+ callback(err);
120
+ });
121
+
122
+ ws.once('close', function close() {
123
+ if (!called) callback(err);
124
+ process.nextTick(emitClose, duplex);
125
+ });
126
+
127
+ if (terminateOnDestroy) ws.terminate();
128
+ };
129
+
130
+ duplex._final = function (callback) {
131
+ if (ws.readyState === ws.CONNECTING) {
132
+ ws.once('open', function open() {
133
+ duplex._final(callback);
134
+ });
135
+ return;
136
+ }
137
+
138
+ // If the value of the `_socket` property is `null` it means that `ws` is a
139
+ // client websocket and the handshake failed. In fact, when this happens, a
140
+ // socket is never assigned to the websocket. Wait for the `'error'` event
141
+ // that will be emitted by the websocket.
142
+ if (ws._socket === null) return;
143
+
144
+ if (ws._socket._writableState.finished) {
145
+ callback();
146
+ if (duplex._readableState.endEmitted) duplex.destroy();
147
+ } else {
148
+ ws._socket.once('finish', function finish() {
149
+ // `duplex` is not destroyed here because the `'end'` event will be
150
+ // emitted on `duplex` after this `'finish'` event. The EOF signaling
151
+ // `null` chunk is, in fact, pushed when the websocket emits `'close'`.
152
+ callback();
153
+ });
154
+ ws.close();
155
+ }
156
+ };
157
+
158
+ duplex._read = function () {
159
+ if (ws.isPaused) ws.resume();
160
+ };
161
+
162
+ duplex._write = function (chunk, encoding, callback) {
163
+ if (ws.readyState === ws.CONNECTING) {
164
+ ws.once('open', function open() {
165
+ duplex._write(chunk, encoding, callback);
166
+ });
167
+ return;
168
+ }
169
+
170
+ ws.send(chunk, callback);
171
+ };
172
+
173
+ duplex.on('end', duplexOnEnd);
174
+ duplex.on('error', duplexOnError);
175
+ return duplex;
176
+ }
177
+
178
+ stream$1 = createWebSocketStream;
179
+ return stream$1;
180
+ }
181
+
182
+ requireStream();
183
+
15
184
  var bufferUtil = {exports: {}};
16
185
 
17
186
  var constants;
@@ -3730,6 +3899,8 @@ var hasRequiredSender;
3730
3899
  function requireSender () {
3731
3900
  if (hasRequiredSender) return sender$1;
3732
3901
  hasRequiredSender = 1;
3902
+
3903
+ const { Duplex } = require$$0;
3733
3904
  const { randomFillSync } = require$$1;
3734
3905
 
3735
3906
  const PerMessageDeflate = requirePermessageDeflate();
@@ -4858,6 +5029,7 @@ function requireWebsocket () {
4858
5029
  const net$1 = net;
4859
5030
  const tls = require$$4;
4860
5031
  const { randomBytes, createHash } = require$$1;
5032
+ const { Duplex, Readable } = require$$0;
4861
5033
  const { URL } = require$$7;
4862
5034
 
4863
5035
  const PerMessageDeflate = requirePermessageDeflate();
@@ -6321,6 +6493,7 @@ function requireWebsocketServer () {
6321
6493
 
6322
6494
  const EventEmitter = require$$0$2;
6323
6495
  const http$1 = http;
6496
+ const { Duplex } = require$$0;
6324
6497
  const { createHash } = require$$1;
6325
6498
 
6326
6499
  const extension = requireExtension();
@@ -9,10 +9,10 @@ import { Readable, Stream, Writable } from "node:stream";
9
9
  import http from "node:http";
10
10
  import { Http2ServerResponse } from "node:http2";
11
11
  import { createReadStream, existsSync, readFileSync, readdirSync, lstatSync, statSync, readFile } from "node:fs";
12
- import { pathToFileURL, fileURLToPath } from "node:url";
13
- import { createHash } from "node:crypto";
14
12
  import { createRequire } from "node:module";
13
+ import { fileURLToPath, pathToFileURL } from "node:url";
15
14
  import { lookup } from "node:dns";
15
+ import { createHash } from "node:crypto";
16
16
 
17
17
  const createCallbackListNotifiedOnce = () => {
18
18
  let callbacks = [];
@@ -1499,15 +1499,8 @@ const createObservable = (producer) => {
1499
1499
  },
1500
1500
  { signal = new AbortController().signal } = {},
1501
1501
  ) => {
1502
- let cleanup = () => {};
1503
1502
  const subscription = {
1504
- active: true,
1505
- signal,
1506
- unsubscribe: () => {
1507
- subscription.closed = true;
1508
- cleanup();
1509
- },
1510
- };
1503
+ active: true};
1511
1504
 
1512
1505
  const teardownCallbackList = [];
1513
1506
  const close = () => {
@@ -1523,7 +1516,7 @@ const createObservable = (producer) => {
1523
1516
  close();
1524
1517
  });
1525
1518
 
1526
- const producerReturnValue = producer({
1519
+ producer({
1527
1520
  next: (value) => {
1528
1521
  if (!subscription.active) {
1529
1522
  return;
@@ -1552,9 +1545,6 @@ const createObservable = (producer) => {
1552
1545
  teardownCallbackList.push(teardownCallback);
1553
1546
  },
1554
1547
  });
1555
- if (typeof producerReturnValue === "function") {
1556
- cleanup = producerReturnValue;
1557
- }
1558
1548
  return undefined;
1559
1549
  },
1560
1550
  };
@@ -1728,7 +1718,7 @@ const fromNodeRequest = (
1728
1718
  `formData() called on a request with content-type: "${contentType}". multipart/form-data was expected.`,
1729
1719
  );
1730
1720
  }
1731
- const { formidable } = await import("./js/formidable.js");
1721
+ const { formidable } = await import("./js/formidable_index.js");
1732
1722
  const form = formidable({});
1733
1723
  nodeRequest.resume(); // was paused in line #53
1734
1724
  const [fields, files] = await form.parse(nodeRequest);
@@ -3403,35 +3393,6 @@ const resourceToExtension = (resource) => {
3403
3393
  return pathnameToExtension(pathname);
3404
3394
  };
3405
3395
 
3406
- const isFileSystemPath$1 = (value) => {
3407
- if (typeof value !== "string") {
3408
- throw new TypeError(
3409
- `isFileSystemPath first arg must be a string, got ${value}`,
3410
- );
3411
- }
3412
- if (value[0] === "/") {
3413
- return true;
3414
- }
3415
- return startsWithWindowsDriveLetter$1(value);
3416
- };
3417
-
3418
- const startsWithWindowsDriveLetter$1 = (string) => {
3419
- const firstChar = string[0];
3420
- if (!/[a-zA-Z]/.test(firstChar)) return false;
3421
-
3422
- const secondChar = string[1];
3423
- if (secondChar !== ":") return false;
3424
-
3425
- return true;
3426
- };
3427
-
3428
- const fileSystemPathToUrl$1 = (value) => {
3429
- if (!isFileSystemPath$1(value)) {
3430
- throw new Error(`value must be a filesystem path, got ${value}`);
3431
- }
3432
- return String(pathToFileURL(value));
3433
- };
3434
-
3435
3396
  const getCommonPathname = (pathname, otherPathname) => {
3436
3397
  if (pathname === otherPathname) {
3437
3398
  return pathname;
@@ -3553,9 +3514,6 @@ const urlToFileSystemPath = (url) => {
3553
3514
  return fileSystemPath;
3554
3515
  };
3555
3516
 
3556
- process.platform === "win32";
3557
- fileSystemPathToUrl$1(process.cwd());
3558
-
3559
3517
  const getParentDirectoryUrl = (url) => {
3560
3518
  if (url.startsWith("file://")) {
3561
3519
  // With node.js new URL('../', 'file:///C:/').href
@@ -4155,34 +4113,6 @@ const URL_META = {
4155
4113
  createFilter,
4156
4114
  };
4157
4115
 
4158
- /*
4159
- * - stats object documentation on Node.js
4160
- * https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
4161
- */
4162
-
4163
-
4164
- process.platform === "win32";
4165
-
4166
- /*
4167
- * - stats object documentation on Node.js
4168
- * https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
4169
- */
4170
-
4171
-
4172
- process.platform === "win32";
4173
-
4174
- process.platform === "win32";
4175
-
4176
- process.platform === "win32";
4177
-
4178
- process.platform === "win32";
4179
-
4180
- process.platform === "linux";
4181
-
4182
- process.platform === "darwin";
4183
- process.platform === "linux";
4184
- process.platform === "freebsd";
4185
-
4186
4116
  const isEscaped = (i, string) => {
4187
4117
  let backslashBeforeCount = 0;
4188
4118
  while (i--) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/server",
3
- "version": "16.0.1",
3
+ "version": "16.0.2",
4
4
  "description": "A modern Node.js HTTP server with declarative routing, content negotiation, and WebSocket support",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -33,6 +33,7 @@
33
33
  "/dist/",
34
34
  "/src/"
35
35
  ],
36
+ "sideEffects": false,
36
37
  "scripts": {
37
38
  "build": "node --experimental-import-meta-resolve ./scripts/build.mjs",
38
39
  "prepublishOnly": "npm run build"
@@ -40,9 +41,9 @@
40
41
  "dependencies": {
41
42
  "launch-editor": "2.10.0",
42
43
  "@jsenv/abort": "4.3.1",
43
- "@jsenv/humanize": "1.3.0",
44
+ "@jsenv/humanize": "1.3.1",
44
45
  "@jsenv/url-meta": "8.5.4",
45
- "@jsenv/utils": "2.2.0",
46
+ "@jsenv/utils": "2.2.1",
46
47
  "ws": "8.18.0",
47
48
  "formidable": "3.5.2"
48
49
  },
@@ -1,12 +1,12 @@
1
1
  import { IncomingForm } from "./vendors.js";
2
2
  export { DummyParser, PersistentFile as File, JSONParser, MultipartParser, OctetStreamParser, OctetStreamParser as OctetstreamParser, PersistentFile, QuerystringParser as QueryStringParser, QuerystringParser, VolatileFile, DEFAULT_OPTIONS as defaultOptions, plugin$3 as json, plugin$2 as multipart, plugin as octetstream, plugin$1 as querystring } from "./vendors.js";
3
- import "node:stream";
4
3
  import "node:os";
5
4
  import "node:path";
6
5
  import "node:fs/promises";
7
6
  import "node:events";
8
7
  import "node:string_decoder";
9
8
  import "node:domain";
9
+ import "node:stream";
10
10
  import "node:fs";
11
11
  import "node:crypto";
12
12