bun-dev-server 0.2.0 → 0.4.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 +23 -22
- package/dist/bunClientHmr.d.ts +3 -0
- package/dist/bunHmrPlugin.d.ts +8 -0
- package/dist/bunManifest.d.ts +2 -0
- package/{bunServeConfig.ts → dist/bunServeConfig.d.ts} +26 -27
- package/dist/bunTSWatcher.d.ts +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1242 -0
- package/dist/server.d.ts +2 -0
- package/dist/tsChecker.d.ts +2 -0
- package/package.json +19 -4
- package/.vscode/launch.json +0 -36
- package/.vscode/settings.json +0 -15
- package/@types/fileTypes.d.ts +0 -5
- package/bunClientHmr.ts +0 -51
- package/bunHmrPlugin.ts +0 -33
- package/bunManifest.ts +0 -18
- package/bunTSWatcher.ts +0 -74
- package/index.ts +0 -247
- package/indexHTMLTemplate.ejs +0 -15
- package/serveOutputTemplate.ejs +0 -16
- package/test/README.md +0 -15
- package/test/bun.lockb +0 -0
- package/test/bunrun.ts +0 -18
- package/test/package.json +0 -16
- package/test/src/@types/filetypes.d.ts +0 -4
- package/test/src/app.ts +0 -10
- package/test/src/assets/something.svg +0 -6
- package/test/src/services/someservice.ts +0 -7
- package/test/src/something.ts +0 -3
- package/test/tsconfig.json +0 -28
- package/tsconfig.json +0 -28
package/dist/index.js
ADDED
|
@@ -0,0 +1,1242 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
|
+
|
|
20
|
+
// node_modules/ejs/lib/utils.js
|
|
21
|
+
var require_utils = __commonJS((exports) => {
|
|
22
|
+
var regExpChars = /[|\\{}()[\]^$+*?.]/g;
|
|
23
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
24
|
+
var hasOwn = function(obj, key) {
|
|
25
|
+
return hasOwnProperty.apply(obj, [key]);
|
|
26
|
+
};
|
|
27
|
+
exports.escapeRegExpChars = function(string) {
|
|
28
|
+
if (!string) {
|
|
29
|
+
return "";
|
|
30
|
+
}
|
|
31
|
+
return String(string).replace(regExpChars, "\\$&");
|
|
32
|
+
};
|
|
33
|
+
var _ENCODE_HTML_RULES = {
|
|
34
|
+
"&": "&",
|
|
35
|
+
"<": "<",
|
|
36
|
+
">": ">",
|
|
37
|
+
'"': """,
|
|
38
|
+
"'": "'"
|
|
39
|
+
};
|
|
40
|
+
var _MATCH_HTML = /[&<>'"]/g;
|
|
41
|
+
function encode_char(c) {
|
|
42
|
+
return _ENCODE_HTML_RULES[c] || c;
|
|
43
|
+
}
|
|
44
|
+
var escapeFuncStr = `var _ENCODE_HTML_RULES = {
|
|
45
|
+
` + ` "&": "&"
|
|
46
|
+
` + ` , "<": "<"
|
|
47
|
+
` + ` , ">": ">"
|
|
48
|
+
` + ` , '"': """
|
|
49
|
+
` + ` , "'": "'"
|
|
50
|
+
` + ` }
|
|
51
|
+
` + ` , _MATCH_HTML = /[&<>'"]/g;
|
|
52
|
+
` + `function encode_char(c) {
|
|
53
|
+
` + ` return _ENCODE_HTML_RULES[c] || c;
|
|
54
|
+
` + `};
|
|
55
|
+
`;
|
|
56
|
+
exports.escapeXML = function(markup) {
|
|
57
|
+
return markup == undefined ? "" : String(markup).replace(_MATCH_HTML, encode_char);
|
|
58
|
+
};
|
|
59
|
+
function escapeXMLToString() {
|
|
60
|
+
return Function.prototype.toString.call(this) + `;
|
|
61
|
+
` + escapeFuncStr;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
if (typeof Object.defineProperty === "function") {
|
|
65
|
+
Object.defineProperty(exports.escapeXML, "toString", { value: escapeXMLToString });
|
|
66
|
+
} else {
|
|
67
|
+
exports.escapeXML.toString = escapeXMLToString;
|
|
68
|
+
}
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.warn("Unable to set escapeXML.toString (is the Function prototype frozen?)");
|
|
71
|
+
}
|
|
72
|
+
exports.shallowCopy = function(to, from) {
|
|
73
|
+
from = from || {};
|
|
74
|
+
if (to !== null && to !== undefined) {
|
|
75
|
+
for (var p in from) {
|
|
76
|
+
if (!hasOwn(from, p)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (p === "__proto__" || p === "constructor") {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
to[p] = from[p];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return to;
|
|
86
|
+
};
|
|
87
|
+
exports.shallowCopyFromList = function(to, from, list) {
|
|
88
|
+
list = list || [];
|
|
89
|
+
from = from || {};
|
|
90
|
+
if (to !== null && to !== undefined) {
|
|
91
|
+
for (var i = 0;i < list.length; i++) {
|
|
92
|
+
var p = list[i];
|
|
93
|
+
if (typeof from[p] != "undefined") {
|
|
94
|
+
if (!hasOwn(from, p)) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (p === "__proto__" || p === "constructor") {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
to[p] = from[p];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return to;
|
|
105
|
+
};
|
|
106
|
+
exports.cache = {
|
|
107
|
+
_data: {},
|
|
108
|
+
set: function(key, val) {
|
|
109
|
+
this._data[key] = val;
|
|
110
|
+
},
|
|
111
|
+
get: function(key) {
|
|
112
|
+
return this._data[key];
|
|
113
|
+
},
|
|
114
|
+
remove: function(key) {
|
|
115
|
+
delete this._data[key];
|
|
116
|
+
},
|
|
117
|
+
reset: function() {
|
|
118
|
+
this._data = {};
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
exports.hyphenToCamel = function(str) {
|
|
122
|
+
return str.replace(/-[a-z]/g, function(match) {
|
|
123
|
+
return match[1].toUpperCase();
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
exports.createNullProtoObjWherePossible = function() {
|
|
127
|
+
if (typeof Object.create == "function") {
|
|
128
|
+
return function() {
|
|
129
|
+
return Object.create(null);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (!({ __proto__: null } instanceof Object)) {
|
|
133
|
+
return function() {
|
|
134
|
+
return { __proto__: null };
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return function() {
|
|
138
|
+
return {};
|
|
139
|
+
};
|
|
140
|
+
}();
|
|
141
|
+
exports.hasOwnOnlyObject = function(obj) {
|
|
142
|
+
var o = exports.createNullProtoObjWherePossible();
|
|
143
|
+
for (var p in obj) {
|
|
144
|
+
if (hasOwn(obj, p)) {
|
|
145
|
+
o[p] = obj[p];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return o;
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// node_modules/ejs/package.json
|
|
153
|
+
var require_package = __commonJS((exports, module) => {
|
|
154
|
+
module.exports = {
|
|
155
|
+
name: "ejs",
|
|
156
|
+
description: "Embedded JavaScript templates",
|
|
157
|
+
keywords: [
|
|
158
|
+
"template",
|
|
159
|
+
"engine",
|
|
160
|
+
"ejs"
|
|
161
|
+
],
|
|
162
|
+
version: "3.1.10",
|
|
163
|
+
author: "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",
|
|
164
|
+
license: "Apache-2.0",
|
|
165
|
+
bin: {
|
|
166
|
+
ejs: "./bin/cli.js"
|
|
167
|
+
},
|
|
168
|
+
main: "./lib/ejs.js",
|
|
169
|
+
jsdelivr: "ejs.min.js",
|
|
170
|
+
unpkg: "ejs.min.js",
|
|
171
|
+
repository: {
|
|
172
|
+
type: "git",
|
|
173
|
+
url: "git://github.com/mde/ejs.git"
|
|
174
|
+
},
|
|
175
|
+
bugs: "https://github.com/mde/ejs/issues",
|
|
176
|
+
homepage: "https://github.com/mde/ejs",
|
|
177
|
+
dependencies: {
|
|
178
|
+
jake: "^10.8.5"
|
|
179
|
+
},
|
|
180
|
+
devDependencies: {
|
|
181
|
+
browserify: "^16.5.1",
|
|
182
|
+
eslint: "^6.8.0",
|
|
183
|
+
"git-directory-deploy": "^1.5.1",
|
|
184
|
+
jsdoc: "^4.0.2",
|
|
185
|
+
"lru-cache": "^4.0.1",
|
|
186
|
+
mocha: "^10.2.0",
|
|
187
|
+
"uglify-js": "^3.3.16"
|
|
188
|
+
},
|
|
189
|
+
engines: {
|
|
190
|
+
node: ">=0.10.0"
|
|
191
|
+
},
|
|
192
|
+
scripts: {
|
|
193
|
+
test: "npx jake test"
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// node_modules/ejs/lib/ejs.js
|
|
199
|
+
var require_ejs = __commonJS((exports) => {
|
|
200
|
+
var fs = import.meta.require("fs");
|
|
201
|
+
var path = import.meta.require("path");
|
|
202
|
+
var utils = require_utils();
|
|
203
|
+
var scopeOptionWarned = false;
|
|
204
|
+
var _VERSION_STRING = require_package().version;
|
|
205
|
+
var _DEFAULT_OPEN_DELIMITER = "<";
|
|
206
|
+
var _DEFAULT_CLOSE_DELIMITER = ">";
|
|
207
|
+
var _DEFAULT_DELIMITER = "%";
|
|
208
|
+
var _DEFAULT_LOCALS_NAME = "locals";
|
|
209
|
+
var _NAME = "ejs";
|
|
210
|
+
var _REGEX_STRING = "(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)";
|
|
211
|
+
var _OPTS_PASSABLE_WITH_DATA = [
|
|
212
|
+
"delimiter",
|
|
213
|
+
"scope",
|
|
214
|
+
"context",
|
|
215
|
+
"debug",
|
|
216
|
+
"compileDebug",
|
|
217
|
+
"client",
|
|
218
|
+
"_with",
|
|
219
|
+
"rmWhitespace",
|
|
220
|
+
"strict",
|
|
221
|
+
"filename",
|
|
222
|
+
"async"
|
|
223
|
+
];
|
|
224
|
+
var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat("cache");
|
|
225
|
+
var _BOM = /^\uFEFF/;
|
|
226
|
+
var _JS_IDENTIFIER = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
|
|
227
|
+
exports.cache = utils.cache;
|
|
228
|
+
exports.fileLoader = fs.readFileSync;
|
|
229
|
+
exports.localsName = _DEFAULT_LOCALS_NAME;
|
|
230
|
+
exports.promiseImpl = new Function("return this;")().Promise;
|
|
231
|
+
exports.resolveInclude = function(name, filename, isDir) {
|
|
232
|
+
var dirname = path.dirname;
|
|
233
|
+
var extname = path.extname;
|
|
234
|
+
var resolve = path.resolve;
|
|
235
|
+
var includePath = resolve(isDir ? filename : dirname(filename), name);
|
|
236
|
+
var ext = extname(name);
|
|
237
|
+
if (!ext) {
|
|
238
|
+
includePath += ".ejs";
|
|
239
|
+
}
|
|
240
|
+
return includePath;
|
|
241
|
+
};
|
|
242
|
+
function resolvePaths(name, paths) {
|
|
243
|
+
var filePath;
|
|
244
|
+
if (paths.some(function(v) {
|
|
245
|
+
filePath = exports.resolveInclude(name, v, true);
|
|
246
|
+
return fs.existsSync(filePath);
|
|
247
|
+
})) {
|
|
248
|
+
return filePath;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function getIncludePath(path2, options) {
|
|
252
|
+
var includePath;
|
|
253
|
+
var filePath;
|
|
254
|
+
var views = options.views;
|
|
255
|
+
var match = /^[A-Za-z]+:\\|^\//.exec(path2);
|
|
256
|
+
if (match && match.length) {
|
|
257
|
+
path2 = path2.replace(/^\/*/, "");
|
|
258
|
+
if (Array.isArray(options.root)) {
|
|
259
|
+
includePath = resolvePaths(path2, options.root);
|
|
260
|
+
} else {
|
|
261
|
+
includePath = exports.resolveInclude(path2, options.root || "/", true);
|
|
262
|
+
}
|
|
263
|
+
} else {
|
|
264
|
+
if (options.filename) {
|
|
265
|
+
filePath = exports.resolveInclude(path2, options.filename);
|
|
266
|
+
if (fs.existsSync(filePath)) {
|
|
267
|
+
includePath = filePath;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (!includePath && Array.isArray(views)) {
|
|
271
|
+
includePath = resolvePaths(path2, views);
|
|
272
|
+
}
|
|
273
|
+
if (!includePath && typeof options.includer !== "function") {
|
|
274
|
+
throw new Error('Could not find the include file "' + options.escapeFunction(path2) + '"');
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return includePath;
|
|
278
|
+
}
|
|
279
|
+
function handleCache(options, template) {
|
|
280
|
+
var func;
|
|
281
|
+
var filename = options.filename;
|
|
282
|
+
var hasTemplate = arguments.length > 1;
|
|
283
|
+
if (options.cache) {
|
|
284
|
+
if (!filename) {
|
|
285
|
+
throw new Error("cache option requires a filename");
|
|
286
|
+
}
|
|
287
|
+
func = exports.cache.get(filename);
|
|
288
|
+
if (func) {
|
|
289
|
+
return func;
|
|
290
|
+
}
|
|
291
|
+
if (!hasTemplate) {
|
|
292
|
+
template = fileLoader(filename).toString().replace(_BOM, "");
|
|
293
|
+
}
|
|
294
|
+
} else if (!hasTemplate) {
|
|
295
|
+
if (!filename) {
|
|
296
|
+
throw new Error("Internal EJS error: no file name or template " + "provided");
|
|
297
|
+
}
|
|
298
|
+
template = fileLoader(filename).toString().replace(_BOM, "");
|
|
299
|
+
}
|
|
300
|
+
func = exports.compile(template, options);
|
|
301
|
+
if (options.cache) {
|
|
302
|
+
exports.cache.set(filename, func);
|
|
303
|
+
}
|
|
304
|
+
return func;
|
|
305
|
+
}
|
|
306
|
+
function tryHandleCache(options, data, cb) {
|
|
307
|
+
var result;
|
|
308
|
+
if (!cb) {
|
|
309
|
+
if (typeof exports.promiseImpl == "function") {
|
|
310
|
+
return new exports.promiseImpl(function(resolve, reject) {
|
|
311
|
+
try {
|
|
312
|
+
result = handleCache(options)(data);
|
|
313
|
+
resolve(result);
|
|
314
|
+
} catch (err) {
|
|
315
|
+
reject(err);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
} else {
|
|
319
|
+
throw new Error("Please provide a callback function");
|
|
320
|
+
}
|
|
321
|
+
} else {
|
|
322
|
+
try {
|
|
323
|
+
result = handleCache(options)(data);
|
|
324
|
+
} catch (err) {
|
|
325
|
+
return cb(err);
|
|
326
|
+
}
|
|
327
|
+
cb(null, result);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function fileLoader(filePath) {
|
|
331
|
+
return exports.fileLoader(filePath);
|
|
332
|
+
}
|
|
333
|
+
function includeFile(path2, options) {
|
|
334
|
+
var opts = utils.shallowCopy(utils.createNullProtoObjWherePossible(), options);
|
|
335
|
+
opts.filename = getIncludePath(path2, opts);
|
|
336
|
+
if (typeof options.includer === "function") {
|
|
337
|
+
var includerResult = options.includer(path2, opts.filename);
|
|
338
|
+
if (includerResult) {
|
|
339
|
+
if (includerResult.filename) {
|
|
340
|
+
opts.filename = includerResult.filename;
|
|
341
|
+
}
|
|
342
|
+
if (includerResult.template) {
|
|
343
|
+
return handleCache(opts, includerResult.template);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return handleCache(opts);
|
|
348
|
+
}
|
|
349
|
+
function rethrow(err, str, flnm, lineno, esc) {
|
|
350
|
+
var lines = str.split(`
|
|
351
|
+
`);
|
|
352
|
+
var start = Math.max(lineno - 3, 0);
|
|
353
|
+
var end = Math.min(lines.length, lineno + 3);
|
|
354
|
+
var filename = esc(flnm);
|
|
355
|
+
var context = lines.slice(start, end).map(function(line, i) {
|
|
356
|
+
var curr = i + start + 1;
|
|
357
|
+
return (curr == lineno ? " >> " : " ") + curr + "| " + line;
|
|
358
|
+
}).join(`
|
|
359
|
+
`);
|
|
360
|
+
err.path = filename;
|
|
361
|
+
err.message = (filename || "ejs") + ":" + lineno + `
|
|
362
|
+
` + context + `
|
|
363
|
+
|
|
364
|
+
` + err.message;
|
|
365
|
+
throw err;
|
|
366
|
+
}
|
|
367
|
+
function stripSemi(str) {
|
|
368
|
+
return str.replace(/;(\s*$)/, "$1");
|
|
369
|
+
}
|
|
370
|
+
exports.compile = function compile(template, opts) {
|
|
371
|
+
var templ;
|
|
372
|
+
if (opts && opts.scope) {
|
|
373
|
+
if (!scopeOptionWarned) {
|
|
374
|
+
console.warn("`scope` option is deprecated and will be removed in EJS 3");
|
|
375
|
+
scopeOptionWarned = true;
|
|
376
|
+
}
|
|
377
|
+
if (!opts.context) {
|
|
378
|
+
opts.context = opts.scope;
|
|
379
|
+
}
|
|
380
|
+
delete opts.scope;
|
|
381
|
+
}
|
|
382
|
+
templ = new Template(template, opts);
|
|
383
|
+
return templ.compile();
|
|
384
|
+
};
|
|
385
|
+
exports.render = function(template, d, o) {
|
|
386
|
+
var data = d || utils.createNullProtoObjWherePossible();
|
|
387
|
+
var opts = o || utils.createNullProtoObjWherePossible();
|
|
388
|
+
if (arguments.length == 2) {
|
|
389
|
+
utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
|
|
390
|
+
}
|
|
391
|
+
return handleCache(opts, template)(data);
|
|
392
|
+
};
|
|
393
|
+
exports.renderFile = function() {
|
|
394
|
+
var args = Array.prototype.slice.call(arguments);
|
|
395
|
+
var filename = args.shift();
|
|
396
|
+
var cb;
|
|
397
|
+
var opts = { filename };
|
|
398
|
+
var data;
|
|
399
|
+
var viewOpts;
|
|
400
|
+
if (typeof arguments[arguments.length - 1] == "function") {
|
|
401
|
+
cb = args.pop();
|
|
402
|
+
}
|
|
403
|
+
if (args.length) {
|
|
404
|
+
data = args.shift();
|
|
405
|
+
if (args.length) {
|
|
406
|
+
utils.shallowCopy(opts, args.pop());
|
|
407
|
+
} else {
|
|
408
|
+
if (data.settings) {
|
|
409
|
+
if (data.settings.views) {
|
|
410
|
+
opts.views = data.settings.views;
|
|
411
|
+
}
|
|
412
|
+
if (data.settings["view cache"]) {
|
|
413
|
+
opts.cache = true;
|
|
414
|
+
}
|
|
415
|
+
viewOpts = data.settings["view options"];
|
|
416
|
+
if (viewOpts) {
|
|
417
|
+
utils.shallowCopy(opts, viewOpts);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS);
|
|
421
|
+
}
|
|
422
|
+
opts.filename = filename;
|
|
423
|
+
} else {
|
|
424
|
+
data = utils.createNullProtoObjWherePossible();
|
|
425
|
+
}
|
|
426
|
+
return tryHandleCache(opts, data, cb);
|
|
427
|
+
};
|
|
428
|
+
exports.Template = Template;
|
|
429
|
+
exports.clearCache = function() {
|
|
430
|
+
exports.cache.reset();
|
|
431
|
+
};
|
|
432
|
+
function Template(text, optsParam) {
|
|
433
|
+
var opts = utils.hasOwnOnlyObject(optsParam);
|
|
434
|
+
var options = utils.createNullProtoObjWherePossible();
|
|
435
|
+
this.templateText = text;
|
|
436
|
+
this.mode = null;
|
|
437
|
+
this.truncate = false;
|
|
438
|
+
this.currentLine = 1;
|
|
439
|
+
this.source = "";
|
|
440
|
+
options.client = opts.client || false;
|
|
441
|
+
options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML;
|
|
442
|
+
options.compileDebug = opts.compileDebug !== false;
|
|
443
|
+
options.debug = !!opts.debug;
|
|
444
|
+
options.filename = opts.filename;
|
|
445
|
+
options.openDelimiter = opts.openDelimiter || exports.openDelimiter || _DEFAULT_OPEN_DELIMITER;
|
|
446
|
+
options.closeDelimiter = opts.closeDelimiter || exports.closeDelimiter || _DEFAULT_CLOSE_DELIMITER;
|
|
447
|
+
options.delimiter = opts.delimiter || exports.delimiter || _DEFAULT_DELIMITER;
|
|
448
|
+
options.strict = opts.strict || false;
|
|
449
|
+
options.context = opts.context;
|
|
450
|
+
options.cache = opts.cache || false;
|
|
451
|
+
options.rmWhitespace = opts.rmWhitespace;
|
|
452
|
+
options.root = opts.root;
|
|
453
|
+
options.includer = opts.includer;
|
|
454
|
+
options.outputFunctionName = opts.outputFunctionName;
|
|
455
|
+
options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME;
|
|
456
|
+
options.views = opts.views;
|
|
457
|
+
options.async = opts.async;
|
|
458
|
+
options.destructuredLocals = opts.destructuredLocals;
|
|
459
|
+
options.legacyInclude = typeof opts.legacyInclude != "undefined" ? !!opts.legacyInclude : true;
|
|
460
|
+
if (options.strict) {
|
|
461
|
+
options._with = false;
|
|
462
|
+
} else {
|
|
463
|
+
options._with = typeof opts._with != "undefined" ? opts._with : true;
|
|
464
|
+
}
|
|
465
|
+
this.opts = options;
|
|
466
|
+
this.regex = this.createRegex();
|
|
467
|
+
}
|
|
468
|
+
Template.modes = {
|
|
469
|
+
EVAL: "eval",
|
|
470
|
+
ESCAPED: "escaped",
|
|
471
|
+
RAW: "raw",
|
|
472
|
+
COMMENT: "comment",
|
|
473
|
+
LITERAL: "literal"
|
|
474
|
+
};
|
|
475
|
+
Template.prototype = {
|
|
476
|
+
createRegex: function() {
|
|
477
|
+
var str = _REGEX_STRING;
|
|
478
|
+
var delim = utils.escapeRegExpChars(this.opts.delimiter);
|
|
479
|
+
var open = utils.escapeRegExpChars(this.opts.openDelimiter);
|
|
480
|
+
var close = utils.escapeRegExpChars(this.opts.closeDelimiter);
|
|
481
|
+
str = str.replace(/%/g, delim).replace(/</g, open).replace(/>/g, close);
|
|
482
|
+
return new RegExp(str);
|
|
483
|
+
},
|
|
484
|
+
compile: function() {
|
|
485
|
+
var src;
|
|
486
|
+
var fn;
|
|
487
|
+
var opts = this.opts;
|
|
488
|
+
var prepended = "";
|
|
489
|
+
var appended = "";
|
|
490
|
+
var escapeFn = opts.escapeFunction;
|
|
491
|
+
var ctor;
|
|
492
|
+
var sanitizedFilename = opts.filename ? JSON.stringify(opts.filename) : "undefined";
|
|
493
|
+
if (!this.source) {
|
|
494
|
+
this.generateSource();
|
|
495
|
+
prepended += ` var __output = "";
|
|
496
|
+
` + ` function __append(s) { if (s !== undefined && s !== null) __output += s }
|
|
497
|
+
`;
|
|
498
|
+
if (opts.outputFunctionName) {
|
|
499
|
+
if (!_JS_IDENTIFIER.test(opts.outputFunctionName)) {
|
|
500
|
+
throw new Error("outputFunctionName is not a valid JS identifier.");
|
|
501
|
+
}
|
|
502
|
+
prepended += " var " + opts.outputFunctionName + " = __append;" + `
|
|
503
|
+
`;
|
|
504
|
+
}
|
|
505
|
+
if (opts.localsName && !_JS_IDENTIFIER.test(opts.localsName)) {
|
|
506
|
+
throw new Error("localsName is not a valid JS identifier.");
|
|
507
|
+
}
|
|
508
|
+
if (opts.destructuredLocals && opts.destructuredLocals.length) {
|
|
509
|
+
var destructuring = " var __locals = (" + opts.localsName + ` || {}),
|
|
510
|
+
`;
|
|
511
|
+
for (var i = 0;i < opts.destructuredLocals.length; i++) {
|
|
512
|
+
var name = opts.destructuredLocals[i];
|
|
513
|
+
if (!_JS_IDENTIFIER.test(name)) {
|
|
514
|
+
throw new Error("destructuredLocals[" + i + "] is not a valid JS identifier.");
|
|
515
|
+
}
|
|
516
|
+
if (i > 0) {
|
|
517
|
+
destructuring += `,
|
|
518
|
+
`;
|
|
519
|
+
}
|
|
520
|
+
destructuring += name + " = __locals." + name;
|
|
521
|
+
}
|
|
522
|
+
prepended += destructuring + `;
|
|
523
|
+
`;
|
|
524
|
+
}
|
|
525
|
+
if (opts._with !== false) {
|
|
526
|
+
prepended += " with (" + opts.localsName + " || {}) {" + `
|
|
527
|
+
`;
|
|
528
|
+
appended += " }" + `
|
|
529
|
+
`;
|
|
530
|
+
}
|
|
531
|
+
appended += " return __output;" + `
|
|
532
|
+
`;
|
|
533
|
+
this.source = prepended + this.source + appended;
|
|
534
|
+
}
|
|
535
|
+
if (opts.compileDebug) {
|
|
536
|
+
src = "var __line = 1" + `
|
|
537
|
+
` + " , __lines = " + JSON.stringify(this.templateText) + `
|
|
538
|
+
` + " , __filename = " + sanitizedFilename + ";" + `
|
|
539
|
+
` + "try {" + `
|
|
540
|
+
` + this.source + "} catch (e) {" + `
|
|
541
|
+
` + " rethrow(e, __lines, __filename, __line, escapeFn);" + `
|
|
542
|
+
` + "}" + `
|
|
543
|
+
`;
|
|
544
|
+
} else {
|
|
545
|
+
src = this.source;
|
|
546
|
+
}
|
|
547
|
+
if (opts.client) {
|
|
548
|
+
src = "escapeFn = escapeFn || " + escapeFn.toString() + ";" + `
|
|
549
|
+
` + src;
|
|
550
|
+
if (opts.compileDebug) {
|
|
551
|
+
src = "rethrow = rethrow || " + rethrow.toString() + ";" + `
|
|
552
|
+
` + src;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (opts.strict) {
|
|
556
|
+
src = `"use strict";
|
|
557
|
+
` + src;
|
|
558
|
+
}
|
|
559
|
+
if (opts.debug) {
|
|
560
|
+
console.log(src);
|
|
561
|
+
}
|
|
562
|
+
if (opts.compileDebug && opts.filename) {
|
|
563
|
+
src = src + `
|
|
564
|
+
` + "//# sourceURL=" + sanitizedFilename + `
|
|
565
|
+
`;
|
|
566
|
+
}
|
|
567
|
+
try {
|
|
568
|
+
if (opts.async) {
|
|
569
|
+
try {
|
|
570
|
+
ctor = new Function("return (async function(){}).constructor;")();
|
|
571
|
+
} catch (e) {
|
|
572
|
+
if (e instanceof SyntaxError) {
|
|
573
|
+
throw new Error("This environment does not support async/await");
|
|
574
|
+
} else {
|
|
575
|
+
throw e;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
} else {
|
|
579
|
+
ctor = Function;
|
|
580
|
+
}
|
|
581
|
+
fn = new ctor(opts.localsName + ", escapeFn, include, rethrow", src);
|
|
582
|
+
} catch (e) {
|
|
583
|
+
if (e instanceof SyntaxError) {
|
|
584
|
+
if (opts.filename) {
|
|
585
|
+
e.message += " in " + opts.filename;
|
|
586
|
+
}
|
|
587
|
+
e.message += ` while compiling ejs
|
|
588
|
+
|
|
589
|
+
`;
|
|
590
|
+
e.message += `If the above error is not helpful, you may want to try EJS-Lint:
|
|
591
|
+
`;
|
|
592
|
+
e.message += "https://github.com/RyanZim/EJS-Lint";
|
|
593
|
+
if (!opts.async) {
|
|
594
|
+
e.message += `
|
|
595
|
+
`;
|
|
596
|
+
e.message += "Or, if you meant to create an async function, pass `async: true` as an option.";
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
throw e;
|
|
600
|
+
}
|
|
601
|
+
var returnedFn = opts.client ? fn : function anonymous(data) {
|
|
602
|
+
var include = function(path2, includeData) {
|
|
603
|
+
var d = utils.shallowCopy(utils.createNullProtoObjWherePossible(), data);
|
|
604
|
+
if (includeData) {
|
|
605
|
+
d = utils.shallowCopy(d, includeData);
|
|
606
|
+
}
|
|
607
|
+
return includeFile(path2, opts)(d);
|
|
608
|
+
};
|
|
609
|
+
return fn.apply(opts.context, [data || utils.createNullProtoObjWherePossible(), escapeFn, include, rethrow]);
|
|
610
|
+
};
|
|
611
|
+
if (opts.filename && typeof Object.defineProperty === "function") {
|
|
612
|
+
var filename = opts.filename;
|
|
613
|
+
var basename = path.basename(filename, path.extname(filename));
|
|
614
|
+
try {
|
|
615
|
+
Object.defineProperty(returnedFn, "name", {
|
|
616
|
+
value: basename,
|
|
617
|
+
writable: false,
|
|
618
|
+
enumerable: false,
|
|
619
|
+
configurable: true
|
|
620
|
+
});
|
|
621
|
+
} catch (e) {
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return returnedFn;
|
|
625
|
+
},
|
|
626
|
+
generateSource: function() {
|
|
627
|
+
var opts = this.opts;
|
|
628
|
+
if (opts.rmWhitespace) {
|
|
629
|
+
this.templateText = this.templateText.replace(/[\r\n]+/g, `
|
|
630
|
+
`).replace(/^\s+|\s+$/gm, "");
|
|
631
|
+
}
|
|
632
|
+
this.templateText = this.templateText.replace(/[ \t]*<%_/gm, "<%_").replace(/_%>[ \t]*/gm, "_%>");
|
|
633
|
+
var self = this;
|
|
634
|
+
var matches = this.parseTemplateText();
|
|
635
|
+
var d = this.opts.delimiter;
|
|
636
|
+
var o = this.opts.openDelimiter;
|
|
637
|
+
var c = this.opts.closeDelimiter;
|
|
638
|
+
if (matches && matches.length) {
|
|
639
|
+
matches.forEach(function(line, index) {
|
|
640
|
+
var closing;
|
|
641
|
+
if (line.indexOf(o + d) === 0 && line.indexOf(o + d + d) !== 0) {
|
|
642
|
+
closing = matches[index + 2];
|
|
643
|
+
if (!(closing == d + c || closing == "-" + d + c || closing == "_" + d + c)) {
|
|
644
|
+
throw new Error('Could not find matching close tag for "' + line + '".');
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
self.scanLine(line);
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
},
|
|
651
|
+
parseTemplateText: function() {
|
|
652
|
+
var str = this.templateText;
|
|
653
|
+
var pat = this.regex;
|
|
654
|
+
var result = pat.exec(str);
|
|
655
|
+
var arr = [];
|
|
656
|
+
var firstPos;
|
|
657
|
+
while (result) {
|
|
658
|
+
firstPos = result.index;
|
|
659
|
+
if (firstPos !== 0) {
|
|
660
|
+
arr.push(str.substring(0, firstPos));
|
|
661
|
+
str = str.slice(firstPos);
|
|
662
|
+
}
|
|
663
|
+
arr.push(result[0]);
|
|
664
|
+
str = str.slice(result[0].length);
|
|
665
|
+
result = pat.exec(str);
|
|
666
|
+
}
|
|
667
|
+
if (str) {
|
|
668
|
+
arr.push(str);
|
|
669
|
+
}
|
|
670
|
+
return arr;
|
|
671
|
+
},
|
|
672
|
+
_addOutput: function(line) {
|
|
673
|
+
if (this.truncate) {
|
|
674
|
+
line = line.replace(/^(?:\r\n|\r|\n)/, "");
|
|
675
|
+
this.truncate = false;
|
|
676
|
+
}
|
|
677
|
+
if (!line) {
|
|
678
|
+
return line;
|
|
679
|
+
}
|
|
680
|
+
line = line.replace(/\\/g, "\\\\");
|
|
681
|
+
line = line.replace(/\n/g, "\\n");
|
|
682
|
+
line = line.replace(/\r/g, "\\r");
|
|
683
|
+
line = line.replace(/"/g, "\\\"");
|
|
684
|
+
this.source += ' ; __append("' + line + '")' + `
|
|
685
|
+
`;
|
|
686
|
+
},
|
|
687
|
+
scanLine: function(line) {
|
|
688
|
+
var self = this;
|
|
689
|
+
var d = this.opts.delimiter;
|
|
690
|
+
var o = this.opts.openDelimiter;
|
|
691
|
+
var c = this.opts.closeDelimiter;
|
|
692
|
+
var newLineCount = 0;
|
|
693
|
+
newLineCount = line.split(`
|
|
694
|
+
`).length - 1;
|
|
695
|
+
switch (line) {
|
|
696
|
+
case o + d:
|
|
697
|
+
case o + d + "_":
|
|
698
|
+
this.mode = Template.modes.EVAL;
|
|
699
|
+
break;
|
|
700
|
+
case o + d + "=":
|
|
701
|
+
this.mode = Template.modes.ESCAPED;
|
|
702
|
+
break;
|
|
703
|
+
case o + d + "-":
|
|
704
|
+
this.mode = Template.modes.RAW;
|
|
705
|
+
break;
|
|
706
|
+
case o + d + "#":
|
|
707
|
+
this.mode = Template.modes.COMMENT;
|
|
708
|
+
break;
|
|
709
|
+
case o + d + d:
|
|
710
|
+
this.mode = Template.modes.LITERAL;
|
|
711
|
+
this.source += ' ; __append("' + line.replace(o + d + d, o + d) + '")' + `
|
|
712
|
+
`;
|
|
713
|
+
break;
|
|
714
|
+
case d + d + c:
|
|
715
|
+
this.mode = Template.modes.LITERAL;
|
|
716
|
+
this.source += ' ; __append("' + line.replace(d + d + c, d + c) + '")' + `
|
|
717
|
+
`;
|
|
718
|
+
break;
|
|
719
|
+
case d + c:
|
|
720
|
+
case "-" + d + c:
|
|
721
|
+
case "_" + d + c:
|
|
722
|
+
if (this.mode == Template.modes.LITERAL) {
|
|
723
|
+
this._addOutput(line);
|
|
724
|
+
}
|
|
725
|
+
this.mode = null;
|
|
726
|
+
this.truncate = line.indexOf("-") === 0 || line.indexOf("_") === 0;
|
|
727
|
+
break;
|
|
728
|
+
default:
|
|
729
|
+
if (this.mode) {
|
|
730
|
+
switch (this.mode) {
|
|
731
|
+
case Template.modes.EVAL:
|
|
732
|
+
case Template.modes.ESCAPED:
|
|
733
|
+
case Template.modes.RAW:
|
|
734
|
+
if (line.lastIndexOf("//") > line.lastIndexOf(`
|
|
735
|
+
`)) {
|
|
736
|
+
line += `
|
|
737
|
+
`;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
switch (this.mode) {
|
|
741
|
+
case Template.modes.EVAL:
|
|
742
|
+
this.source += " ; " + line + `
|
|
743
|
+
`;
|
|
744
|
+
break;
|
|
745
|
+
case Template.modes.ESCAPED:
|
|
746
|
+
this.source += " ; __append(escapeFn(" + stripSemi(line) + "))" + `
|
|
747
|
+
`;
|
|
748
|
+
break;
|
|
749
|
+
case Template.modes.RAW:
|
|
750
|
+
this.source += " ; __append(" + stripSemi(line) + ")" + `
|
|
751
|
+
`;
|
|
752
|
+
break;
|
|
753
|
+
case Template.modes.COMMENT:
|
|
754
|
+
break;
|
|
755
|
+
case Template.modes.LITERAL:
|
|
756
|
+
this._addOutput(line);
|
|
757
|
+
break;
|
|
758
|
+
}
|
|
759
|
+
} else {
|
|
760
|
+
this._addOutput(line);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
if (self.opts.compileDebug && newLineCount) {
|
|
764
|
+
this.currentLine += newLineCount;
|
|
765
|
+
this.source += " ; __line = " + this.currentLine + `
|
|
766
|
+
`;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
exports.escapeXML = utils.escapeXML;
|
|
771
|
+
exports.__express = exports.renderFile;
|
|
772
|
+
exports.VERSION = _VERSION_STRING;
|
|
773
|
+
exports.name = _NAME;
|
|
774
|
+
if (typeof window != "undefined") {
|
|
775
|
+
window.ejs = exports;
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
// node_modules/picocolors/picocolors.js
|
|
780
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
781
|
+
var p = process || {};
|
|
782
|
+
var argv = p.argv || [];
|
|
783
|
+
var env = p.env || {};
|
|
784
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
785
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
786
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
787
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
788
|
+
};
|
|
789
|
+
var replaceClose = (string, close, replace, index) => {
|
|
790
|
+
let result = "", cursor = 0;
|
|
791
|
+
do {
|
|
792
|
+
result += string.substring(cursor, index) + replace;
|
|
793
|
+
cursor = index + close.length;
|
|
794
|
+
index = string.indexOf(close, cursor);
|
|
795
|
+
} while (~index);
|
|
796
|
+
return result + string.substring(cursor);
|
|
797
|
+
};
|
|
798
|
+
var createColors = (enabled = isColorSupported) => {
|
|
799
|
+
let f = enabled ? formatter : () => String;
|
|
800
|
+
return {
|
|
801
|
+
isColorSupported: enabled,
|
|
802
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
803
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
804
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
805
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
806
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
807
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
808
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
809
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
810
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
811
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
812
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
813
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
814
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
815
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
816
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
817
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
818
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
819
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
820
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
821
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
822
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
823
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
824
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
825
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
826
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
827
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
828
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
829
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
830
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
831
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
832
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
833
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
834
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
835
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
836
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
837
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
838
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
839
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
840
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
841
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
842
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
843
|
+
};
|
|
844
|
+
};
|
|
845
|
+
module.exports = createColors();
|
|
846
|
+
module.exports.createColors = createColors;
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
// src/server.ts
|
|
850
|
+
var import_ejs = __toESM(require_ejs(), 1);
|
|
851
|
+
var Bun = globalThis.Bun;
|
|
852
|
+
var {$: $2 } = Bun;
|
|
853
|
+
|
|
854
|
+
// src/serveOutputTemplate.ejs
|
|
855
|
+
var serveOutputTemplate_default = `<!DOCTYPE html>\r
|
|
856
|
+
<html lang="en">\r
|
|
857
|
+
\r
|
|
858
|
+
<head>\r
|
|
859
|
+
<meta charset="UTF-8" />\r
|
|
860
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />\r
|
|
861
|
+
<title>Document</title>\r
|
|
862
|
+
</head>\r
|
|
863
|
+
\r
|
|
864
|
+
<body>\r
|
|
865
|
+
<a href="../">..</a>\r
|
|
866
|
+
<% dirs.forEach(element => { %> <br /><a href=".<%= element.requestPath %>/<%= element.name %>"><%= element.name %></a> <% }) %>\r
|
|
867
|
+
<% files.forEach(element => { %> <br /><a href=".<%= element.requestPath %>/<%= element.name %>"><%= element.name %></a> <% }) %>\r
|
|
868
|
+
</body>\r
|
|
869
|
+
\r
|
|
870
|
+
</html>`;
|
|
871
|
+
|
|
872
|
+
// src/indexHTMLTemplate.ejs
|
|
873
|
+
var indexHTMLTemplate_default = `<!DOCTYPE html>\r
|
|
874
|
+
<html lang="en">\r
|
|
875
|
+
<head>\r
|
|
876
|
+
<meta charset="UTF-8" />\r
|
|
877
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />\r
|
|
878
|
+
<title>Bun HTML File</title>\r
|
|
879
|
+
<% for (const hashedJs of hashedImports) { %>\r
|
|
880
|
+
<script type="module" src="<%= hashedJs %>"></script>\r
|
|
881
|
+
<% } %>\r
|
|
882
|
+
</head>\r
|
|
883
|
+
\r
|
|
884
|
+
<body>\r
|
|
885
|
+
<div id="app"></div>\r
|
|
886
|
+
</body>\r
|
|
887
|
+
</html>\r
|
|
888
|
+
`;
|
|
889
|
+
|
|
890
|
+
// src/server.ts
|
|
891
|
+
import { watch, readdir, exists, readFile as readFile2 } from "fs/promises";
|
|
892
|
+
|
|
893
|
+
// src/bunClientHmr.ts
|
|
894
|
+
function hotReload() {
|
|
895
|
+
if (window.BUN_HMR_INITED) {
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
window.BUN_HMR_INITED = true;
|
|
899
|
+
const hmrSock = new WebSocket("[REPLACE_ENDPOINT]");
|
|
900
|
+
hmrSock.addEventListener("error", (err) => {
|
|
901
|
+
console.error("HMR ERROR", err);
|
|
902
|
+
});
|
|
903
|
+
hmrSock.addEventListener("message", (msg) => {
|
|
904
|
+
let parsed = msg.data;
|
|
905
|
+
try {
|
|
906
|
+
parsed = JSON.parse(msg.data);
|
|
907
|
+
} catch (e) {
|
|
908
|
+
}
|
|
909
|
+
if (parsed?.type === "message") {
|
|
910
|
+
console.log(parsed.message);
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
if (parsed?.type === "output") {
|
|
914
|
+
console.table(parsed.message);
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
if (parsed?.type === "reload") {
|
|
918
|
+
window.location.reload();
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
if (parsed?.type === "error") {
|
|
922
|
+
console.error(parsed.message);
|
|
923
|
+
let newDiv = window.document.getElementById("bun-hmr-error");
|
|
924
|
+
const divExists = !!newDiv;
|
|
925
|
+
if (!newDiv) {
|
|
926
|
+
newDiv = window.document.createElement("div");
|
|
927
|
+
}
|
|
928
|
+
newDiv.id = "bun-hmr-error";
|
|
929
|
+
newDiv.innerText += parsed.message;
|
|
930
|
+
if (!divExists) {
|
|
931
|
+
window.document.body.appendChild(newDiv);
|
|
932
|
+
}
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
var DEFAULT_HMR_PATH = "/hmr-ws";
|
|
938
|
+
function bunHotReload(bunServerConfig) {
|
|
939
|
+
const socketPath = bunServerConfig.websocketPath || DEFAULT_HMR_PATH;
|
|
940
|
+
const endPath = socketPath.startsWith("/") ? socketPath : `/${socketPath}`;
|
|
941
|
+
const path = `${bunServerConfig.secure ? "wss" : "ws"}://localhost:${bunServerConfig.port}${endPath}`;
|
|
942
|
+
return hotReload.toString().replace("[REPLACE_ENDPOINT]", path);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// src/bunHmrPlugin.ts
|
|
946
|
+
import { readFile } from "fs/promises";
|
|
947
|
+
function bunHotReloadPlugin(config) {
|
|
948
|
+
const bunHMRPlugin = {
|
|
949
|
+
name: "hmr",
|
|
950
|
+
target: "browser",
|
|
951
|
+
setup(build) {
|
|
952
|
+
const entryPoints = [];
|
|
953
|
+
const addedEnryPoints = new Set;
|
|
954
|
+
build.config.entrypoints.forEach((entry) => {
|
|
955
|
+
let entryPath = entry.replace(/^\.*/, "");
|
|
956
|
+
if (process.platform === "win32") {
|
|
957
|
+
entryPath = entryPath.replace(/\//g, "\\");
|
|
958
|
+
}
|
|
959
|
+
entryPoints.push(entryPath);
|
|
960
|
+
});
|
|
961
|
+
build.onLoad({ filter: /\.m?tsx?/ }, async (args) => {
|
|
962
|
+
const contents = await readFile(args.path, { encoding: "utf-8" });
|
|
963
|
+
const isTSx = /\.m?tsx$/.test(args.path);
|
|
964
|
+
const isJSx = /\.m?jsx$/.test(args.path);
|
|
965
|
+
const isJS = /\.m?js$/.test(args.path);
|
|
966
|
+
const isTS = /\.m?ts$/.test(args.path);
|
|
967
|
+
const loader = isTSx ? "tsx" : isJSx ? "jsx" : isTS ? "ts" : isJS ? "js" : "text";
|
|
968
|
+
const isEntry = entryPoints.some((entry) => args.path.endsWith(entry));
|
|
969
|
+
if (!addedEnryPoints.has(args.path) && isEntry) {
|
|
970
|
+
addedEnryPoints.add(args.path);
|
|
971
|
+
return { contents: `import "bun-hot-reload"
|
|
972
|
+
` + contents, loader };
|
|
973
|
+
}
|
|
974
|
+
return { contents, loader };
|
|
975
|
+
});
|
|
976
|
+
build.onLoad({ filter: /./, namespace: "bun-hot-reload" }, async (args) => {
|
|
977
|
+
return { contents: `(${bunHotReload(config)})()
|
|
978
|
+
`, loader: "ts" };
|
|
979
|
+
});
|
|
980
|
+
build.onResolve({ filter: /^bun-hot-reload$/ }, (args) => {
|
|
981
|
+
return { path: args.path, namespace: "bun-hot-reload" };
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
return bunHMRPlugin;
|
|
986
|
+
}
|
|
987
|
+
function getBunHMRFooter(config) {
|
|
988
|
+
return `;(${bunHotReload(config)})();`;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
// src/bunManifest.ts
|
|
992
|
+
var {write, pathToFileURL } = globalThis.Bun;
|
|
993
|
+
function writeManifest(output, outdir, withHash = false, manifestName = "bunmanifest.txt") {
|
|
994
|
+
const entryPoints = output.outputs.filter((o) => o.kind === "entry-point");
|
|
995
|
+
const epTable = [];
|
|
996
|
+
for (const ep of entryPoints) {
|
|
997
|
+
const basePathUrl = pathToFileURL(outdir);
|
|
998
|
+
const epUrl = pathToFileURL(ep.path);
|
|
999
|
+
const relativePath = epUrl.href.replace(`${basePathUrl.href}/`, "");
|
|
1000
|
+
const hashedImport = `${relativePath}${withHash ? `?${ep.hash}` : ``}`;
|
|
1001
|
+
epTable.push(hashedImport);
|
|
1002
|
+
}
|
|
1003
|
+
const outObj = { js: epTable };
|
|
1004
|
+
write(`${outdir}/${manifestName}`, JSON.stringify(outObj));
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// src/tsChecker.ts
|
|
1008
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
1009
|
+
var {$ } = globalThis.Bun;
|
|
1010
|
+
async function performTSC(finalConfig) {
|
|
1011
|
+
if (finalConfig.enableTSC) {
|
|
1012
|
+
console.log("Performing TSC check");
|
|
1013
|
+
const tsc = await $`tsc`.nothrow().quiet();
|
|
1014
|
+
if (tsc.exitCode === 0) {
|
|
1015
|
+
console.log(import_picocolors.default.bgGreen("\u2714 [SUCCESS]"), "TSC check passed");
|
|
1016
|
+
} else {
|
|
1017
|
+
console.log(import_picocolors.default.bgRed("\u2718 [ERROR]"), `\r
|
|
1018
|
+
${tsc.stdout.toString()}`);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// src/server.ts
|
|
1024
|
+
async function startBunDevServer(serverConfig) {
|
|
1025
|
+
const defaultConfig = {
|
|
1026
|
+
port: 3000,
|
|
1027
|
+
websocketPath: DEFAULT_HMR_PATH,
|
|
1028
|
+
serveOutputEjs: serveOutputTemplate_default,
|
|
1029
|
+
serveOutputHtml: indexHTMLTemplate_default
|
|
1030
|
+
};
|
|
1031
|
+
const finalConfig = { ...defaultConfig, ...serverConfig };
|
|
1032
|
+
if (!finalConfig.watchDir) {
|
|
1033
|
+
throw new Error("watchDir must be set");
|
|
1034
|
+
}
|
|
1035
|
+
const serveDestination = finalConfig.buildConfig.outdir ?? finalConfig.servePath ?? "dist";
|
|
1036
|
+
const bunDestinationPath = Bun.pathToFileURL(serveDestination);
|
|
1037
|
+
const bunWatchDirPath = Bun.pathToFileURL(finalConfig.watchDir);
|
|
1038
|
+
const dst = process.platform === "win32" ? bunDestinationPath.pathname.substring(1) : bunDestinationPath.pathname;
|
|
1039
|
+
const srcWatch = process.platform === "win32" ? bunWatchDirPath.pathname.substring(1) : bunWatchDirPath.pathname;
|
|
1040
|
+
try {
|
|
1041
|
+
await readdir(dst);
|
|
1042
|
+
} catch (e) {
|
|
1043
|
+
if (e.code === "ENOENT") {
|
|
1044
|
+
console.log("Directory not found, creating it...");
|
|
1045
|
+
await $2`mkdir ${dst}`;
|
|
1046
|
+
} else {
|
|
1047
|
+
throw e;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
const buncfg = { port: finalConfig.port, tls: finalConfig.tls, websocketPath: finalConfig.websocketPath };
|
|
1051
|
+
const buildCfg = {
|
|
1052
|
+
...serverConfig.buildConfig,
|
|
1053
|
+
outdir: dst
|
|
1054
|
+
};
|
|
1055
|
+
if (finalConfig.hotReload === "footer") {
|
|
1056
|
+
if (!buildCfg.footer) {
|
|
1057
|
+
buildCfg.footer = "";
|
|
1058
|
+
}
|
|
1059
|
+
buildCfg.footer += getBunHMRFooter(buncfg);
|
|
1060
|
+
}
|
|
1061
|
+
if (finalConfig.hotReload === "plugin") {
|
|
1062
|
+
if (!buildCfg.plugins) {
|
|
1063
|
+
buildCfg.plugins = [];
|
|
1064
|
+
}
|
|
1065
|
+
buildCfg.plugins.push(bunHotReloadPlugin(buncfg));
|
|
1066
|
+
}
|
|
1067
|
+
if (serverConfig.cleanServePath) {
|
|
1068
|
+
await cleanDirectory(dst);
|
|
1069
|
+
}
|
|
1070
|
+
console.log("Starting Bun Dev Server on port", finalConfig.port);
|
|
1071
|
+
const bunServer = Bun.serve({
|
|
1072
|
+
port: finalConfig.port,
|
|
1073
|
+
development: true,
|
|
1074
|
+
tls: finalConfig.tls,
|
|
1075
|
+
async fetch(req, server) {
|
|
1076
|
+
if (req.method === "OPTIONS") {
|
|
1077
|
+
const response = new Response("", { status: 200 });
|
|
1078
|
+
augumentHeaders(req, response);
|
|
1079
|
+
return response;
|
|
1080
|
+
}
|
|
1081
|
+
if (req.url.toLowerCase().endsWith("/favicon.ico")) {
|
|
1082
|
+
const response = new Response("", { status: 404 });
|
|
1083
|
+
augumentHeaders(req, response);
|
|
1084
|
+
return response;
|
|
1085
|
+
}
|
|
1086
|
+
if (req.url.toLowerCase().endsWith(finalConfig.websocketPath)) {
|
|
1087
|
+
if (server.upgrade(req)) {
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
const url = new URL(req.url);
|
|
1092
|
+
const requestPath = url.pathname;
|
|
1093
|
+
const objThere = await exists(dst + requestPath);
|
|
1094
|
+
let isDirectory = false;
|
|
1095
|
+
if (objThere) {
|
|
1096
|
+
try {
|
|
1097
|
+
await readFile2(dst + requestPath);
|
|
1098
|
+
} catch (e) {
|
|
1099
|
+
if (e.code === "EISDIR") {
|
|
1100
|
+
isDirectory = true;
|
|
1101
|
+
} else {
|
|
1102
|
+
throw e;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
} else {
|
|
1106
|
+
const response = new Response("", { status: 404 });
|
|
1107
|
+
augumentHeaders(req, response);
|
|
1108
|
+
return response;
|
|
1109
|
+
}
|
|
1110
|
+
if (!isDirectory) {
|
|
1111
|
+
try {
|
|
1112
|
+
const fl = Bun.file(dst + requestPath);
|
|
1113
|
+
const response = new Response(fl);
|
|
1114
|
+
augumentHeaders(req, response);
|
|
1115
|
+
return response;
|
|
1116
|
+
} catch (e) {
|
|
1117
|
+
if (e.code === "ENOENT") {
|
|
1118
|
+
const response = new Response("", { status: 404 });
|
|
1119
|
+
augumentHeaders(req, response);
|
|
1120
|
+
return response;
|
|
1121
|
+
} else {
|
|
1122
|
+
throw e;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
try {
|
|
1127
|
+
const allEntries = await readdir(dst + requestPath, {
|
|
1128
|
+
withFileTypes: true
|
|
1129
|
+
});
|
|
1130
|
+
const dirs = allEntries.filter((entry) => entry.isDirectory()).map((entry) => {
|
|
1131
|
+
return {
|
|
1132
|
+
requestPath: requestPath === "/" ? "" : requestPath,
|
|
1133
|
+
name: entry.name
|
|
1134
|
+
};
|
|
1135
|
+
});
|
|
1136
|
+
const files = allEntries.filter((entry) => entry.isFile()).map((entry) => {
|
|
1137
|
+
return {
|
|
1138
|
+
requestPath: requestPath === "/" ? "" : requestPath,
|
|
1139
|
+
name: entry.name
|
|
1140
|
+
};
|
|
1141
|
+
});
|
|
1142
|
+
const rnd = import_ejs.render(finalConfig.serveOutputEjs, { dirs, files });
|
|
1143
|
+
const response = new Response(rnd, { headers: { "Content-Type": "text/html" } });
|
|
1144
|
+
augumentHeaders(req, response);
|
|
1145
|
+
return response;
|
|
1146
|
+
} catch {
|
|
1147
|
+
const response = new Response("Not Found", { status: 404 });
|
|
1148
|
+
augumentHeaders(req, response);
|
|
1149
|
+
return response;
|
|
1150
|
+
}
|
|
1151
|
+
},
|
|
1152
|
+
websocket: {
|
|
1153
|
+
open(ws) {
|
|
1154
|
+
ws.subscribe("message");
|
|
1155
|
+
},
|
|
1156
|
+
message(ws, message) {
|
|
1157
|
+
},
|
|
1158
|
+
sendPings: true
|
|
1159
|
+
}
|
|
1160
|
+
});
|
|
1161
|
+
const output = await Bun.build(buildCfg);
|
|
1162
|
+
publishOutputLogs(output, { filename: "Initial", eventType: "change" });
|
|
1163
|
+
publishIndexHTML(output, { filename: "Initial", eventType: "change" });
|
|
1164
|
+
if (finalConfig.writeManifest) {
|
|
1165
|
+
writeManifest(output, dst, finalConfig.manifestWithHash, finalConfig.manifestName);
|
|
1166
|
+
}
|
|
1167
|
+
await performTSC(finalConfig);
|
|
1168
|
+
const watcher = watch(srcWatch, { recursive: true });
|
|
1169
|
+
for await (const event of watcher) {
|
|
1170
|
+
if (finalConfig.cleanServePath) {
|
|
1171
|
+
await cleanDirectory(dst);
|
|
1172
|
+
}
|
|
1173
|
+
const output2 = await Bun.build(buildCfg);
|
|
1174
|
+
publishOutputLogs(output2, event);
|
|
1175
|
+
publishIndexHTML(output2, event);
|
|
1176
|
+
if (finalConfig.writeManifest) {
|
|
1177
|
+
writeManifest(output2, dst, finalConfig.manifestWithHash, finalConfig.manifestName);
|
|
1178
|
+
}
|
|
1179
|
+
await performTSC(finalConfig);
|
|
1180
|
+
if (finalConfig.reloadOnChange) {
|
|
1181
|
+
bunServer.publish("message", JSON.stringify({ type: "reload" }));
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
function publishOutputLogs(output2, event) {
|
|
1185
|
+
output2.logs.forEach(console.log);
|
|
1186
|
+
bunServer.publish("message", JSON.stringify({ type: "message", message: `[Bun HMR] ${event.filename} ${event.eventType}` }));
|
|
1187
|
+
const outTable = output2.outputs.filter((o) => o.kind !== "sourcemap").map((o) => {
|
|
1188
|
+
const a = Bun.pathToFileURL(o.path);
|
|
1189
|
+
const fileName = a.href.substring(a.href.lastIndexOf("/") + 1);
|
|
1190
|
+
return {
|
|
1191
|
+
name: fileName,
|
|
1192
|
+
path: o.path,
|
|
1193
|
+
size: convertBytes(o.size)
|
|
1194
|
+
};
|
|
1195
|
+
});
|
|
1196
|
+
console.table(outTable);
|
|
1197
|
+
bunServer.publish("message", JSON.stringify({ type: "output", message: outTable }));
|
|
1198
|
+
}
|
|
1199
|
+
function publishIndexHTML(output2, event) {
|
|
1200
|
+
const eps = output2.outputs.filter((o) => o.kind === "entry-point");
|
|
1201
|
+
const hashedImports = [];
|
|
1202
|
+
for (const ep of eps) {
|
|
1203
|
+
const basePathUrl = Bun.pathToFileURL(dst);
|
|
1204
|
+
const epUrl = Bun.pathToFileURL(ep.path);
|
|
1205
|
+
const hashedImport = `${epUrl.href.replace(basePathUrl.href, "")}?${ep.hash}`;
|
|
1206
|
+
hashedImports.push(hashedImport);
|
|
1207
|
+
}
|
|
1208
|
+
Bun.write(dst + "/index.html", import_ejs.render(finalConfig.serveOutputHtml, { hashedImports }));
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
function augumentHeaders(request, response) {
|
|
1212
|
+
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin") ?? "*");
|
|
1213
|
+
response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
1214
|
+
response.headers.set("Access-Control-Allow-Credentials", "true");
|
|
1215
|
+
}
|
|
1216
|
+
async function cleanDirectory(dst) {
|
|
1217
|
+
const { stderr, exitCode } = await $2`rm -rf ${dst}/*`.nothrow();
|
|
1218
|
+
if (exitCode !== 0) {
|
|
1219
|
+
if (stderr.indexOf("no matches found") > -1) {
|
|
1220
|
+
console.log("Directory is empty");
|
|
1221
|
+
} else {
|
|
1222
|
+
throw stderr;
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
function convertBytes(bytes) {
|
|
1227
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
|
1228
|
+
if (bytes == 0) {
|
|
1229
|
+
return "n/a";
|
|
1230
|
+
}
|
|
1231
|
+
const floored = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
1232
|
+
const i = floored;
|
|
1233
|
+
if (i == 0) {
|
|
1234
|
+
return bytes + " " + sizes[i];
|
|
1235
|
+
}
|
|
1236
|
+
return (bytes / Math.pow(1024, i)).toFixed(1) + " " + sizes[i];
|
|
1237
|
+
}
|
|
1238
|
+
export {
|
|
1239
|
+
startBunDevServer,
|
|
1240
|
+
getBunHMRFooter,
|
|
1241
|
+
bunHotReloadPlugin
|
|
1242
|
+
};
|