wapplr 1.0.79 → 1.0.81

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.
@@ -13,7 +13,8 @@ var _utils = require("./utils");
13
13
  function copy(obj) {
14
14
  var r = {};
15
15
  try {
16
- r = structuredClone(obj);
16
+ var c = obj.toJSON ? obj.toJSON() : obj;
17
+ r = structuredClone(c);
17
18
  } catch (e) {
18
19
  try {
19
20
  r = (0, _utils.copyObject)(obj);
@@ -251,7 +251,7 @@ function createMiddlewares(p) {
251
251
  return t;
252
252
  }).join('; '));
253
253
  }
254
- if (!res.getHeader("Content-Length") && !dontSetContentLength) {
254
+ if (!res.getHeader("Content-Length") && !dontSetContentLength && _html) {
255
255
  res.setHeader("Content-Length", Buffer.byteLength(_html));
256
256
  }
257
257
  if (!res.getHeader("Last-Modified") && mtime) {
@@ -9,99 +9,98 @@ exports["default"] = serveStatic;
9
9
  exports.endStream = endStream;
10
10
  var _regenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/regenerator"));
11
11
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
12
- var fs = require("node:fs/promises");
13
- var fsSync = require("node:fs");
14
- var path = require("path");
15
- function destroy(stream) {
16
- if (!(stream !== null && stream !== void 0 && stream.__destroyed)) {
17
- stream.destroy();
18
- stream.__destroyed = true;
12
+ var _nodeFs = require("node:fs");
13
+ var _nodePath = _interopRequireDefault(require("node:path"));
14
+ function endStream(req, res, stream) {
15
+ if (!stream) {
16
+ return;
17
+ }
18
+ if (stream.__destroyed) {
19
+ return;
20
+ }
21
+ stream.__destroyed = true;
22
+ var cleanup = stream.__cleanup;
23
+ if (cleanup) {
24
+ try {
25
+ var _req$off, _req$off2, _res$off, _stream$off, _stream$off2;
26
+ req === null || req === void 0 ? void 0 : (_req$off = req.off) === null || _req$off === void 0 ? void 0 : _req$off.call(req, "aborted", cleanup);
27
+ req === null || req === void 0 ? void 0 : (_req$off2 = req.off) === null || _req$off2 === void 0 ? void 0 : _req$off2.call(req, "close", cleanup);
28
+ res === null || res === void 0 ? void 0 : (_res$off = res.off) === null || _res$off === void 0 ? void 0 : _res$off.call(res, "close", cleanup);
29
+ stream === null || stream === void 0 ? void 0 : (_stream$off = stream.off) === null || _stream$off === void 0 ? void 0 : _stream$off.call(stream, "error", cleanup);
30
+ stream === null || stream === void 0 ? void 0 : (_stream$off2 = stream.off) === null || _stream$off2 === void 0 ? void 0 : _stream$off2.call(stream, "close", cleanup);
31
+ } catch (_unused) {}
32
+ stream.__cleanup = null;
33
+ }
34
+ try {
35
+ var _stream$destroy;
36
+ (_stream$destroy = stream.destroy) === null || _stream$destroy === void 0 ? void 0 : _stream$destroy.call(stream);
37
+ } catch (_unused2) {}
38
+ try {
19
39
  if (typeof stream.close === "function") {
20
- stream.on("open", function onOpenClose() {
40
+ var _stream$once;
41
+ (_stream$once = stream.once) === null || _stream$once === void 0 ? void 0 : _stream$once.call(stream, "open", function onOpenClose() {
21
42
  if (typeof this.fd === "number") {
22
43
  this.close();
23
44
  }
24
45
  });
25
46
  }
26
- }
27
- return stream;
47
+ } catch (_unused3) {}
28
48
  }
29
- function onFinished(req, res, callback) {
30
- function isFinishedResponse() {
31
- var socket = res.socket;
32
- if (typeof res.finished === "boolean") {
33
- return Boolean(res.finished || res.writableEnded || socket && !socket.writable);
34
- }
35
- }
36
- function isFinishedRequest() {
37
- var socket = req.socket;
38
- if (typeof req.complete === "boolean") {
39
- return Boolean(req.upgrade || !socket || !socket.readable || req.complete && !req.readable);
40
- }
41
- }
42
- function removeListener() {
43
- if (req.__onFinishedInterval) {
44
- clearInterval(req.__onFinishedInterval);
45
- req.__onFinishedInterval = 0;
46
- }
47
- if (res.__onFinishedInterval) {
48
- clearInterval(res.__onFinishedInterval);
49
- res.__onFinishedInterval = 0;
50
- }
49
+ function addCloseEventsForReadableStream(req, res, stream) {
50
+ var _req$on, _req$on2, _res$on, _stream$on, _stream$on2;
51
+ if (!req || !res || !stream) {
52
+ return;
51
53
  }
52
- function listener() {
53
- var result = isFinishedRequest() || isFinishedResponse();
54
- if (result) {
55
- removeListener();
56
- callback();
54
+ var finished = false;
55
+ var cleanup = function cleanup(err) {
56
+ if (finished) {
57
+ return;
57
58
  }
58
- }
59
- req.__onFinishedInterval = res.__onFinishedInterval = setInterval(listener, 100);
60
- req.__onFinishedRemoveListener = res.__onFinishedRemoveListener = removeListener;
59
+ finished = true;
60
+ try {
61
+ var _stream$destroy2;
62
+ (_stream$destroy2 = stream.destroy) === null || _stream$destroy2 === void 0 ? void 0 : _stream$destroy2.call(stream, err);
63
+ } catch (_unused4) {}
64
+ };
65
+ stream.__cleanup = cleanup;
66
+ (_req$on = req.on) === null || _req$on === void 0 ? void 0 : _req$on.call(req, "aborted", cleanup);
67
+ (_req$on2 = req.on) === null || _req$on2 === void 0 ? void 0 : _req$on2.call(req, "close", cleanup);
68
+ (_res$on = res.on) === null || _res$on === void 0 ? void 0 : _res$on.call(res, "close", cleanup);
69
+ (_stream$on = stream.on) === null || _stream$on === void 0 ? void 0 : _stream$on.call(stream, "error", cleanup);
70
+ (_stream$on2 = stream.on) === null || _stream$on2 === void 0 ? void 0 : _stream$on2.call(stream, "close", cleanup);
61
71
  }
62
- function endStream(req, res, stream) {
63
- if (req.__onFinishedRemoveListener) {
64
- req.__onFinishedRemoveListener();
65
- req.__onFinishedRemoveListener = null;
72
+ function safeJoin(root, reqPathname) {
73
+ var decoded;
74
+ try {
75
+ decoded = decodeURIComponent(reqPathname || "/");
76
+ } catch (_unused5) {
77
+ return null;
66
78
  }
67
- if (res.__onFinishedRemoveListener) {
68
- res.__onFinishedRemoveListener();
69
- res.__onFinishedRemoveListener = null;
79
+ if (decoded.includes("\0")) {
80
+ return null;
70
81
  }
71
- destroy(stream);
72
- }
73
- function addCloseEventsForReadableStream(req, res, stream) {
74
- req.on("close", function () {
75
- endStream(req, res, stream);
76
- });
77
- req.connection.on("close", function () {
78
- endStream(req, res, stream);
79
- });
80
- onFinished(req, res, function () {
81
- endStream(req, res, stream);
82
- });
83
- stream.on("close", function onclose() {
84
- endStream(req, res, stream);
85
- });
82
+ var absRoot = _nodePath["default"].resolve(root);
83
+ var absPath = _nodePath["default"].resolve(absRoot, "." + decoded);
84
+ var rel = _nodePath["default"].relative(absRoot, absPath);
85
+ if (rel.startsWith("..") || _nodePath["default"].isAbsolute(rel)) {
86
+ return null;
87
+ }
88
+ return absPath;
86
89
  }
87
90
  function serveStatic(publicPath) {
91
+ var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
92
+ var root = _nodePath["default"].resolve(publicPath);
93
+ var _opts$allowDotfiles = opts.allowDotfiles,
94
+ allowDotfiles = _opts$allowDotfiles === void 0 ? false : _opts$allowDotfiles;
88
95
  return /*#__PURE__*/function () {
89
96
  var _staticMiddleware = (0, _asyncToGenerator2["default"])(/*#__PURE__*/(0, _regenerator2["default"])().m(function _callee(req, res, next) {
90
- var parsedUrl, sanitizePath, pathname, parsedSanitizePath, ext, stream, data, stats, _t, _t2;
97
+ var _req$headers, _res$setHeader3, _res$setHeader4;
98
+ var method, urlObj, joined, parsed, stats, size, start, end, statusCode, range, m, hasStart, hasEnd, suffixLength, _res$setHeader, contentLength, _res$setHeader2, runSend, stream, _t, _t2, _t3;
91
99
  return (0, _regenerator2["default"])().w(function (_context) {
92
100
  while (1) switch (_context.p = _context.n) {
93
101
  case 0:
94
- parsedUrl = {
95
- pathname: req.wappRequest.path
96
- };
97
- try {
98
- parsedUrl = new URL(req.wappRequest.url);
99
- } catch (e) {}
100
- sanitizePath = path.normalize(parsedUrl.pathname).replace(/^(\.\.[\/\\])+/, "");
101
- pathname = path.join(publicPath, sanitizePath);
102
- parsedSanitizePath = path.parse(pathname);
103
- ext = parsedSanitizePath.ext;
104
- if (ext) {
102
+ method = (req.wappRequest.method || req.method || "GET").toUpperCase();
103
+ if (!(method !== "GET" && method !== "HEAD")) {
105
104
  _context.n = 2;
106
105
  break;
107
106
  }
@@ -111,61 +110,225 @@ function serveStatic(publicPath) {
111
110
  return _context.a(2, _context.v);
112
111
  case 2:
113
112
  _context.p = 2;
114
- _context.n = 3;
115
- return fs.access(pathname);
116
- case 3:
117
- _context.n = 6;
113
+ urlObj = new URL(req.wappRequest.url || req.url, "http://localhost");
114
+ _context.n = 5;
118
115
  break;
119
- case 4:
120
- _context.p = 4;
116
+ case 3:
117
+ _context.p = 3;
121
118
  _t = _context.v;
122
- _context.n = 5;
119
+ _context.n = 4;
123
120
  return next();
124
- case 5:
121
+ case 4:
125
122
  return _context.a(2, _context.v);
123
+ case 5:
124
+ joined = safeJoin(root, urlObj.pathname);
125
+ if (joined) {
126
+ _context.n = 7;
127
+ break;
128
+ }
129
+ _context.n = 6;
130
+ return next();
126
131
  case 6:
127
- _context.p = 6;
128
- _context.n = 7;
129
- return fs.readFile(pathname);
132
+ return _context.a(2, _context.v);
130
133
  case 7:
131
- data = _context.v;
134
+ parsed = _nodePath["default"].parse(joined);
135
+ if (parsed.ext) {
136
+ _context.n = 9;
137
+ break;
138
+ }
132
139
  _context.n = 8;
133
- return fs.stat(pathname);
140
+ return next();
134
141
  case 8:
142
+ return _context.a(2, _context.v);
143
+ case 9:
144
+ if (!(!allowDotfiles && parsed.base.startsWith("."))) {
145
+ _context.n = 11;
146
+ break;
147
+ }
148
+ _context.n = 10;
149
+ return next();
150
+ case 10:
151
+ return _context.a(2, _context.v);
152
+ case 11:
153
+ _context.p = 11;
154
+ _context.n = 12;
155
+ return _nodeFs.promises.stat(joined);
156
+ case 12:
135
157
  stats = _context.v;
136
- res.wappResponse.status(200);
158
+ if (stats.isFile()) {
159
+ _context.n = 14;
160
+ break;
161
+ }
162
+ _context.n = 13;
163
+ return next();
164
+ case 13:
165
+ return _context.a(2, _context.v);
166
+ case 14:
167
+ _context.n = 19;
168
+ break;
169
+ case 15:
170
+ _context.p = 15;
171
+ _t2 = _context.v;
172
+ if (!((_t2 === null || _t2 === void 0 ? void 0 : _t2.code) === "ENOENT")) {
173
+ _context.n = 17;
174
+ break;
175
+ }
176
+ _context.n = 16;
177
+ return next();
178
+ case 16:
179
+ return _context.a(2, _context.v);
180
+ case 17:
181
+ res.wappResponse.status(500, _t2);
182
+ res.wapp.log(_t2, req, res);
183
+ _context.n = 18;
184
+ return next(_t2);
185
+ case 18:
186
+ return _context.a(2, _context.v);
187
+ case 19:
188
+ size = stats.size;
189
+ start = 0;
190
+ end = size > 0 ? size - 1 : 0;
191
+ statusCode = 200;
192
+ range = (_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : _req$headers.range;
193
+ if (!(range && /^bytes=/.test(range))) {
194
+ _context.n = 21;
195
+ break;
196
+ }
197
+ m = /bytes=(\d*)-(\d*)/.exec(range);
198
+ if (!m) {
199
+ _context.n = 21;
200
+ break;
201
+ }
202
+ hasStart = m[1] !== "";
203
+ hasEnd = m[2] !== "";
204
+ if (hasStart) {
205
+ start = parseInt(m[1], 10);
206
+ }
207
+ if (hasEnd) {
208
+ end = parseInt(m[2], 10);
209
+ }
210
+ if (!hasStart && hasEnd) {
211
+ suffixLength = end;
212
+ if (Number.isFinite(suffixLength)) {
213
+ if (suffixLength > size) {
214
+ start = 0;
215
+ } else {
216
+ start = size - suffixLength;
217
+ }
218
+ end = size > 0 ? size - 1 : 0;
219
+ }
220
+ }
221
+ if (hasStart && !hasEnd) {
222
+ end = size > 0 ? size - 1 : 0;
223
+ }
224
+ if (!(Number.isNaN(start) || Number.isNaN(end) || start > end || start < 0 || end >= size)) {
225
+ _context.n = 20;
226
+ break;
227
+ }
228
+ (_res$setHeader = res.setHeader) === null || _res$setHeader === void 0 ? void 0 : _res$setHeader.call(res, "Content-Range", "bytes */".concat(size));
229
+ res.wappResponse.status(416);
137
230
  res.wappResponse.sendData = {
138
- data: data,
139
231
  stats: stats,
140
- parsedPath: parsedSanitizePath
232
+ parsedPath: parsed,
233
+ dontSetContentLength: true
234
+ };
235
+ return _context.a(2, res.wapp.middleware.runSendMiddlewares(req, res, function () {
236
+ res.end();
237
+ }));
238
+ case 20:
239
+ statusCode = 206;
240
+ case 21:
241
+ contentLength = statusCode === 206 ? end - start + 1 : size;
242
+ res.wappResponse.status(statusCode);
243
+ res.wappResponse.sendData = {
244
+ stats: stats,
245
+ parsedPath: parsed,
246
+ dontSetContentLength: true
247
+ };
248
+ if (statusCode === 206) {
249
+ (_res$setHeader2 = res.setHeader) === null || _res$setHeader2 === void 0 ? void 0 : _res$setHeader2.call(res, "Content-Range", "bytes ".concat(start, "-").concat(end, "/").concat(size));
250
+ }
251
+ (_res$setHeader3 = res.setHeader) === null || _res$setHeader3 === void 0 ? void 0 : _res$setHeader3.call(res, "Accept-Ranges", "bytes");
252
+ (_res$setHeader4 = res.setHeader) === null || _res$setHeader4 === void 0 ? void 0 : _res$setHeader4.call(res, "Content-Length", String(contentLength));
253
+ runSend = function runSend() {
254
+ return new Promise(function (resolve) {
255
+ var _res$wapp, _res$wapp$middleware;
256
+ if ((_res$wapp = res.wapp) !== null && _res$wapp !== void 0 && (_res$wapp$middleware = _res$wapp.middleware) !== null && _res$wapp$middleware !== void 0 && _res$wapp$middleware.runSendMiddlewares) {
257
+ res.wapp.middleware.runSendMiddlewares(req, res, function () {
258
+ return resolve();
259
+ });
260
+ } else {
261
+ resolve();
262
+ }
263
+ });
141
264
  };
142
- stream = fsSync.createReadStream(pathname);
265
+ _context.p = 22;
266
+ _context.n = 23;
267
+ return runSend();
268
+ case 23:
269
+ if (!res.writableEnded) {
270
+ _context.n = 24;
271
+ break;
272
+ }
273
+ return _context.a(2);
274
+ case 24:
275
+ if (!(method === "HEAD")) {
276
+ _context.n = 25;
277
+ break;
278
+ }
279
+ res.end();
280
+ return _context.a(2);
281
+ case 25:
282
+ stream = statusCode === 206 ? (0, _nodeFs.createReadStream)(joined, {
283
+ start: start,
284
+ end: end
285
+ }) : (0, _nodeFs.createReadStream)(joined);
143
286
  addCloseEventsForReadableStream(req, res, stream);
144
- stream.on("error", function onerror(err) {
287
+ stream.on("error", function (err) {
288
+ var _res$wapp2, _res$wapp2$log;
145
289
  endStream(req, res, stream);
146
- res.wappResponse.status(err.statusCode || 500, err);
147
- res.wapp.log(err, req, res);
148
- next(err);
149
- });
150
- stream.on("open", function onopen() {
151
- res.wapp.middleware.runSendMiddlewares(req, res, function next() {
152
- res.wapp.log(req, res);
153
- stream.pipe(res);
154
- });
290
+ (_res$wapp2 = res.wapp) === null || _res$wapp2 === void 0 ? void 0 : (_res$wapp2$log = _res$wapp2.log) === null || _res$wapp2$log === void 0 ? void 0 : _res$wapp2$log.call(_res$wapp2, err, req, res);
291
+ if (!res.headersSent) {
292
+ res.wappResponse.status(err.statusCode || 500, err);
293
+ }
294
+ if (!res.writableEnded) {
295
+ try {
296
+ res.end();
297
+ } catch (_unused7) {}
298
+ }
299
+ if (typeof next === "function") {
300
+ next(err);
301
+ }
155
302
  });
156
- _context.n = 10;
157
- break;
158
- case 9:
159
- _context.p = 9;
160
- _t2 = _context.v;
303
+ if (!res.writableEnded) {
304
+ _context.n = 26;
305
+ break;
306
+ }
161
307
  endStream(req, res, stream);
162
- res.wappResponse.status(_t2.statusCode || 500, _t2);
163
- res.wapp.log(_t2, req, res);
164
- next(_t2);
165
- case 10:
308
+ return _context.a(2);
309
+ case 26:
310
+ res.wapp.log(req, res);
311
+ stream.pipe(res);
312
+ _context.n = 28;
313
+ break;
314
+ case 27:
315
+ _context.p = 27;
316
+ _t3 = _context.v;
317
+ res.wapp.log(_t3, req, res);
318
+ if (!res.writableEnded) {
319
+ res.wappResponse.status(_t3.statusCode || 500, _t3);
320
+ res.end();
321
+ }
322
+ if (!(typeof next === "function")) {
323
+ _context.n = 28;
324
+ break;
325
+ }
326
+ _context.n = 28;
327
+ return next(_t3);
328
+ case 28:
166
329
  return _context.a(2);
167
330
  }
168
- }, _callee, null, [[6, 9], [2, 4]]);
331
+ }, _callee, null, [[22, 27], [11, 15], [2, 3]]);
169
332
  }));
170
333
  function staticMiddleware(_x, _x2, _x3) {
171
334
  return _staticMiddleware.apply(this, arguments);
package/package.json CHANGED
@@ -22,7 +22,7 @@
22
22
  "files": [
23
23
  "dist/*"
24
24
  ],
25
- "version": "1.0.79",
25
+ "version": "1.0.81",
26
26
  "main": "dist/server",
27
27
  "browser": "dist/client",
28
28
  "repository": {