elit 2.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +275 -128
- package/dist/build.d.mts +10 -1
- package/dist/build.d.ts +10 -1
- package/dist/build.js +670 -1
- package/dist/build.mjs +641 -1
- package/dist/chokidar.d.mts +134 -0
- package/dist/chokidar.d.ts +134 -0
- package/dist/chokidar.js +240 -0
- package/dist/chokidar.mjs +221 -0
- package/dist/cli.js +2792 -495
- package/dist/dom.d.mts +10 -3
- package/dist/dom.d.ts +10 -3
- package/dist/dom.js +676 -1
- package/dist/dom.mjs +647 -1
- package/dist/el.d.mts +16 -36
- package/dist/el.d.ts +16 -36
- package/dist/el.js +789 -1
- package/dist/el.mjs +583 -1
- package/dist/fs.d.mts +255 -0
- package/dist/fs.d.ts +255 -0
- package/dist/fs.js +513 -0
- package/dist/fs.mjs +469 -0
- package/dist/hmr.js +112 -1
- package/dist/hmr.mjs +91 -1
- package/dist/http.d.mts +163 -0
- package/dist/http.d.ts +163 -0
- package/dist/http.js +632 -0
- package/dist/http.mjs +605 -0
- package/dist/https.d.mts +108 -0
- package/dist/https.d.ts +108 -0
- package/dist/https.js +907 -0
- package/dist/https.mjs +901 -0
- package/dist/index.d.mts +613 -33
- package/dist/index.d.ts +613 -33
- package/dist/index.js +2589 -1
- package/dist/index.mjs +2312 -1
- package/dist/mime-types.d.mts +48 -0
- package/dist/mime-types.d.ts +48 -0
- package/dist/mime-types.js +197 -0
- package/dist/mime-types.mjs +166 -0
- package/dist/path.d.mts +163 -0
- package/dist/path.d.ts +163 -0
- package/dist/path.js +350 -0
- package/dist/path.mjs +310 -0
- package/dist/router.d.mts +3 -1
- package/dist/router.d.ts +3 -1
- package/dist/router.js +830 -1
- package/dist/router.mjs +801 -1
- package/dist/runtime.d.mts +97 -0
- package/dist/runtime.d.ts +97 -0
- package/dist/runtime.js +43 -0
- package/dist/runtime.mjs +15 -0
- package/dist/server.d.mts +5 -1
- package/dist/server.d.ts +5 -1
- package/dist/server.js +3267 -1
- package/dist/server.mjs +3241 -1
- package/dist/state.d.mts +3 -1
- package/dist/state.d.ts +3 -1
- package/dist/state.js +1036 -1
- package/dist/state.mjs +992 -1
- package/dist/style.d.mts +47 -1
- package/dist/style.d.ts +47 -1
- package/dist/style.js +551 -1
- package/dist/style.mjs +483 -1
- package/dist/{types-DOAdFFJB.d.ts → types-C0nGi6MX.d.mts} +29 -13
- package/dist/{types-DOAdFFJB.d.mts → types-Du6kfwTm.d.ts} +29 -13
- package/dist/types.d.mts +452 -3
- package/dist/types.d.ts +452 -3
- package/dist/types.js +18 -1
- package/dist/ws.d.mts +195 -0
- package/dist/ws.d.ts +195 -0
- package/dist/ws.js +380 -0
- package/dist/ws.mjs +358 -0
- package/dist/wss.d.mts +108 -0
- package/dist/wss.d.ts +108 -0
- package/dist/wss.js +1306 -0
- package/dist/wss.mjs +1300 -0
- package/package.json +53 -6
- package/dist/client.d.mts +0 -9
- package/dist/client.d.ts +0 -9
- package/dist/client.js +0 -1
- package/dist/client.mjs +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
2
|
"use strict";
|
|
4
3
|
var __create = Object.create;
|
|
5
4
|
var __defProp = Object.defineProperty;
|
|
@@ -7,9 +6,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
7
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
9
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
10
12
|
var __commonJS = (cb, mod) => function __require() {
|
|
11
13
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
12
14
|
};
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
13
19
|
var __copyProps = (to, from, except, desc) => {
|
|
14
20
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
21
|
for (let key of __getOwnPropNames(from))
|
|
@@ -26,13 +32,1387 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
32
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
33
|
mod
|
|
28
34
|
));
|
|
35
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
|
+
|
|
37
|
+
// src/runtime.ts
|
|
38
|
+
var runtime, isNode, isBun, isDeno;
|
|
39
|
+
var init_runtime = __esm({
|
|
40
|
+
"src/runtime.ts"() {
|
|
41
|
+
"use strict";
|
|
42
|
+
runtime = (() => {
|
|
43
|
+
if (typeof Deno !== "undefined") return "deno";
|
|
44
|
+
if (typeof Bun !== "undefined") return "bun";
|
|
45
|
+
return "node";
|
|
46
|
+
})();
|
|
47
|
+
isNode = runtime === "node";
|
|
48
|
+
isBun = runtime === "bun";
|
|
49
|
+
isDeno = runtime === "deno";
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// src/fs.ts
|
|
54
|
+
var fs_exports = {};
|
|
55
|
+
__export(fs_exports, {
|
|
56
|
+
appendFile: () => appendFile,
|
|
57
|
+
appendFileSync: () => appendFileSync,
|
|
58
|
+
copyFile: () => copyFile,
|
|
59
|
+
copyFileSync: () => copyFileSync,
|
|
60
|
+
default: () => fs_default,
|
|
61
|
+
exists: () => exists,
|
|
62
|
+
existsSync: () => existsSync,
|
|
63
|
+
getRuntime: () => getRuntime,
|
|
64
|
+
mkdir: () => mkdir,
|
|
65
|
+
mkdirSync: () => mkdirSync,
|
|
66
|
+
promises: () => promises,
|
|
67
|
+
readFile: () => readFile,
|
|
68
|
+
readFileSync: () => readFileSync,
|
|
69
|
+
readdir: () => readdir,
|
|
70
|
+
readdirSync: () => readdirSync,
|
|
71
|
+
realpath: () => realpath,
|
|
72
|
+
realpathSync: () => realpathSync,
|
|
73
|
+
rename: () => rename,
|
|
74
|
+
renameSync: () => renameSync,
|
|
75
|
+
rmdir: () => rmdir,
|
|
76
|
+
rmdirSync: () => rmdirSync,
|
|
77
|
+
stat: () => stat,
|
|
78
|
+
statSync: () => statSync,
|
|
79
|
+
unlink: () => unlink,
|
|
80
|
+
unlinkSync: () => unlinkSync,
|
|
81
|
+
writeFile: () => writeFile,
|
|
82
|
+
writeFileSync: () => writeFileSync
|
|
83
|
+
});
|
|
84
|
+
function parseOptions(options, defaultValue) {
|
|
85
|
+
return typeof options === "string" ? { encoding: options } : options || defaultValue;
|
|
86
|
+
}
|
|
87
|
+
function decodeContent(content, encoding) {
|
|
88
|
+
if (encoding) {
|
|
89
|
+
return new TextDecoder(encoding).decode(content);
|
|
90
|
+
}
|
|
91
|
+
return Buffer.from(content instanceof ArrayBuffer ? new Uint8Array(content) : content);
|
|
92
|
+
}
|
|
93
|
+
function dataToUint8Array(data) {
|
|
94
|
+
if (typeof data === "string") {
|
|
95
|
+
return new TextEncoder().encode(data);
|
|
96
|
+
}
|
|
97
|
+
if (data instanceof Buffer) {
|
|
98
|
+
return new Uint8Array(data);
|
|
99
|
+
}
|
|
100
|
+
return data;
|
|
101
|
+
}
|
|
102
|
+
function processDenoEntries(iterator, withFileTypes) {
|
|
103
|
+
const entries = [];
|
|
104
|
+
for (const entry of iterator) {
|
|
105
|
+
if (withFileTypes) {
|
|
106
|
+
entries.push(createDirentFromDenoEntry(entry));
|
|
107
|
+
} else {
|
|
108
|
+
entries.push(entry.name);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return entries;
|
|
112
|
+
}
|
|
113
|
+
async function processDenoEntriesAsync(iterator, withFileTypes) {
|
|
114
|
+
const entries = [];
|
|
115
|
+
for await (const entry of iterator) {
|
|
116
|
+
if (withFileTypes) {
|
|
117
|
+
entries.push(createDirentFromDenoEntry(entry));
|
|
118
|
+
} else {
|
|
119
|
+
entries.push(entry.name);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return entries;
|
|
123
|
+
}
|
|
124
|
+
async function readFile(path, options) {
|
|
125
|
+
const opts = parseOptions(options, {});
|
|
126
|
+
if (isNode) {
|
|
127
|
+
return fsPromises.readFile(path, opts);
|
|
128
|
+
} else if (isBun) {
|
|
129
|
+
const file = Bun.file(path);
|
|
130
|
+
const content = await file.arrayBuffer();
|
|
131
|
+
return decodeContent(content, opts.encoding);
|
|
132
|
+
} else if (isDeno) {
|
|
133
|
+
const content = await Deno.readFile(path);
|
|
134
|
+
return decodeContent(content, opts.encoding);
|
|
135
|
+
}
|
|
136
|
+
throw new Error("Unsupported runtime");
|
|
137
|
+
}
|
|
138
|
+
function readFileSync(path, options) {
|
|
139
|
+
const opts = parseOptions(options, {});
|
|
140
|
+
if (isNode) {
|
|
141
|
+
return fs.readFileSync(path, opts);
|
|
142
|
+
} else if (isBun) {
|
|
143
|
+
const file = Bun.file(path);
|
|
144
|
+
const content = file.arrayBuffer();
|
|
145
|
+
return decodeContent(content, opts.encoding);
|
|
146
|
+
} else if (isDeno) {
|
|
147
|
+
const content = Deno.readFileSync(path);
|
|
148
|
+
return decodeContent(content, opts.encoding);
|
|
149
|
+
}
|
|
150
|
+
throw new Error("Unsupported runtime");
|
|
151
|
+
}
|
|
152
|
+
async function writeFile(path, data, options) {
|
|
153
|
+
const opts = parseOptions(options, {});
|
|
154
|
+
if (isNode) {
|
|
155
|
+
return fsPromises.writeFile(path, data, opts);
|
|
156
|
+
} else if (isBun) {
|
|
157
|
+
await Bun.write(path, data);
|
|
158
|
+
} else if (isDeno) {
|
|
159
|
+
await Deno.writeFile(path, dataToUint8Array(data));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function writeFileSync(path, data, options) {
|
|
163
|
+
const opts = parseOptions(options, {});
|
|
164
|
+
if (isNode) {
|
|
165
|
+
fs.writeFileSync(path, data, opts);
|
|
166
|
+
} else if (isBun) {
|
|
167
|
+
Bun.write(path, data);
|
|
168
|
+
} else if (isDeno) {
|
|
169
|
+
Deno.writeFileSync(path, dataToUint8Array(data));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function appendFile(path, data, options) {
|
|
173
|
+
const opts = parseOptions(options, {});
|
|
174
|
+
if (isNode) {
|
|
175
|
+
return fsPromises.appendFile(path, data, opts);
|
|
176
|
+
} else {
|
|
177
|
+
if (await exists(path)) {
|
|
178
|
+
const existing = await readFile(path);
|
|
179
|
+
const combined = Buffer.isBuffer(existing) ? Buffer.concat([existing, Buffer.isBuffer(data) ? data : Buffer.from(data)]) : existing + (Buffer.isBuffer(data) ? data.toString() : data);
|
|
180
|
+
await writeFile(path, combined, opts);
|
|
181
|
+
} else {
|
|
182
|
+
await writeFile(path, data, opts);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function appendFileSync(path, data, options) {
|
|
187
|
+
const opts = parseOptions(options, {});
|
|
188
|
+
if (isNode) {
|
|
189
|
+
fs.appendFileSync(path, data, opts);
|
|
190
|
+
} else {
|
|
191
|
+
if (existsSync(path)) {
|
|
192
|
+
const existing = readFileSync(path);
|
|
193
|
+
const combined = Buffer.isBuffer(existing) ? Buffer.concat([existing, Buffer.isBuffer(data) ? data : Buffer.from(data)]) : existing + (Buffer.isBuffer(data) ? data.toString() : data);
|
|
194
|
+
writeFileSync(path, combined, opts);
|
|
195
|
+
} else {
|
|
196
|
+
writeFileSync(path, data, opts);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async function exists(path) {
|
|
201
|
+
try {
|
|
202
|
+
await stat(path);
|
|
203
|
+
return true;
|
|
204
|
+
} catch {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function existsSync(path) {
|
|
209
|
+
try {
|
|
210
|
+
statSync(path);
|
|
211
|
+
return true;
|
|
212
|
+
} catch {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async function stat(path) {
|
|
217
|
+
if (isNode) {
|
|
218
|
+
return fsPromises.stat(path);
|
|
219
|
+
} else if (isBun) {
|
|
220
|
+
const file = Bun.file(path);
|
|
221
|
+
const size = file.size;
|
|
222
|
+
const exists2 = await file.exists();
|
|
223
|
+
if (!exists2) {
|
|
224
|
+
throw new Error(`ENOENT: no such file or directory, stat '${path}'`);
|
|
225
|
+
}
|
|
226
|
+
return createStatsObject(path, size, false);
|
|
227
|
+
} else if (isDeno) {
|
|
228
|
+
const info = await Deno.stat(path);
|
|
229
|
+
return createStatsFromDenoFileInfo(info);
|
|
230
|
+
}
|
|
231
|
+
throw new Error("Unsupported runtime");
|
|
232
|
+
}
|
|
233
|
+
function statSync(path) {
|
|
234
|
+
if (isNode) {
|
|
235
|
+
return fs.statSync(path);
|
|
236
|
+
} else if (isBun) {
|
|
237
|
+
const file = Bun.file(path);
|
|
238
|
+
const size = file.size;
|
|
239
|
+
try {
|
|
240
|
+
file.arrayBuffer();
|
|
241
|
+
} catch {
|
|
242
|
+
throw new Error(`ENOENT: no such file or directory, stat '${path}'`);
|
|
243
|
+
}
|
|
244
|
+
return createStatsObject(path, size, false);
|
|
245
|
+
} else if (isDeno) {
|
|
246
|
+
const info = Deno.statSync(path);
|
|
247
|
+
return createStatsFromDenoFileInfo(info);
|
|
248
|
+
}
|
|
249
|
+
throw new Error("Unsupported runtime");
|
|
250
|
+
}
|
|
251
|
+
async function mkdir(path, options) {
|
|
252
|
+
const opts = typeof options === "number" ? { mode: options } : options || {};
|
|
253
|
+
if (isNode) {
|
|
254
|
+
await fsPromises.mkdir(path, opts);
|
|
255
|
+
} else if (isBun) {
|
|
256
|
+
await Deno.mkdir(path, { recursive: opts.recursive });
|
|
257
|
+
} else if (isDeno) {
|
|
258
|
+
await Deno.mkdir(path, { recursive: opts.recursive });
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function mkdirSync(path, options) {
|
|
262
|
+
const opts = typeof options === "number" ? { mode: options } : options || {};
|
|
263
|
+
if (isNode) {
|
|
264
|
+
fs.mkdirSync(path, opts);
|
|
265
|
+
} else if (isBun) {
|
|
266
|
+
Deno.mkdirSync(path, { recursive: opts.recursive });
|
|
267
|
+
} else if (isDeno) {
|
|
268
|
+
Deno.mkdirSync(path, { recursive: opts.recursive });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async function readdir(path, options) {
|
|
272
|
+
const opts = parseOptions(options, {});
|
|
273
|
+
if (isNode) {
|
|
274
|
+
return fsPromises.readdir(path, opts);
|
|
275
|
+
} else if (isBunOrDeno) {
|
|
276
|
+
return processDenoEntriesAsync(Deno.readDir(path), opts.withFileTypes);
|
|
277
|
+
}
|
|
278
|
+
throw new Error("Unsupported runtime");
|
|
279
|
+
}
|
|
280
|
+
function readdirSync(path, options) {
|
|
281
|
+
const opts = parseOptions(options, {});
|
|
282
|
+
if (isNode) {
|
|
283
|
+
return fs.readdirSync(path, opts);
|
|
284
|
+
} else if (isBunOrDeno) {
|
|
285
|
+
return processDenoEntries(Deno.readDirSync(path), opts.withFileTypes);
|
|
286
|
+
}
|
|
287
|
+
throw new Error("Unsupported runtime");
|
|
288
|
+
}
|
|
289
|
+
async function unlink(path) {
|
|
290
|
+
if (isNode) {
|
|
291
|
+
return fsPromises.unlink(path);
|
|
292
|
+
} else if (isBun) {
|
|
293
|
+
await Deno.remove(path);
|
|
294
|
+
} else if (isDeno) {
|
|
295
|
+
await Deno.remove(path);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function unlinkSync(path) {
|
|
299
|
+
if (isNode) {
|
|
300
|
+
fs.unlinkSync(path);
|
|
301
|
+
} else if (isBun) {
|
|
302
|
+
Deno.removeSync(path);
|
|
303
|
+
} else if (isDeno) {
|
|
304
|
+
Deno.removeSync(path);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
async function rmdir(path, options) {
|
|
308
|
+
if (isNode) {
|
|
309
|
+
return fsPromises.rmdir(path, options);
|
|
310
|
+
} else if (isBun) {
|
|
311
|
+
await Deno.remove(path, { recursive: options?.recursive });
|
|
312
|
+
} else if (isDeno) {
|
|
313
|
+
await Deno.remove(path, { recursive: options?.recursive });
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function rmdirSync(path, options) {
|
|
317
|
+
if (isNode) {
|
|
318
|
+
fs.rmdirSync(path, options);
|
|
319
|
+
} else if (isBun) {
|
|
320
|
+
Deno.removeSync(path, { recursive: options?.recursive });
|
|
321
|
+
} else if (isDeno) {
|
|
322
|
+
Deno.removeSync(path, { recursive: options?.recursive });
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
async function rename(oldPath, newPath) {
|
|
326
|
+
if (isNode) {
|
|
327
|
+
return fsPromises.rename(oldPath, newPath);
|
|
328
|
+
} else if (isBun) {
|
|
329
|
+
await Deno.rename(oldPath, newPath);
|
|
330
|
+
} else if (isDeno) {
|
|
331
|
+
await Deno.rename(oldPath, newPath);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function renameSync(oldPath, newPath) {
|
|
335
|
+
if (isNode) {
|
|
336
|
+
fs.renameSync(oldPath, newPath);
|
|
337
|
+
} else if (isBun) {
|
|
338
|
+
Deno.renameSync(oldPath, newPath);
|
|
339
|
+
} else if (isDeno) {
|
|
340
|
+
Deno.renameSync(oldPath, newPath);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
async function copyFile(src, dest, flags) {
|
|
344
|
+
if (isNode) {
|
|
345
|
+
return fsPromises.copyFile(src, dest, flags);
|
|
346
|
+
} else if (isBun) {
|
|
347
|
+
await Deno.copyFile(src, dest);
|
|
348
|
+
} else if (isDeno) {
|
|
349
|
+
await Deno.copyFile(src, dest);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function copyFileSync(src, dest, flags) {
|
|
353
|
+
if (isNode) {
|
|
354
|
+
fs.copyFileSync(src, dest, flags);
|
|
355
|
+
} else if (isBun) {
|
|
356
|
+
Deno.copyFileSync(src, dest);
|
|
357
|
+
} else if (isDeno) {
|
|
358
|
+
Deno.copyFileSync(src, dest);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
async function realpath(path, options) {
|
|
362
|
+
if (isNode) {
|
|
363
|
+
return fsPromises.realpath(path, options);
|
|
364
|
+
} else if (isBun) {
|
|
365
|
+
const fs2 = require("fs/promises");
|
|
366
|
+
return fs2.realpath(path, options);
|
|
367
|
+
} else if (isDeno) {
|
|
368
|
+
return await Deno.realPath(path);
|
|
369
|
+
}
|
|
370
|
+
return path;
|
|
371
|
+
}
|
|
372
|
+
function realpathSync(path, options) {
|
|
373
|
+
if (isNode) {
|
|
374
|
+
return fs.realpathSync(path, options);
|
|
375
|
+
} else if (isBun) {
|
|
376
|
+
const fs2 = require("fs");
|
|
377
|
+
return fs2.realpathSync(path, options);
|
|
378
|
+
} else if (isDeno) {
|
|
379
|
+
return Deno.realPathSync(path);
|
|
380
|
+
}
|
|
381
|
+
return path;
|
|
382
|
+
}
|
|
383
|
+
function createStatsObject(_path, size, isDir) {
|
|
384
|
+
const now = Date.now();
|
|
385
|
+
return {
|
|
386
|
+
isFile: () => !isDir,
|
|
387
|
+
isDirectory: () => isDir,
|
|
388
|
+
isBlockDevice: () => false,
|
|
389
|
+
isCharacterDevice: () => false,
|
|
390
|
+
isSymbolicLink: () => false,
|
|
391
|
+
isFIFO: () => false,
|
|
392
|
+
isSocket: () => false,
|
|
393
|
+
dev: 0,
|
|
394
|
+
ino: 0,
|
|
395
|
+
mode: isDir ? 16877 : 33188,
|
|
396
|
+
nlink: 1,
|
|
397
|
+
uid: 0,
|
|
398
|
+
gid: 0,
|
|
399
|
+
rdev: 0,
|
|
400
|
+
size,
|
|
401
|
+
blksize: 4096,
|
|
402
|
+
blocks: Math.ceil(size / 512),
|
|
403
|
+
atimeMs: now,
|
|
404
|
+
mtimeMs: now,
|
|
405
|
+
ctimeMs: now,
|
|
406
|
+
birthtimeMs: now,
|
|
407
|
+
atime: new Date(now),
|
|
408
|
+
mtime: new Date(now),
|
|
409
|
+
ctime: new Date(now),
|
|
410
|
+
birthtime: new Date(now)
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
function createStatsFromDenoFileInfo(info) {
|
|
414
|
+
return {
|
|
415
|
+
isFile: () => info.isFile,
|
|
416
|
+
isDirectory: () => info.isDirectory,
|
|
417
|
+
isBlockDevice: () => false,
|
|
418
|
+
isCharacterDevice: () => false,
|
|
419
|
+
isSymbolicLink: () => info.isSymlink || false,
|
|
420
|
+
isFIFO: () => false,
|
|
421
|
+
isSocket: () => false,
|
|
422
|
+
dev: info.dev || 0,
|
|
423
|
+
ino: info.ino || 0,
|
|
424
|
+
mode: info.mode || 0,
|
|
425
|
+
nlink: info.nlink || 1,
|
|
426
|
+
uid: info.uid || 0,
|
|
427
|
+
gid: info.gid || 0,
|
|
428
|
+
rdev: 0,
|
|
429
|
+
size: info.size,
|
|
430
|
+
blksize: info.blksize || 4096,
|
|
431
|
+
blocks: info.blocks || Math.ceil(info.size / 512),
|
|
432
|
+
atimeMs: info.atime?.getTime() || Date.now(),
|
|
433
|
+
mtimeMs: info.mtime?.getTime() || Date.now(),
|
|
434
|
+
ctimeMs: info.birthtime?.getTime() || Date.now(),
|
|
435
|
+
birthtimeMs: info.birthtime?.getTime() || Date.now(),
|
|
436
|
+
atime: info.atime || /* @__PURE__ */ new Date(),
|
|
437
|
+
mtime: info.mtime || /* @__PURE__ */ new Date(),
|
|
438
|
+
ctime: info.birthtime || /* @__PURE__ */ new Date(),
|
|
439
|
+
birthtime: info.birthtime || /* @__PURE__ */ new Date()
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function createDirentFromDenoEntry(entry) {
|
|
443
|
+
return {
|
|
444
|
+
name: entry.name,
|
|
445
|
+
isFile: () => entry.isFile,
|
|
446
|
+
isDirectory: () => entry.isDirectory,
|
|
447
|
+
isBlockDevice: () => false,
|
|
448
|
+
isCharacterDevice: () => false,
|
|
449
|
+
isSymbolicLink: () => entry.isSymlink || false,
|
|
450
|
+
isFIFO: () => false,
|
|
451
|
+
isSocket: () => false
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
function getRuntime() {
|
|
455
|
+
return runtime;
|
|
456
|
+
}
|
|
457
|
+
var isBunOrDeno, fs, fsPromises, promises, fs_default;
|
|
458
|
+
var init_fs = __esm({
|
|
459
|
+
"src/fs.ts"() {
|
|
460
|
+
"use strict";
|
|
461
|
+
init_runtime();
|
|
462
|
+
isBunOrDeno = isBun || isDeno;
|
|
463
|
+
if (isNode) {
|
|
464
|
+
fs = require("fs");
|
|
465
|
+
fsPromises = require("fs/promises");
|
|
466
|
+
}
|
|
467
|
+
promises = {
|
|
468
|
+
readFile,
|
|
469
|
+
writeFile,
|
|
470
|
+
appendFile,
|
|
471
|
+
stat,
|
|
472
|
+
mkdir,
|
|
473
|
+
readdir,
|
|
474
|
+
unlink,
|
|
475
|
+
rmdir,
|
|
476
|
+
rename,
|
|
477
|
+
copyFile,
|
|
478
|
+
realpath
|
|
479
|
+
};
|
|
480
|
+
fs_default = {
|
|
481
|
+
readFile,
|
|
482
|
+
readFileSync,
|
|
483
|
+
writeFile,
|
|
484
|
+
writeFileSync,
|
|
485
|
+
appendFile,
|
|
486
|
+
appendFileSync,
|
|
487
|
+
exists,
|
|
488
|
+
existsSync,
|
|
489
|
+
stat,
|
|
490
|
+
statSync,
|
|
491
|
+
mkdir,
|
|
492
|
+
mkdirSync,
|
|
493
|
+
readdir,
|
|
494
|
+
readdirSync,
|
|
495
|
+
unlink,
|
|
496
|
+
unlinkSync,
|
|
497
|
+
rmdir,
|
|
498
|
+
rmdirSync,
|
|
499
|
+
rename,
|
|
500
|
+
renameSync,
|
|
501
|
+
copyFile,
|
|
502
|
+
copyFileSync,
|
|
503
|
+
realpath,
|
|
504
|
+
realpathSync,
|
|
505
|
+
promises,
|
|
506
|
+
getRuntime
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
// src/path.ts
|
|
512
|
+
var path_exports = {};
|
|
513
|
+
__export(path_exports, {
|
|
514
|
+
basename: () => basename,
|
|
515
|
+
default: () => path_default,
|
|
516
|
+
delimiter: () => delimiter,
|
|
517
|
+
dirname: () => dirname,
|
|
518
|
+
extname: () => extname,
|
|
519
|
+
format: () => format,
|
|
520
|
+
getRuntime: () => getRuntime2,
|
|
521
|
+
isAbsolute: () => isAbsolute,
|
|
522
|
+
join: () => join,
|
|
523
|
+
normalize: () => normalize,
|
|
524
|
+
parse: () => parse,
|
|
525
|
+
posix: () => posix,
|
|
526
|
+
relative: () => relative,
|
|
527
|
+
resolve: () => resolve,
|
|
528
|
+
sep: () => sep,
|
|
529
|
+
toNamespacedPath: () => toNamespacedPath,
|
|
530
|
+
win32: () => win32
|
|
531
|
+
});
|
|
532
|
+
function getSeparator(isWin) {
|
|
533
|
+
return isWin ? "\\" : "/";
|
|
534
|
+
}
|
|
535
|
+
function getCwd() {
|
|
536
|
+
if (isNode || isBun) {
|
|
537
|
+
return process.cwd();
|
|
538
|
+
} else if (isDeno) {
|
|
539
|
+
return Deno.cwd();
|
|
540
|
+
}
|
|
541
|
+
return "/";
|
|
542
|
+
}
|
|
543
|
+
function findLastSeparator(path) {
|
|
544
|
+
return Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
545
|
+
}
|
|
546
|
+
function createPathOps(isWin) {
|
|
547
|
+
return {
|
|
548
|
+
sep: getSeparator(isWin),
|
|
549
|
+
delimiter: isWin ? ";" : ":",
|
|
550
|
+
normalize: (path) => normalizePath(path, isWin),
|
|
551
|
+
join: (...paths) => joinPaths(paths, isWin),
|
|
552
|
+
resolve: (...paths) => resolvePaths(paths, isWin),
|
|
553
|
+
isAbsolute: (path) => isWin ? isAbsoluteWin(path) : isAbsolutePosix(path),
|
|
554
|
+
relative: (from, to) => relativePath(from, to, isWin),
|
|
555
|
+
dirname: (path) => getDirname(path, isWin),
|
|
556
|
+
basename: (path, ext) => getBasename(path, ext, isWin),
|
|
557
|
+
extname: (path) => getExtname(path),
|
|
558
|
+
parse: (path) => parsePath(path, isWin),
|
|
559
|
+
format: (pathObject) => formatPath(pathObject, isWin)
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
function isAbsolutePosix(path) {
|
|
563
|
+
return path.length > 0 && path[0] === "/";
|
|
564
|
+
}
|
|
565
|
+
function isAbsoluteWin(path) {
|
|
566
|
+
const len = path.length;
|
|
567
|
+
if (len === 0) return false;
|
|
568
|
+
const code = path.charCodeAt(0);
|
|
569
|
+
if (code === 47 || code === 92) {
|
|
570
|
+
return true;
|
|
571
|
+
}
|
|
572
|
+
if (code >= 65 && code <= 90 || code >= 97 && code <= 122) {
|
|
573
|
+
if (len > 2 && path.charCodeAt(1) === 58) {
|
|
574
|
+
const code2 = path.charCodeAt(2);
|
|
575
|
+
if (code2 === 47 || code2 === 92) {
|
|
576
|
+
return true;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
function normalizePath(path, isWin) {
|
|
583
|
+
if (path.length === 0) return ".";
|
|
584
|
+
const separator = getSeparator(isWin);
|
|
585
|
+
const isAbsolute2 = isWin ? isAbsoluteWin(path) : isAbsolutePosix(path);
|
|
586
|
+
const trailingSeparator = path[path.length - 1] === separator || isWin && path[path.length - 1] === "/";
|
|
587
|
+
let normalized = path.replace(isWin ? /[\/\\]+/g : /\/+/g, separator);
|
|
588
|
+
const parts = normalized.split(separator);
|
|
589
|
+
const result = [];
|
|
590
|
+
for (let i = 0; i < parts.length; i++) {
|
|
591
|
+
const part = parts[i];
|
|
592
|
+
if (part === "" || part === ".") {
|
|
593
|
+
if (i === 0 && isAbsolute2) result.push("");
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
if (part === "..") {
|
|
597
|
+
if (result.length > 0 && result[result.length - 1] !== "..") {
|
|
598
|
+
if (!(result.length === 1 && result[0] === "")) {
|
|
599
|
+
result.pop();
|
|
600
|
+
}
|
|
601
|
+
} else if (!isAbsolute2) {
|
|
602
|
+
result.push("..");
|
|
603
|
+
}
|
|
604
|
+
} else {
|
|
605
|
+
result.push(part);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
let final = result.join(separator);
|
|
609
|
+
if (final.length === 0) {
|
|
610
|
+
return isAbsolute2 ? separator : ".";
|
|
611
|
+
}
|
|
612
|
+
if (trailingSeparator && final[final.length - 1] !== separator) {
|
|
613
|
+
final += separator;
|
|
614
|
+
}
|
|
615
|
+
return final;
|
|
616
|
+
}
|
|
617
|
+
function joinPaths(paths, isWin) {
|
|
618
|
+
if (paths.length === 0) return ".";
|
|
619
|
+
const separator = getSeparator(isWin);
|
|
620
|
+
let joined = "";
|
|
621
|
+
for (let i = 0; i < paths.length; i++) {
|
|
622
|
+
const path = paths[i];
|
|
623
|
+
if (path && path.length > 0) {
|
|
624
|
+
if (joined.length === 0) {
|
|
625
|
+
joined = path;
|
|
626
|
+
} else {
|
|
627
|
+
joined += separator + path;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
if (joined.length === 0) return ".";
|
|
632
|
+
return normalizePath(joined, isWin);
|
|
633
|
+
}
|
|
634
|
+
function resolvePaths(paths, isWin) {
|
|
635
|
+
const separator = getSeparator(isWin);
|
|
636
|
+
let resolved = "";
|
|
637
|
+
let isAbsolute2 = false;
|
|
638
|
+
for (let i = paths.length - 1; i >= 0 && !isAbsolute2; i--) {
|
|
639
|
+
const path = paths[i];
|
|
640
|
+
if (path && path.length > 0) {
|
|
641
|
+
resolved = path + (resolved.length > 0 ? separator + resolved : "");
|
|
642
|
+
isAbsolute2 = isWin ? isAbsoluteWin(resolved) : isAbsolutePosix(resolved);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (!isAbsolute2) {
|
|
646
|
+
const cwd = getCwd();
|
|
647
|
+
resolved = cwd + (resolved.length > 0 ? separator + resolved : "");
|
|
648
|
+
}
|
|
649
|
+
return normalizePath(resolved, isWin);
|
|
650
|
+
}
|
|
651
|
+
function relativePath(from, to, isWin) {
|
|
652
|
+
from = resolvePaths([from], isWin);
|
|
653
|
+
to = resolvePaths([to], isWin);
|
|
654
|
+
if (from === to) return "";
|
|
655
|
+
const separator = getSeparator(isWin);
|
|
656
|
+
const fromParts = from.split(separator).filter((p) => p.length > 0);
|
|
657
|
+
const toParts = to.split(separator).filter((p) => p.length > 0);
|
|
658
|
+
let commonLength = 0;
|
|
659
|
+
const minLength = Math.min(fromParts.length, toParts.length);
|
|
660
|
+
for (let i = 0; i < minLength; i++) {
|
|
661
|
+
if (fromParts[i] === toParts[i]) {
|
|
662
|
+
commonLength++;
|
|
663
|
+
} else {
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
const upCount = fromParts.length - commonLength;
|
|
668
|
+
const result = [];
|
|
669
|
+
for (let i = 0; i < upCount; i++) {
|
|
670
|
+
result.push("..");
|
|
671
|
+
}
|
|
672
|
+
for (let i = commonLength; i < toParts.length; i++) {
|
|
673
|
+
result.push(toParts[i]);
|
|
674
|
+
}
|
|
675
|
+
return result.join(separator) || ".";
|
|
676
|
+
}
|
|
677
|
+
function getDirname(path, isWin) {
|
|
678
|
+
if (path.length === 0) return ".";
|
|
679
|
+
const separator = getSeparator(isWin);
|
|
680
|
+
const normalized = normalizePath(path, isWin);
|
|
681
|
+
const lastSepIndex = normalized.lastIndexOf(separator);
|
|
682
|
+
if (lastSepIndex === -1) return ".";
|
|
683
|
+
if (lastSepIndex === 0) return separator;
|
|
684
|
+
return normalized.slice(0, lastSepIndex);
|
|
685
|
+
}
|
|
686
|
+
function getBasename(path, ext, isWin) {
|
|
687
|
+
if (path.length === 0) return "";
|
|
688
|
+
const lastSepIndex = isWin ? findLastSeparator(path) : path.lastIndexOf("/");
|
|
689
|
+
let base = lastSepIndex === -1 ? path : path.slice(lastSepIndex + 1);
|
|
690
|
+
if (ext && base.endsWith(ext)) {
|
|
691
|
+
base = base.slice(0, base.length - ext.length);
|
|
692
|
+
}
|
|
693
|
+
return base;
|
|
694
|
+
}
|
|
695
|
+
function getExtname(path) {
|
|
696
|
+
const lastDotIndex = path.lastIndexOf(".");
|
|
697
|
+
const lastSepIndex = findLastSeparator(path);
|
|
698
|
+
if (lastDotIndex === -1 || lastDotIndex < lastSepIndex || lastDotIndex === path.length - 1) {
|
|
699
|
+
return "";
|
|
700
|
+
}
|
|
701
|
+
return path.slice(lastDotIndex);
|
|
702
|
+
}
|
|
703
|
+
function parsePath(path, isWin) {
|
|
704
|
+
let root = "";
|
|
705
|
+
if (isWin) {
|
|
706
|
+
if (path.length >= 2 && path[1] === ":") {
|
|
707
|
+
root = path.slice(0, 2);
|
|
708
|
+
if (path.length > 2 && (path[2] === "\\" || path[2] === "/")) {
|
|
709
|
+
root += "\\";
|
|
710
|
+
}
|
|
711
|
+
} else if (path[0] === "\\" || path[0] === "/") {
|
|
712
|
+
root = "\\";
|
|
713
|
+
}
|
|
714
|
+
} else {
|
|
715
|
+
if (path[0] === "/") {
|
|
716
|
+
root = "/";
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
const dir = getDirname(path, isWin);
|
|
720
|
+
const base = getBasename(path, void 0, isWin);
|
|
721
|
+
const ext = getExtname(path);
|
|
722
|
+
const name = ext ? base.slice(0, base.length - ext.length) : base;
|
|
723
|
+
return { root, dir, base, ext, name };
|
|
724
|
+
}
|
|
725
|
+
function formatPath(pathObject, isWin) {
|
|
726
|
+
const separator = getSeparator(isWin);
|
|
727
|
+
const dir = pathObject.dir || pathObject.root || "";
|
|
728
|
+
const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
|
|
729
|
+
if (!dir) return base;
|
|
730
|
+
if (dir === pathObject.root) return dir + base;
|
|
731
|
+
return dir + separator + base;
|
|
732
|
+
}
|
|
733
|
+
function normalize(path) {
|
|
734
|
+
return normalizePath(path, isWindows);
|
|
735
|
+
}
|
|
736
|
+
function join(...paths) {
|
|
737
|
+
return joinPaths(paths, isWindows);
|
|
738
|
+
}
|
|
739
|
+
function resolve(...paths) {
|
|
740
|
+
return resolvePaths(paths, isWindows);
|
|
741
|
+
}
|
|
742
|
+
function isAbsolute(path) {
|
|
743
|
+
return isWindows ? win32.isAbsolute(path) : posix.isAbsolute(path);
|
|
744
|
+
}
|
|
745
|
+
function relative(from, to) {
|
|
746
|
+
return relativePath(from, to, isWindows);
|
|
747
|
+
}
|
|
748
|
+
function dirname(path) {
|
|
749
|
+
return getDirname(path, isWindows);
|
|
750
|
+
}
|
|
751
|
+
function basename(path, ext) {
|
|
752
|
+
return getBasename(path, ext, isWindows);
|
|
753
|
+
}
|
|
754
|
+
function extname(path) {
|
|
755
|
+
return getExtname(path);
|
|
756
|
+
}
|
|
757
|
+
function parse(path) {
|
|
758
|
+
return parsePath(path, isWindows);
|
|
759
|
+
}
|
|
760
|
+
function format(pathObject) {
|
|
761
|
+
return formatPath(pathObject, isWindows);
|
|
762
|
+
}
|
|
763
|
+
function toNamespacedPath(path) {
|
|
764
|
+
if (!isWindows || path.length === 0) return path;
|
|
765
|
+
const resolved = resolve(path);
|
|
766
|
+
if (resolved.length >= 3) {
|
|
767
|
+
if (resolved[0] === "\\") {
|
|
768
|
+
if (resolved[1] === "\\" && resolved[2] !== "?") {
|
|
769
|
+
return "\\\\?\\UNC\\" + resolved.slice(2);
|
|
770
|
+
}
|
|
771
|
+
} else if (resolved[1] === ":" && resolved[2] === "\\") {
|
|
772
|
+
return "\\\\?\\" + resolved;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
return path;
|
|
776
|
+
}
|
|
777
|
+
function getRuntime2() {
|
|
778
|
+
return runtime;
|
|
779
|
+
}
|
|
780
|
+
var isWindows, sep, delimiter, posix, win32, path_default;
|
|
781
|
+
var init_path = __esm({
|
|
782
|
+
"src/path.ts"() {
|
|
783
|
+
"use strict";
|
|
784
|
+
init_runtime();
|
|
785
|
+
isWindows = (() => {
|
|
786
|
+
if (isNode) {
|
|
787
|
+
return process.platform === "win32";
|
|
788
|
+
} else if (isDeno) {
|
|
789
|
+
return Deno.build.os === "windows";
|
|
790
|
+
}
|
|
791
|
+
return typeof process !== "undefined" && process.platform === "win32";
|
|
792
|
+
})();
|
|
793
|
+
sep = isWindows ? "\\" : "/";
|
|
794
|
+
delimiter = isWindows ? ";" : ":";
|
|
795
|
+
posix = createPathOps(false);
|
|
796
|
+
win32 = createPathOps(true);
|
|
797
|
+
path_default = {
|
|
798
|
+
sep,
|
|
799
|
+
delimiter,
|
|
800
|
+
normalize,
|
|
801
|
+
join,
|
|
802
|
+
resolve,
|
|
803
|
+
isAbsolute,
|
|
804
|
+
relative,
|
|
805
|
+
dirname,
|
|
806
|
+
basename,
|
|
807
|
+
extname,
|
|
808
|
+
parse,
|
|
809
|
+
format,
|
|
810
|
+
toNamespacedPath,
|
|
811
|
+
posix,
|
|
812
|
+
win32,
|
|
813
|
+
getRuntime: getRuntime2
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
// src/http.ts
|
|
819
|
+
var http_exports = {};
|
|
820
|
+
__export(http_exports, {
|
|
821
|
+
Agent: () => Agent,
|
|
822
|
+
ClientRequest: () => ClientRequest,
|
|
823
|
+
IncomingMessage: () => IncomingMessage,
|
|
824
|
+
METHODS: () => METHODS,
|
|
825
|
+
STATUS_CODES: () => STATUS_CODES,
|
|
826
|
+
Server: () => Server,
|
|
827
|
+
ServerResponse: () => ServerResponse,
|
|
828
|
+
createServer: () => createServer,
|
|
829
|
+
default: () => http_default,
|
|
830
|
+
get: () => get,
|
|
831
|
+
getRuntime: () => getRuntime3,
|
|
832
|
+
request: () => request
|
|
833
|
+
});
|
|
834
|
+
function queueCallback(callback) {
|
|
835
|
+
if (callback) queueMicrotask(callback);
|
|
836
|
+
}
|
|
837
|
+
function headersToInit(headers) {
|
|
838
|
+
const result = {};
|
|
839
|
+
for (const key in headers) {
|
|
840
|
+
const value = headers[key];
|
|
841
|
+
result[key] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
842
|
+
}
|
|
843
|
+
return result;
|
|
844
|
+
}
|
|
845
|
+
function createAddress(port, address, family = "IPv4") {
|
|
846
|
+
return { port, family, address };
|
|
847
|
+
}
|
|
848
|
+
function createErrorResponse() {
|
|
849
|
+
return new Response("Internal Server Error", { status: 500 });
|
|
850
|
+
}
|
|
851
|
+
function emitListeningWithCallback(server, callback) {
|
|
852
|
+
server._listening = true;
|
|
853
|
+
server.emit("listening");
|
|
854
|
+
queueCallback(callback);
|
|
855
|
+
}
|
|
856
|
+
function closeAndEmit(server, callback) {
|
|
857
|
+
server._listening = false;
|
|
858
|
+
server.emit("close");
|
|
859
|
+
if (callback) queueMicrotask(() => callback());
|
|
860
|
+
}
|
|
861
|
+
function createServer(optionsOrListener, requestListener) {
|
|
862
|
+
return new Server(typeof optionsOrListener === "function" ? optionsOrListener : requestListener);
|
|
863
|
+
}
|
|
864
|
+
function request(url, options, callback) {
|
|
865
|
+
const urlString = typeof url === "string" ? url : url.toString();
|
|
866
|
+
const req = new ClientRequest(urlString, options);
|
|
867
|
+
if (isNode) {
|
|
868
|
+
const urlObj = new URL(urlString);
|
|
869
|
+
const client = urlObj.protocol === "https:" ? https : http;
|
|
870
|
+
const nodeReq = client.request(urlString, {
|
|
871
|
+
method: options?.method || "GET",
|
|
872
|
+
headers: options?.headers,
|
|
873
|
+
timeout: options?.timeout,
|
|
874
|
+
signal: options?.signal
|
|
875
|
+
}, (res) => {
|
|
876
|
+
const incomingMessage = new IncomingMessage(res);
|
|
877
|
+
if (callback) callback(incomingMessage);
|
|
878
|
+
req.emit("response", incomingMessage);
|
|
879
|
+
});
|
|
880
|
+
nodeReq.on("error", (error) => req.emit("error", error));
|
|
881
|
+
nodeReq.end();
|
|
882
|
+
} else {
|
|
883
|
+
queueMicrotask(async () => {
|
|
884
|
+
try {
|
|
885
|
+
const response = await fetch(urlString, {
|
|
886
|
+
method: options?.method || "GET",
|
|
887
|
+
headers: options?.headers,
|
|
888
|
+
signal: options?.signal
|
|
889
|
+
});
|
|
890
|
+
const fetchRequest = new Request(urlString);
|
|
891
|
+
const incomingMessage = new IncomingMessage(fetchRequest);
|
|
892
|
+
incomingMessage.statusCode = response.status;
|
|
893
|
+
incomingMessage.statusMessage = response.statusText;
|
|
894
|
+
if (callback) callback(incomingMessage);
|
|
895
|
+
req.emit("response", incomingMessage);
|
|
896
|
+
} catch (error) {
|
|
897
|
+
req.emit("error", error);
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
return req;
|
|
902
|
+
}
|
|
903
|
+
function get(url, options, callback) {
|
|
904
|
+
return request(url, { ...options, method: "GET" }, callback);
|
|
905
|
+
}
|
|
906
|
+
function getRuntime3() {
|
|
907
|
+
return runtime;
|
|
908
|
+
}
|
|
909
|
+
var import_node_events, http, https, METHODS, STATUS_CODES, IncomingMessage, ServerResponse, Server, ClientRequest, Agent, http_default;
|
|
910
|
+
var init_http = __esm({
|
|
911
|
+
"src/http.ts"() {
|
|
912
|
+
"use strict";
|
|
913
|
+
import_node_events = require("events");
|
|
914
|
+
init_runtime();
|
|
915
|
+
if (isNode && typeof process !== "undefined") {
|
|
916
|
+
try {
|
|
917
|
+
http = require("http");
|
|
918
|
+
https = require("https");
|
|
919
|
+
} catch (e) {
|
|
920
|
+
http = require("http");
|
|
921
|
+
https = require("https");
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
METHODS = [
|
|
925
|
+
"GET",
|
|
926
|
+
"POST",
|
|
927
|
+
"PUT",
|
|
928
|
+
"DELETE",
|
|
929
|
+
"PATCH",
|
|
930
|
+
"HEAD",
|
|
931
|
+
"OPTIONS",
|
|
932
|
+
"CONNECT",
|
|
933
|
+
"TRACE"
|
|
934
|
+
];
|
|
935
|
+
STATUS_CODES = {
|
|
936
|
+
100: "Continue",
|
|
937
|
+
101: "Switching Protocols",
|
|
938
|
+
102: "Processing",
|
|
939
|
+
200: "OK",
|
|
940
|
+
201: "Created",
|
|
941
|
+
202: "Accepted",
|
|
942
|
+
203: "Non-Authoritative Information",
|
|
943
|
+
204: "No Content",
|
|
944
|
+
205: "Reset Content",
|
|
945
|
+
206: "Partial Content",
|
|
946
|
+
300: "Multiple Choices",
|
|
947
|
+
301: "Moved Permanently",
|
|
948
|
+
302: "Found",
|
|
949
|
+
303: "See Other",
|
|
950
|
+
304: "Not Modified",
|
|
951
|
+
307: "Temporary Redirect",
|
|
952
|
+
308: "Permanent Redirect",
|
|
953
|
+
400: "Bad Request",
|
|
954
|
+
401: "Unauthorized",
|
|
955
|
+
402: "Payment Required",
|
|
956
|
+
403: "Forbidden",
|
|
957
|
+
404: "Not Found",
|
|
958
|
+
405: "Method Not Allowed",
|
|
959
|
+
406: "Not Acceptable",
|
|
960
|
+
407: "Proxy Authentication Required",
|
|
961
|
+
408: "Request Timeout",
|
|
962
|
+
409: "Conflict",
|
|
963
|
+
410: "Gone",
|
|
964
|
+
411: "Length Required",
|
|
965
|
+
412: "Precondition Failed",
|
|
966
|
+
413: "Payload Too Large",
|
|
967
|
+
414: "URI Too Long",
|
|
968
|
+
415: "Unsupported Media Type",
|
|
969
|
+
416: "Range Not Satisfiable",
|
|
970
|
+
417: "Expectation Failed",
|
|
971
|
+
418: "I'm a teapot",
|
|
972
|
+
422: "Unprocessable Entity",
|
|
973
|
+
425: "Too Early",
|
|
974
|
+
426: "Upgrade Required",
|
|
975
|
+
428: "Precondition Required",
|
|
976
|
+
429: "Too Many Requests",
|
|
977
|
+
431: "Request Header Fields Too Large",
|
|
978
|
+
451: "Unavailable For Legal Reasons",
|
|
979
|
+
500: "Internal Server Error",
|
|
980
|
+
501: "Not Implemented",
|
|
981
|
+
502: "Bad Gateway",
|
|
982
|
+
503: "Service Unavailable",
|
|
983
|
+
504: "Gateway Timeout",
|
|
984
|
+
505: "HTTP Version Not Supported",
|
|
985
|
+
506: "Variant Also Negotiates",
|
|
986
|
+
507: "Insufficient Storage",
|
|
987
|
+
508: "Loop Detected",
|
|
988
|
+
510: "Not Extended",
|
|
989
|
+
511: "Network Authentication Required"
|
|
990
|
+
};
|
|
991
|
+
IncomingMessage = class extends import_node_events.EventEmitter {
|
|
992
|
+
constructor(req) {
|
|
993
|
+
super();
|
|
994
|
+
this.httpVersion = "1.1";
|
|
995
|
+
this.rawHeaders = [];
|
|
996
|
+
this._req = req;
|
|
997
|
+
if (isNode) {
|
|
998
|
+
this.method = req.method;
|
|
999
|
+
this.url = req.url;
|
|
1000
|
+
this.headers = req.headers;
|
|
1001
|
+
this.statusCode = req.statusCode;
|
|
1002
|
+
this.statusMessage = req.statusMessage;
|
|
1003
|
+
this.httpVersion = req.httpVersion;
|
|
1004
|
+
this.rawHeaders = req.rawHeaders;
|
|
1005
|
+
this.socket = req.socket;
|
|
1006
|
+
} else {
|
|
1007
|
+
this.method = req.method;
|
|
1008
|
+
const urlObj = new URL(req.url);
|
|
1009
|
+
this.url = urlObj.pathname + urlObj.search;
|
|
1010
|
+
this.headers = req.headers;
|
|
1011
|
+
this.rawHeaders = [];
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
async text() {
|
|
1015
|
+
if (isNode) {
|
|
1016
|
+
return new Promise((resolve2, reject) => {
|
|
1017
|
+
const chunks = [];
|
|
1018
|
+
this._req.on("data", (chunk) => chunks.push(chunk));
|
|
1019
|
+
this._req.on("end", () => resolve2(Buffer.concat(chunks).toString("utf8")));
|
|
1020
|
+
this._req.on("error", reject);
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
return this._req.text();
|
|
1024
|
+
}
|
|
1025
|
+
async json() {
|
|
1026
|
+
if (isNode) {
|
|
1027
|
+
const text = await this.text();
|
|
1028
|
+
return JSON.parse(text);
|
|
1029
|
+
}
|
|
1030
|
+
return this._req.json();
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
ServerResponse = class extends import_node_events.EventEmitter {
|
|
1034
|
+
constructor(_req, nodeRes) {
|
|
1035
|
+
super();
|
|
1036
|
+
this.statusCode = 200;
|
|
1037
|
+
this.statusMessage = "OK";
|
|
1038
|
+
this.headersSent = false;
|
|
1039
|
+
this._body = "";
|
|
1040
|
+
this._finished = false;
|
|
1041
|
+
this._nodeRes = nodeRes;
|
|
1042
|
+
this._headers = /* @__PURE__ */ Object.create(null);
|
|
1043
|
+
}
|
|
1044
|
+
setHeader(name, value) {
|
|
1045
|
+
if (this.headersSent) {
|
|
1046
|
+
throw new Error("Cannot set headers after they are sent");
|
|
1047
|
+
}
|
|
1048
|
+
if (isNode && this._nodeRes) {
|
|
1049
|
+
this._nodeRes.setHeader(name, value);
|
|
1050
|
+
}
|
|
1051
|
+
this._headers[name.toLowerCase()] = value;
|
|
1052
|
+
return this;
|
|
1053
|
+
}
|
|
1054
|
+
getHeader(name) {
|
|
1055
|
+
if (isNode && this._nodeRes) {
|
|
1056
|
+
return this._nodeRes.getHeader(name);
|
|
1057
|
+
}
|
|
1058
|
+
return this._headers[name.toLowerCase()];
|
|
1059
|
+
}
|
|
1060
|
+
getHeaders() {
|
|
1061
|
+
if (isNode && this._nodeRes) {
|
|
1062
|
+
return this._nodeRes.getHeaders();
|
|
1063
|
+
}
|
|
1064
|
+
return { ...this._headers };
|
|
1065
|
+
}
|
|
1066
|
+
getHeaderNames() {
|
|
1067
|
+
if (isNode && this._nodeRes) {
|
|
1068
|
+
return this._nodeRes.getHeaderNames();
|
|
1069
|
+
}
|
|
1070
|
+
return Object.keys(this._headers);
|
|
1071
|
+
}
|
|
1072
|
+
hasHeader(name) {
|
|
1073
|
+
if (isNode && this._nodeRes) {
|
|
1074
|
+
return this._nodeRes.hasHeader(name);
|
|
1075
|
+
}
|
|
1076
|
+
return name.toLowerCase() in this._headers;
|
|
1077
|
+
}
|
|
1078
|
+
removeHeader(name) {
|
|
1079
|
+
if (this.headersSent) {
|
|
1080
|
+
throw new Error("Cannot remove headers after they are sent");
|
|
1081
|
+
}
|
|
1082
|
+
if (isNode && this._nodeRes) {
|
|
1083
|
+
this._nodeRes.removeHeader(name);
|
|
1084
|
+
}
|
|
1085
|
+
delete this._headers[name.toLowerCase()];
|
|
1086
|
+
}
|
|
1087
|
+
writeHead(statusCode, statusMessage, headers) {
|
|
1088
|
+
if (this.headersSent) {
|
|
1089
|
+
throw new Error("Cannot write headers after they are sent");
|
|
1090
|
+
}
|
|
1091
|
+
this.statusCode = statusCode;
|
|
1092
|
+
if (typeof statusMessage === "string") {
|
|
1093
|
+
this.statusMessage = statusMessage;
|
|
1094
|
+
if (headers) {
|
|
1095
|
+
for (const key in headers) {
|
|
1096
|
+
this.setHeader(key, headers[key]);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
} else if (statusMessage) {
|
|
1100
|
+
for (const key in statusMessage) {
|
|
1101
|
+
this.setHeader(key, statusMessage[key]);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
if (isNode && this._nodeRes) {
|
|
1105
|
+
if (typeof statusMessage === "string") {
|
|
1106
|
+
this._nodeRes.writeHead(statusCode, statusMessage, headers);
|
|
1107
|
+
} else {
|
|
1108
|
+
this._nodeRes.writeHead(statusCode, statusMessage);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
this.headersSent = true;
|
|
1112
|
+
return this;
|
|
1113
|
+
}
|
|
1114
|
+
write(chunk, encoding, callback) {
|
|
1115
|
+
if (typeof encoding === "function") {
|
|
1116
|
+
callback = encoding;
|
|
1117
|
+
encoding = "utf8";
|
|
1118
|
+
}
|
|
1119
|
+
if (!this.headersSent) {
|
|
1120
|
+
this.writeHead(this.statusCode);
|
|
1121
|
+
}
|
|
1122
|
+
if (isNode && this._nodeRes) {
|
|
1123
|
+
return this._nodeRes.write(chunk, encoding, callback);
|
|
1124
|
+
}
|
|
1125
|
+
this._body += chunk;
|
|
1126
|
+
queueCallback(callback);
|
|
1127
|
+
return true;
|
|
1128
|
+
}
|
|
1129
|
+
end(chunk, encoding, callback) {
|
|
1130
|
+
if (this._finished) {
|
|
1131
|
+
return this;
|
|
1132
|
+
}
|
|
1133
|
+
if (typeof chunk === "function") {
|
|
1134
|
+
callback = chunk;
|
|
1135
|
+
chunk = void 0;
|
|
1136
|
+
} else if (typeof encoding === "function") {
|
|
1137
|
+
callback = encoding;
|
|
1138
|
+
encoding = "utf8";
|
|
1139
|
+
}
|
|
1140
|
+
if (chunk !== void 0) {
|
|
1141
|
+
this.write(chunk, encoding);
|
|
1142
|
+
}
|
|
1143
|
+
if (!this.headersSent) {
|
|
1144
|
+
this.writeHead(this.statusCode);
|
|
1145
|
+
}
|
|
1146
|
+
this._finished = true;
|
|
1147
|
+
if (isNode && this._nodeRes) {
|
|
1148
|
+
this._nodeRes.end(callback);
|
|
1149
|
+
this.emit("finish");
|
|
1150
|
+
} else {
|
|
1151
|
+
const response = new Response(this._body, {
|
|
1152
|
+
status: this.statusCode,
|
|
1153
|
+
statusText: this.statusMessage,
|
|
1154
|
+
headers: headersToInit(this._headers)
|
|
1155
|
+
});
|
|
1156
|
+
if (this._resolve) {
|
|
1157
|
+
this._resolve(response);
|
|
1158
|
+
}
|
|
1159
|
+
queueCallback(callback);
|
|
1160
|
+
}
|
|
1161
|
+
return this;
|
|
1162
|
+
}
|
|
1163
|
+
_setResolver(resolve2) {
|
|
1164
|
+
this._resolve = resolve2;
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
Server = class extends import_node_events.EventEmitter {
|
|
1168
|
+
constructor(requestListener) {
|
|
1169
|
+
super();
|
|
1170
|
+
this._listening = false;
|
|
1171
|
+
this.requestListener = requestListener;
|
|
1172
|
+
}
|
|
1173
|
+
listen(...args) {
|
|
1174
|
+
let port = 3e3;
|
|
1175
|
+
let hostname = "0.0.0.0";
|
|
1176
|
+
let callback;
|
|
1177
|
+
const firstArg = args[0];
|
|
1178
|
+
if (typeof firstArg === "number") {
|
|
1179
|
+
port = firstArg;
|
|
1180
|
+
const secondArg = args[1];
|
|
1181
|
+
if (typeof secondArg === "string") {
|
|
1182
|
+
hostname = secondArg;
|
|
1183
|
+
callback = args[2] || args[3];
|
|
1184
|
+
} else if (typeof secondArg === "function") {
|
|
1185
|
+
callback = secondArg;
|
|
1186
|
+
}
|
|
1187
|
+
} else if (firstArg && typeof firstArg === "object") {
|
|
1188
|
+
port = firstArg.port || 3e3;
|
|
1189
|
+
hostname = firstArg.hostname || "0.0.0.0";
|
|
1190
|
+
callback = args[1];
|
|
1191
|
+
}
|
|
1192
|
+
const self = this;
|
|
1193
|
+
if (isNode) {
|
|
1194
|
+
this.nativeServer = http.createServer((req, res) => {
|
|
1195
|
+
const incomingMessage = new IncomingMessage(req);
|
|
1196
|
+
const serverResponse = new ServerResponse(incomingMessage, res);
|
|
1197
|
+
if (self.requestListener) {
|
|
1198
|
+
self.requestListener(incomingMessage, serverResponse);
|
|
1199
|
+
} else {
|
|
1200
|
+
self.emit("request", incomingMessage, serverResponse);
|
|
1201
|
+
}
|
|
1202
|
+
});
|
|
1203
|
+
this.nativeServer.on("upgrade", (req, socket, head) => {
|
|
1204
|
+
self.emit("upgrade", req, socket, head);
|
|
1205
|
+
});
|
|
1206
|
+
this.nativeServer.listen(port, hostname, () => {
|
|
1207
|
+
this._listening = true;
|
|
1208
|
+
this.emit("listening");
|
|
1209
|
+
if (callback) callback();
|
|
1210
|
+
});
|
|
1211
|
+
this.nativeServer.on("error", (err) => this.emit("error", err));
|
|
1212
|
+
this.nativeServer.on("close", () => {
|
|
1213
|
+
this._listening = false;
|
|
1214
|
+
this.emit("close");
|
|
1215
|
+
});
|
|
1216
|
+
} else if (isBun) {
|
|
1217
|
+
this.nativeServer = Bun.serve({
|
|
1218
|
+
port,
|
|
1219
|
+
hostname,
|
|
1220
|
+
fetch: (req) => {
|
|
1221
|
+
const urlObj = new URL(req.url);
|
|
1222
|
+
const pathname = urlObj.pathname + urlObj.search;
|
|
1223
|
+
let statusCode = 200;
|
|
1224
|
+
let statusMessage = "OK";
|
|
1225
|
+
let body = "";
|
|
1226
|
+
const headers = /* @__PURE__ */ Object.create(null);
|
|
1227
|
+
let responseReady = false;
|
|
1228
|
+
const incomingMessage = {
|
|
1229
|
+
method: req.method,
|
|
1230
|
+
url: pathname,
|
|
1231
|
+
headers: req.headers,
|
|
1232
|
+
httpVersion: "1.1",
|
|
1233
|
+
rawHeaders: [],
|
|
1234
|
+
_req: req,
|
|
1235
|
+
text: () => req.text(),
|
|
1236
|
+
json: () => req.json()
|
|
1237
|
+
};
|
|
1238
|
+
const serverResponse = {
|
|
1239
|
+
statusCode: 200,
|
|
1240
|
+
statusMessage: "OK",
|
|
1241
|
+
headersSent: false,
|
|
1242
|
+
_headers: headers,
|
|
1243
|
+
setHeader(name, value) {
|
|
1244
|
+
headers[name.toLowerCase()] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
1245
|
+
return this;
|
|
1246
|
+
},
|
|
1247
|
+
getHeader(name) {
|
|
1248
|
+
return headers[name.toLowerCase()];
|
|
1249
|
+
},
|
|
1250
|
+
getHeaders() {
|
|
1251
|
+
return { ...headers };
|
|
1252
|
+
},
|
|
1253
|
+
writeHead(status, arg2, arg3) {
|
|
1254
|
+
statusCode = status;
|
|
1255
|
+
this.statusCode = status;
|
|
1256
|
+
this.headersSent = true;
|
|
1257
|
+
if (typeof arg2 === "string") {
|
|
1258
|
+
statusMessage = arg2;
|
|
1259
|
+
this.statusMessage = arg2;
|
|
1260
|
+
if (arg3) {
|
|
1261
|
+
for (const key in arg3) {
|
|
1262
|
+
headers[key.toLowerCase()] = arg3[key];
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
} else if (arg2) {
|
|
1266
|
+
for (const key in arg2) {
|
|
1267
|
+
headers[key.toLowerCase()] = arg2[key];
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
return this;
|
|
1271
|
+
},
|
|
1272
|
+
write(chunk) {
|
|
1273
|
+
if (!this.headersSent) {
|
|
1274
|
+
this.writeHead(statusCode);
|
|
1275
|
+
}
|
|
1276
|
+
body += chunk;
|
|
1277
|
+
return true;
|
|
1278
|
+
},
|
|
1279
|
+
end(chunk) {
|
|
1280
|
+
if (chunk !== void 0) {
|
|
1281
|
+
this.write(chunk);
|
|
1282
|
+
}
|
|
1283
|
+
if (!this.headersSent) {
|
|
1284
|
+
this.writeHead(statusCode);
|
|
1285
|
+
}
|
|
1286
|
+
responseReady = true;
|
|
1287
|
+
return this;
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1290
|
+
if (self.requestListener) {
|
|
1291
|
+
self.requestListener(incomingMessage, serverResponse);
|
|
1292
|
+
}
|
|
1293
|
+
if (responseReady) {
|
|
1294
|
+
return new Response(body, {
|
|
1295
|
+
status: statusCode,
|
|
1296
|
+
statusText: statusMessage,
|
|
1297
|
+
headers
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
return new Promise((resolve2) => {
|
|
1301
|
+
serverResponse.end = (chunk) => {
|
|
1302
|
+
if (chunk !== void 0) {
|
|
1303
|
+
body += chunk;
|
|
1304
|
+
}
|
|
1305
|
+
resolve2(new Response(body, {
|
|
1306
|
+
status: statusCode,
|
|
1307
|
+
statusText: statusMessage,
|
|
1308
|
+
headers
|
|
1309
|
+
}));
|
|
1310
|
+
};
|
|
1311
|
+
});
|
|
1312
|
+
},
|
|
1313
|
+
error: createErrorResponse
|
|
1314
|
+
});
|
|
1315
|
+
emitListeningWithCallback(this, callback);
|
|
1316
|
+
} else if (isDeno) {
|
|
1317
|
+
this.nativeServer = Deno.serve({
|
|
1318
|
+
port,
|
|
1319
|
+
hostname,
|
|
1320
|
+
handler: (req) => {
|
|
1321
|
+
return new Promise((resolve2) => {
|
|
1322
|
+
const incomingMessage = new IncomingMessage(req);
|
|
1323
|
+
const serverResponse = new ServerResponse();
|
|
1324
|
+
serverResponse._setResolver(resolve2);
|
|
1325
|
+
if (self.requestListener) {
|
|
1326
|
+
self.requestListener(incomingMessage, serverResponse);
|
|
1327
|
+
} else {
|
|
1328
|
+
self.emit("request", incomingMessage, serverResponse);
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
1331
|
+
},
|
|
1332
|
+
onError: (error) => {
|
|
1333
|
+
this.emit("error", error);
|
|
1334
|
+
return createErrorResponse();
|
|
1335
|
+
}
|
|
1336
|
+
});
|
|
1337
|
+
emitListeningWithCallback(this, callback);
|
|
1338
|
+
}
|
|
1339
|
+
return this;
|
|
1340
|
+
}
|
|
1341
|
+
close(callback) {
|
|
1342
|
+
if (!this.nativeServer) {
|
|
1343
|
+
if (callback) queueMicrotask(() => callback());
|
|
1344
|
+
return this;
|
|
1345
|
+
}
|
|
1346
|
+
if (isNode) {
|
|
1347
|
+
this.nativeServer.close(callback);
|
|
1348
|
+
} else if (isBun) {
|
|
1349
|
+
this.nativeServer.stop();
|
|
1350
|
+
closeAndEmit(this, callback);
|
|
1351
|
+
} else if (isDeno) {
|
|
1352
|
+
this.nativeServer.shutdown();
|
|
1353
|
+
closeAndEmit(this, callback);
|
|
1354
|
+
}
|
|
1355
|
+
return this;
|
|
1356
|
+
}
|
|
1357
|
+
address() {
|
|
1358
|
+
if (!this.nativeServer) return null;
|
|
1359
|
+
if (isNode) {
|
|
1360
|
+
const addr = this.nativeServer.address();
|
|
1361
|
+
if (!addr) return null;
|
|
1362
|
+
if (typeof addr === "string") {
|
|
1363
|
+
return createAddress(0, addr, "unix");
|
|
1364
|
+
}
|
|
1365
|
+
return addr;
|
|
1366
|
+
} else if (isBun) {
|
|
1367
|
+
return createAddress(this.nativeServer.port, this.nativeServer.hostname);
|
|
1368
|
+
} else if (isDeno) {
|
|
1369
|
+
const addr = this.nativeServer.addr;
|
|
1370
|
+
return createAddress(addr.port, addr.hostname);
|
|
1371
|
+
}
|
|
1372
|
+
return null;
|
|
1373
|
+
}
|
|
1374
|
+
get listening() {
|
|
1375
|
+
return this._listening;
|
|
1376
|
+
}
|
|
1377
|
+
};
|
|
1378
|
+
ClientRequest = class extends import_node_events.EventEmitter {
|
|
1379
|
+
constructor(_url, _options = {}) {
|
|
1380
|
+
super();
|
|
1381
|
+
}
|
|
1382
|
+
write(_chunk) {
|
|
1383
|
+
return true;
|
|
1384
|
+
}
|
|
1385
|
+
end(callback) {
|
|
1386
|
+
queueCallback(callback);
|
|
1387
|
+
}
|
|
1388
|
+
};
|
|
1389
|
+
Agent = class {
|
|
1390
|
+
constructor(options) {
|
|
1391
|
+
this.options = options;
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
http_default = {
|
|
1395
|
+
createServer,
|
|
1396
|
+
request,
|
|
1397
|
+
get,
|
|
1398
|
+
Server,
|
|
1399
|
+
IncomingMessage,
|
|
1400
|
+
ServerResponse,
|
|
1401
|
+
Agent,
|
|
1402
|
+
ClientRequest,
|
|
1403
|
+
METHODS,
|
|
1404
|
+
STATUS_CODES,
|
|
1405
|
+
getRuntime: getRuntime3
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
});
|
|
29
1409
|
|
|
30
1410
|
// package.json
|
|
31
1411
|
var require_package = __commonJS({
|
|
32
1412
|
"package.json"(exports2, module2) {
|
|
33
1413
|
module2.exports = {
|
|
34
1414
|
name: "elit",
|
|
35
|
-
version: "
|
|
1415
|
+
version: "3.0.0",
|
|
36
1416
|
description: "Optimized lightweight library for creating DOM elements with reactive state",
|
|
37
1417
|
main: "dist/index.js",
|
|
38
1418
|
module: "dist/index.mjs",
|
|
@@ -85,12 +1465,59 @@ var require_package = __commonJS({
|
|
|
85
1465
|
types: "./dist/build.d.ts",
|
|
86
1466
|
import: "./dist/build.mjs",
|
|
87
1467
|
require: "./dist/build.js"
|
|
1468
|
+
},
|
|
1469
|
+
"./http": {
|
|
1470
|
+
types: "./dist/http.d.ts",
|
|
1471
|
+
import: "./dist/http.mjs",
|
|
1472
|
+
require: "./dist/http.js"
|
|
1473
|
+
},
|
|
1474
|
+
"./https": {
|
|
1475
|
+
types: "./dist/https.d.ts",
|
|
1476
|
+
import: "./dist/https.mjs",
|
|
1477
|
+
require: "./dist/https.js"
|
|
1478
|
+
},
|
|
1479
|
+
"./ws": {
|
|
1480
|
+
types: "./dist/ws.d.ts",
|
|
1481
|
+
import: "./dist/ws.mjs",
|
|
1482
|
+
require: "./dist/ws.js"
|
|
1483
|
+
},
|
|
1484
|
+
"./fs": {
|
|
1485
|
+
types: "./dist/fs.d.ts",
|
|
1486
|
+
import: "./dist/fs.mjs",
|
|
1487
|
+
require: "./dist/fs.js"
|
|
1488
|
+
},
|
|
1489
|
+
"./mime-types": {
|
|
1490
|
+
types: "./dist/mime-types.d.ts",
|
|
1491
|
+
import: "./dist/mime-types.mjs",
|
|
1492
|
+
require: "./dist/mime-types.js"
|
|
1493
|
+
},
|
|
1494
|
+
"./chokidar": {
|
|
1495
|
+
types: "./dist/chokidar.d.ts",
|
|
1496
|
+
import: "./dist/chokidar.mjs",
|
|
1497
|
+
require: "./dist/chokidar.js"
|
|
1498
|
+
},
|
|
1499
|
+
"./path": {
|
|
1500
|
+
types: "./dist/path.d.ts",
|
|
1501
|
+
import: "./dist/path.mjs",
|
|
1502
|
+
require: "./dist/path.js"
|
|
1503
|
+
},
|
|
1504
|
+
"./wss": {
|
|
1505
|
+
types: "./dist/wss.d.ts",
|
|
1506
|
+
import: "./dist/wss.mjs",
|
|
1507
|
+
require: "./dist/wss.js"
|
|
1508
|
+
},
|
|
1509
|
+
"./runtime": {
|
|
1510
|
+
types: "./dist/runtime.d.ts",
|
|
1511
|
+
import: "./dist/runtime.mjs",
|
|
1512
|
+
require: "./dist/runtime.js"
|
|
88
1513
|
}
|
|
89
1514
|
},
|
|
90
1515
|
scripts: {
|
|
91
1516
|
build: "tsup",
|
|
92
1517
|
dev: "tsup --watch",
|
|
93
1518
|
typecheck: "tsc --noEmit",
|
|
1519
|
+
benchmark: "node benchmark/server-benchmark.js",
|
|
1520
|
+
"benchmark:router": "node benchmark/router-benchmark.js",
|
|
94
1521
|
"docs:dev": "npm run --prefix docs dev",
|
|
95
1522
|
"docs:build": "npm run --prefix docs build",
|
|
96
1523
|
"docs:preview": "npm run --prefix docs preview",
|
|
@@ -129,18 +1556,18 @@ var require_package = __commonJS({
|
|
|
129
1556
|
bugs: {
|
|
130
1557
|
url: "https://github.com/d-osc/elit/issues"
|
|
131
1558
|
},
|
|
132
|
-
homepage: "https://
|
|
1559
|
+
homepage: "https://d-osc.github.io/elit/",
|
|
133
1560
|
dependencies: {
|
|
134
|
-
chokidar: "^4.0.3",
|
|
135
1561
|
esbuild: "^0.24.2",
|
|
136
|
-
|
|
137
|
-
open: "^11.0.0",
|
|
138
|
-
ws: "^8.18.0"
|
|
1562
|
+
open: "^11.0.0"
|
|
139
1563
|
},
|
|
140
1564
|
devDependencies: {
|
|
1565
|
+
"@types/express": "^5.0.6",
|
|
141
1566
|
"@types/mime-types": "^2.1.4",
|
|
142
1567
|
"@types/node": "^22.0.0",
|
|
143
1568
|
"@types/ws": "^8.5.13",
|
|
1569
|
+
express: "^5.2.1",
|
|
1570
|
+
elysia: "^1.4.19",
|
|
144
1571
|
terser: "^5.44.1",
|
|
145
1572
|
tsup: "^8.0.0",
|
|
146
1573
|
typescript: "^5.3.0"
|
|
@@ -155,8 +1582,31 @@ var require_package = __commonJS({
|
|
|
155
1582
|
});
|
|
156
1583
|
|
|
157
1584
|
// src/config.ts
|
|
158
|
-
|
|
159
|
-
|
|
1585
|
+
init_fs();
|
|
1586
|
+
init_path();
|
|
1587
|
+
function readFileAsString(filePath) {
|
|
1588
|
+
const contentBuffer = readFileSync(filePath, "utf-8");
|
|
1589
|
+
return typeof contentBuffer === "string" ? contentBuffer : contentBuffer.toString("utf-8");
|
|
1590
|
+
}
|
|
1591
|
+
function removeQuotes(value) {
|
|
1592
|
+
const trimmed = value.trim();
|
|
1593
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
1594
|
+
return trimmed.slice(1, -1);
|
|
1595
|
+
}
|
|
1596
|
+
return trimmed;
|
|
1597
|
+
}
|
|
1598
|
+
async function importConfigModule(configPath) {
|
|
1599
|
+
const { pathToFileURL } = await import("url");
|
|
1600
|
+
const configModule = await import(pathToFileURL(configPath).href);
|
|
1601
|
+
return configModule.default || configModule;
|
|
1602
|
+
}
|
|
1603
|
+
async function safeCleanup(filePath) {
|
|
1604
|
+
try {
|
|
1605
|
+
const { unlinkSync: unlinkSync2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
1606
|
+
unlinkSync2(filePath);
|
|
1607
|
+
} catch {
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
160
1610
|
var CONFIG_FILES = [
|
|
161
1611
|
"elit.config.ts",
|
|
162
1612
|
"elit.config.js",
|
|
@@ -173,9 +1623,9 @@ function loadEnv(mode = "development", cwd = process.cwd()) {
|
|
|
173
1623
|
`.env`
|
|
174
1624
|
];
|
|
175
1625
|
for (const file of envFiles) {
|
|
176
|
-
const filePath =
|
|
177
|
-
if (
|
|
178
|
-
const content = (
|
|
1626
|
+
const filePath = resolve(cwd, file);
|
|
1627
|
+
if (existsSync(filePath)) {
|
|
1628
|
+
const content = readFileAsString(filePath);
|
|
179
1629
|
const lines = content.split("\n");
|
|
180
1630
|
for (const line of lines) {
|
|
181
1631
|
const trimmed = line.trim();
|
|
@@ -183,10 +1633,7 @@ function loadEnv(mode = "development", cwd = process.cwd()) {
|
|
|
183
1633
|
const match = trimmed.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
|
|
184
1634
|
if (match) {
|
|
185
1635
|
const [, key, value] = match;
|
|
186
|
-
|
|
187
|
-
if (cleanValue.startsWith('"') && cleanValue.endsWith('"') || cleanValue.startsWith("'") && cleanValue.endsWith("'")) {
|
|
188
|
-
cleanValue = cleanValue.slice(1, -1);
|
|
189
|
-
}
|
|
1636
|
+
const cleanValue = removeQuotes(value);
|
|
190
1637
|
if (!(key in env)) {
|
|
191
1638
|
env[key] = cleanValue;
|
|
192
1639
|
}
|
|
@@ -194,70 +1641,759 @@ function loadEnv(mode = "development", cwd = process.cwd()) {
|
|
|
194
1641
|
}
|
|
195
1642
|
}
|
|
196
1643
|
}
|
|
197
|
-
return env;
|
|
198
|
-
}
|
|
199
|
-
async function loadConfig(cwd = process.cwd()) {
|
|
200
|
-
for (const configFile of CONFIG_FILES) {
|
|
201
|
-
const configPath =
|
|
202
|
-
if (
|
|
203
|
-
try {
|
|
204
|
-
return await loadConfigFile(configPath);
|
|
205
|
-
} catch (error) {
|
|
206
|
-
console.error(`Error loading config file: ${configFile}`);
|
|
207
|
-
console.error(error);
|
|
208
|
-
throw error;
|
|
1644
|
+
return env;
|
|
1645
|
+
}
|
|
1646
|
+
async function loadConfig(cwd = process.cwd()) {
|
|
1647
|
+
for (const configFile of CONFIG_FILES) {
|
|
1648
|
+
const configPath = resolve(cwd, configFile);
|
|
1649
|
+
if (existsSync(configPath)) {
|
|
1650
|
+
try {
|
|
1651
|
+
return await loadConfigFile(configPath);
|
|
1652
|
+
} catch (error) {
|
|
1653
|
+
console.error(`Error loading config file: ${configFile}`);
|
|
1654
|
+
console.error(error);
|
|
1655
|
+
throw error;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
return null;
|
|
1660
|
+
}
|
|
1661
|
+
async function loadConfigFile(configPath) {
|
|
1662
|
+
const ext = configPath.split(".").pop();
|
|
1663
|
+
if (ext === "json") {
|
|
1664
|
+
const content = readFileAsString(configPath);
|
|
1665
|
+
return JSON.parse(content);
|
|
1666
|
+
} else if (ext === "ts") {
|
|
1667
|
+
try {
|
|
1668
|
+
const { build: build2 } = await import("esbuild");
|
|
1669
|
+
const { tmpdir } = await import("os");
|
|
1670
|
+
const { join: join2, dirname: dirname2 } = await Promise.resolve().then(() => (init_path(), path_exports));
|
|
1671
|
+
const tempFile = join2(tmpdir(), `elit-config-${Date.now()}.mjs`);
|
|
1672
|
+
const configDir = dirname2(configPath);
|
|
1673
|
+
await build2({
|
|
1674
|
+
entryPoints: [configPath],
|
|
1675
|
+
bundle: true,
|
|
1676
|
+
format: "esm",
|
|
1677
|
+
platform: "node",
|
|
1678
|
+
outfile: tempFile,
|
|
1679
|
+
write: true,
|
|
1680
|
+
target: "es2020",
|
|
1681
|
+
// Bundle everything including elit/* so config can use elit modules
|
|
1682
|
+
// Only mark Node.js built-ins as external
|
|
1683
|
+
external: ["node:*"],
|
|
1684
|
+
// Use the config directory as the working directory for resolution
|
|
1685
|
+
absWorkingDir: configDir
|
|
1686
|
+
});
|
|
1687
|
+
const config = await importConfigModule(tempFile);
|
|
1688
|
+
await safeCleanup(tempFile);
|
|
1689
|
+
return config;
|
|
1690
|
+
} catch (error) {
|
|
1691
|
+
console.error("Failed to load TypeScript config file.");
|
|
1692
|
+
console.error("You can use a .js, .mjs, or .json config file instead.");
|
|
1693
|
+
throw error;
|
|
1694
|
+
}
|
|
1695
|
+
} else {
|
|
1696
|
+
return await importConfigModule(configPath);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
function mergeConfig(config, cliArgs) {
|
|
1700
|
+
if (!config) {
|
|
1701
|
+
return cliArgs;
|
|
1702
|
+
}
|
|
1703
|
+
return {
|
|
1704
|
+
...config,
|
|
1705
|
+
...Object.fromEntries(
|
|
1706
|
+
Object.entries(cliArgs).filter(([_, v]) => v !== void 0)
|
|
1707
|
+
)
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
// src/server.ts
|
|
1712
|
+
init_http();
|
|
1713
|
+
|
|
1714
|
+
// src/https.ts
|
|
1715
|
+
var import_events = require("events");
|
|
1716
|
+
init_runtime();
|
|
1717
|
+
function queueCallback2(callback) {
|
|
1718
|
+
if (callback) queueMicrotask(callback);
|
|
1719
|
+
}
|
|
1720
|
+
function loadHttpClasses() {
|
|
1721
|
+
const httpModule = (init_http(), __toCommonJS(http_exports));
|
|
1722
|
+
return {
|
|
1723
|
+
IncomingMessage: httpModule.IncomingMessage,
|
|
1724
|
+
ServerResponse: httpModule.ServerResponse
|
|
1725
|
+
};
|
|
1726
|
+
}
|
|
1727
|
+
var https2;
|
|
1728
|
+
var ClientRequest2 = class extends import_events.EventEmitter {
|
|
1729
|
+
constructor(_url, _options = {}) {
|
|
1730
|
+
super();
|
|
1731
|
+
}
|
|
1732
|
+
write(_chunk) {
|
|
1733
|
+
return true;
|
|
1734
|
+
}
|
|
1735
|
+
end(callback) {
|
|
1736
|
+
queueCallback2(callback);
|
|
1737
|
+
}
|
|
1738
|
+
};
|
|
1739
|
+
function request2(url, options, callback) {
|
|
1740
|
+
const urlString = typeof url === "string" ? url : url.toString();
|
|
1741
|
+
const req = new ClientRequest2(urlString, options);
|
|
1742
|
+
if (isNode) {
|
|
1743
|
+
const { IncomingMessage: IncomingMessage3 } = loadHttpClasses();
|
|
1744
|
+
if (!https2) https2 = require("https");
|
|
1745
|
+
const nodeReq = https2.request(urlString, {
|
|
1746
|
+
method: options?.method || "GET",
|
|
1747
|
+
headers: options?.headers,
|
|
1748
|
+
timeout: options?.timeout,
|
|
1749
|
+
signal: options?.signal
|
|
1750
|
+
}, (res) => {
|
|
1751
|
+
const incomingMessage = new IncomingMessage3(res);
|
|
1752
|
+
if (callback) callback(incomingMessage);
|
|
1753
|
+
req.emit("response", incomingMessage);
|
|
1754
|
+
});
|
|
1755
|
+
nodeReq.on("error", (error) => req.emit("error", error));
|
|
1756
|
+
nodeReq.end();
|
|
1757
|
+
} else {
|
|
1758
|
+
const { IncomingMessage: IncomingMessage3 } = loadHttpClasses();
|
|
1759
|
+
queueMicrotask(async () => {
|
|
1760
|
+
try {
|
|
1761
|
+
const response = await fetch(urlString, {
|
|
1762
|
+
method: options?.method || "GET",
|
|
1763
|
+
headers: options?.headers,
|
|
1764
|
+
signal: options?.signal
|
|
1765
|
+
});
|
|
1766
|
+
const fetchRequest = new Request(urlString);
|
|
1767
|
+
const incomingMessage = new IncomingMessage3(fetchRequest);
|
|
1768
|
+
incomingMessage.statusCode = response.status;
|
|
1769
|
+
incomingMessage.statusMessage = response.statusText;
|
|
1770
|
+
if (callback) callback(incomingMessage);
|
|
1771
|
+
req.emit("response", incomingMessage);
|
|
1772
|
+
} catch (error) {
|
|
1773
|
+
req.emit("error", error);
|
|
1774
|
+
}
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
return req;
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
// src/ws.ts
|
|
1781
|
+
var import_events2 = require("events");
|
|
1782
|
+
init_runtime();
|
|
1783
|
+
var CLOSE_CODES = {
|
|
1784
|
+
NORMAL: 1e3,
|
|
1785
|
+
GOING_AWAY: 1001,
|
|
1786
|
+
PROTOCOL_ERROR: 1002,
|
|
1787
|
+
UNSUPPORTED_DATA: 1003,
|
|
1788
|
+
NO_STATUS: 1005,
|
|
1789
|
+
ABNORMAL: 1006,
|
|
1790
|
+
INVALID_DATA: 1007,
|
|
1791
|
+
POLICY_VIOLATION: 1008,
|
|
1792
|
+
MESSAGE_TOO_BIG: 1009,
|
|
1793
|
+
EXTENSION_REQUIRED: 1010,
|
|
1794
|
+
INTERNAL_ERROR: 1011,
|
|
1795
|
+
SERVICE_RESTART: 1012,
|
|
1796
|
+
TRY_AGAIN_LATER: 1013,
|
|
1797
|
+
BAD_GATEWAY: 1014,
|
|
1798
|
+
TLS_HANDSHAKE_FAIL: 1015
|
|
1799
|
+
};
|
|
1800
|
+
function queueCallback3(callback, error) {
|
|
1801
|
+
if (callback) {
|
|
1802
|
+
queueMicrotask(() => callback(error));
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
function createNativeWebSocket(url, protocols) {
|
|
1806
|
+
if (runtime === "node" && typeof globalThis.WebSocket === "undefined") {
|
|
1807
|
+
throw new Error("WebSocket is not available. Please use Node.js 18+ or install ws package.");
|
|
1808
|
+
}
|
|
1809
|
+
return new globalThis.WebSocket(url, protocols);
|
|
1810
|
+
}
|
|
1811
|
+
var WebSocket = class extends import_events2.EventEmitter {
|
|
1812
|
+
constructor(address, protocols, _options) {
|
|
1813
|
+
super();
|
|
1814
|
+
this.readyState = 0 /* CONNECTING */;
|
|
1815
|
+
this.protocol = "";
|
|
1816
|
+
this.extensions = "";
|
|
1817
|
+
this.binaryType = "nodebuffer";
|
|
1818
|
+
this.url = typeof address === "string" ? address : address.toString();
|
|
1819
|
+
const protocolsArray = Array.isArray(protocols) ? protocols : protocols ? [protocols] : void 0;
|
|
1820
|
+
this._socket = createNativeWebSocket(this.url, protocolsArray);
|
|
1821
|
+
this._setupNativeSocket();
|
|
1822
|
+
}
|
|
1823
|
+
_setupNativeSocket() {
|
|
1824
|
+
this._socket.onopen = () => {
|
|
1825
|
+
this.readyState = 1 /* OPEN */;
|
|
1826
|
+
this.emit("open");
|
|
1827
|
+
};
|
|
1828
|
+
this._socket.onmessage = (event) => {
|
|
1829
|
+
const isBinary = event.data instanceof ArrayBuffer || event.data instanceof Blob;
|
|
1830
|
+
this.emit("message", event.data, isBinary);
|
|
1831
|
+
};
|
|
1832
|
+
this._socket.onclose = (event) => {
|
|
1833
|
+
this.readyState = 3 /* CLOSED */;
|
|
1834
|
+
this.emit("close", event.code, event.reason);
|
|
1835
|
+
};
|
|
1836
|
+
this._socket.onerror = () => {
|
|
1837
|
+
this.emit("error", new Error("WebSocket error"));
|
|
1838
|
+
};
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* Send data through WebSocket
|
|
1842
|
+
*/
|
|
1843
|
+
send(data, options, callback) {
|
|
1844
|
+
const cb = typeof options === "function" ? options : callback;
|
|
1845
|
+
if (this.readyState !== 1 /* OPEN */) {
|
|
1846
|
+
return queueCallback3(cb, new Error("WebSocket is not open"));
|
|
1847
|
+
}
|
|
1848
|
+
try {
|
|
1849
|
+
this._socket.send(data);
|
|
1850
|
+
queueCallback3(cb);
|
|
1851
|
+
} catch (error) {
|
|
1852
|
+
queueCallback3(cb, error);
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
/**
|
|
1856
|
+
* Close the WebSocket connection
|
|
1857
|
+
*/
|
|
1858
|
+
close(code, reason) {
|
|
1859
|
+
if (this.readyState === 3 /* CLOSED */ || this.readyState === 2 /* CLOSING */) {
|
|
1860
|
+
return;
|
|
1861
|
+
}
|
|
1862
|
+
this.readyState = 2 /* CLOSING */;
|
|
1863
|
+
this._socket.close(code, typeof reason === "string" ? reason : reason?.toString());
|
|
1864
|
+
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Pause the socket (no-op for native WebSocket)
|
|
1867
|
+
*/
|
|
1868
|
+
pause() {
|
|
1869
|
+
}
|
|
1870
|
+
/**
|
|
1871
|
+
* Resume the socket (no-op for native WebSocket)
|
|
1872
|
+
*/
|
|
1873
|
+
resume() {
|
|
1874
|
+
}
|
|
1875
|
+
/**
|
|
1876
|
+
* Send a ping frame (no-op for native WebSocket)
|
|
1877
|
+
*/
|
|
1878
|
+
ping(_data, _mask, callback) {
|
|
1879
|
+
queueCallback3(callback);
|
|
1880
|
+
}
|
|
1881
|
+
/**
|
|
1882
|
+
* Send a pong frame (no-op for native WebSocket)
|
|
1883
|
+
*/
|
|
1884
|
+
pong(_data, _mask, callback) {
|
|
1885
|
+
queueCallback3(callback);
|
|
1886
|
+
}
|
|
1887
|
+
/**
|
|
1888
|
+
* Terminate the connection
|
|
1889
|
+
*/
|
|
1890
|
+
terminate() {
|
|
1891
|
+
this._socket.close();
|
|
1892
|
+
this.readyState = 3 /* CLOSED */;
|
|
1893
|
+
}
|
|
1894
|
+
/**
|
|
1895
|
+
* Get buffered amount
|
|
1896
|
+
*/
|
|
1897
|
+
get bufferedAmount() {
|
|
1898
|
+
return this._socket.bufferedAmount || 0;
|
|
1899
|
+
}
|
|
1900
|
+
};
|
|
1901
|
+
var WebSocketServer = class extends import_events2.EventEmitter {
|
|
1902
|
+
constructor(options, callback) {
|
|
1903
|
+
super();
|
|
1904
|
+
this.clients = /* @__PURE__ */ new Set();
|
|
1905
|
+
this.options = options || {};
|
|
1906
|
+
this.path = options?.path || "/";
|
|
1907
|
+
if (runtime === "node") {
|
|
1908
|
+
if (options?.server) {
|
|
1909
|
+
this._httpServer = options.server;
|
|
1910
|
+
this._setupUpgradeHandler();
|
|
1911
|
+
} else if (options?.noServer) {
|
|
1912
|
+
} else {
|
|
1913
|
+
const http2 = require("http");
|
|
1914
|
+
this._httpServer = http2.createServer();
|
|
1915
|
+
this._setupUpgradeHandler();
|
|
1916
|
+
if (options?.port) {
|
|
1917
|
+
this._httpServer.listen(options.port, options.host, callback);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
} else {
|
|
1921
|
+
queueCallback3(callback);
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
_setupUpgradeHandler() {
|
|
1925
|
+
this._httpServer.on("upgrade", (request3, socket, head) => {
|
|
1926
|
+
console.log("[WebSocket] Upgrade request:", request3.url, "Expected:", this.path);
|
|
1927
|
+
if (this.path && this.path !== "/" && request3.url !== this.path) {
|
|
1928
|
+
console.log("[WebSocket] Path mismatch, ignoring");
|
|
1929
|
+
return;
|
|
1930
|
+
}
|
|
1931
|
+
this.handleUpgrade(request3, socket, head, (client) => {
|
|
1932
|
+
console.log("[WebSocket] Client connected");
|
|
1933
|
+
this.emit("connection", client, request3);
|
|
1934
|
+
});
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
/**
|
|
1938
|
+
* Handle HTTP upgrade for WebSocket
|
|
1939
|
+
*/
|
|
1940
|
+
handleUpgrade(request3, socket, _head, callback) {
|
|
1941
|
+
const key = request3.headers["sec-websocket-key"];
|
|
1942
|
+
if (!key) {
|
|
1943
|
+
socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1946
|
+
const crypto = require("crypto");
|
|
1947
|
+
const acceptKey = crypto.createHash("sha1").update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64");
|
|
1948
|
+
const headers = [
|
|
1949
|
+
"HTTP/1.1 101 Switching Protocols",
|
|
1950
|
+
"Upgrade: websocket",
|
|
1951
|
+
"Connection: Upgrade",
|
|
1952
|
+
`Sec-WebSocket-Accept: ${acceptKey}`,
|
|
1953
|
+
"",
|
|
1954
|
+
""
|
|
1955
|
+
];
|
|
1956
|
+
socket.write(headers.join("\r\n"));
|
|
1957
|
+
const client = this._createClientFromSocket(socket);
|
|
1958
|
+
if (this.options.clientTracking !== false) {
|
|
1959
|
+
this.clients.add(client);
|
|
1960
|
+
client.on("close", () => {
|
|
1961
|
+
this.clients.delete(client);
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1964
|
+
callback(client);
|
|
1965
|
+
}
|
|
1966
|
+
_createClientFromSocket(socket) {
|
|
1967
|
+
const client = Object.create(WebSocket.prototype);
|
|
1968
|
+
import_events2.EventEmitter.call(client);
|
|
1969
|
+
client.readyState = 1 /* OPEN */;
|
|
1970
|
+
client.url = "ws://localhost";
|
|
1971
|
+
client.protocol = "";
|
|
1972
|
+
client.extensions = "";
|
|
1973
|
+
client.binaryType = "nodebuffer";
|
|
1974
|
+
client._socket = socket;
|
|
1975
|
+
socket.on("data", (data) => {
|
|
1976
|
+
try {
|
|
1977
|
+
const message = this._parseFrame(data);
|
|
1978
|
+
if (message) {
|
|
1979
|
+
client.emit("message", message, false);
|
|
1980
|
+
}
|
|
1981
|
+
} catch (error) {
|
|
1982
|
+
client.emit("error", error);
|
|
1983
|
+
}
|
|
1984
|
+
});
|
|
1985
|
+
socket.on("end", () => {
|
|
1986
|
+
client.readyState = 3 /* CLOSED */;
|
|
1987
|
+
client.emit("close", CLOSE_CODES.NORMAL, "");
|
|
1988
|
+
});
|
|
1989
|
+
socket.on("error", (error) => {
|
|
1990
|
+
client.emit("error", error);
|
|
1991
|
+
});
|
|
1992
|
+
client.send = (data, _options, callback) => {
|
|
1993
|
+
try {
|
|
1994
|
+
const frame = this._createFrame(data);
|
|
1995
|
+
socket.write(frame);
|
|
1996
|
+
queueCallback3(callback);
|
|
1997
|
+
} catch (error) {
|
|
1998
|
+
queueCallback3(callback, error);
|
|
1999
|
+
}
|
|
2000
|
+
};
|
|
2001
|
+
client.close = (_code, _reason) => {
|
|
2002
|
+
socket.end();
|
|
2003
|
+
client.readyState = 3 /* CLOSED */;
|
|
2004
|
+
};
|
|
2005
|
+
return client;
|
|
2006
|
+
}
|
|
2007
|
+
_parseFrame(data) {
|
|
2008
|
+
if (data.length < 2) return null;
|
|
2009
|
+
const firstByte = data[0];
|
|
2010
|
+
const secondByte = data[1];
|
|
2011
|
+
const opcode = firstByte & 15;
|
|
2012
|
+
const isMasked = (secondByte & 128) === 128;
|
|
2013
|
+
let payloadLength = secondByte & 127;
|
|
2014
|
+
let offset = 2;
|
|
2015
|
+
if (payloadLength === 126) {
|
|
2016
|
+
payloadLength = data.readUInt16BE(2);
|
|
2017
|
+
offset = 4;
|
|
2018
|
+
} else if (payloadLength === 127) {
|
|
2019
|
+
payloadLength = Number(data.readBigUInt64BE(2));
|
|
2020
|
+
offset = 10;
|
|
2021
|
+
}
|
|
2022
|
+
let payload = data.subarray(offset);
|
|
2023
|
+
if (isMasked) {
|
|
2024
|
+
const maskKey = data.subarray(offset, offset + 4);
|
|
2025
|
+
payload = data.subarray(offset + 4, offset + 4 + payloadLength);
|
|
2026
|
+
for (let i = 0; i < payload.length; i++) {
|
|
2027
|
+
payload[i] ^= maskKey[i % 4];
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
if (opcode === 1) {
|
|
2031
|
+
return payload.toString("utf8");
|
|
2032
|
+
}
|
|
2033
|
+
return null;
|
|
2034
|
+
}
|
|
2035
|
+
_createFrame(data) {
|
|
2036
|
+
const payload = typeof data === "string" ? Buffer.from(data) : data;
|
|
2037
|
+
const payloadLength = Buffer.isBuffer(payload) ? payload.length : 0;
|
|
2038
|
+
let frame;
|
|
2039
|
+
let offset = 2;
|
|
2040
|
+
if (payloadLength < 126) {
|
|
2041
|
+
frame = Buffer.allocUnsafe(2 + payloadLength);
|
|
2042
|
+
frame[1] = payloadLength;
|
|
2043
|
+
} else if (payloadLength < 65536) {
|
|
2044
|
+
frame = Buffer.allocUnsafe(4 + payloadLength);
|
|
2045
|
+
frame[1] = 126;
|
|
2046
|
+
frame.writeUInt16BE(payloadLength, 2);
|
|
2047
|
+
offset = 4;
|
|
2048
|
+
} else {
|
|
2049
|
+
frame = Buffer.allocUnsafe(10 + payloadLength);
|
|
2050
|
+
frame[1] = 127;
|
|
2051
|
+
frame.writeBigUInt64BE(BigInt(payloadLength), 2);
|
|
2052
|
+
offset = 10;
|
|
2053
|
+
}
|
|
2054
|
+
frame[0] = 129;
|
|
2055
|
+
if (Buffer.isBuffer(payload)) {
|
|
2056
|
+
payload.copy(frame, offset);
|
|
2057
|
+
}
|
|
2058
|
+
return frame;
|
|
2059
|
+
}
|
|
2060
|
+
/**
|
|
2061
|
+
* Close the server
|
|
2062
|
+
*/
|
|
2063
|
+
close(callback) {
|
|
2064
|
+
this.clients.forEach((client) => client.close());
|
|
2065
|
+
this.clients.clear();
|
|
2066
|
+
if (this._httpServer) {
|
|
2067
|
+
this._httpServer.close(callback);
|
|
2068
|
+
} else {
|
|
2069
|
+
this.emit("close");
|
|
2070
|
+
queueCallback3(callback);
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
/**
|
|
2074
|
+
* Check if server should handle request
|
|
2075
|
+
*/
|
|
2076
|
+
shouldHandle(request3) {
|
|
2077
|
+
if (this.path && request3.url !== this.path) {
|
|
2078
|
+
return false;
|
|
2079
|
+
}
|
|
2080
|
+
return true;
|
|
2081
|
+
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Get server address
|
|
2084
|
+
*/
|
|
2085
|
+
address() {
|
|
2086
|
+
if (this._httpServer && this._httpServer.address) {
|
|
2087
|
+
return this._httpServer.address();
|
|
2088
|
+
}
|
|
2089
|
+
return null;
|
|
2090
|
+
}
|
|
2091
|
+
};
|
|
2092
|
+
|
|
2093
|
+
// src/chokidar.ts
|
|
2094
|
+
var import_events3 = require("events");
|
|
2095
|
+
init_runtime();
|
|
2096
|
+
function normalizePath2(path) {
|
|
2097
|
+
return path.replace(/\\/g, "/");
|
|
2098
|
+
}
|
|
2099
|
+
function emitEvent(watcher, eventType, path) {
|
|
2100
|
+
watcher.emit(eventType, path);
|
|
2101
|
+
watcher.emit("all", eventType, path);
|
|
2102
|
+
}
|
|
2103
|
+
function matchesAnyPattern(path, patterns) {
|
|
2104
|
+
return patterns.some((pattern) => matchesPattern(path, pattern));
|
|
2105
|
+
}
|
|
2106
|
+
function handleRenameEvent(watcher, fullPath, fs2) {
|
|
2107
|
+
try {
|
|
2108
|
+
fs2.statSync(fullPath);
|
|
2109
|
+
emitEvent(watcher, "add", fullPath);
|
|
2110
|
+
} catch {
|
|
2111
|
+
emitEvent(watcher, "unlink", fullPath);
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
function setupFsWatch(watcher, baseDir, patterns, fs2) {
|
|
2115
|
+
try {
|
|
2116
|
+
const nativeWatcher = fs2.watch(baseDir, { recursive: true }, (eventType, filename) => {
|
|
2117
|
+
if (!filename) return;
|
|
2118
|
+
const fullPath = normalizePath2(`${baseDir}/${filename}`);
|
|
2119
|
+
if (!matchesAnyPattern(fullPath, patterns)) return;
|
|
2120
|
+
if (eventType === "rename") {
|
|
2121
|
+
handleRenameEvent(watcher, fullPath, fs2);
|
|
2122
|
+
} else if (eventType === "change") {
|
|
2123
|
+
emitEvent(watcher, "change", fullPath);
|
|
2124
|
+
}
|
|
2125
|
+
});
|
|
2126
|
+
watcher._setWatcher(nativeWatcher);
|
|
2127
|
+
watcher["_watched"].add(baseDir);
|
|
2128
|
+
queueMicrotask(() => watcher.emit("ready"));
|
|
2129
|
+
} catch (error) {
|
|
2130
|
+
watcher.emit("error", error);
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
var FSWatcher = class extends import_events3.EventEmitter {
|
|
2134
|
+
constructor(options) {
|
|
2135
|
+
super();
|
|
2136
|
+
this._closed = false;
|
|
2137
|
+
this._watched = /* @__PURE__ */ new Set();
|
|
2138
|
+
this.options = options || {};
|
|
2139
|
+
}
|
|
2140
|
+
/**
|
|
2141
|
+
* Add paths to be watched
|
|
2142
|
+
*/
|
|
2143
|
+
add(paths) {
|
|
2144
|
+
if (this._closed) {
|
|
2145
|
+
throw new Error("Watcher has been closed");
|
|
2146
|
+
}
|
|
2147
|
+
const pathArray = Array.isArray(paths) ? paths : [paths];
|
|
2148
|
+
if (runtime === "node") {
|
|
2149
|
+
if (this._watcher) {
|
|
2150
|
+
this._watcher.add(pathArray);
|
|
2151
|
+
}
|
|
2152
|
+
} else {
|
|
2153
|
+
pathArray.forEach((path) => this._watched.add(path));
|
|
2154
|
+
}
|
|
2155
|
+
return this;
|
|
2156
|
+
}
|
|
2157
|
+
/**
|
|
2158
|
+
* Stop watching paths
|
|
2159
|
+
*/
|
|
2160
|
+
unwatch(paths) {
|
|
2161
|
+
if (this._closed) {
|
|
2162
|
+
return this;
|
|
2163
|
+
}
|
|
2164
|
+
const pathArray = Array.isArray(paths) ? paths : [paths];
|
|
2165
|
+
if (runtime === "node") {
|
|
2166
|
+
if (this._watcher) {
|
|
2167
|
+
this._watcher.unwatch(pathArray);
|
|
2168
|
+
}
|
|
2169
|
+
} else {
|
|
2170
|
+
pathArray.forEach((path) => this._watched.delete(path));
|
|
2171
|
+
}
|
|
2172
|
+
return this;
|
|
2173
|
+
}
|
|
2174
|
+
/**
|
|
2175
|
+
* Close the watcher
|
|
2176
|
+
*/
|
|
2177
|
+
async close() {
|
|
2178
|
+
if (this._closed) {
|
|
2179
|
+
return;
|
|
2180
|
+
}
|
|
2181
|
+
this._closed = true;
|
|
2182
|
+
if (runtime === "node") {
|
|
2183
|
+
if (this._watcher) {
|
|
2184
|
+
await this._watcher.close();
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
this.removeAllListeners();
|
|
2188
|
+
}
|
|
2189
|
+
/**
|
|
2190
|
+
* Get watched paths
|
|
2191
|
+
*/
|
|
2192
|
+
getWatched() {
|
|
2193
|
+
if (runtime === "node" && this._watcher) {
|
|
2194
|
+
return this._watcher.getWatched();
|
|
2195
|
+
}
|
|
2196
|
+
const result = {};
|
|
2197
|
+
this._watched.forEach((path) => {
|
|
2198
|
+
const dir = path.substring(0, path.lastIndexOf("/")) || ".";
|
|
2199
|
+
const file = path.substring(path.lastIndexOf("/") + 1);
|
|
2200
|
+
if (!result[dir]) {
|
|
2201
|
+
result[dir] = [];
|
|
209
2202
|
}
|
|
2203
|
+
result[dir].push(file);
|
|
2204
|
+
});
|
|
2205
|
+
return result;
|
|
2206
|
+
}
|
|
2207
|
+
/**
|
|
2208
|
+
* Internal method to set native watcher
|
|
2209
|
+
* @internal
|
|
2210
|
+
*/
|
|
2211
|
+
_setWatcher(watcher) {
|
|
2212
|
+
this._watcher = watcher;
|
|
2213
|
+
}
|
|
2214
|
+
};
|
|
2215
|
+
function getBaseDirectory(pattern) {
|
|
2216
|
+
const parts = pattern.split(/[\\\/]/);
|
|
2217
|
+
let baseDir = "";
|
|
2218
|
+
for (const part of parts) {
|
|
2219
|
+
if (part.includes("*") || part.includes("?")) {
|
|
2220
|
+
break;
|
|
210
2221
|
}
|
|
2222
|
+
baseDir = baseDir ? `${baseDir}/${part}` : part;
|
|
211
2223
|
}
|
|
212
|
-
return
|
|
2224
|
+
return baseDir || ".";
|
|
213
2225
|
}
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
2226
|
+
function matchesPattern(filePath, pattern) {
|
|
2227
|
+
const regexPattern = normalizePath2(pattern).replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\?/g, ".");
|
|
2228
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
2229
|
+
const normalizedPath = normalizePath2(filePath);
|
|
2230
|
+
return regex.test(normalizedPath);
|
|
2231
|
+
}
|
|
2232
|
+
function watch(paths, options) {
|
|
2233
|
+
const watcher = new FSWatcher(options);
|
|
2234
|
+
const pathArray = Array.isArray(paths) ? paths : [paths];
|
|
2235
|
+
const watchMap = /* @__PURE__ */ new Map();
|
|
2236
|
+
pathArray.forEach((path) => {
|
|
2237
|
+
const baseDir = getBaseDirectory(path);
|
|
2238
|
+
if (!watchMap.has(baseDir)) {
|
|
2239
|
+
watchMap.set(baseDir, []);
|
|
2240
|
+
}
|
|
2241
|
+
watchMap.get(baseDir).push(path);
|
|
2242
|
+
});
|
|
2243
|
+
if (runtime === "node") {
|
|
2244
|
+
const fs2 = require("fs");
|
|
2245
|
+
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns, fs2));
|
|
2246
|
+
} else if (runtime === "bun") {
|
|
2247
|
+
const fs2 = require("fs");
|
|
2248
|
+
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns, fs2));
|
|
2249
|
+
} else if (runtime === "deno") {
|
|
2250
|
+
const baseDirs = Array.from(watchMap.keys());
|
|
2251
|
+
const allPatterns = Array.from(watchMap.values()).flat();
|
|
2252
|
+
(async () => {
|
|
221
2253
|
try {
|
|
222
|
-
const
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
2254
|
+
const denoWatcher = Deno.watchFs(baseDirs);
|
|
2255
|
+
for await (const event of denoWatcher) {
|
|
2256
|
+
if (watcher["_closed"]) break;
|
|
2257
|
+
for (const path of event.paths) {
|
|
2258
|
+
const normalizedPath = normalizePath2(path);
|
|
2259
|
+
if (!matchesAnyPattern(normalizedPath, allPatterns)) continue;
|
|
2260
|
+
switch (event.kind) {
|
|
2261
|
+
case "create":
|
|
2262
|
+
emitEvent(watcher, "add", path);
|
|
2263
|
+
break;
|
|
2264
|
+
case "modify":
|
|
2265
|
+
emitEvent(watcher, "change", path);
|
|
2266
|
+
break;
|
|
2267
|
+
case "remove":
|
|
2268
|
+
emitEvent(watcher, "unlink", path);
|
|
2269
|
+
break;
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
} catch (error) {
|
|
2274
|
+
if (!watcher["_closed"]) {
|
|
2275
|
+
watcher.emit("error", error);
|
|
2276
|
+
}
|
|
230
2277
|
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
return configModule.default || configModule;
|
|
235
|
-
}
|
|
2278
|
+
})();
|
|
2279
|
+
pathArray.forEach((path) => watcher.add(path));
|
|
2280
|
+
queueMicrotask(() => watcher.emit("ready"));
|
|
236
2281
|
}
|
|
2282
|
+
return watcher;
|
|
237
2283
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
2284
|
+
|
|
2285
|
+
// src/server.ts
|
|
2286
|
+
init_fs();
|
|
2287
|
+
init_path();
|
|
2288
|
+
|
|
2289
|
+
// src/mime-types.ts
|
|
2290
|
+
init_runtime();
|
|
2291
|
+
var MIME_TYPES = {
|
|
2292
|
+
// Text
|
|
2293
|
+
"txt": "text/plain",
|
|
2294
|
+
"html": "text/html",
|
|
2295
|
+
"htm": "text/html",
|
|
2296
|
+
"css": "text/css",
|
|
2297
|
+
"js": "text/javascript",
|
|
2298
|
+
"mjs": "text/javascript",
|
|
2299
|
+
"json": "application/json",
|
|
2300
|
+
"xml": "application/xml",
|
|
2301
|
+
"csv": "text/csv",
|
|
2302
|
+
"md": "text/markdown",
|
|
2303
|
+
"markdown": "text/x-markdown",
|
|
2304
|
+
// Images
|
|
2305
|
+
"png": "image/png",
|
|
2306
|
+
"jpg": "image/jpeg",
|
|
2307
|
+
"jpeg": "image/jpeg",
|
|
2308
|
+
"gif": "image/gif",
|
|
2309
|
+
"svg": "image/svg+xml",
|
|
2310
|
+
"webp": "image/webp",
|
|
2311
|
+
"ico": "image/x-icon",
|
|
2312
|
+
"bmp": "image/bmp",
|
|
2313
|
+
"tiff": "image/tiff",
|
|
2314
|
+
"tif": "image/tiff",
|
|
2315
|
+
// Audio
|
|
2316
|
+
"mp3": "audio/mpeg",
|
|
2317
|
+
"wav": "audio/wav",
|
|
2318
|
+
"ogg": "audio/ogg",
|
|
2319
|
+
"aac": "audio/aac",
|
|
2320
|
+
"m4a": "audio/mp4",
|
|
2321
|
+
"flac": "audio/flac",
|
|
2322
|
+
// Video
|
|
2323
|
+
"mp4": "video/mp4",
|
|
2324
|
+
"webm": "video/webm",
|
|
2325
|
+
"avi": "video/x-msvideo",
|
|
2326
|
+
"mov": "video/quicktime",
|
|
2327
|
+
"mkv": "video/x-matroska",
|
|
2328
|
+
"flv": "video/x-flv",
|
|
2329
|
+
// Application
|
|
2330
|
+
"pdf": "application/pdf",
|
|
2331
|
+
"zip": "application/zip",
|
|
2332
|
+
"gz": "application/gzip",
|
|
2333
|
+
"tar": "application/x-tar",
|
|
2334
|
+
"rar": "application/x-rar-compressed",
|
|
2335
|
+
"7z": "application/x-7z-compressed",
|
|
2336
|
+
// Documents
|
|
2337
|
+
"doc": "application/msword",
|
|
2338
|
+
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
2339
|
+
"xls": "application/vnd.ms-excel",
|
|
2340
|
+
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
2341
|
+
"ppt": "application/vnd.ms-powerpoint",
|
|
2342
|
+
"pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
2343
|
+
// Fonts
|
|
2344
|
+
"woff": "font/woff",
|
|
2345
|
+
"woff2": "font/woff2",
|
|
2346
|
+
"ttf": "font/ttf",
|
|
2347
|
+
"otf": "font/otf",
|
|
2348
|
+
"eot": "application/vnd.ms-fontobject",
|
|
2349
|
+
// Web
|
|
2350
|
+
"wasm": "application/wasm",
|
|
2351
|
+
"manifest": "application/manifest+json",
|
|
2352
|
+
// Binary
|
|
2353
|
+
"bin": "application/octet-stream",
|
|
2354
|
+
"exe": "application/x-msdownload",
|
|
2355
|
+
"dll": "application/x-msdownload",
|
|
2356
|
+
// TypeScript/Modern JS
|
|
2357
|
+
"ts": "text/typescript",
|
|
2358
|
+
"tsx": "text/tsx",
|
|
2359
|
+
"jsx": "text/jsx"
|
|
2360
|
+
};
|
|
2361
|
+
var TYPE_TO_EXTENSIONS = {};
|
|
2362
|
+
for (const ext in MIME_TYPES) {
|
|
2363
|
+
const type = MIME_TYPES[ext];
|
|
2364
|
+
if (!TYPE_TO_EXTENSIONS[type]) {
|
|
2365
|
+
TYPE_TO_EXTENSIONS[type] = [];
|
|
241
2366
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
2367
|
+
TYPE_TO_EXTENSIONS[type].push(ext);
|
|
2368
|
+
}
|
|
2369
|
+
function getExtension(path) {
|
|
2370
|
+
const match = /\.([^./\\]+)$/.exec(path);
|
|
2371
|
+
return match ? match[1].toLowerCase() : "";
|
|
2372
|
+
}
|
|
2373
|
+
function lookup(path) {
|
|
2374
|
+
const ext = getExtension(path) || path.toLowerCase();
|
|
2375
|
+
return MIME_TYPES[ext] || false;
|
|
248
2376
|
}
|
|
249
2377
|
|
|
250
2378
|
// src/server.ts
|
|
251
|
-
|
|
252
|
-
var import_https = require("https");
|
|
253
|
-
var import_ws = require("ws");
|
|
254
|
-
var import_chokidar = require("chokidar");
|
|
255
|
-
var import_promises = require("fs/promises");
|
|
256
|
-
var import_path2 = require("path");
|
|
257
|
-
var import_mime_types = require("mime-types");
|
|
258
|
-
var import_esbuild = require("esbuild");
|
|
2379
|
+
init_runtime();
|
|
259
2380
|
|
|
260
2381
|
// src/dom.ts
|
|
2382
|
+
function resolveElement(rootElement) {
|
|
2383
|
+
return typeof rootElement === "string" ? document.getElementById(rootElement.replace("#", "")) : rootElement;
|
|
2384
|
+
}
|
|
2385
|
+
function ensureElement(el, rootElement) {
|
|
2386
|
+
if (!el) {
|
|
2387
|
+
throw new Error(`Element not found: ${rootElement}`);
|
|
2388
|
+
}
|
|
2389
|
+
return el;
|
|
2390
|
+
}
|
|
2391
|
+
function shouldSkipChild(child) {
|
|
2392
|
+
return child == null || child === false;
|
|
2393
|
+
}
|
|
2394
|
+
function isPrimitiveJson(json2) {
|
|
2395
|
+
return json2 == null || typeof json2 === "boolean" || typeof json2 === "string" || typeof json2 === "number";
|
|
2396
|
+
}
|
|
261
2397
|
var DomNode = class {
|
|
262
2398
|
constructor() {
|
|
263
2399
|
this.elementCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -309,11 +2445,11 @@ var DomNode = class {
|
|
|
309
2445
|
const renderChildren = (target) => {
|
|
310
2446
|
for (let i = 0; i < len; i++) {
|
|
311
2447
|
const child = children[i];
|
|
312
|
-
if (child
|
|
2448
|
+
if (shouldSkipChild(child)) continue;
|
|
313
2449
|
if (Array.isArray(child)) {
|
|
314
2450
|
for (let j = 0, cLen = child.length; j < cLen; j++) {
|
|
315
2451
|
const c = child[j];
|
|
316
|
-
c
|
|
2452
|
+
!shouldSkipChild(c) && this.renderToDOM(c, target);
|
|
317
2453
|
}
|
|
318
2454
|
} else {
|
|
319
2455
|
this.renderToDOM(child, target);
|
|
@@ -330,10 +2466,8 @@ var DomNode = class {
|
|
|
330
2466
|
parent.appendChild(el);
|
|
331
2467
|
}
|
|
332
2468
|
render(rootElement, vNode) {
|
|
333
|
-
const el =
|
|
334
|
-
|
|
335
|
-
throw new Error(`Element not found: ${rootElement}`);
|
|
336
|
-
}
|
|
2469
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
2470
|
+
el.innerHTML = "";
|
|
337
2471
|
if (vNode.children && vNode.children.length > 500) {
|
|
338
2472
|
const fragment = document.createDocumentFragment();
|
|
339
2473
|
this.renderToDOM(vNode, fragment);
|
|
@@ -344,10 +2478,7 @@ var DomNode = class {
|
|
|
344
2478
|
return el;
|
|
345
2479
|
}
|
|
346
2480
|
batchRender(rootElement, vNodes) {
|
|
347
|
-
const el =
|
|
348
|
-
if (!el) {
|
|
349
|
-
throw new Error(`Element not found: ${rootElement}`);
|
|
350
|
-
}
|
|
2481
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
351
2482
|
const len = vNodes.length;
|
|
352
2483
|
if (len > 3e3) {
|
|
353
2484
|
const fragment = document.createDocumentFragment();
|
|
@@ -376,10 +2507,7 @@ var DomNode = class {
|
|
|
376
2507
|
return el;
|
|
377
2508
|
}
|
|
378
2509
|
renderChunked(rootElement, vNodes, chunkSize = 5e3, onProgress) {
|
|
379
|
-
const el =
|
|
380
|
-
if (!el) {
|
|
381
|
-
throw new Error(`Element not found: ${rootElement}`);
|
|
382
|
-
}
|
|
2510
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
383
2511
|
const len = vNodes.length;
|
|
384
2512
|
let index = 0;
|
|
385
2513
|
const renderChunk = () => {
|
|
@@ -489,7 +2617,7 @@ var DomNode = class {
|
|
|
489
2617
|
const end = Math.min(items.length, Math.ceil((scrollTop + viewportHeight) / itemHeight) + bufferSize);
|
|
490
2618
|
return { start, end };
|
|
491
2619
|
};
|
|
492
|
-
const
|
|
2620
|
+
const render2 = () => {
|
|
493
2621
|
const { start, end } = getVisibleRange();
|
|
494
2622
|
const wrapper = document.createElement("div");
|
|
495
2623
|
wrapper.style.cssText = `height:${totalHeight}px;position:relative`;
|
|
@@ -504,12 +2632,12 @@ var DomNode = class {
|
|
|
504
2632
|
};
|
|
505
2633
|
const scrollHandler = () => {
|
|
506
2634
|
scrollTop = container.scrollTop;
|
|
507
|
-
requestAnimationFrame(
|
|
2635
|
+
requestAnimationFrame(render2);
|
|
508
2636
|
};
|
|
509
2637
|
container.addEventListener("scroll", scrollHandler);
|
|
510
|
-
|
|
2638
|
+
render2();
|
|
511
2639
|
return {
|
|
512
|
-
render,
|
|
2640
|
+
render: render2,
|
|
513
2641
|
destroy: () => {
|
|
514
2642
|
container.removeEventListener("scroll", scrollHandler);
|
|
515
2643
|
container.innerHTML = "";
|
|
@@ -586,10 +2714,10 @@ var DomNode = class {
|
|
|
586
2714
|
if (pretty && hasComplexChildren) {
|
|
587
2715
|
html += newLine;
|
|
588
2716
|
for (const child of resolvedChildren) {
|
|
589
|
-
if (child
|
|
2717
|
+
if (shouldSkipChild(child)) continue;
|
|
590
2718
|
if (Array.isArray(child)) {
|
|
591
2719
|
for (const c of child) {
|
|
592
|
-
if (c
|
|
2720
|
+
if (!shouldSkipChild(c)) {
|
|
593
2721
|
html += this.renderToString(c, { pretty, indent: indent + 1 });
|
|
594
2722
|
}
|
|
595
2723
|
}
|
|
@@ -600,10 +2728,10 @@ var DomNode = class {
|
|
|
600
2728
|
html += indentStr;
|
|
601
2729
|
} else {
|
|
602
2730
|
for (const child of resolvedChildren) {
|
|
603
|
-
if (child
|
|
2731
|
+
if (shouldSkipChild(child)) continue;
|
|
604
2732
|
if (Array.isArray(child)) {
|
|
605
2733
|
for (const c of child) {
|
|
606
|
-
if (c
|
|
2734
|
+
if (!shouldSkipChild(c)) {
|
|
607
2735
|
html += this.renderToString(c, { pretty: false, indent: 0 });
|
|
608
2736
|
}
|
|
609
2737
|
}
|
|
@@ -744,17 +2872,14 @@ var DomNode = class {
|
|
|
744
2872
|
}
|
|
745
2873
|
return currentValue;
|
|
746
2874
|
}
|
|
747
|
-
jsonToVNode(
|
|
748
|
-
if (this.isState(
|
|
749
|
-
return this.createReactiveChild(
|
|
2875
|
+
jsonToVNode(json2) {
|
|
2876
|
+
if (this.isState(json2)) {
|
|
2877
|
+
return this.createReactiveChild(json2, (v) => v);
|
|
750
2878
|
}
|
|
751
|
-
if (
|
|
752
|
-
return
|
|
2879
|
+
if (isPrimitiveJson(json2)) {
|
|
2880
|
+
return json2;
|
|
753
2881
|
}
|
|
754
|
-
|
|
755
|
-
return json;
|
|
756
|
-
}
|
|
757
|
-
const { tag, attributes = {}, children } = json;
|
|
2882
|
+
const { tag, attributes = {}, children } = json2;
|
|
758
2883
|
const props = {};
|
|
759
2884
|
for (const key in attributes) {
|
|
760
2885
|
const value = attributes[key];
|
|
@@ -790,17 +2915,14 @@ var DomNode = class {
|
|
|
790
2915
|
}
|
|
791
2916
|
return { tagName: tag, props, children: childrenArray };
|
|
792
2917
|
}
|
|
793
|
-
vNodeJsonToVNode(
|
|
794
|
-
if (this.isState(
|
|
795
|
-
return this.createReactiveChild(
|
|
796
|
-
}
|
|
797
|
-
if (json == null || typeof json === "boolean") {
|
|
798
|
-
return json;
|
|
2918
|
+
vNodeJsonToVNode(json2) {
|
|
2919
|
+
if (this.isState(json2)) {
|
|
2920
|
+
return this.createReactiveChild(json2, (v) => v);
|
|
799
2921
|
}
|
|
800
|
-
if (
|
|
801
|
-
return
|
|
2922
|
+
if (isPrimitiveJson(json2)) {
|
|
2923
|
+
return json2;
|
|
802
2924
|
}
|
|
803
|
-
const { tagName, props = {}, children = [] } =
|
|
2925
|
+
const { tagName, props = {}, children = [] } = json2;
|
|
804
2926
|
const resolvedProps = {};
|
|
805
2927
|
for (const key in props) {
|
|
806
2928
|
const value = props[key];
|
|
@@ -819,57 +2941,28 @@ var DomNode = class {
|
|
|
819
2941
|
}
|
|
820
2942
|
return { tagName, props: resolvedProps, children: childrenArray };
|
|
821
2943
|
}
|
|
822
|
-
renderJson(rootElement,
|
|
823
|
-
const vNode = this.jsonToVNode(
|
|
2944
|
+
renderJson(rootElement, json2) {
|
|
2945
|
+
const vNode = this.jsonToVNode(json2);
|
|
824
2946
|
if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
|
|
825
2947
|
throw new Error("Invalid JSON structure");
|
|
826
2948
|
}
|
|
827
2949
|
return this.render(rootElement, vNode);
|
|
828
2950
|
}
|
|
829
|
-
renderVNode(rootElement,
|
|
830
|
-
const vNode = this.vNodeJsonToVNode(
|
|
2951
|
+
renderVNode(rootElement, json2) {
|
|
2952
|
+
const vNode = this.vNodeJsonToVNode(json2);
|
|
831
2953
|
if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
|
|
832
2954
|
throw new Error("Invalid VNode JSON structure");
|
|
833
2955
|
}
|
|
834
2956
|
return this.render(rootElement, vNode);
|
|
835
2957
|
}
|
|
836
|
-
renderJsonToString(
|
|
837
|
-
const vNode = this.jsonToVNode(
|
|
2958
|
+
renderJsonToString(json2, options = {}) {
|
|
2959
|
+
const vNode = this.jsonToVNode(json2);
|
|
838
2960
|
return this.renderToString(vNode, options);
|
|
839
2961
|
}
|
|
840
|
-
renderVNodeToString(
|
|
841
|
-
const vNode = this.vNodeJsonToVNode(
|
|
2962
|
+
renderVNodeToString(json2, options = {}) {
|
|
2963
|
+
const vNode = this.vNodeJsonToVNode(json2);
|
|
842
2964
|
return this.renderToString(vNode, options);
|
|
843
2965
|
}
|
|
844
|
-
// Server-side rendering - Render complete HTML document VNode to document
|
|
845
|
-
renderServer(vNode) {
|
|
846
|
-
if (typeof vNode !== "object" || vNode === null || !("tagName" in vNode)) throw new Error("renderServer requires a VNode with html tag");
|
|
847
|
-
if (vNode.tagName !== "html") throw new Error("renderServer requires a VNode with html tag as root");
|
|
848
|
-
const htmlVNode = vNode;
|
|
849
|
-
let headVNode = null, bodyVNode = null;
|
|
850
|
-
for (const child of htmlVNode.children || []) {
|
|
851
|
-
if (typeof child === "object" && child !== null && "tagName" in child) {
|
|
852
|
-
if (child.tagName === "head") headVNode = child;
|
|
853
|
-
if (child.tagName === "body") bodyVNode = child;
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
if (htmlVNode.props) for (const k in htmlVNode.props) {
|
|
857
|
-
const v = htmlVNode.props[k];
|
|
858
|
-
if (v !== void 0 && v !== null && v !== false) document.documentElement.setAttribute(k, String(v));
|
|
859
|
-
}
|
|
860
|
-
if (headVNode) {
|
|
861
|
-
document.head.innerHTML = "";
|
|
862
|
-
for (const child of headVNode.children || []) this.renderToDOM(child, document.head);
|
|
863
|
-
}
|
|
864
|
-
if (bodyVNode) {
|
|
865
|
-
document.body.innerHTML = "";
|
|
866
|
-
if (bodyVNode.props) for (const k in bodyVNode.props) {
|
|
867
|
-
const v = bodyVNode.props[k];
|
|
868
|
-
if (v !== void 0 && v !== null && v !== false) document.body.setAttribute(k, String(v));
|
|
869
|
-
}
|
|
870
|
-
for (const child of bodyVNode.children || []) this.renderToDOM(child, document.body);
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
2966
|
// Generate complete HTML document as string (for SSR)
|
|
874
2967
|
renderToHTMLDocument(vNode, options = {}) {
|
|
875
2968
|
const { title = "", meta = [], links = [], scripts = [], styles = [], lang = "en", head = "", bodyAttrs = {}, pretty = false } = options;
|
|
@@ -922,8 +3015,49 @@ var DomNode = class {
|
|
|
922
3015
|
}
|
|
923
3016
|
};
|
|
924
3017
|
var dom = new DomNode();
|
|
3018
|
+
var render = dom.render.bind(dom);
|
|
3019
|
+
var renderToString = dom.renderToString.bind(dom);
|
|
925
3020
|
|
|
926
3021
|
// src/server.ts
|
|
3022
|
+
var json = (res, data, status = 200) => (res.writeHead(status, { "Content-Type": "application/json" }), res.end(JSON.stringify(data)));
|
|
3023
|
+
var sendError = (res, code, msg) => {
|
|
3024
|
+
res.writeHead(code, { "Content-Type": "text/plain" });
|
|
3025
|
+
res.end(msg);
|
|
3026
|
+
};
|
|
3027
|
+
var send404 = (res, msg = "Not Found") => sendError(res, 404, msg);
|
|
3028
|
+
var send403 = (res, msg = "Forbidden") => sendError(res, 403, msg);
|
|
3029
|
+
var send500 = (res, msg = "Internal Server Error") => sendError(res, 500, msg);
|
|
3030
|
+
var createElitImportMap = (basePath = "", mode = "dev") => {
|
|
3031
|
+
const srcPath = mode === "dev" ? basePath ? `${basePath}/node_modules/elit/src` : "/node_modules/elit/src" : basePath ? `${basePath}/dist` : "/dist";
|
|
3032
|
+
const fileExt = mode === "dev" ? ".ts" : ".mjs";
|
|
3033
|
+
return `<script type="importmap">{"imports":{"elit":"${srcPath}/index${fileExt}","elit/":"${srcPath}/","elit/dom":"${srcPath}/dom${fileExt}","elit/state":"${srcPath}/state${fileExt}","elit/style":"${srcPath}/style${fileExt}","elit/el":"${srcPath}/el${fileExt}","elit/router":"${srcPath}/router${fileExt}","elit/hmr":"${srcPath}/hmr${fileExt}","elit/types":"${srcPath}/types${fileExt}"}}</script>`;
|
|
3034
|
+
};
|
|
3035
|
+
var createHMRScript = (port, wsPath) => `<script>(function(){let ws;let retries=0;let maxRetries=5;function connect(){ws=new WebSocket('ws://'+window.location.hostname+':${port}${wsPath}');ws.onopen=()=>{console.log('[Elit HMR] Connected');retries=0};ws.onmessage=(e)=>{const d=JSON.parse(e.data);if(d.type==='update'){console.log('[Elit HMR] File updated:',d.path);window.location.reload()}else if(d.type==='reload'){console.log('[Elit HMR] Reloading...');window.location.reload()}else if(d.type==='error')console.error('[Elit HMR] Error:',d.error)};ws.onclose=()=>{if(retries<maxRetries){retries++;setTimeout(connect,1000*retries)}else if(retries===maxRetries){console.log('[Elit HMR] Connection closed. Start dev server to reconnect.')}};ws.onerror=()=>{ws.close()}}connect()})();</script>`;
|
|
3036
|
+
var rewriteRelativePaths = (html, basePath) => {
|
|
3037
|
+
if (!basePath) return html;
|
|
3038
|
+
html = html.replace(/(<script[^>]+src=["'])(?!https?:\/\/|\/)(\.\/)?([^"']+)(["'])/g, `$1${basePath}/$3$4`);
|
|
3039
|
+
html = html.replace(/(<link[^>]+href=["'])(?!https?:\/\/|\/)(\.\/)?([^"']+)(["'])/g, `$1${basePath}/$3$4`);
|
|
3040
|
+
return html;
|
|
3041
|
+
};
|
|
3042
|
+
var normalizeBasePath = (basePath) => basePath && basePath !== "/" ? basePath : "";
|
|
3043
|
+
async function findSpecialDir(startDir, targetDir) {
|
|
3044
|
+
let currentDir = startDir;
|
|
3045
|
+
const maxLevels = 5;
|
|
3046
|
+
for (let i = 0; i < maxLevels; i++) {
|
|
3047
|
+
const targetPath = resolve(currentDir, targetDir);
|
|
3048
|
+
try {
|
|
3049
|
+
const stats = await stat(targetPath);
|
|
3050
|
+
if (stats.isDirectory()) {
|
|
3051
|
+
return currentDir;
|
|
3052
|
+
}
|
|
3053
|
+
} catch {
|
|
3054
|
+
}
|
|
3055
|
+
const parentDir = resolve(currentDir, "..");
|
|
3056
|
+
if (parentDir === currentDir) break;
|
|
3057
|
+
currentDir = parentDir;
|
|
3058
|
+
}
|
|
3059
|
+
return null;
|
|
3060
|
+
}
|
|
927
3061
|
function rewritePath(path, pathRewrite) {
|
|
928
3062
|
if (!pathRewrite) return path;
|
|
929
3063
|
for (const [from, to] of Object.entries(pathRewrite)) {
|
|
@@ -944,34 +3078,49 @@ function createProxyHandler(proxyConfigs) {
|
|
|
944
3078
|
try {
|
|
945
3079
|
const targetUrl = new URL(target);
|
|
946
3080
|
const isHttps = targetUrl.protocol === "https:";
|
|
947
|
-
const requestLib = isHttps ?
|
|
3081
|
+
const requestLib = isHttps ? request2 : request;
|
|
948
3082
|
let proxyPath = rewritePath(url, pathRewrite);
|
|
949
|
-
const
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
headers: {
|
|
955
|
-
...req.headers,
|
|
956
|
-
...headers || {}
|
|
3083
|
+
const proxyUrl = `${isHttps ? "https" : "http"}://${targetUrl.hostname}:${targetUrl.port || (isHttps ? 443 : 80)}${proxyPath}`;
|
|
3084
|
+
const proxyReqHeaders = {};
|
|
3085
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
3086
|
+
if (value !== void 0) {
|
|
3087
|
+
proxyReqHeaders[key] = value;
|
|
957
3088
|
}
|
|
958
|
-
}
|
|
3089
|
+
}
|
|
3090
|
+
if (headers) {
|
|
3091
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
3092
|
+
if (value !== void 0) {
|
|
3093
|
+
proxyReqHeaders[key] = value;
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
959
3097
|
if (changeOrigin) {
|
|
960
|
-
|
|
3098
|
+
proxyReqHeaders.host = targetUrl.host;
|
|
961
3099
|
}
|
|
962
|
-
delete
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
3100
|
+
delete proxyReqHeaders["host"];
|
|
3101
|
+
const proxyReqOptions = {
|
|
3102
|
+
method: req.method,
|
|
3103
|
+
headers: proxyReqHeaders
|
|
3104
|
+
};
|
|
3105
|
+
const proxyReq = requestLib(proxyUrl, proxyReqOptions, (proxyRes) => {
|
|
3106
|
+
const outgoingHeaders = {};
|
|
3107
|
+
for (const [key, value] of Object.entries(proxyRes.headers)) {
|
|
3108
|
+
if (value !== void 0) {
|
|
3109
|
+
outgoingHeaders[key] = value;
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
res.writeHead(proxyRes.statusCode || 200, outgoingHeaders);
|
|
3113
|
+
proxyRes.on("data", (chunk) => res.write(chunk));
|
|
3114
|
+
proxyRes.on("end", () => res.end());
|
|
966
3115
|
});
|
|
967
3116
|
proxyReq.on("error", (error) => {
|
|
968
3117
|
console.error("[Proxy] Error proxying %s to %s:", url, target, error.message);
|
|
969
3118
|
if (!res.headersSent) {
|
|
970
|
-
res
|
|
971
|
-
res.end(JSON.stringify({ error: "Bad Gateway", message: "Proxy error" }));
|
|
3119
|
+
json(res, { error: "Bad Gateway", message: "Proxy error" }, 502);
|
|
972
3120
|
}
|
|
973
3121
|
});
|
|
974
|
-
req.
|
|
3122
|
+
req.on("data", (chunk) => proxyReq.write(chunk));
|
|
3123
|
+
req.on("end", () => proxyReq.end());
|
|
975
3124
|
return true;
|
|
976
3125
|
} catch (error) {
|
|
977
3126
|
console.error("[Proxy] Invalid proxy configuration for %s:", path, error);
|
|
@@ -1017,10 +3166,10 @@ var SharedState = class {
|
|
|
1017
3166
|
}
|
|
1018
3167
|
broadcast() {
|
|
1019
3168
|
const message = JSON.stringify({ type: "state:update", key: this.key, value: this._value, timestamp: Date.now() });
|
|
1020
|
-
this.listeners.forEach((ws) => ws.readyState ===
|
|
3169
|
+
this.listeners.forEach((ws) => ws.readyState === 1 /* OPEN */ && ws.send(message));
|
|
1021
3170
|
}
|
|
1022
3171
|
sendTo(ws) {
|
|
1023
|
-
if (ws.readyState ===
|
|
3172
|
+
if (ws.readyState === 1 /* OPEN */) {
|
|
1024
3173
|
ws.send(JSON.stringify({ type: "state:init", key: this.key, value: this._value, timestamp: Date.now() }));
|
|
1025
3174
|
}
|
|
1026
3175
|
}
|
|
@@ -1086,13 +3235,14 @@ var defaultOptions = {
|
|
|
1086
3235
|
ignore: ["node_modules/**", "dist/**", ".git/**", "**/*.d.ts"],
|
|
1087
3236
|
logging: true,
|
|
1088
3237
|
middleware: [],
|
|
1089
|
-
worker: []
|
|
3238
|
+
worker: [],
|
|
3239
|
+
mode: "dev"
|
|
1090
3240
|
};
|
|
1091
3241
|
function createDevServer(options) {
|
|
1092
3242
|
const config = { ...defaultOptions, ...options };
|
|
1093
3243
|
const wsClients = /* @__PURE__ */ new Set();
|
|
1094
3244
|
const stateManager = new StateManager();
|
|
1095
|
-
const clientsToNormalize = config.clients?.length ? config.clients : config.root ? [{ root: config.root, basePath: config.basePath || "", ssr: config.ssr, proxy: config.proxy }] : null;
|
|
3245
|
+
const clientsToNormalize = config.clients?.length ? config.clients : config.root ? [{ root: config.root, basePath: config.basePath || "", index: config.index, ssr: config.ssr, api: config.api, proxy: config.proxy, mode: config.mode }] : null;
|
|
1096
3246
|
if (!clientsToNormalize) throw new Error('DevServerOptions must include either "clients" array or "root" directory');
|
|
1097
3247
|
const normalizedClients = clientsToNormalize.map((client) => {
|
|
1098
3248
|
let basePath = client.basePath || "";
|
|
@@ -1101,22 +3251,28 @@ function createDevServer(options) {
|
|
|
1101
3251
|
while (basePath.endsWith("/")) basePath = basePath.slice(0, -1);
|
|
1102
3252
|
basePath = basePath ? "/" + basePath : "";
|
|
1103
3253
|
}
|
|
3254
|
+
let indexPath = client.index;
|
|
3255
|
+
if (indexPath) {
|
|
3256
|
+
indexPath = indexPath.replace(/^\.\//, "/");
|
|
3257
|
+
if (!indexPath.startsWith("/")) {
|
|
3258
|
+
indexPath = "/" + indexPath;
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
1104
3261
|
return {
|
|
1105
3262
|
root: client.root,
|
|
1106
3263
|
basePath,
|
|
3264
|
+
index: indexPath,
|
|
1107
3265
|
ssr: client.ssr,
|
|
1108
|
-
|
|
3266
|
+
api: client.api,
|
|
3267
|
+
proxyHandler: client.proxy ? createProxyHandler(client.proxy) : void 0,
|
|
3268
|
+
mode: client.mode || "dev"
|
|
1109
3269
|
};
|
|
1110
3270
|
});
|
|
1111
3271
|
const globalProxyHandler = config.proxy ? createProxyHandler(config.proxy) : null;
|
|
1112
|
-
const server =
|
|
3272
|
+
const server = createServer(async (req, res) => {
|
|
1113
3273
|
const originalUrl = req.url || "/";
|
|
1114
3274
|
const matchedClient = normalizedClients.find((c) => c.basePath && originalUrl.startsWith(c.basePath)) || normalizedClients.find((c) => !c.basePath);
|
|
1115
|
-
if (!matchedClient)
|
|
1116
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
1117
|
-
res.end("404 Not Found");
|
|
1118
|
-
return;
|
|
1119
|
-
}
|
|
3275
|
+
if (!matchedClient) return send404(res, "404 Not Found");
|
|
1120
3276
|
if (matchedClient.proxyHandler) {
|
|
1121
3277
|
try {
|
|
1122
3278
|
const proxied = await matchedClient.proxyHandler(req, res);
|
|
@@ -1140,42 +3296,52 @@ function createDevServer(options) {
|
|
|
1140
3296
|
}
|
|
1141
3297
|
}
|
|
1142
3298
|
const url = matchedClient.basePath ? originalUrl.slice(matchedClient.basePath.length) || "/" : originalUrl;
|
|
3299
|
+
if (matchedClient.api && url.startsWith("/api")) {
|
|
3300
|
+
const handled = await matchedClient.api.handle(req, res);
|
|
3301
|
+
if (handled) return;
|
|
3302
|
+
}
|
|
1143
3303
|
if (config.api && url.startsWith("/api")) {
|
|
1144
3304
|
const handled = await config.api.handle(req, res);
|
|
1145
3305
|
if (handled) return;
|
|
1146
3306
|
}
|
|
1147
|
-
let filePath
|
|
3307
|
+
let filePath;
|
|
3308
|
+
if (url === "/" && matchedClient.ssr && !matchedClient.index) {
|
|
3309
|
+
return serveSSR(res, matchedClient);
|
|
3310
|
+
} else {
|
|
3311
|
+
filePath = url === "/" ? matchedClient.index || "/index.html" : url;
|
|
3312
|
+
}
|
|
1148
3313
|
filePath = filePath.split("?")[0];
|
|
1149
3314
|
if (config.logging && filePath === "/src/pages") {
|
|
1150
3315
|
console.log(`[DEBUG] Request for /src/pages received`);
|
|
1151
3316
|
}
|
|
1152
3317
|
if (filePath.includes("\0")) {
|
|
1153
3318
|
if (config.logging) console.log(`[403] Rejected path with null byte: ${filePath}`);
|
|
1154
|
-
res
|
|
1155
|
-
res.end("403 Forbidden");
|
|
1156
|
-
return;
|
|
3319
|
+
return send403(res, "403 Forbidden");
|
|
1157
3320
|
}
|
|
1158
3321
|
const isDistRequest = filePath.startsWith("/dist/");
|
|
3322
|
+
const isNodeModulesRequest = filePath.startsWith("/node_modules/");
|
|
1159
3323
|
let normalizedPath;
|
|
1160
|
-
const tempPath =
|
|
3324
|
+
const tempPath = normalize(filePath).replace(/\\/g, "/").replace(/^\/+/, "");
|
|
1161
3325
|
if (tempPath.includes("..")) {
|
|
1162
3326
|
if (config.logging) console.log(`[403] Path traversal attempt: ${filePath}`);
|
|
1163
|
-
res
|
|
1164
|
-
res.end("403 Forbidden");
|
|
1165
|
-
return;
|
|
3327
|
+
return send403(res, "403 Forbidden");
|
|
1166
3328
|
}
|
|
1167
3329
|
normalizedPath = tempPath;
|
|
1168
|
-
const rootDir = await
|
|
1169
|
-
|
|
3330
|
+
const rootDir = await realpath(resolve(matchedClient.root));
|
|
3331
|
+
let baseDir = rootDir;
|
|
3332
|
+
if (isDistRequest || isNodeModulesRequest) {
|
|
3333
|
+
const targetDir = isDistRequest ? "dist" : "node_modules";
|
|
3334
|
+
const foundDir = await findSpecialDir(matchedClient.root, targetDir);
|
|
3335
|
+
baseDir = foundDir ? await realpath(foundDir) : rootDir;
|
|
3336
|
+
}
|
|
1170
3337
|
let fullPath;
|
|
1171
3338
|
try {
|
|
1172
|
-
|
|
1173
|
-
if (!
|
|
1174
|
-
if (config.logging) console.log(`[403] File access outside of root: ${
|
|
1175
|
-
res
|
|
1176
|
-
res.end("403 Forbidden");
|
|
1177
|
-
return;
|
|
3339
|
+
const unresolvedPath = resolve(join(baseDir, normalizedPath));
|
|
3340
|
+
if (!unresolvedPath.startsWith(baseDir.endsWith(sep) ? baseDir : baseDir + sep)) {
|
|
3341
|
+
if (config.logging) console.log(`[403] File access outside of root (before symlink): ${unresolvedPath}`);
|
|
3342
|
+
return send403(res, "403 Forbidden");
|
|
1178
3343
|
}
|
|
3344
|
+
fullPath = await realpath(unresolvedPath);
|
|
1179
3345
|
if (config.logging && filePath === "/src/pages") {
|
|
1180
3346
|
console.log(`[DEBUG] Initial resolve succeeded: ${fullPath}`);
|
|
1181
3347
|
}
|
|
@@ -1187,12 +3353,10 @@ function createDevServer(options) {
|
|
|
1187
3353
|
if (normalizedPath.endsWith(".js")) {
|
|
1188
3354
|
const tsPath = normalizedPath.replace(/\.js$/, ".ts");
|
|
1189
3355
|
try {
|
|
1190
|
-
const tsFullPath = await
|
|
1191
|
-
if (!tsFullPath.startsWith(baseDir.endsWith(
|
|
3356
|
+
const tsFullPath = await realpath(resolve(join(baseDir, tsPath)));
|
|
3357
|
+
if (!tsFullPath.startsWith(baseDir.endsWith(sep) ? baseDir : baseDir + sep)) {
|
|
1192
3358
|
if (config.logging) console.log(`[403] Fallback TS path outside of root: ${tsFullPath}`);
|
|
1193
|
-
res
|
|
1194
|
-
res.end("403 Forbidden");
|
|
1195
|
-
return;
|
|
3359
|
+
return send403(res, "403 Forbidden");
|
|
1196
3360
|
}
|
|
1197
3361
|
resolvedPath = tsFullPath;
|
|
1198
3362
|
} catch {
|
|
@@ -1200,19 +3364,19 @@ function createDevServer(options) {
|
|
|
1200
3364
|
}
|
|
1201
3365
|
if (!resolvedPath && !normalizedPath.includes(".")) {
|
|
1202
3366
|
try {
|
|
1203
|
-
resolvedPath = await
|
|
3367
|
+
resolvedPath = await realpath(resolve(join(baseDir, normalizedPath + ".ts")));
|
|
1204
3368
|
if (config.logging) console.log(`[DEBUG] Found: ${normalizedPath}.ts`);
|
|
1205
3369
|
} catch {
|
|
1206
3370
|
try {
|
|
1207
|
-
resolvedPath = await
|
|
3371
|
+
resolvedPath = await realpath(resolve(join(baseDir, normalizedPath + ".js")));
|
|
1208
3372
|
if (config.logging) console.log(`[DEBUG] Found: ${normalizedPath}.js`);
|
|
1209
3373
|
} catch {
|
|
1210
3374
|
try {
|
|
1211
|
-
resolvedPath = await
|
|
3375
|
+
resolvedPath = await realpath(resolve(join(baseDir, normalizedPath, "index.ts")));
|
|
1212
3376
|
if (config.logging) console.log(`[DEBUG] Found: ${normalizedPath}/index.ts`);
|
|
1213
3377
|
} catch {
|
|
1214
3378
|
try {
|
|
1215
|
-
resolvedPath = await
|
|
3379
|
+
resolvedPath = await realpath(resolve(join(baseDir, normalizedPath, "index.js")));
|
|
1216
3380
|
if (config.logging) console.log(`[DEBUG] Found: ${normalizedPath}/index.js`);
|
|
1217
3381
|
} catch {
|
|
1218
3382
|
if (config.logging) console.log(`[DEBUG] Not found: all attempts failed for ${normalizedPath}`);
|
|
@@ -1222,134 +3386,173 @@ function createDevServer(options) {
|
|
|
1222
3386
|
}
|
|
1223
3387
|
}
|
|
1224
3388
|
if (!resolvedPath) {
|
|
1225
|
-
res.
|
|
1226
|
-
|
|
3389
|
+
if (!res.headersSent) {
|
|
3390
|
+
if (filePath === "/index.html" && matchedClient.ssr) {
|
|
3391
|
+
return serveSSR(res, matchedClient);
|
|
3392
|
+
}
|
|
3393
|
+
if (config.logging) console.log(`[404] ${filePath}`);
|
|
3394
|
+
return send404(res, "404 Not Found");
|
|
3395
|
+
}
|
|
1227
3396
|
return;
|
|
1228
3397
|
}
|
|
1229
3398
|
fullPath = resolvedPath;
|
|
1230
3399
|
}
|
|
1231
3400
|
try {
|
|
1232
|
-
const stats = await
|
|
3401
|
+
const stats = await stat(fullPath);
|
|
1233
3402
|
if (stats.isDirectory()) {
|
|
1234
3403
|
if (config.logging) console.log(`[DEBUG] Path is directory: ${fullPath}, trying index files...`);
|
|
1235
3404
|
let indexPath;
|
|
1236
3405
|
try {
|
|
1237
|
-
indexPath = await
|
|
3406
|
+
indexPath = await realpath(resolve(join(fullPath, "index.ts")));
|
|
1238
3407
|
if (config.logging) console.log(`[DEBUG] Found index.ts in directory`);
|
|
1239
3408
|
} catch {
|
|
1240
3409
|
try {
|
|
1241
|
-
indexPath = await
|
|
3410
|
+
indexPath = await realpath(resolve(join(fullPath, "index.js")));
|
|
1242
3411
|
if (config.logging) console.log(`[DEBUG] Found index.js in directory`);
|
|
1243
3412
|
} catch {
|
|
1244
3413
|
if (config.logging) console.log(`[DEBUG] No index file found in directory`);
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
3414
|
+
if (matchedClient.ssr) {
|
|
3415
|
+
return serveSSR(res, matchedClient);
|
|
3416
|
+
}
|
|
3417
|
+
return send404(res, "404 Not Found");
|
|
1248
3418
|
}
|
|
1249
3419
|
}
|
|
1250
3420
|
fullPath = indexPath;
|
|
1251
3421
|
}
|
|
1252
3422
|
} catch (statError) {
|
|
1253
|
-
|
|
1254
|
-
res
|
|
1255
|
-
return;
|
|
1256
|
-
}
|
|
1257
|
-
const parentDir = await (0, import_promises.realpath)((0, import_path2.resolve)(matchedClient.root, ".."));
|
|
1258
|
-
const isInRoot = fullPath.startsWith(rootDir + import_path2.sep) || fullPath === rootDir;
|
|
1259
|
-
const isInParent = isDistRequest && (fullPath.startsWith(parentDir + import_path2.sep) || fullPath === parentDir);
|
|
1260
|
-
if (!isInRoot && !isInParent) {
|
|
1261
|
-
if (config.logging) console.log(`[403] Path outside allowed directories: ${filePath}`);
|
|
1262
|
-
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
1263
|
-
res.end("403 Forbidden");
|
|
1264
|
-
return;
|
|
3423
|
+
if (config.logging) console.log(`[404] ${filePath}`);
|
|
3424
|
+
return send404(res, "404 Not Found");
|
|
1265
3425
|
}
|
|
1266
3426
|
try {
|
|
1267
|
-
const stats = await
|
|
3427
|
+
const stats = await stat(fullPath);
|
|
1268
3428
|
if (stats.isDirectory()) {
|
|
1269
3429
|
try {
|
|
1270
|
-
const indexPath = await
|
|
1271
|
-
if (!indexPath.startsWith(rootDir +
|
|
1272
|
-
res
|
|
1273
|
-
res.end("403 Forbidden");
|
|
1274
|
-
return;
|
|
3430
|
+
const indexPath = await realpath(resolve(join(fullPath, "index.html")));
|
|
3431
|
+
if (!indexPath.startsWith(rootDir + sep) && indexPath !== rootDir) {
|
|
3432
|
+
return send403(res, "403 Forbidden");
|
|
1275
3433
|
}
|
|
1276
|
-
await
|
|
3434
|
+
await stat(indexPath);
|
|
1277
3435
|
return serveFile(indexPath, res, matchedClient);
|
|
1278
3436
|
} catch {
|
|
1279
|
-
res
|
|
1280
|
-
res.end("404 Not Found");
|
|
1281
|
-
return;
|
|
3437
|
+
return send404(res, "404 Not Found");
|
|
1282
3438
|
}
|
|
1283
3439
|
}
|
|
1284
3440
|
await serveFile(fullPath, res, matchedClient);
|
|
1285
3441
|
} catch (error) {
|
|
1286
|
-
if (
|
|
1287
|
-
|
|
1288
|
-
|
|
3442
|
+
if (!res.headersSent) {
|
|
3443
|
+
if (config.logging) console.log(`[404] ${filePath}`);
|
|
3444
|
+
send404(res, "404 Not Found");
|
|
3445
|
+
}
|
|
1289
3446
|
}
|
|
1290
3447
|
});
|
|
1291
3448
|
async function serveFile(filePath, res, client) {
|
|
1292
3449
|
try {
|
|
1293
|
-
const rootDir = await
|
|
1294
|
-
const
|
|
3450
|
+
const rootDir = await realpath(resolve(client.root));
|
|
3451
|
+
const unresolvedPath = resolve(filePath);
|
|
3452
|
+
const isNodeModules = filePath.includes("/node_modules/") || filePath.includes("\\node_modules\\");
|
|
3453
|
+
const isDist = filePath.includes("/dist/") || filePath.includes("\\dist\\");
|
|
3454
|
+
const projectRoot = await realpath(resolve(client.root, ".."));
|
|
3455
|
+
const isInProjectRoot = unresolvedPath.startsWith(projectRoot + sep) || unresolvedPath === projectRoot;
|
|
3456
|
+
if (!unresolvedPath.startsWith(rootDir + sep) && unresolvedPath !== rootDir && !isInProjectRoot) {
|
|
3457
|
+
if (!isNodeModules && !isDist) {
|
|
3458
|
+
if (config.logging) console.log(`[403] Attempted to serve file outside allowed directories: ${filePath}`);
|
|
3459
|
+
return send403(res, "403 Forbidden");
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
1295
3462
|
let resolvedPath;
|
|
1296
3463
|
try {
|
|
1297
|
-
resolvedPath = await
|
|
3464
|
+
resolvedPath = await realpath(unresolvedPath);
|
|
1298
3465
|
} catch {
|
|
1299
3466
|
if (filePath.endsWith("index.html") && client.ssr) {
|
|
1300
3467
|
return serveSSR(res, client);
|
|
1301
3468
|
}
|
|
1302
|
-
res
|
|
1303
|
-
res.end("404 Not Found");
|
|
1304
|
-
return;
|
|
1305
|
-
}
|
|
1306
|
-
const isInRoot = resolvedPath.startsWith(rootDir + import_path2.sep) || resolvedPath === rootDir;
|
|
1307
|
-
const isInParentDist = resolvedPath.startsWith(parentDir + import_path2.sep + "dist" + import_path2.sep);
|
|
1308
|
-
if (!isInRoot && !isInParentDist) {
|
|
1309
|
-
if (config.logging) console.log(`[403] Attempted to serve file outside allowed directories: ${filePath}`);
|
|
1310
|
-
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
1311
|
-
res.end("403 Forbidden");
|
|
1312
|
-
return;
|
|
3469
|
+
return send404(res, "404 Not Found");
|
|
1313
3470
|
}
|
|
1314
|
-
let content = await
|
|
1315
|
-
const ext =
|
|
1316
|
-
let mimeType =
|
|
3471
|
+
let content = await readFile(resolvedPath);
|
|
3472
|
+
const ext = extname(resolvedPath);
|
|
3473
|
+
let mimeType = lookup(resolvedPath) || "application/octet-stream";
|
|
1317
3474
|
if (ext === ".ts" || ext === ".tsx") {
|
|
1318
3475
|
try {
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
3476
|
+
let transpiled;
|
|
3477
|
+
if (isDeno) {
|
|
3478
|
+
const result = await Deno.emit(resolvedPath, {
|
|
3479
|
+
check: false,
|
|
3480
|
+
compilerOptions: {
|
|
3481
|
+
sourceMap: true,
|
|
3482
|
+
inlineSourceMap: true,
|
|
3483
|
+
target: "ES2020",
|
|
3484
|
+
module: "esnext"
|
|
3485
|
+
},
|
|
3486
|
+
sources: {
|
|
3487
|
+
[resolvedPath]: content.toString()
|
|
3488
|
+
}
|
|
3489
|
+
});
|
|
3490
|
+
transpiled = result.files[resolvedPath.replace(/\.tsx?$/, ".js")] || "";
|
|
3491
|
+
} else if (isBun) {
|
|
3492
|
+
const transpiler = new Bun.Transpiler({
|
|
1322
3493
|
loader: ext === ".tsx" ? "tsx" : "ts",
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
3494
|
+
target: "browser"
|
|
3495
|
+
});
|
|
3496
|
+
transpiled = transpiler.transformSync(content.toString());
|
|
3497
|
+
} else {
|
|
3498
|
+
const { build: build2 } = await import("esbuild");
|
|
3499
|
+
const result = await build2({
|
|
3500
|
+
stdin: {
|
|
3501
|
+
contents: content.toString(),
|
|
3502
|
+
loader: ext === ".tsx" ? "tsx" : "ts",
|
|
3503
|
+
resolveDir: resolve(resolvedPath, ".."),
|
|
3504
|
+
sourcefile: resolvedPath
|
|
3505
|
+
},
|
|
3506
|
+
format: "esm",
|
|
3507
|
+
target: "es2020",
|
|
3508
|
+
write: false,
|
|
3509
|
+
bundle: false,
|
|
3510
|
+
sourcemap: "inline"
|
|
3511
|
+
});
|
|
3512
|
+
transpiled = result.outputFiles[0].text;
|
|
3513
|
+
}
|
|
3514
|
+
transpiled = transpiled.replace(
|
|
3515
|
+
/from\s+["']([^"']+)\.ts(x?)["']/g,
|
|
3516
|
+
(_, path, tsx) => `from "${path}.js${tsx}"`
|
|
3517
|
+
);
|
|
3518
|
+
transpiled = transpiled.replace(
|
|
3519
|
+
/import\s+["']([^"']+)\.ts(x?)["']/g,
|
|
3520
|
+
(_, path, tsx) => `import "${path}.js${tsx}"`
|
|
3521
|
+
);
|
|
3522
|
+
content = Buffer.from(transpiled);
|
|
1333
3523
|
mimeType = "application/javascript";
|
|
1334
3524
|
} catch (error) {
|
|
1335
|
-
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
1336
|
-
res.end(`TypeScript compilation error:
|
|
1337
|
-
${error}`);
|
|
1338
3525
|
if (config.logging) console.error("[500] TypeScript compilation error:", error);
|
|
1339
|
-
return
|
|
3526
|
+
return send500(res, `TypeScript compilation error:
|
|
3527
|
+
${error}`);
|
|
1340
3528
|
}
|
|
1341
3529
|
}
|
|
1342
3530
|
if (ext === ".html") {
|
|
1343
|
-
const
|
|
1344
|
-
const
|
|
1345
|
-
{
|
|
1346
|
-
"imports": {
|
|
1347
|
-
"elit": "${elitPath}"
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
</script>`;
|
|
1351
|
-
const hmrScript = `<script>(function(){const ws=new WebSocket('ws://${config.host}:${config.port}${client.basePath}');ws.onopen=()=>console.log('[Elit HMR] Connected');ws.onmessage=(e)=>{const d=JSON.parse(e.data);if(d.type==='update'){console.log('[Elit HMR] File updated:',d.path);window.location.reload()}else if(d.type==='reload'){console.log('[Elit HMR] Reloading...');window.location.reload()}else if(d.type==='error')console.error('[Elit HMR] Error:',d.error)};ws.onclose=()=>{console.log('[Elit HMR] Disconnected - Retrying...');setTimeout(()=>window.location.reload(),1000)};ws.onerror=(e)=>console.error('[Elit HMR] WebSocket error:',e)})();</script>`;
|
|
3531
|
+
const wsPath = normalizeBasePath(client.basePath);
|
|
3532
|
+
const hmrScript = createHMRScript(config.port, wsPath);
|
|
1352
3533
|
let html = content.toString();
|
|
3534
|
+
let ssrStyles = "";
|
|
3535
|
+
if (client.ssr) {
|
|
3536
|
+
try {
|
|
3537
|
+
const result = client.ssr();
|
|
3538
|
+
let ssrHtml;
|
|
3539
|
+
if (typeof result === "string") {
|
|
3540
|
+
ssrHtml = result;
|
|
3541
|
+
} else if (typeof result === "object" && result !== null && "tagName" in result) {
|
|
3542
|
+
ssrHtml = dom.renderToString(result);
|
|
3543
|
+
} else {
|
|
3544
|
+
ssrHtml = String(result);
|
|
3545
|
+
}
|
|
3546
|
+
const styleMatches = ssrHtml.match(/<style[^>]*>[\s\S]*?<\/style>/g);
|
|
3547
|
+
if (styleMatches) {
|
|
3548
|
+
ssrStyles = styleMatches.join("\n");
|
|
3549
|
+
}
|
|
3550
|
+
} catch (error) {
|
|
3551
|
+
if (config.logging) console.error("[Warning] Failed to extract styles from SSR:", error);
|
|
3552
|
+
}
|
|
3553
|
+
}
|
|
3554
|
+
const basePath = normalizeBasePath(client.basePath);
|
|
3555
|
+
html = rewriteRelativePaths(html, basePath);
|
|
1353
3556
|
if (client.basePath && client.basePath !== "/") {
|
|
1354
3557
|
const baseTag = `<base href="${client.basePath}/">`;
|
|
1355
3558
|
if (!html.includes("<base")) {
|
|
@@ -1365,7 +3568,10 @@ ${error}`);
|
|
|
1365
3568
|
}
|
|
1366
3569
|
}
|
|
1367
3570
|
}
|
|
1368
|
-
|
|
3571
|
+
const elitImportMap = createElitImportMap(basePath, client.mode);
|
|
3572
|
+
const headInjection = ssrStyles ? `${ssrStyles}
|
|
3573
|
+
${elitImportMap}` : elitImportMap;
|
|
3574
|
+
html = html.includes("</head>") ? html.replace("</head>", `${headInjection}</head>`) : html;
|
|
1369
3575
|
html = html.includes("</body>") ? html.replace("</body>", `${hmrScript}</body>`) : html + hmrScript;
|
|
1370
3576
|
content = Buffer.from(html);
|
|
1371
3577
|
}
|
|
@@ -1386,19 +3592,16 @@ ${error}`);
|
|
|
1386
3592
|
res.writeHead(200, headers);
|
|
1387
3593
|
res.end(content);
|
|
1388
3594
|
}
|
|
1389
|
-
if (config.logging) console.log(`[200] ${
|
|
3595
|
+
if (config.logging) console.log(`[200] ${relative(client.root, filePath)}`);
|
|
1390
3596
|
} catch (error) {
|
|
1391
|
-
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
1392
|
-
res.end("500 Internal Server Error");
|
|
1393
3597
|
if (config.logging) console.error("[500] Error reading file:", error);
|
|
3598
|
+
send500(res, "500 Internal Server Error");
|
|
1394
3599
|
}
|
|
1395
3600
|
}
|
|
1396
3601
|
function serveSSR(res, client) {
|
|
1397
3602
|
try {
|
|
1398
3603
|
if (!client.ssr) {
|
|
1399
|
-
res
|
|
1400
|
-
res.end("SSR function not configured");
|
|
1401
|
-
return;
|
|
3604
|
+
return send500(res, "SSR function not configured");
|
|
1402
3605
|
}
|
|
1403
3606
|
const result = client.ssr();
|
|
1404
3607
|
let html;
|
|
@@ -1414,24 +3617,30 @@ ${error}`);
|
|
|
1414
3617
|
} else {
|
|
1415
3618
|
html = String(result);
|
|
1416
3619
|
}
|
|
1417
|
-
const
|
|
3620
|
+
const basePath = normalizeBasePath(client.basePath);
|
|
3621
|
+
html = rewriteRelativePaths(html, basePath);
|
|
3622
|
+
const hmrScript = createHMRScript(config.port, basePath);
|
|
3623
|
+
const elitImportMap = createElitImportMap(basePath, client.mode);
|
|
3624
|
+
html = html.includes("</head>") ? html.replace("</head>", `${elitImportMap}</head>`) : html;
|
|
1418
3625
|
html = html.includes("</body>") ? html.replace("</body>", `${hmrScript}</body>`) : html + hmrScript;
|
|
1419
3626
|
res.writeHead(200, { "Content-Type": "text/html", "Cache-Control": "no-cache, no-store, must-revalidate" });
|
|
1420
3627
|
res.end(html);
|
|
1421
3628
|
if (config.logging) console.log(`[200] SSR rendered`);
|
|
1422
3629
|
} catch (error) {
|
|
1423
|
-
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
1424
|
-
res.end("500 SSR Error");
|
|
1425
3630
|
if (config.logging) console.error("[500] SSR Error:", error);
|
|
3631
|
+
send500(res, "500 SSR Error");
|
|
1426
3632
|
}
|
|
1427
3633
|
}
|
|
1428
|
-
const wss = new
|
|
1429
|
-
|
|
3634
|
+
const wss = new WebSocketServer({ server });
|
|
3635
|
+
if (config.logging) {
|
|
3636
|
+
console.log("[HMR] WebSocket server initialized");
|
|
3637
|
+
}
|
|
3638
|
+
wss.on("connection", (ws, req) => {
|
|
1430
3639
|
wsClients.add(ws);
|
|
1431
3640
|
const message = { type: "connected", timestamp: Date.now() };
|
|
1432
3641
|
ws.send(JSON.stringify(message));
|
|
1433
3642
|
if (config.logging) {
|
|
1434
|
-
console.log("[HMR] Client connected");
|
|
3643
|
+
console.log("[HMR] Client connected from", req.socket.remoteAddress);
|
|
1435
3644
|
}
|
|
1436
3645
|
ws.on("message", (data) => {
|
|
1437
3646
|
try {
|
|
@@ -1467,17 +3676,17 @@ ${error}`);
|
|
|
1467
3676
|
});
|
|
1468
3677
|
});
|
|
1469
3678
|
const watchPaths = normalizedClients.flatMap(
|
|
1470
|
-
(client) => config.watch.map((pattern) =>
|
|
3679
|
+
(client) => config.watch.map((pattern) => join(client.root, pattern))
|
|
1471
3680
|
);
|
|
1472
|
-
const watcher =
|
|
1473
|
-
ignored: config.ignore,
|
|
3681
|
+
const watcher = watch(watchPaths, {
|
|
3682
|
+
ignored: (path) => config.ignore.some((pattern) => path.includes(pattern.replace("/**", "").replace("**/", ""))),
|
|
1474
3683
|
ignoreInitial: true,
|
|
1475
3684
|
persistent: true
|
|
1476
3685
|
});
|
|
1477
3686
|
watcher.on("change", (path) => {
|
|
1478
3687
|
if (config.logging) console.log(`[HMR] File changed: ${path}`);
|
|
1479
3688
|
const message = JSON.stringify({ type: "update", path, timestamp: Date.now() });
|
|
1480
|
-
wsClients.forEach((client) => client.readyState ===
|
|
3689
|
+
wsClients.forEach((client) => client.readyState === 1 /* OPEN */ && client.send(message));
|
|
1481
3690
|
});
|
|
1482
3691
|
watcher.on("add", (path) => config.logging && console.log(`[HMR] File added: ${path}`));
|
|
1483
3692
|
watcher.on("unlink", (path) => config.logging && console.log(`[HMR] File removed: ${path}`));
|
|
@@ -1524,10 +3733,10 @@ ${error}`);
|
|
|
1524
3733
|
wss.close();
|
|
1525
3734
|
wsClients.forEach((client) => client.close());
|
|
1526
3735
|
wsClients.clear();
|
|
1527
|
-
return new Promise((
|
|
3736
|
+
return new Promise((resolve2) => {
|
|
1528
3737
|
server.close(() => {
|
|
1529
3738
|
if (config.logging) console.log("[Server] Closed");
|
|
1530
|
-
|
|
3739
|
+
resolve2();
|
|
1531
3740
|
});
|
|
1532
3741
|
});
|
|
1533
3742
|
};
|
|
@@ -1543,9 +3752,47 @@ ${error}`);
|
|
|
1543
3752
|
}
|
|
1544
3753
|
|
|
1545
3754
|
// src/build.ts
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
3755
|
+
init_fs();
|
|
3756
|
+
init_path();
|
|
3757
|
+
init_runtime();
|
|
3758
|
+
function ensureDir(dirPath) {
|
|
3759
|
+
try {
|
|
3760
|
+
mkdirSync(dirPath, { recursive: true });
|
|
3761
|
+
} catch (error) {
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
function calculateBuildMetrics(startTime, outputPath) {
|
|
3765
|
+
const buildTime = Date.now() - startTime;
|
|
3766
|
+
const stats = statSync(outputPath);
|
|
3767
|
+
return { buildTime, size: stats.size };
|
|
3768
|
+
}
|
|
3769
|
+
function readFileAsString2(filePath) {
|
|
3770
|
+
const contentBuffer = readFileSync(filePath, "utf-8");
|
|
3771
|
+
return typeof contentBuffer === "string" ? contentBuffer : contentBuffer.toString("utf-8");
|
|
3772
|
+
}
|
|
3773
|
+
function getMinifyOptions(minify) {
|
|
3774
|
+
return minify ? {
|
|
3775
|
+
minifyWhitespace: true,
|
|
3776
|
+
minifyIdentifiers: true,
|
|
3777
|
+
minifySyntax: true,
|
|
3778
|
+
legalComments: "none",
|
|
3779
|
+
mangleProps: /^_/,
|
|
3780
|
+
keepNames: false
|
|
3781
|
+
} : {};
|
|
3782
|
+
}
|
|
3783
|
+
function logBuildInfo(config, outputPath) {
|
|
3784
|
+
console.log("\n\u{1F528} Building...");
|
|
3785
|
+
console.log(` Entry: ${config.entry}`);
|
|
3786
|
+
console.log(` Output: ${outputPath}`);
|
|
3787
|
+
console.log(` Format: ${config.format}`);
|
|
3788
|
+
console.log(` Target: ${config.target}`);
|
|
3789
|
+
}
|
|
3790
|
+
function logBuildSuccess(buildTime, size) {
|
|
3791
|
+
console.log(`
|
|
3792
|
+
\u2705 Build successful!`);
|
|
3793
|
+
console.log(` Time: ${buildTime}ms`);
|
|
3794
|
+
console.log(` Size: ${formatBytes(size)}`);
|
|
3795
|
+
}
|
|
1549
3796
|
var defaultOptions2 = {
|
|
1550
3797
|
outDir: "dist",
|
|
1551
3798
|
minify: true,
|
|
@@ -1556,42 +3803,35 @@ var defaultOptions2 = {
|
|
|
1556
3803
|
logging: true,
|
|
1557
3804
|
external: []
|
|
1558
3805
|
};
|
|
1559
|
-
async function
|
|
3806
|
+
async function build(options) {
|
|
1560
3807
|
const config = { ...defaultOptions2, ...options };
|
|
1561
3808
|
const startTime = Date.now();
|
|
1562
3809
|
if (!config.entry) {
|
|
1563
3810
|
throw new Error("Entry file is required");
|
|
1564
3811
|
}
|
|
1565
|
-
const entryPath =
|
|
1566
|
-
const outDir =
|
|
3812
|
+
const entryPath = resolve(config.entry);
|
|
3813
|
+
const outDir = resolve(config.outDir);
|
|
1567
3814
|
let outFile = config.outFile;
|
|
1568
3815
|
if (!outFile) {
|
|
1569
|
-
const baseName =
|
|
3816
|
+
const baseName = basename(config.entry, extname(config.entry));
|
|
1570
3817
|
const ext = config.format === "cjs" ? ".cjs" : ".js";
|
|
1571
3818
|
outFile = baseName + ext;
|
|
1572
3819
|
}
|
|
1573
|
-
const outputPath =
|
|
1574
|
-
|
|
1575
|
-
(0, import_fs2.mkdirSync)(outDir, { recursive: true });
|
|
1576
|
-
} catch (error) {
|
|
1577
|
-
}
|
|
3820
|
+
const outputPath = join(outDir, outFile);
|
|
3821
|
+
ensureDir(outDir);
|
|
1578
3822
|
if (config.logging) {
|
|
1579
|
-
|
|
1580
|
-
console.log(` Entry: ${config.entry}`);
|
|
1581
|
-
console.log(` Output: ${outputPath}`);
|
|
1582
|
-
console.log(` Format: ${config.format}`);
|
|
1583
|
-
console.log(` Target: ${config.target}`);
|
|
3823
|
+
logBuildInfo(config, outputPath);
|
|
1584
3824
|
}
|
|
1585
3825
|
const browserOnlyPlugin = {
|
|
1586
3826
|
name: "browser-only",
|
|
1587
|
-
setup(
|
|
1588
|
-
|
|
3827
|
+
setup(build2) {
|
|
3828
|
+
build2.onResolve({ filter: /^(node:.*|fs|path|http|https|url|os|child_process|net|tls|crypto|stream|util|events|buffer|zlib|readline|process|assert|constants|dns|domain|punycode|querystring|repl|string_decoder|sys|timers|tty|v8|vm)$/ }, () => {
|
|
1589
3829
|
return { path: "node-builtin", external: true, sideEffects: false };
|
|
1590
3830
|
});
|
|
1591
|
-
|
|
3831
|
+
build2.onResolve({ filter: /^(chokidar|esbuild|mime-types|open|ws|fs\/promises)$/ }, () => {
|
|
1592
3832
|
return { path: "server-dep", external: true, sideEffects: false };
|
|
1593
3833
|
});
|
|
1594
|
-
|
|
3834
|
+
build2.onLoad({ filter: /[\\/](server|config|cli)\.ts$/ }, () => {
|
|
1595
3835
|
return {
|
|
1596
3836
|
contents: "export {}",
|
|
1597
3837
|
loader: "js"
|
|
@@ -1615,54 +3855,83 @@ async function build2(options) {
|
|
|
1615
3855
|
define["import.meta.env.DEV"] = JSON.stringify(config.env.MODE !== "production");
|
|
1616
3856
|
define["import.meta.env.PROD"] = JSON.stringify(config.env.MODE === "production");
|
|
1617
3857
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
3858
|
+
let result;
|
|
3859
|
+
let buildTime;
|
|
3860
|
+
let size;
|
|
3861
|
+
if (runtime === "node") {
|
|
3862
|
+
const { build: esbuild } = await import("esbuild");
|
|
3863
|
+
result = await esbuild({
|
|
3864
|
+
entryPoints: [entryPath],
|
|
3865
|
+
bundle: true,
|
|
3866
|
+
outfile: outputPath,
|
|
3867
|
+
format: config.format,
|
|
3868
|
+
target: config.target,
|
|
3869
|
+
minify: config.minify,
|
|
3870
|
+
sourcemap: config.sourcemap,
|
|
3871
|
+
external: config.external,
|
|
3872
|
+
treeShaking: config.treeshake,
|
|
3873
|
+
globalName: config.globalName,
|
|
3874
|
+
platform,
|
|
3875
|
+
plugins,
|
|
3876
|
+
define,
|
|
3877
|
+
logLevel: config.logging ? "info" : "silent",
|
|
3878
|
+
metafile: true,
|
|
3879
|
+
// Additional optimizations
|
|
3880
|
+
...getMinifyOptions(config.minify)
|
|
3881
|
+
});
|
|
3882
|
+
({ buildTime, size } = calculateBuildMetrics(startTime, outputPath));
|
|
3883
|
+
} else if (runtime === "bun") {
|
|
3884
|
+
result = await Bun.build({
|
|
3885
|
+
entrypoints: [entryPath],
|
|
3886
|
+
outdir: outDir,
|
|
3887
|
+
target: "bun",
|
|
3888
|
+
format: config.format === "cjs" ? "cjs" : "esm",
|
|
3889
|
+
minify: config.minify,
|
|
3890
|
+
sourcemap: config.sourcemap ? "external" : "none",
|
|
3891
|
+
external: config.external,
|
|
3892
|
+
naming: outFile,
|
|
3893
|
+
define
|
|
3894
|
+
});
|
|
3895
|
+
if (!result.success) {
|
|
3896
|
+
throw new Error("Bun build failed: " + JSON.stringify(result.logs));
|
|
1643
3897
|
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
3898
|
+
({ buildTime, size } = calculateBuildMetrics(startTime, outputPath));
|
|
3899
|
+
} else {
|
|
3900
|
+
result = await Deno.emit(entryPath, {
|
|
3901
|
+
bundle: "module",
|
|
3902
|
+
check: false,
|
|
3903
|
+
compilerOptions: {
|
|
3904
|
+
target: config.target,
|
|
3905
|
+
module: config.format === "cjs" ? "commonjs" : "esnext",
|
|
3906
|
+
sourceMap: config.sourcemap
|
|
3907
|
+
}
|
|
3908
|
+
});
|
|
3909
|
+
const bundledCode = result.files["deno:///bundle.js"];
|
|
3910
|
+
if (bundledCode) {
|
|
3911
|
+
await Deno.writeTextFile(outputPath, bundledCode);
|
|
3912
|
+
}
|
|
3913
|
+
({ buildTime, size } = calculateBuildMetrics(startTime, outputPath));
|
|
3914
|
+
}
|
|
1648
3915
|
if (config.logging) {
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
console.log(` Time: ${buildTime}ms`);
|
|
1652
|
-
console.log(` Size: ${formatBytes(size)}`);
|
|
1653
|
-
if (result.metafile) {
|
|
3916
|
+
logBuildSuccess(buildTime, size);
|
|
3917
|
+
if (runtime === "node" && result.metafile) {
|
|
1654
3918
|
const inputs = Object.keys(result.metafile.inputs).length;
|
|
1655
3919
|
console.log(` Files: ${inputs} input(s)`);
|
|
1656
3920
|
const outputKeys = Object.keys(result.metafile.outputs);
|
|
1657
3921
|
if (outputKeys.length > 0) {
|
|
1658
3922
|
const mainOutput = result.metafile.outputs[outputKeys[0]];
|
|
1659
3923
|
if (mainOutput && mainOutput.inputs) {
|
|
1660
|
-
const sortedInputs = Object.entries(mainOutput.inputs).sort(([, a], [, b]) =>
|
|
3924
|
+
const sortedInputs = Object.entries(mainOutput.inputs).sort(([, a], [, b]) => {
|
|
3925
|
+
const aBytes = a.bytesInOutput || 0;
|
|
3926
|
+
const bBytes = b.bytesInOutput || 0;
|
|
3927
|
+
return bBytes - aBytes;
|
|
3928
|
+
}).slice(0, 5);
|
|
1661
3929
|
if (sortedInputs.length > 0) {
|
|
1662
3930
|
console.log("\n \u{1F4CA} Top 5 largest modules:");
|
|
1663
3931
|
sortedInputs.forEach(([file, info]) => {
|
|
1664
3932
|
const fileName = file.split(/[/\\]/).pop() || file;
|
|
1665
|
-
|
|
3933
|
+
const infoBytes = info.bytesInOutput || 0;
|
|
3934
|
+
console.log(` ${fileName.padEnd(30)} ${formatBytes(infoBytes)}`);
|
|
1666
3935
|
});
|
|
1667
3936
|
}
|
|
1668
3937
|
}
|
|
@@ -1679,19 +3948,19 @@ async function build2(options) {
|
|
|
1679
3948
|
console.log("\n\u{1F4E6} Copying files...");
|
|
1680
3949
|
}
|
|
1681
3950
|
for (const copyItem of config.copy) {
|
|
1682
|
-
const fromPath =
|
|
1683
|
-
const toPath =
|
|
1684
|
-
const targetDir =
|
|
1685
|
-
if (!
|
|
1686
|
-
(
|
|
3951
|
+
const fromPath = resolve(copyItem.from);
|
|
3952
|
+
const toPath = resolve(outDir, copyItem.to);
|
|
3953
|
+
const targetDir = dirname(toPath);
|
|
3954
|
+
if (!existsSync(targetDir)) {
|
|
3955
|
+
ensureDir(targetDir);
|
|
1687
3956
|
}
|
|
1688
|
-
if (
|
|
3957
|
+
if (existsSync(fromPath)) {
|
|
1689
3958
|
if (copyItem.transform) {
|
|
1690
|
-
const content = (
|
|
3959
|
+
const content = readFileAsString2(fromPath);
|
|
1691
3960
|
const transformed = copyItem.transform(content, config);
|
|
1692
|
-
|
|
3961
|
+
writeFileSync(toPath, transformed);
|
|
1693
3962
|
} else {
|
|
1694
|
-
|
|
3963
|
+
copyFileSync(fromPath, toPath);
|
|
1695
3964
|
}
|
|
1696
3965
|
if (config.logging) {
|
|
1697
3966
|
console.log(` \u2713 ${copyItem.from} \u2192 ${copyItem.to}`);
|
|
@@ -1726,6 +3995,50 @@ function formatBytes(bytes) {
|
|
|
1726
3995
|
|
|
1727
3996
|
// src/cli.ts
|
|
1728
3997
|
var COMMANDS = ["dev", "build", "preview", "help", "version"];
|
|
3998
|
+
function setupShutdownHandlers(closeFunc) {
|
|
3999
|
+
const shutdown = async () => {
|
|
4000
|
+
console.log("\n[Server] Shutting down...");
|
|
4001
|
+
await closeFunc();
|
|
4002
|
+
process.exit(0);
|
|
4003
|
+
};
|
|
4004
|
+
process.on("SIGINT", shutdown);
|
|
4005
|
+
process.on("SIGTERM", shutdown);
|
|
4006
|
+
}
|
|
4007
|
+
async function executeBuild(options) {
|
|
4008
|
+
try {
|
|
4009
|
+
await build(options);
|
|
4010
|
+
} catch (error) {
|
|
4011
|
+
process.exit(1);
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
function validateEntry(entry, buildIndex) {
|
|
4015
|
+
if (!entry) {
|
|
4016
|
+
if (buildIndex !== void 0) {
|
|
4017
|
+
console.error(`Error: Entry file is required for build #${buildIndex + 1}`);
|
|
4018
|
+
} else {
|
|
4019
|
+
console.error("Error: Entry file is required");
|
|
4020
|
+
console.error("Specify in config file or use --entry <file>");
|
|
4021
|
+
}
|
|
4022
|
+
process.exit(1);
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
function ensureEnv(options, env) {
|
|
4026
|
+
if (!options.env) {
|
|
4027
|
+
options.env = env;
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
function parseArgs(args, handlers, options) {
|
|
4031
|
+
for (let i = 0; i < args.length; i++) {
|
|
4032
|
+
const arg = args[i];
|
|
4033
|
+
const handler = handlers[arg];
|
|
4034
|
+
if (handler) {
|
|
4035
|
+
const index = { current: i };
|
|
4036
|
+
handler(options, args[i + 1], index);
|
|
4037
|
+
i = index.current;
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4040
|
+
return options;
|
|
4041
|
+
}
|
|
1729
4042
|
async function main() {
|
|
1730
4043
|
const args = process.argv.slice(2);
|
|
1731
4044
|
const command = args[0] || "help";
|
|
@@ -1760,14 +4073,9 @@ async function runDev(args) {
|
|
|
1760
4073
|
if (!options.root && (!options.clients || options.clients.length === 0)) {
|
|
1761
4074
|
options.root = process.cwd();
|
|
1762
4075
|
}
|
|
4076
|
+
options.mode = "dev";
|
|
1763
4077
|
const devServer = createDevServer(options);
|
|
1764
|
-
|
|
1765
|
-
console.log("\n[Server] Shutting down...");
|
|
1766
|
-
await devServer.close();
|
|
1767
|
-
process.exit(0);
|
|
1768
|
-
};
|
|
1769
|
-
process.on("SIGINT", shutdown);
|
|
1770
|
-
process.on("SIGTERM", shutdown);
|
|
4078
|
+
setupShutdownHandlers(() => devServer.close());
|
|
1771
4079
|
}
|
|
1772
4080
|
async function runBuild(args) {
|
|
1773
4081
|
const cliOptions = parseBuildArgs(args);
|
|
@@ -1778,34 +4086,19 @@ async function runBuild(args) {
|
|
|
1778
4086
|
const builds = Array.isArray(config.build) ? config.build : [config.build];
|
|
1779
4087
|
if (Object.keys(cliOptions).length > 0) {
|
|
1780
4088
|
const options = mergeConfig(builds[0] || {}, cliOptions);
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
if (!options.entry) {
|
|
1785
|
-
console.error("Error: Entry file is required");
|
|
1786
|
-
console.error("Specify in config file or use --entry <file>");
|
|
1787
|
-
process.exit(1);
|
|
1788
|
-
}
|
|
1789
|
-
try {
|
|
1790
|
-
await build2(options);
|
|
1791
|
-
} catch (error) {
|
|
1792
|
-
process.exit(1);
|
|
1793
|
-
}
|
|
4089
|
+
ensureEnv(options, env);
|
|
4090
|
+
validateEntry(options.entry);
|
|
4091
|
+
await executeBuild(options);
|
|
1794
4092
|
} else {
|
|
1795
4093
|
console.log(`Building ${builds.length} ${builds.length === 1 ? "entry" : "entries"}...
|
|
1796
4094
|
`);
|
|
1797
4095
|
for (let i = 0; i < builds.length; i++) {
|
|
1798
4096
|
const buildConfig = builds[i];
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
}
|
|
1802
|
-
if (!buildConfig.entry) {
|
|
1803
|
-
console.error(`Error: Entry file is required for build #${i + 1}`);
|
|
1804
|
-
process.exit(1);
|
|
1805
|
-
}
|
|
4097
|
+
ensureEnv(buildConfig, env);
|
|
4098
|
+
validateEntry(buildConfig.entry, i);
|
|
1806
4099
|
console.log(`[${i + 1}/${builds.length}] Building ${buildConfig.entry}...`);
|
|
1807
4100
|
try {
|
|
1808
|
-
await
|
|
4101
|
+
await build(buildConfig);
|
|
1809
4102
|
} catch (error) {
|
|
1810
4103
|
console.error(`Build #${i + 1} failed`);
|
|
1811
4104
|
process.exit(1);
|
|
@@ -1819,19 +4112,9 @@ async function runBuild(args) {
|
|
|
1819
4112
|
}
|
|
1820
4113
|
} else {
|
|
1821
4114
|
const options = cliOptions;
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
if (!options.entry) {
|
|
1826
|
-
console.error("Error: Entry file is required");
|
|
1827
|
-
console.error("Specify in config file or use --entry <file>");
|
|
1828
|
-
process.exit(1);
|
|
1829
|
-
}
|
|
1830
|
-
try {
|
|
1831
|
-
await build2(options);
|
|
1832
|
-
} catch (error) {
|
|
1833
|
-
process.exit(1);
|
|
1834
|
-
}
|
|
4115
|
+
ensureEnv(options, env);
|
|
4116
|
+
validateEntry(options.entry);
|
|
4117
|
+
await executeBuild(options);
|
|
1835
4118
|
}
|
|
1836
4119
|
}
|
|
1837
4120
|
async function runPreview(args) {
|
|
@@ -1862,6 +4145,7 @@ async function runPreview(args) {
|
|
|
1862
4145
|
const defaultOutDir = Array.isArray(buildConfig) ? buildConfig[0]?.outDir : buildConfig?.outDir;
|
|
1863
4146
|
options.root = mergedOptions.root || defaultOutDir || "dist";
|
|
1864
4147
|
options.basePath = mergedOptions.basePath;
|
|
4148
|
+
options.index = mergedOptions.index;
|
|
1865
4149
|
console.log("Starting preview server...");
|
|
1866
4150
|
console.log(` Root: ${options.root}`);
|
|
1867
4151
|
}
|
|
@@ -1883,115 +4167,128 @@ async function runPreview(args) {
|
|
|
1883
4167
|
if (mergedOptions.ssr) {
|
|
1884
4168
|
options.ssr = mergedOptions.ssr;
|
|
1885
4169
|
}
|
|
4170
|
+
options.mode = "preview";
|
|
1886
4171
|
const devServer = createDevServer(options);
|
|
1887
|
-
|
|
1888
|
-
console.log("\n[Server] Shutting down...");
|
|
1889
|
-
await devServer.close();
|
|
1890
|
-
process.exit(0);
|
|
1891
|
-
};
|
|
1892
|
-
process.on("SIGINT", shutdown);
|
|
1893
|
-
process.on("SIGTERM", shutdown);
|
|
4172
|
+
setupShutdownHandlers(() => devServer.close());
|
|
1894
4173
|
}
|
|
1895
4174
|
function parseDevArgs(args) {
|
|
1896
4175
|
const options = {};
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
4176
|
+
const handlers = {
|
|
4177
|
+
"-p": (opts, value, index) => {
|
|
4178
|
+
opts.port = parseInt(value, 10);
|
|
4179
|
+
index.current++;
|
|
4180
|
+
},
|
|
4181
|
+
"--port": (opts, value, index) => {
|
|
4182
|
+
opts.port = parseInt(value, 10);
|
|
4183
|
+
index.current++;
|
|
4184
|
+
},
|
|
4185
|
+
"-h": (opts, value, index) => {
|
|
4186
|
+
opts.host = value;
|
|
4187
|
+
index.current++;
|
|
4188
|
+
},
|
|
4189
|
+
"--host": (opts, value, index) => {
|
|
4190
|
+
opts.host = value;
|
|
4191
|
+
index.current++;
|
|
4192
|
+
},
|
|
4193
|
+
"-r": (opts, value, index) => {
|
|
4194
|
+
opts.root = value;
|
|
4195
|
+
index.current++;
|
|
4196
|
+
},
|
|
4197
|
+
"--root": (opts, value, index) => {
|
|
4198
|
+
opts.root = value;
|
|
4199
|
+
index.current++;
|
|
4200
|
+
},
|
|
4201
|
+
"--no-open": (opts) => {
|
|
4202
|
+
opts.open = false;
|
|
4203
|
+
},
|
|
4204
|
+
"--silent": (opts) => {
|
|
4205
|
+
opts.logging = false;
|
|
1922
4206
|
}
|
|
1923
|
-
}
|
|
1924
|
-
return options;
|
|
4207
|
+
};
|
|
4208
|
+
return parseArgs(args, handlers, options);
|
|
1925
4209
|
}
|
|
1926
4210
|
function parseBuildArgs(args) {
|
|
1927
4211
|
const options = {};
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
4212
|
+
const handlers = {
|
|
4213
|
+
"-e": (opts, value, index) => {
|
|
4214
|
+
opts.entry = value;
|
|
4215
|
+
index.current++;
|
|
4216
|
+
},
|
|
4217
|
+
"--entry": (opts, value, index) => {
|
|
4218
|
+
opts.entry = value;
|
|
4219
|
+
index.current++;
|
|
4220
|
+
},
|
|
4221
|
+
"-o": (opts, value, index) => {
|
|
4222
|
+
opts.outDir = value;
|
|
4223
|
+
index.current++;
|
|
4224
|
+
},
|
|
4225
|
+
"--out-dir": (opts, value, index) => {
|
|
4226
|
+
opts.outDir = value;
|
|
4227
|
+
index.current++;
|
|
4228
|
+
},
|
|
4229
|
+
"--no-minify": (opts) => {
|
|
4230
|
+
opts.minify = false;
|
|
4231
|
+
},
|
|
4232
|
+
"--sourcemap": (opts) => {
|
|
4233
|
+
opts.sourcemap = true;
|
|
4234
|
+
},
|
|
4235
|
+
"-f": (opts, value, index) => {
|
|
4236
|
+
opts.format = value;
|
|
4237
|
+
index.current++;
|
|
4238
|
+
},
|
|
4239
|
+
"--format": (opts, value, index) => {
|
|
4240
|
+
opts.format = value;
|
|
4241
|
+
index.current++;
|
|
4242
|
+
},
|
|
4243
|
+
"--silent": (opts) => {
|
|
4244
|
+
opts.logging = false;
|
|
1956
4245
|
}
|
|
1957
|
-
}
|
|
1958
|
-
return options;
|
|
4246
|
+
};
|
|
4247
|
+
return parseArgs(args, handlers, options);
|
|
1959
4248
|
}
|
|
1960
4249
|
function parsePreviewArgs(args) {
|
|
1961
4250
|
const options = {};
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
4251
|
+
const handlers = {
|
|
4252
|
+
"-p": (opts, value, index) => {
|
|
4253
|
+
opts.port = parseInt(value, 10);
|
|
4254
|
+
index.current++;
|
|
4255
|
+
},
|
|
4256
|
+
"--port": (opts, value, index) => {
|
|
4257
|
+
opts.port = parseInt(value, 10);
|
|
4258
|
+
index.current++;
|
|
4259
|
+
},
|
|
4260
|
+
"-h": (opts, value, index) => {
|
|
4261
|
+
opts.host = value;
|
|
4262
|
+
index.current++;
|
|
4263
|
+
},
|
|
4264
|
+
"--host": (opts, value, index) => {
|
|
4265
|
+
opts.host = value;
|
|
4266
|
+
index.current++;
|
|
4267
|
+
},
|
|
4268
|
+
"-r": (opts, value, index) => {
|
|
4269
|
+
opts.root = value;
|
|
4270
|
+
index.current++;
|
|
4271
|
+
},
|
|
4272
|
+
"--root": (opts, value, index) => {
|
|
4273
|
+
opts.root = value;
|
|
4274
|
+
index.current++;
|
|
4275
|
+
},
|
|
4276
|
+
"-b": (opts, value, index) => {
|
|
4277
|
+
opts.basePath = value;
|
|
4278
|
+
index.current++;
|
|
4279
|
+
},
|
|
4280
|
+
"--base-path": (opts, value, index) => {
|
|
4281
|
+
opts.basePath = value;
|
|
4282
|
+
index.current++;
|
|
4283
|
+
},
|
|
4284
|
+
"--no-open": (opts) => {
|
|
4285
|
+
opts.open = false;
|
|
4286
|
+
},
|
|
4287
|
+
"--silent": (opts) => {
|
|
4288
|
+
opts.logging = false;
|
|
1992
4289
|
}
|
|
1993
|
-
}
|
|
1994
|
-
return options;
|
|
4290
|
+
};
|
|
4291
|
+
return parseArgs(args, handlers, options);
|
|
1995
4292
|
}
|
|
1996
4293
|
function printHelp() {
|
|
1997
4294
|
console.log(`
|