@geektech/tsone-cli 0.2.1 → 0.3.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 +16 -6
- package/dist/cli.d.ts +4 -1
- package/dist/cli.js +14 -4
- package/dist/cli.js.map +3 -3
- package/dist/create.d.ts +16 -0
- package/dist/index-r68229k4.js +2978 -0
- package/dist/index-r68229k4.js.map +19 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/index-8cbw0a0y.js +0 -3258
- package/dist/index-8cbw0a0y.js.map +0 -18
|
@@ -0,0 +1,2978 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/config.ts
|
|
3
|
+
import { existsSync } from "fs";
|
|
4
|
+
import { resolve } from "path";
|
|
5
|
+
var DEFAULT_CONFIG = {
|
|
6
|
+
entry: "src/main.ts",
|
|
7
|
+
server: {
|
|
8
|
+
host: "127.0.0.1",
|
|
9
|
+
port: 52211,
|
|
10
|
+
proxy: {}
|
|
11
|
+
},
|
|
12
|
+
build: {
|
|
13
|
+
outDir: "dist"
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function defineConfig(config) {
|
|
17
|
+
return config;
|
|
18
|
+
}
|
|
19
|
+
async function resolveConfig(options = {}) {
|
|
20
|
+
const root = resolve(options.root ?? process.cwd());
|
|
21
|
+
const configFile = resolve(root, "tsone.config.ts");
|
|
22
|
+
const hasInlineConfig = options.config !== undefined;
|
|
23
|
+
const loadedConfig = hasInlineConfig ? { exists: false } : await loadConfigFile(configFile);
|
|
24
|
+
let fileConfig = {};
|
|
25
|
+
if (loadedConfig.exists) {
|
|
26
|
+
const config2 = loadedConfig.config;
|
|
27
|
+
validateUserConfig(config2);
|
|
28
|
+
fileConfig = config2;
|
|
29
|
+
}
|
|
30
|
+
if (hasInlineConfig) {
|
|
31
|
+
validateUserConfig(options.config);
|
|
32
|
+
}
|
|
33
|
+
const inlineOverrides = toInlineOverrides(options);
|
|
34
|
+
validateUserConfig(inlineOverrides);
|
|
35
|
+
const config = mergeConfig(fileConfig, options.config ?? {}, inlineOverrides);
|
|
36
|
+
const entry = resolve(root, config.entry);
|
|
37
|
+
if (!existsSync(entry)) {
|
|
38
|
+
throw new Error(`Entry file does not exist: ${entry}`);
|
|
39
|
+
}
|
|
40
|
+
const pages = await resolvePages(root, entry, config.pages);
|
|
41
|
+
return {
|
|
42
|
+
root,
|
|
43
|
+
...loadedConfig.exists ? { configFile } : {},
|
|
44
|
+
entry,
|
|
45
|
+
pages,
|
|
46
|
+
server: {
|
|
47
|
+
host: config.server.host,
|
|
48
|
+
port: config.server.port,
|
|
49
|
+
proxy: config.server.proxy
|
|
50
|
+
},
|
|
51
|
+
build: {
|
|
52
|
+
outDir: resolve(root, config.build.outDir)
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async function resolvePages(root, entry, pages) {
|
|
57
|
+
const resolved = { "/": entry };
|
|
58
|
+
for (const [route, pageEntry] of Object.entries(pages ?? {})) {
|
|
59
|
+
const normalized = normalizePageRoute(route);
|
|
60
|
+
const absolute = resolve(root, pageEntry);
|
|
61
|
+
if (!existsSync(absolute)) {
|
|
62
|
+
throw new Error(`Page entry file does not exist for "${normalized}": ${absolute}`);
|
|
63
|
+
}
|
|
64
|
+
resolved[normalized] = absolute;
|
|
65
|
+
}
|
|
66
|
+
return resolved;
|
|
67
|
+
}
|
|
68
|
+
function normalizePageRoute(route) {
|
|
69
|
+
if (route === "/") {
|
|
70
|
+
throw new Error('Config pages must not redefine the root page "/"; use config.entry instead');
|
|
71
|
+
}
|
|
72
|
+
const normalized = route.replace(/\/+$/, "");
|
|
73
|
+
if (normalized === "") {
|
|
74
|
+
throw new Error(`Page route must not be empty: ${route}`);
|
|
75
|
+
}
|
|
76
|
+
return normalized;
|
|
77
|
+
}
|
|
78
|
+
var configLoadSequence = 0;
|
|
79
|
+
async function loadConfigFile(configFile) {
|
|
80
|
+
if (!existsSync(configFile)) {
|
|
81
|
+
return { exists: false };
|
|
82
|
+
}
|
|
83
|
+
configLoadSequence += 1;
|
|
84
|
+
const module = await import(`${configFile}?tsone_config=${configLoadSequence}`);
|
|
85
|
+
return { exists: true, config: module.default };
|
|
86
|
+
}
|
|
87
|
+
function toInlineOverrides(options) {
|
|
88
|
+
const server = {};
|
|
89
|
+
const build = {};
|
|
90
|
+
if (options.host !== undefined) {
|
|
91
|
+
server.host = options.host;
|
|
92
|
+
}
|
|
93
|
+
if (options.port !== undefined) {
|
|
94
|
+
server.port = options.port;
|
|
95
|
+
}
|
|
96
|
+
if (options.outDir !== undefined) {
|
|
97
|
+
build.outDir = options.outDir;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
...Object.keys(server).length > 0 ? { server } : {},
|
|
101
|
+
...Object.keys(build).length > 0 ? { build } : {}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function mergeConfig(...configs) {
|
|
105
|
+
return configs.reduce((merged, config) => {
|
|
106
|
+
const server = config.server;
|
|
107
|
+
const build = config.build;
|
|
108
|
+
return {
|
|
109
|
+
entry: config.entry ?? merged.entry,
|
|
110
|
+
pages: config.pages ?? merged.pages,
|
|
111
|
+
server: {
|
|
112
|
+
host: server?.host ?? merged.server.host,
|
|
113
|
+
port: server?.port ?? merged.server.port,
|
|
114
|
+
proxy: {
|
|
115
|
+
...merged.server.proxy,
|
|
116
|
+
...server?.proxy
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
build: {
|
|
120
|
+
outDir: build?.outDir ?? merged.build.outDir
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}, DEFAULT_CONFIG);
|
|
124
|
+
}
|
|
125
|
+
function validateUserConfig(config) {
|
|
126
|
+
assertRecord(config, "Config");
|
|
127
|
+
if (config.entry !== undefined && typeof config.entry !== "string") {
|
|
128
|
+
throw new Error("Config entry must be a string");
|
|
129
|
+
}
|
|
130
|
+
if (config.pages !== undefined) {
|
|
131
|
+
validatePagesConfig(config.pages);
|
|
132
|
+
}
|
|
133
|
+
if (config.server !== undefined) {
|
|
134
|
+
validateServerConfig(config.server);
|
|
135
|
+
}
|
|
136
|
+
if (config.build !== undefined) {
|
|
137
|
+
validateBuildConfig(config.build);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function validatePagesConfig(pages) {
|
|
141
|
+
assertRecord(pages, "Config pages");
|
|
142
|
+
for (const [route, entry] of Object.entries(pages)) {
|
|
143
|
+
if (!route.startsWith("/")) {
|
|
144
|
+
throw new Error(`Page route must start with "/": ${route}`);
|
|
145
|
+
}
|
|
146
|
+
if (typeof entry !== "string") {
|
|
147
|
+
throw new Error(`Page entry for "${route}" must be a string`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function validateServerConfig(server) {
|
|
152
|
+
assertRecord(server, "Config server");
|
|
153
|
+
if (server.host !== undefined && typeof server.host !== "string") {
|
|
154
|
+
throw new Error("Config server.host must be a string");
|
|
155
|
+
}
|
|
156
|
+
const port = server.port;
|
|
157
|
+
if (port !== undefined && (typeof port !== "number" || !Number.isInteger(port) || port < 0 || port > 65535)) {
|
|
158
|
+
throw new Error("Config server.port must be an integer between 0 and 65535");
|
|
159
|
+
}
|
|
160
|
+
if (server.proxy === undefined) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
assertRecord(server.proxy, "Config server.proxy");
|
|
164
|
+
for (const [prefix, value] of Object.entries(server.proxy)) {
|
|
165
|
+
if (!prefix.startsWith("/")) {
|
|
166
|
+
throw new Error(`Proxy prefix must start with "/": ${prefix}`);
|
|
167
|
+
}
|
|
168
|
+
const target = getProxyTarget(value);
|
|
169
|
+
validateProxyTarget(target);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function validateBuildConfig(build) {
|
|
173
|
+
assertRecord(build, "Config build");
|
|
174
|
+
if (build.outDir !== undefined && typeof build.outDir !== "string") {
|
|
175
|
+
throw new Error("Config build.outDir must be a string");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function getProxyTarget(value) {
|
|
179
|
+
if (typeof value === "string") {
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
182
|
+
assertRecord(value, "Proxy options");
|
|
183
|
+
if (typeof value.target !== "string") {
|
|
184
|
+
throw new Error("Proxy target must be a string");
|
|
185
|
+
}
|
|
186
|
+
if (value.changeOrigin !== undefined && typeof value.changeOrigin !== "boolean") {
|
|
187
|
+
throw new Error("Proxy changeOrigin must be a boolean");
|
|
188
|
+
}
|
|
189
|
+
if (value.rewrite !== undefined && typeof value.rewrite !== "function") {
|
|
190
|
+
throw new Error("Proxy rewrite must be a function");
|
|
191
|
+
}
|
|
192
|
+
return value.target;
|
|
193
|
+
}
|
|
194
|
+
function validateProxyTarget(target) {
|
|
195
|
+
try {
|
|
196
|
+
const url = new URL(target);
|
|
197
|
+
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
} catch {}
|
|
201
|
+
throw new Error(`Proxy target must use http or https: ${target}`);
|
|
202
|
+
}
|
|
203
|
+
function assertRecord(value, name) {
|
|
204
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
|
|
205
|
+
throw new Error(`${name} must be an object`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/build.ts
|
|
210
|
+
import { mkdir, rm, writeFile } from "fs/promises";
|
|
211
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve3, sep as sep2 } from "path";
|
|
212
|
+
|
|
213
|
+
// src/build-output.ts
|
|
214
|
+
function isEntryJavaScriptOutput(output) {
|
|
215
|
+
return output.kind === "entry-point" && isJavaScriptPath(output.path);
|
|
216
|
+
}
|
|
217
|
+
function isStylesheetOutput(output) {
|
|
218
|
+
return /\.css$/i.test(output.path);
|
|
219
|
+
}
|
|
220
|
+
function isJavaScriptPath(path) {
|
|
221
|
+
return /\.(?:[cm]?js)$/i.test(path);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ../tsone/dist/dom/index.js
|
|
225
|
+
var ce;
|
|
226
|
+
((s) => {
|
|
227
|
+
s[s.ELEMENT_NODE = 1] = "ELEMENT_NODE";
|
|
228
|
+
s[s.TEXT_NODE = 3] = "TEXT_NODE";
|
|
229
|
+
s[s.COMMENT_NODE = 8] = "COMMENT_NODE";
|
|
230
|
+
s[s.DOCUMENT_NODE = 9] = "DOCUMENT_NODE";
|
|
231
|
+
s[s.DOCUMENT_FRAGMENT_NODE = 11] = "DOCUMENT_FRAGMENT_NODE";
|
|
232
|
+
})(ce ||= {});
|
|
233
|
+
|
|
234
|
+
class K extends Error {
|
|
235
|
+
code;
|
|
236
|
+
constructor(e, t = "Error") {
|
|
237
|
+
super(e);
|
|
238
|
+
this.name = t, this.code = 0;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
class A {
|
|
243
|
+
listenerMap = new Map;
|
|
244
|
+
addEventListener(e, t, n) {
|
|
245
|
+
if (!t)
|
|
246
|
+
return;
|
|
247
|
+
let i = typeof n === "boolean" ? n : n?.capture ?? false, r = typeof n === "object" ? n.once ?? false : false, s = typeof n === "object" ? n.passive ?? false : false, l = this.listenerMap.get(e);
|
|
248
|
+
if (!l)
|
|
249
|
+
l = [], this.listenerMap.set(e, l);
|
|
250
|
+
if (l.some((a) => a.listener === t && a.capture === i))
|
|
251
|
+
return;
|
|
252
|
+
l.push({ listener: t, capture: i, once: r, passive: s });
|
|
253
|
+
}
|
|
254
|
+
removeEventListener(e, t, n) {
|
|
255
|
+
if (!t)
|
|
256
|
+
return;
|
|
257
|
+
let i = typeof n === "boolean" ? n : n?.capture ?? false, r = this.listenerMap.get(e);
|
|
258
|
+
if (!r)
|
|
259
|
+
return;
|
|
260
|
+
let s = r.findIndex((l) => l.listener === t && l.capture === i);
|
|
261
|
+
if (s >= 0)
|
|
262
|
+
r.splice(s, 1);
|
|
263
|
+
if (r.length === 0)
|
|
264
|
+
this.listenerMap.delete(e);
|
|
265
|
+
}
|
|
266
|
+
dispatchEvent(e) {
|
|
267
|
+
if (!(e instanceof c))
|
|
268
|
+
throw TypeError("dispatchEvent requires an Event instance");
|
|
269
|
+
if (e.dispatched)
|
|
270
|
+
throw Error("Event has already been dispatched");
|
|
271
|
+
return pe(this, e);
|
|
272
|
+
}
|
|
273
|
+
getListeners(e) {
|
|
274
|
+
return this.listenerMap.get(e) ?? [];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
class c {
|
|
279
|
+
static NONE = 0;
|
|
280
|
+
static CAPTURING_PHASE = 1;
|
|
281
|
+
static AT_TARGET = 2;
|
|
282
|
+
static BUBBLING_PHASE = 3;
|
|
283
|
+
type;
|
|
284
|
+
bubbles;
|
|
285
|
+
cancelable;
|
|
286
|
+
composed;
|
|
287
|
+
target = null;
|
|
288
|
+
currentTarget = null;
|
|
289
|
+
eventPhase = c.NONE;
|
|
290
|
+
defaultPrevented = false;
|
|
291
|
+
isTrusted = false;
|
|
292
|
+
timeStamp;
|
|
293
|
+
cancelBubble = false;
|
|
294
|
+
dispatched = false;
|
|
295
|
+
propagationStopped = false;
|
|
296
|
+
immediateStopped = false;
|
|
297
|
+
canceled = false;
|
|
298
|
+
constructor(e, t) {
|
|
299
|
+
this.type = e, this.bubbles = t?.bubbles ?? false, this.cancelable = t?.cancelable ?? false, this.composed = t?.composed ?? false, this.timeStamp = Date.now();
|
|
300
|
+
}
|
|
301
|
+
preventDefault() {
|
|
302
|
+
if (this.cancelable)
|
|
303
|
+
this.canceled = true;
|
|
304
|
+
}
|
|
305
|
+
stopPropagation() {
|
|
306
|
+
this.propagationStopped = true, this.cancelBubble = true;
|
|
307
|
+
}
|
|
308
|
+
stopImmediatePropagation() {
|
|
309
|
+
this.propagationStopped = true, this.immediateStopped = true, this.cancelBubble = true;
|
|
310
|
+
}
|
|
311
|
+
propagationPrevented() {
|
|
312
|
+
return this.propagationStopped;
|
|
313
|
+
}
|
|
314
|
+
immediatePrevented() {
|
|
315
|
+
return this.immediateStopped;
|
|
316
|
+
}
|
|
317
|
+
wasCanceled() {
|
|
318
|
+
return this.canceled;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
class I extends c {
|
|
323
|
+
detail;
|
|
324
|
+
constructor(e, t) {
|
|
325
|
+
super(e, t);
|
|
326
|
+
this.detail = t?.detail;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
class O extends c {
|
|
331
|
+
clientX;
|
|
332
|
+
clientY;
|
|
333
|
+
button;
|
|
334
|
+
buttons;
|
|
335
|
+
relatedTarget;
|
|
336
|
+
constructor(e, t) {
|
|
337
|
+
super(e, t);
|
|
338
|
+
this.clientX = t?.clientX ?? 0, this.clientY = t?.clientY ?? 0, this.button = t?.button ?? 0, this.buttons = t?.buttons ?? 0, this.relatedTarget = t?.relatedTarget ?? null;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
class H extends c {
|
|
343
|
+
key;
|
|
344
|
+
code;
|
|
345
|
+
constructor(e, t) {
|
|
346
|
+
super(e, t);
|
|
347
|
+
this.key = t?.key ?? "", this.code = t?.code ?? "";
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function de(e, t) {
|
|
351
|
+
let n = e.listener;
|
|
352
|
+
if (typeof n === "function")
|
|
353
|
+
n.call(t.currentTarget, t);
|
|
354
|
+
else
|
|
355
|
+
n.handleEvent(t);
|
|
356
|
+
}
|
|
357
|
+
function pe(e, t) {
|
|
358
|
+
t.dispatched = true, t.target = e;
|
|
359
|
+
let i = [...he(e)].reverse(), r = i.length - 1;
|
|
360
|
+
t.eventPhase = c.CAPTURING_PHASE;
|
|
361
|
+
for (let s = 0;s < r; s += 1) {
|
|
362
|
+
let l = i[s];
|
|
363
|
+
if (t.propagationPrevented())
|
|
364
|
+
break;
|
|
365
|
+
t.currentTarget = l, x(l, t, true);
|
|
366
|
+
}
|
|
367
|
+
if (!t.propagationPrevented()) {
|
|
368
|
+
if (t.eventPhase = c.AT_TARGET, t.currentTarget = e, x(e, t, true), !t.immediatePrevented())
|
|
369
|
+
x(e, t, false);
|
|
370
|
+
}
|
|
371
|
+
if (t.bubbles && !t.propagationPrevented()) {
|
|
372
|
+
t.eventPhase = c.BUBBLING_PHASE;
|
|
373
|
+
for (let s = i.length - 2;s >= 0; s -= 1) {
|
|
374
|
+
let l = i[s];
|
|
375
|
+
if (t.propagationPrevented())
|
|
376
|
+
break;
|
|
377
|
+
t.currentTarget = l, x(l, t, false);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return t.eventPhase = c.NONE, t.currentTarget = null, !t.wasCanceled();
|
|
381
|
+
}
|
|
382
|
+
function x(e, t, n) {
|
|
383
|
+
let i = e.getListeners(t.type);
|
|
384
|
+
for (let r of [...i]) {
|
|
385
|
+
if (r.capture !== n)
|
|
386
|
+
continue;
|
|
387
|
+
if (t.immediatePrevented())
|
|
388
|
+
break;
|
|
389
|
+
if (r.once)
|
|
390
|
+
e.removeEventListener(t.type, r.listener, { capture: r.capture });
|
|
391
|
+
de(r, t);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
function he(e) {
|
|
395
|
+
let t = [], n = e;
|
|
396
|
+
while (n) {
|
|
397
|
+
t.push(n);
|
|
398
|
+
let i = n;
|
|
399
|
+
if (i.nodeType === 9) {
|
|
400
|
+
let s = i.defaultView;
|
|
401
|
+
if (s)
|
|
402
|
+
t.push(s);
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
let r = i.parentNode;
|
|
406
|
+
if (r) {
|
|
407
|
+
n = r;
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
return t;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
class X {
|
|
416
|
+
element;
|
|
417
|
+
attributeName;
|
|
418
|
+
constructor(e, t = "class") {
|
|
419
|
+
this.element = e, this.attributeName = t;
|
|
420
|
+
}
|
|
421
|
+
get length() {
|
|
422
|
+
return this.tokens().length;
|
|
423
|
+
}
|
|
424
|
+
get value() {
|
|
425
|
+
return this.element.getAttribute(this.attributeName) ?? "";
|
|
426
|
+
}
|
|
427
|
+
set value(e) {
|
|
428
|
+
this.setTokens(q(e));
|
|
429
|
+
}
|
|
430
|
+
item(e) {
|
|
431
|
+
return this.tokens()[e] ?? null;
|
|
432
|
+
}
|
|
433
|
+
contains(e) {
|
|
434
|
+
return this.tokens().includes(e);
|
|
435
|
+
}
|
|
436
|
+
add(...e) {
|
|
437
|
+
let t = new Set(this.tokens());
|
|
438
|
+
for (let n of e)
|
|
439
|
+
if (n)
|
|
440
|
+
t.add(n);
|
|
441
|
+
this.setTokens([...t]);
|
|
442
|
+
}
|
|
443
|
+
remove(...e) {
|
|
444
|
+
let t = new Set(this.tokens());
|
|
445
|
+
for (let n of e)
|
|
446
|
+
t.delete(n);
|
|
447
|
+
this.setTokens([...t]);
|
|
448
|
+
}
|
|
449
|
+
toggle(e, t) {
|
|
450
|
+
let n = new Set(this.tokens()), i = t ?? !n.has(e);
|
|
451
|
+
if (i)
|
|
452
|
+
n.add(e);
|
|
453
|
+
else
|
|
454
|
+
n.delete(e);
|
|
455
|
+
return this.setTokens([...n]), i;
|
|
456
|
+
}
|
|
457
|
+
replace(e, t) {
|
|
458
|
+
let n = this.tokens(), i = n.indexOf(e);
|
|
459
|
+
if (i < 0)
|
|
460
|
+
return false;
|
|
461
|
+
return n[i] = t, this.setTokens(n), true;
|
|
462
|
+
}
|
|
463
|
+
[Symbol.iterator]() {
|
|
464
|
+
return this.tokens()[Symbol.iterator]();
|
|
465
|
+
}
|
|
466
|
+
forEach(e) {
|
|
467
|
+
this.tokens().forEach((t, n) => e(t, n, this));
|
|
468
|
+
}
|
|
469
|
+
toString() {
|
|
470
|
+
return this.value;
|
|
471
|
+
}
|
|
472
|
+
tokens() {
|
|
473
|
+
return q(this.element.getAttribute(this.attributeName) ?? "");
|
|
474
|
+
}
|
|
475
|
+
setTokens(e) {
|
|
476
|
+
let t = e.filter(Boolean).join(" ");
|
|
477
|
+
if (t)
|
|
478
|
+
this.element.setAttribute(this.attributeName, t);
|
|
479
|
+
else
|
|
480
|
+
this.element.removeAttribute(this.attributeName);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
function q(e) {
|
|
484
|
+
return e.trim().split(/\s+/).filter(Boolean);
|
|
485
|
+
}
|
|
486
|
+
function L(e) {
|
|
487
|
+
return e.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`);
|
|
488
|
+
}
|
|
489
|
+
function R() {
|
|
490
|
+
let e = new Map, t = { properties: e, setProperty(i, r, s = "") {
|
|
491
|
+
let l = L(i);
|
|
492
|
+
if (r === "")
|
|
493
|
+
e.delete(l);
|
|
494
|
+
else
|
|
495
|
+
e.set(l, { value: r, priority: s });
|
|
496
|
+
}, getPropertyValue(i) {
|
|
497
|
+
return e.get(L(i))?.value ?? "";
|
|
498
|
+
}, getPropertyPriority(i) {
|
|
499
|
+
return e.get(L(i))?.priority ?? "";
|
|
500
|
+
}, removeProperty(i) {
|
|
501
|
+
let r = L(i), s = e.get(r)?.value ?? "";
|
|
502
|
+
return e.delete(r), s;
|
|
503
|
+
}, item(i) {
|
|
504
|
+
return [...e.keys()][i] ?? "";
|
|
505
|
+
}, get length() {
|
|
506
|
+
return e.size;
|
|
507
|
+
}, get cssText() {
|
|
508
|
+
return [...e.entries()].map(([i, r]) => `${i}: ${r.value}${r.priority ? ` ${r.priority}` : ""};`).join(" ");
|
|
509
|
+
}, set cssText(i) {
|
|
510
|
+
e.clear();
|
|
511
|
+
for (let r of i.split(";")) {
|
|
512
|
+
let s = r.trim();
|
|
513
|
+
if (!s)
|
|
514
|
+
continue;
|
|
515
|
+
let l = s.indexOf(":");
|
|
516
|
+
if (l < 0)
|
|
517
|
+
continue;
|
|
518
|
+
let a = s.slice(0, l).trim(), o = s.slice(l + 1).trim();
|
|
519
|
+
if (a)
|
|
520
|
+
t.setProperty(a, o);
|
|
521
|
+
}
|
|
522
|
+
} };
|
|
523
|
+
return new Proxy(t, { get(i, r, s) {
|
|
524
|
+
if (typeof r === "symbol")
|
|
525
|
+
return Reflect.get(i, r, s);
|
|
526
|
+
if (r in i) {
|
|
527
|
+
let l = Reflect.get(i, r, s);
|
|
528
|
+
return typeof l === "function" ? l.bind(i) : l;
|
|
529
|
+
}
|
|
530
|
+
return i.getPropertyValue(r);
|
|
531
|
+
}, set(i, r, s, l) {
|
|
532
|
+
if (typeof r === "symbol")
|
|
533
|
+
return Reflect.set(i, r, s, l);
|
|
534
|
+
if (r in i)
|
|
535
|
+
return Reflect.set(i, r, s, l);
|
|
536
|
+
return i.setProperty(r, String(s)), true;
|
|
537
|
+
}, has(i, r) {
|
|
538
|
+
if (typeof r === "symbol")
|
|
539
|
+
return Reflect.has(i, r);
|
|
540
|
+
if (r in i)
|
|
541
|
+
return true;
|
|
542
|
+
return i.getPropertyValue(r) !== "";
|
|
543
|
+
}, ownKeys() {
|
|
544
|
+
return [...Reflect.ownKeys(t), ...[...e.keys()].map((i) => be(i))];
|
|
545
|
+
}, getOwnPropertyDescriptor(i, r) {
|
|
546
|
+
if (typeof r === "symbol")
|
|
547
|
+
return Reflect.getOwnPropertyDescriptor(i, r);
|
|
548
|
+
if (r in i)
|
|
549
|
+
return Reflect.getOwnPropertyDescriptor(i, r);
|
|
550
|
+
let s = i.getPropertyValue(r);
|
|
551
|
+
if (s !== "")
|
|
552
|
+
return { configurable: true, enumerable: true, writable: true, value: s };
|
|
553
|
+
return;
|
|
554
|
+
} });
|
|
555
|
+
}
|
|
556
|
+
function be(e) {
|
|
557
|
+
return e.replace(/-([a-z])/g, (t, n) => n.toUpperCase());
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
class f {
|
|
561
|
+
items;
|
|
562
|
+
constructor(e = []) {
|
|
563
|
+
this.items = e;
|
|
564
|
+
for (let t = 0;t < e.length; t += 1)
|
|
565
|
+
Object.defineProperty(this, String(t), { configurable: true, enumerable: true, get: () => this.items[t] });
|
|
566
|
+
}
|
|
567
|
+
get length() {
|
|
568
|
+
return this.items.length;
|
|
569
|
+
}
|
|
570
|
+
item(e) {
|
|
571
|
+
return this.items[e] ?? null;
|
|
572
|
+
}
|
|
573
|
+
[Symbol.iterator]() {
|
|
574
|
+
return this.items[Symbol.iterator]();
|
|
575
|
+
}
|
|
576
|
+
forEach(e) {
|
|
577
|
+
this.items.forEach((t, n) => e(t, n, this));
|
|
578
|
+
}
|
|
579
|
+
entries() {
|
|
580
|
+
return this.items.entries();
|
|
581
|
+
}
|
|
582
|
+
keys() {
|
|
583
|
+
return this.items.keys();
|
|
584
|
+
}
|
|
585
|
+
values() {
|
|
586
|
+
return this.items.values();
|
|
587
|
+
}
|
|
588
|
+
toArray() {
|
|
589
|
+
return [...this.items];
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
class b extends A {
|
|
594
|
+
static ELEMENT_NODE = 1;
|
|
595
|
+
static TEXT_NODE = 3;
|
|
596
|
+
static COMMENT_NODE = 8;
|
|
597
|
+
static DOCUMENT_NODE = 9;
|
|
598
|
+
static DOCUMENT_FRAGMENT_NODE = 11;
|
|
599
|
+
nodeType;
|
|
600
|
+
nodeName;
|
|
601
|
+
parentNode = null;
|
|
602
|
+
ownerDocument = null;
|
|
603
|
+
childList = [];
|
|
604
|
+
constructor(e, t) {
|
|
605
|
+
super();
|
|
606
|
+
this.nodeType = e, this.nodeName = t;
|
|
607
|
+
}
|
|
608
|
+
get parentElement() {
|
|
609
|
+
let e = this.parentNode;
|
|
610
|
+
return e instanceof M ? e : null;
|
|
611
|
+
}
|
|
612
|
+
get childNodes() {
|
|
613
|
+
return new f([...this.childList]);
|
|
614
|
+
}
|
|
615
|
+
get firstChild() {
|
|
616
|
+
return this.childList[0] ?? null;
|
|
617
|
+
}
|
|
618
|
+
get lastChild() {
|
|
619
|
+
return this.childList[this.childList.length - 1] ?? null;
|
|
620
|
+
}
|
|
621
|
+
get nextSibling() {
|
|
622
|
+
let e = this.parentNode;
|
|
623
|
+
if (!e)
|
|
624
|
+
return null;
|
|
625
|
+
let t = e.childList.indexOf(this);
|
|
626
|
+
return t >= 0 ? e.childList[t + 1] ?? null : null;
|
|
627
|
+
}
|
|
628
|
+
get previousSibling() {
|
|
629
|
+
let e = this.parentNode;
|
|
630
|
+
if (!e)
|
|
631
|
+
return null;
|
|
632
|
+
let t = e.childList.indexOf(this);
|
|
633
|
+
return t > 0 ? e.childList[t - 1] : null;
|
|
634
|
+
}
|
|
635
|
+
get textContent() {
|
|
636
|
+
let e = "";
|
|
637
|
+
for (let t of this.childList)
|
|
638
|
+
if (t.nodeType === 3)
|
|
639
|
+
e += t.data;
|
|
640
|
+
else if (t.nodeType === 1)
|
|
641
|
+
e += t.textContent;
|
|
642
|
+
return e;
|
|
643
|
+
}
|
|
644
|
+
set textContent(e) {
|
|
645
|
+
if (this.childList = [], e) {
|
|
646
|
+
let t = new u(e);
|
|
647
|
+
t.ownerDocument = this.ownerDocument, t.parentNode = this, this.childList.push(t);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
hasChildNodes() {
|
|
651
|
+
return this.childList.length > 0;
|
|
652
|
+
}
|
|
653
|
+
appendChild(e) {
|
|
654
|
+
if (e === this)
|
|
655
|
+
throw Error("Cannot append a node to itself");
|
|
656
|
+
return this.insertBefore(e, null), e;
|
|
657
|
+
}
|
|
658
|
+
insertBefore(e, t) {
|
|
659
|
+
if (e === this)
|
|
660
|
+
throw Error("Cannot insert a node before itself");
|
|
661
|
+
if (e.parentNode)
|
|
662
|
+
e.parentNode.removeChild(e);
|
|
663
|
+
if (e.parentNode = this, e.ownerDocument === null)
|
|
664
|
+
e.ownerDocument = this.ownerDocument;
|
|
665
|
+
if (t === null)
|
|
666
|
+
return this.childList.push(e), e;
|
|
667
|
+
let n = this.childList.indexOf(t);
|
|
668
|
+
if (n < 0)
|
|
669
|
+
throw Error("Reference node is not a child of this node");
|
|
670
|
+
return this.childList.splice(n, 0, e), e;
|
|
671
|
+
}
|
|
672
|
+
removeChild(e) {
|
|
673
|
+
let t = this.childList.indexOf(e);
|
|
674
|
+
if (t < 0)
|
|
675
|
+
throw Error("Node is not a child of this node");
|
|
676
|
+
return this.childList.splice(t, 1), e.parentNode = null, e;
|
|
677
|
+
}
|
|
678
|
+
replaceChild(e, t) {
|
|
679
|
+
let n = this.childList.indexOf(t);
|
|
680
|
+
if (n < 0)
|
|
681
|
+
throw Error("Old child is not a child of this node");
|
|
682
|
+
if (e.parentNode)
|
|
683
|
+
e.parentNode.removeChild(e);
|
|
684
|
+
if (e.parentNode = this, e.ownerDocument === null)
|
|
685
|
+
e.ownerDocument = this.ownerDocument;
|
|
686
|
+
return this.childList[n] = e, t.parentNode = null, e;
|
|
687
|
+
}
|
|
688
|
+
replaceChildren(...e) {
|
|
689
|
+
for (let t of [...this.childList])
|
|
690
|
+
this.removeChild(t);
|
|
691
|
+
for (let t of e)
|
|
692
|
+
this.appendChild(t);
|
|
693
|
+
}
|
|
694
|
+
contains(e) {
|
|
695
|
+
if (!e)
|
|
696
|
+
return false;
|
|
697
|
+
let t = e;
|
|
698
|
+
while (t) {
|
|
699
|
+
if (t === this)
|
|
700
|
+
return true;
|
|
701
|
+
t = t.parentNode;
|
|
702
|
+
}
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
remove() {
|
|
706
|
+
this.parentNode?.removeChild(this);
|
|
707
|
+
}
|
|
708
|
+
cloneNode(e = false) {
|
|
709
|
+
let t = this.createClone();
|
|
710
|
+
if (e)
|
|
711
|
+
for (let n of this.childList)
|
|
712
|
+
t.appendChild(n.cloneNode(true));
|
|
713
|
+
return t;
|
|
714
|
+
}
|
|
715
|
+
createClone() {
|
|
716
|
+
let e = new b(this.nodeType, this.nodeName);
|
|
717
|
+
return e.ownerDocument = this.ownerDocument, e;
|
|
718
|
+
}
|
|
719
|
+
getRootNode() {
|
|
720
|
+
if (!this.parentNode)
|
|
721
|
+
return this;
|
|
722
|
+
let e = this.parentNode;
|
|
723
|
+
while (e.parentNode)
|
|
724
|
+
e = e.parentNode;
|
|
725
|
+
return e;
|
|
726
|
+
}
|
|
727
|
+
isConnected() {
|
|
728
|
+
return this.getRootNode().nodeType === 9;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
class M extends b {
|
|
733
|
+
namespaceURI;
|
|
734
|
+
attributeList = [];
|
|
735
|
+
styleValue;
|
|
736
|
+
classListValue;
|
|
737
|
+
datasetProxy;
|
|
738
|
+
constructor(e, t = null) {
|
|
739
|
+
super(1, e.toUpperCase());
|
|
740
|
+
this.namespaceURI = t;
|
|
741
|
+
}
|
|
742
|
+
get tagName() {
|
|
743
|
+
return this.nodeName;
|
|
744
|
+
}
|
|
745
|
+
get localName() {
|
|
746
|
+
return this.nodeName.toLowerCase();
|
|
747
|
+
}
|
|
748
|
+
get id() {
|
|
749
|
+
return this.getAttribute("id") ?? "";
|
|
750
|
+
}
|
|
751
|
+
set id(e) {
|
|
752
|
+
this.setAttribute("id", e);
|
|
753
|
+
}
|
|
754
|
+
get className() {
|
|
755
|
+
return this.getAttribute("class") ?? "";
|
|
756
|
+
}
|
|
757
|
+
set className(e) {
|
|
758
|
+
this.setAttribute("class", e);
|
|
759
|
+
}
|
|
760
|
+
get classList() {
|
|
761
|
+
if (!this.classListValue)
|
|
762
|
+
this.classListValue = new X(this, "class");
|
|
763
|
+
return this.classListValue;
|
|
764
|
+
}
|
|
765
|
+
get style() {
|
|
766
|
+
if (!this.styleValue)
|
|
767
|
+
this.styleValue = R();
|
|
768
|
+
return this.styleValue;
|
|
769
|
+
}
|
|
770
|
+
get dataset() {
|
|
771
|
+
if (!this.datasetProxy)
|
|
772
|
+
this.datasetProxy = Ce(this);
|
|
773
|
+
return this.datasetProxy;
|
|
774
|
+
}
|
|
775
|
+
get children() {
|
|
776
|
+
return new f(this.childList.filter((e) => e.nodeType === 1));
|
|
777
|
+
}
|
|
778
|
+
get firstElementChild() {
|
|
779
|
+
return this.children.item(0);
|
|
780
|
+
}
|
|
781
|
+
get lastElementChild() {
|
|
782
|
+
return this.children.item(this.children.length - 1);
|
|
783
|
+
}
|
|
784
|
+
get childElementCount() {
|
|
785
|
+
return this.children.length;
|
|
786
|
+
}
|
|
787
|
+
get attributes() {
|
|
788
|
+
return new Z(this);
|
|
789
|
+
}
|
|
790
|
+
getAttribute(e) {
|
|
791
|
+
let t = this.findAttribute(e);
|
|
792
|
+
return t ? t.value : null;
|
|
793
|
+
}
|
|
794
|
+
getAttributeNames() {
|
|
795
|
+
return this.attributeList.map((e) => e.name);
|
|
796
|
+
}
|
|
797
|
+
setAttribute(e, t) {
|
|
798
|
+
let n = String(t);
|
|
799
|
+
if (e === "style")
|
|
800
|
+
this.styleValue = R(), this.styleValue.cssText = n;
|
|
801
|
+
let i = this.findAttribute(e);
|
|
802
|
+
if (i)
|
|
803
|
+
i.value = n;
|
|
804
|
+
else
|
|
805
|
+
this.attributeList.push({ name: e, value: n });
|
|
806
|
+
}
|
|
807
|
+
removeAttribute(e) {
|
|
808
|
+
if (e === "style")
|
|
809
|
+
this.styleValue = R();
|
|
810
|
+
let t = this.attributeList.findIndex((n) => n.name === e);
|
|
811
|
+
if (t >= 0)
|
|
812
|
+
this.attributeList.splice(t, 1);
|
|
813
|
+
}
|
|
814
|
+
hasAttribute(e) {
|
|
815
|
+
return this.findAttribute(e) !== undefined;
|
|
816
|
+
}
|
|
817
|
+
toggleAttribute(e, t) {
|
|
818
|
+
let n = t ?? !this.hasAttribute(e);
|
|
819
|
+
if (n)
|
|
820
|
+
this.setAttribute(e, "");
|
|
821
|
+
else
|
|
822
|
+
this.removeAttribute(e);
|
|
823
|
+
return n;
|
|
824
|
+
}
|
|
825
|
+
hasAttributes() {
|
|
826
|
+
return this.attributeList.length > 0;
|
|
827
|
+
}
|
|
828
|
+
get innerHTML() {
|
|
829
|
+
return oe(this);
|
|
830
|
+
}
|
|
831
|
+
set innerHTML(e) {
|
|
832
|
+
this.replaceChildren(...ye(e, this.ownerDocument));
|
|
833
|
+
}
|
|
834
|
+
get outerHTML() {
|
|
835
|
+
return le(this);
|
|
836
|
+
}
|
|
837
|
+
get value() {
|
|
838
|
+
return this.getAttribute("value") ?? "";
|
|
839
|
+
}
|
|
840
|
+
set value(e) {
|
|
841
|
+
this.setAttribute("value", e);
|
|
842
|
+
}
|
|
843
|
+
querySelector(e) {
|
|
844
|
+
return C(this, e).item(0);
|
|
845
|
+
}
|
|
846
|
+
querySelectorAll(e) {
|
|
847
|
+
return C(this, e);
|
|
848
|
+
}
|
|
849
|
+
getElementsByTagName(e) {
|
|
850
|
+
let t = e.toLowerCase(), n = [];
|
|
851
|
+
return N(this, (i) => {
|
|
852
|
+
if (i.localName === t)
|
|
853
|
+
n.push(i);
|
|
854
|
+
}), new f(n);
|
|
855
|
+
}
|
|
856
|
+
matches(e) {
|
|
857
|
+
return ue(this, e);
|
|
858
|
+
}
|
|
859
|
+
closest(e) {
|
|
860
|
+
if (this.matches(e))
|
|
861
|
+
return this;
|
|
862
|
+
let t = this.parentElement;
|
|
863
|
+
while (t) {
|
|
864
|
+
if (t.matches(e))
|
|
865
|
+
return t;
|
|
866
|
+
t = t.parentElement;
|
|
867
|
+
}
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
getBoundingClientRect() {
|
|
871
|
+
return { x: 0, y: 0, top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0, toJSON() {
|
|
872
|
+
return { x: 0, y: 0, top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0 };
|
|
873
|
+
} };
|
|
874
|
+
}
|
|
875
|
+
scrollIntoView() {}
|
|
876
|
+
focus() {}
|
|
877
|
+
blur() {}
|
|
878
|
+
click() {
|
|
879
|
+
this.dispatchEvent(new O("click", { bubbles: true, cancelable: true }));
|
|
880
|
+
}
|
|
881
|
+
append(...e) {
|
|
882
|
+
for (let t of e)
|
|
883
|
+
if (typeof t === "string") {
|
|
884
|
+
let n = new u(t);
|
|
885
|
+
n.ownerDocument = this.ownerDocument, this.appendChild(n);
|
|
886
|
+
} else
|
|
887
|
+
this.appendChild(t);
|
|
888
|
+
}
|
|
889
|
+
prepend(...e) {
|
|
890
|
+
let t = this.firstChild;
|
|
891
|
+
for (let n of e)
|
|
892
|
+
if (typeof n === "string") {
|
|
893
|
+
let i = new u(n);
|
|
894
|
+
i.ownerDocument = this.ownerDocument, this.insertBefore(i, t);
|
|
895
|
+
} else
|
|
896
|
+
this.insertBefore(n, t);
|
|
897
|
+
}
|
|
898
|
+
before(...e) {
|
|
899
|
+
let t = this.parentNode;
|
|
900
|
+
if (!t)
|
|
901
|
+
return;
|
|
902
|
+
for (let n of e)
|
|
903
|
+
if (typeof n === "string") {
|
|
904
|
+
let i = new u(n);
|
|
905
|
+
i.ownerDocument = this.ownerDocument, t.insertBefore(i, this);
|
|
906
|
+
} else
|
|
907
|
+
t.insertBefore(n, this);
|
|
908
|
+
}
|
|
909
|
+
after(...e) {
|
|
910
|
+
let t = this.parentNode;
|
|
911
|
+
if (!t)
|
|
912
|
+
return;
|
|
913
|
+
let n = this.nextSibling;
|
|
914
|
+
for (let i of e)
|
|
915
|
+
if (typeof i === "string") {
|
|
916
|
+
let r = new u(i);
|
|
917
|
+
r.ownerDocument = this.ownerDocument, t.insertBefore(r, n);
|
|
918
|
+
} else
|
|
919
|
+
t.insertBefore(i, n);
|
|
920
|
+
}
|
|
921
|
+
replaceWith(...e) {
|
|
922
|
+
let t = this.parentNode;
|
|
923
|
+
if (!t)
|
|
924
|
+
return;
|
|
925
|
+
let n = this.nextSibling;
|
|
926
|
+
t.removeChild(this);
|
|
927
|
+
for (let i of e)
|
|
928
|
+
if (typeof i === "string") {
|
|
929
|
+
let r = new u(i);
|
|
930
|
+
r.ownerDocument = this.ownerDocument, t.insertBefore(r, n);
|
|
931
|
+
} else
|
|
932
|
+
t.insertBefore(i, n);
|
|
933
|
+
}
|
|
934
|
+
setAttributeNS(e, t, n) {
|
|
935
|
+
this.setAttribute(t, n);
|
|
936
|
+
}
|
|
937
|
+
removeAttributeNS(e, t) {
|
|
938
|
+
this.removeAttribute(t);
|
|
939
|
+
}
|
|
940
|
+
hasAttributeNS(e, t) {
|
|
941
|
+
return this.hasAttribute(t);
|
|
942
|
+
}
|
|
943
|
+
getAttributeNS(e, t) {
|
|
944
|
+
return this.getAttribute(t);
|
|
945
|
+
}
|
|
946
|
+
findAttribute(e) {
|
|
947
|
+
return this.attributeList.find((t) => t.name === e);
|
|
948
|
+
}
|
|
949
|
+
attributeEntries() {
|
|
950
|
+
return [...this.attributeList];
|
|
951
|
+
}
|
|
952
|
+
inlineStyleText() {
|
|
953
|
+
return this.styleValue?.cssText ?? "";
|
|
954
|
+
}
|
|
955
|
+
createClone() {
|
|
956
|
+
let e = m(this.localName, this.ownerDocument);
|
|
957
|
+
for (let t of this.attributeList)
|
|
958
|
+
e.setAttribute(t.name, t.value);
|
|
959
|
+
return e;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
class p extends M {
|
|
964
|
+
constructor(e) {
|
|
965
|
+
super(e);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
class Z {
|
|
970
|
+
element;
|
|
971
|
+
constructor(e) {
|
|
972
|
+
this.element = e;
|
|
973
|
+
for (let t = 0;t < e.attributeEntries().length; t += 1)
|
|
974
|
+
Object.defineProperty(this, String(t), { configurable: true, enumerable: true, get: () => this.element.attributeEntries()[t] ?? null });
|
|
975
|
+
}
|
|
976
|
+
get length() {
|
|
977
|
+
return this.element.attributeEntries().length;
|
|
978
|
+
}
|
|
979
|
+
item(e) {
|
|
980
|
+
return this.element.attributeEntries()[e] ?? null;
|
|
981
|
+
}
|
|
982
|
+
getNamedItem(e) {
|
|
983
|
+
return this.element.findAttribute(e) ?? null;
|
|
984
|
+
}
|
|
985
|
+
setNamedItem(e) {
|
|
986
|
+
this.element.setAttribute(e.name, e.value);
|
|
987
|
+
}
|
|
988
|
+
removeNamedItem(e) {
|
|
989
|
+
this.element.removeAttribute(e);
|
|
990
|
+
}
|
|
991
|
+
[Symbol.iterator]() {
|
|
992
|
+
return this.element.attributeEntries()[Symbol.iterator]();
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
class k extends p {
|
|
997
|
+
selectedValue;
|
|
998
|
+
constructor(e = "option") {
|
|
999
|
+
super(e);
|
|
1000
|
+
}
|
|
1001
|
+
get value() {
|
|
1002
|
+
return this.getAttribute("value") ?? this.textContent;
|
|
1003
|
+
}
|
|
1004
|
+
set value(e) {
|
|
1005
|
+
this.setAttribute("value", e);
|
|
1006
|
+
}
|
|
1007
|
+
get text() {
|
|
1008
|
+
return this.textContent;
|
|
1009
|
+
}
|
|
1010
|
+
get label() {
|
|
1011
|
+
return this.getAttribute("label") ?? this.textContent;
|
|
1012
|
+
}
|
|
1013
|
+
get selected() {
|
|
1014
|
+
return this.hasSelectedValue();
|
|
1015
|
+
}
|
|
1016
|
+
set selected(e) {
|
|
1017
|
+
if (this.setSelectedRaw(e), e) {
|
|
1018
|
+
let t = this.parentElement;
|
|
1019
|
+
if (t instanceof P && !t.multiple) {
|
|
1020
|
+
for (let n of t.options.toArray())
|
|
1021
|
+
if (n !== this)
|
|
1022
|
+
n.setSelectedRaw(false);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
setSelectedRaw(e) {
|
|
1027
|
+
if (this.selectedValue = e, e)
|
|
1028
|
+
this.setAttribute("selected", "");
|
|
1029
|
+
else
|
|
1030
|
+
this.removeAttribute("selected");
|
|
1031
|
+
}
|
|
1032
|
+
hasSelectedValue() {
|
|
1033
|
+
if (this.selectedValue !== undefined)
|
|
1034
|
+
return this.selectedValue;
|
|
1035
|
+
return this.hasAttribute("selected");
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
class P extends p {
|
|
1040
|
+
constructor(e = "select") {
|
|
1041
|
+
super(e);
|
|
1042
|
+
}
|
|
1043
|
+
get multiple() {
|
|
1044
|
+
return this.hasAttribute("multiple");
|
|
1045
|
+
}
|
|
1046
|
+
set multiple(e) {
|
|
1047
|
+
if (e)
|
|
1048
|
+
this.setAttribute("multiple", "");
|
|
1049
|
+
else
|
|
1050
|
+
this.removeAttribute("multiple");
|
|
1051
|
+
}
|
|
1052
|
+
get options() {
|
|
1053
|
+
let e = [];
|
|
1054
|
+
return N(this, (t) => {
|
|
1055
|
+
if (t instanceof k)
|
|
1056
|
+
e.push(t);
|
|
1057
|
+
}), new Q(e);
|
|
1058
|
+
}
|
|
1059
|
+
get selectedOptions() {
|
|
1060
|
+
return new f(this.options.toArray().filter((e) => e.hasSelectedValue()));
|
|
1061
|
+
}
|
|
1062
|
+
get selectedIndex() {
|
|
1063
|
+
return this.options.toArray().findIndex((e) => e.hasSelectedValue());
|
|
1064
|
+
}
|
|
1065
|
+
set selectedIndex(e) {
|
|
1066
|
+
this.options.toArray().forEach((n, i) => n.setSelectedRaw(i === e));
|
|
1067
|
+
}
|
|
1068
|
+
get value() {
|
|
1069
|
+
let e = this.options.toArray(), t = e.find((n) => n.hasSelectedValue());
|
|
1070
|
+
if (t)
|
|
1071
|
+
return t.value;
|
|
1072
|
+
if (!this.multiple && e.length > 0)
|
|
1073
|
+
return e[0].value;
|
|
1074
|
+
return "";
|
|
1075
|
+
}
|
|
1076
|
+
set value(e) {
|
|
1077
|
+
let t = this.options.toArray();
|
|
1078
|
+
for (let n of t)
|
|
1079
|
+
if (n.value === e)
|
|
1080
|
+
if (this.multiple)
|
|
1081
|
+
n.setSelectedRaw(true);
|
|
1082
|
+
else {
|
|
1083
|
+
for (let r of t)
|
|
1084
|
+
r.setSelectedRaw(r === n);
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
add(e) {
|
|
1089
|
+
this.appendChild(e);
|
|
1090
|
+
}
|
|
1091
|
+
removeOption(e) {
|
|
1092
|
+
let n = this.options.toArray()[e];
|
|
1093
|
+
if (n)
|
|
1094
|
+
n.remove();
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
class Q {
|
|
1099
|
+
items;
|
|
1100
|
+
constructor(e) {
|
|
1101
|
+
this.items = e;
|
|
1102
|
+
for (let t = 0;t < e.length; t += 1)
|
|
1103
|
+
Object.defineProperty(this, String(t), { configurable: true, enumerable: true, get: () => this.items[t] });
|
|
1104
|
+
}
|
|
1105
|
+
get length() {
|
|
1106
|
+
return this.items.length;
|
|
1107
|
+
}
|
|
1108
|
+
item(e) {
|
|
1109
|
+
return this.items[e] ?? null;
|
|
1110
|
+
}
|
|
1111
|
+
get value() {
|
|
1112
|
+
return this.items.find((e) => e.hasSelectedValue())?.value ?? "";
|
|
1113
|
+
}
|
|
1114
|
+
get selectedIndex() {
|
|
1115
|
+
return this.items.findIndex((e) => e.hasSelectedValue());
|
|
1116
|
+
}
|
|
1117
|
+
toArray() {
|
|
1118
|
+
return [...this.items];
|
|
1119
|
+
}
|
|
1120
|
+
[Symbol.iterator]() {
|
|
1121
|
+
return this.items[Symbol.iterator]();
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
class U extends p {
|
|
1126
|
+
inputValue;
|
|
1127
|
+
checkedValue;
|
|
1128
|
+
constructor(e = "input") {
|
|
1129
|
+
super(e);
|
|
1130
|
+
}
|
|
1131
|
+
get type() {
|
|
1132
|
+
return this.getAttribute("type") ?? "text";
|
|
1133
|
+
}
|
|
1134
|
+
set type(e) {
|
|
1135
|
+
this.setAttribute("type", e);
|
|
1136
|
+
}
|
|
1137
|
+
get name() {
|
|
1138
|
+
return this.getAttribute("name") ?? "";
|
|
1139
|
+
}
|
|
1140
|
+
set name(e) {
|
|
1141
|
+
this.setAttribute("name", e);
|
|
1142
|
+
}
|
|
1143
|
+
get value() {
|
|
1144
|
+
return this.inputValue ?? this.getAttribute("value") ?? "";
|
|
1145
|
+
}
|
|
1146
|
+
set value(e) {
|
|
1147
|
+
this.inputValue = e;
|
|
1148
|
+
}
|
|
1149
|
+
get defaultValue() {
|
|
1150
|
+
return this.getAttribute("value") ?? "";
|
|
1151
|
+
}
|
|
1152
|
+
get checked() {
|
|
1153
|
+
return this.checkedValue ?? this.hasAttribute("checked");
|
|
1154
|
+
}
|
|
1155
|
+
set checked(e) {
|
|
1156
|
+
this.checkedValue = e;
|
|
1157
|
+
}
|
|
1158
|
+
get disabled() {
|
|
1159
|
+
return this.hasAttribute("disabled");
|
|
1160
|
+
}
|
|
1161
|
+
set disabled(e) {
|
|
1162
|
+
if (e)
|
|
1163
|
+
this.setAttribute("disabled", "");
|
|
1164
|
+
else
|
|
1165
|
+
this.removeAttribute("disabled");
|
|
1166
|
+
}
|
|
1167
|
+
createClone() {
|
|
1168
|
+
let e = super.createClone();
|
|
1169
|
+
return e.inputValue = this.inputValue, e.checkedValue = this.checkedValue, e;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
class B extends p {
|
|
1174
|
+
textareaValue;
|
|
1175
|
+
constructor(e = "textarea") {
|
|
1176
|
+
super(e);
|
|
1177
|
+
}
|
|
1178
|
+
get value() {
|
|
1179
|
+
return this.textareaValue ?? this.textContent;
|
|
1180
|
+
}
|
|
1181
|
+
set value(e) {
|
|
1182
|
+
this.textareaValue = e;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
class W extends p {
|
|
1187
|
+
constructor(e = "button") {
|
|
1188
|
+
super(e);
|
|
1189
|
+
}
|
|
1190
|
+
get type() {
|
|
1191
|
+
return this.getAttribute("type") ?? "submit";
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
class z extends p {
|
|
1196
|
+
constructor(e = "style") {
|
|
1197
|
+
super(e);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
class G extends p {
|
|
1202
|
+
constructor(e = "a") {
|
|
1203
|
+
super(e);
|
|
1204
|
+
}
|
|
1205
|
+
get href() {
|
|
1206
|
+
return this.getAttribute("href") ?? "";
|
|
1207
|
+
}
|
|
1208
|
+
set href(e) {
|
|
1209
|
+
this.setAttribute("href", e);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
class u extends b {
|
|
1214
|
+
data;
|
|
1215
|
+
constructor(e = "") {
|
|
1216
|
+
super(3, "#text");
|
|
1217
|
+
this.data = e;
|
|
1218
|
+
}
|
|
1219
|
+
get nodeValue() {
|
|
1220
|
+
return this.data;
|
|
1221
|
+
}
|
|
1222
|
+
set nodeValue(e) {
|
|
1223
|
+
this.data = e;
|
|
1224
|
+
}
|
|
1225
|
+
get textContent() {
|
|
1226
|
+
return this.data;
|
|
1227
|
+
}
|
|
1228
|
+
set textContent(e) {
|
|
1229
|
+
this.data = e;
|
|
1230
|
+
}
|
|
1231
|
+
get wholeText() {
|
|
1232
|
+
return this.data;
|
|
1233
|
+
}
|
|
1234
|
+
createClone() {
|
|
1235
|
+
let e = new u(this.data);
|
|
1236
|
+
return e.ownerDocument = this.ownerDocument, e;
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
class w extends b {
|
|
1241
|
+
data;
|
|
1242
|
+
constructor(e = "") {
|
|
1243
|
+
super(8, "#comment");
|
|
1244
|
+
this.data = e;
|
|
1245
|
+
}
|
|
1246
|
+
get nodeValue() {
|
|
1247
|
+
return this.data;
|
|
1248
|
+
}
|
|
1249
|
+
set nodeValue(e) {
|
|
1250
|
+
this.data = e;
|
|
1251
|
+
}
|
|
1252
|
+
createClone() {
|
|
1253
|
+
let e = new w(this.data);
|
|
1254
|
+
return e.ownerDocument = this.ownerDocument, e;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
class _ extends b {
|
|
1259
|
+
constructor() {
|
|
1260
|
+
super(11, "#document-fragment");
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
class S extends b {
|
|
1265
|
+
defaultView = null;
|
|
1266
|
+
constructor() {
|
|
1267
|
+
super(9, "#document");
|
|
1268
|
+
}
|
|
1269
|
+
createElement(e) {
|
|
1270
|
+
return m(e, this);
|
|
1271
|
+
}
|
|
1272
|
+
createElementNS(e, t) {
|
|
1273
|
+
let n = m(t, this);
|
|
1274
|
+
return n.namespaceURI = e, n;
|
|
1275
|
+
}
|
|
1276
|
+
createTextNode(e) {
|
|
1277
|
+
let t = new u(e);
|
|
1278
|
+
return t.ownerDocument = this, t;
|
|
1279
|
+
}
|
|
1280
|
+
createComment(e) {
|
|
1281
|
+
let t = new w(e);
|
|
1282
|
+
return t.ownerDocument = this, t;
|
|
1283
|
+
}
|
|
1284
|
+
createDocumentFragment() {
|
|
1285
|
+
let e = new _;
|
|
1286
|
+
return e.ownerDocument = this, e;
|
|
1287
|
+
}
|
|
1288
|
+
createEvent(e) {
|
|
1289
|
+
if (e === "MouseEvent" || e === "mouseevent")
|
|
1290
|
+
return new O("");
|
|
1291
|
+
if (e === "KeyboardEvent" || e === "keyboardevent")
|
|
1292
|
+
return new H("");
|
|
1293
|
+
if (e === "CustomEvent" || e === "customevent")
|
|
1294
|
+
return new I("");
|
|
1295
|
+
return new c("");
|
|
1296
|
+
}
|
|
1297
|
+
get documentElement() {
|
|
1298
|
+
let e = this.childList.find((n) => n.nodeType === 1);
|
|
1299
|
+
if (e)
|
|
1300
|
+
return e;
|
|
1301
|
+
let t = m("html", this);
|
|
1302
|
+
return this.appendChild(t), t;
|
|
1303
|
+
}
|
|
1304
|
+
get head() {
|
|
1305
|
+
return this.ensureDocumentChild("head");
|
|
1306
|
+
}
|
|
1307
|
+
get body() {
|
|
1308
|
+
return this.ensureDocumentChild("body");
|
|
1309
|
+
}
|
|
1310
|
+
get title() {
|
|
1311
|
+
return this.querySelector("title")?.textContent ?? "";
|
|
1312
|
+
}
|
|
1313
|
+
set title(e) {
|
|
1314
|
+
let t = this.querySelector("title");
|
|
1315
|
+
if (!t)
|
|
1316
|
+
t = m("title", this), this.head.appendChild(t);
|
|
1317
|
+
t.textContent = e;
|
|
1318
|
+
}
|
|
1319
|
+
querySelector(e) {
|
|
1320
|
+
return C(this, e).item(0);
|
|
1321
|
+
}
|
|
1322
|
+
querySelectorAll(e) {
|
|
1323
|
+
return C(this, e);
|
|
1324
|
+
}
|
|
1325
|
+
getElementById(e) {
|
|
1326
|
+
let t = null;
|
|
1327
|
+
return N(this, (n) => {
|
|
1328
|
+
if (!t && n.id === e)
|
|
1329
|
+
t = n;
|
|
1330
|
+
}), t;
|
|
1331
|
+
}
|
|
1332
|
+
getElementsByTagName(e) {
|
|
1333
|
+
return this.documentElement.getElementsByTagName(e);
|
|
1334
|
+
}
|
|
1335
|
+
createClone() {
|
|
1336
|
+
return new S;
|
|
1337
|
+
}
|
|
1338
|
+
ensureDocumentChild(e) {
|
|
1339
|
+
let t = this.documentElement, n = t.childList.find((i) => i.nodeType === 1 && i.localName === e);
|
|
1340
|
+
if (!n)
|
|
1341
|
+
n = m(e, this), t.appendChild(n);
|
|
1342
|
+
return n;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
class Y {
|
|
1347
|
+
url;
|
|
1348
|
+
constructor(e) {
|
|
1349
|
+
this.url = new URL(e);
|
|
1350
|
+
}
|
|
1351
|
+
get href() {
|
|
1352
|
+
return this.url.href;
|
|
1353
|
+
}
|
|
1354
|
+
set href(e) {
|
|
1355
|
+
this.url = new URL(e, this.url.href);
|
|
1356
|
+
}
|
|
1357
|
+
get origin() {
|
|
1358
|
+
return this.url.origin;
|
|
1359
|
+
}
|
|
1360
|
+
get protocol() {
|
|
1361
|
+
return this.url.protocol;
|
|
1362
|
+
}
|
|
1363
|
+
get host() {
|
|
1364
|
+
return this.url.host;
|
|
1365
|
+
}
|
|
1366
|
+
get hostname() {
|
|
1367
|
+
return this.url.hostname;
|
|
1368
|
+
}
|
|
1369
|
+
get port() {
|
|
1370
|
+
return this.url.port;
|
|
1371
|
+
}
|
|
1372
|
+
get pathname() {
|
|
1373
|
+
return this.url.pathname;
|
|
1374
|
+
}
|
|
1375
|
+
set pathname(e) {
|
|
1376
|
+
let t = this.url, n = new URL(e, t.href);
|
|
1377
|
+
t.pathname = n.pathname;
|
|
1378
|
+
}
|
|
1379
|
+
get search() {
|
|
1380
|
+
return this.url.search;
|
|
1381
|
+
}
|
|
1382
|
+
set search(e) {
|
|
1383
|
+
this.url.search = e.startsWith("?") ? e : `?${e}`;
|
|
1384
|
+
}
|
|
1385
|
+
get hash() {
|
|
1386
|
+
return this.url.hash;
|
|
1387
|
+
}
|
|
1388
|
+
set hash(e) {
|
|
1389
|
+
let t = e.startsWith("#") ? e : `#${e}`;
|
|
1390
|
+
this.url.hash = t;
|
|
1391
|
+
}
|
|
1392
|
+
get username() {
|
|
1393
|
+
return this.url.username;
|
|
1394
|
+
}
|
|
1395
|
+
get password() {
|
|
1396
|
+
return this.url.password;
|
|
1397
|
+
}
|
|
1398
|
+
assign(e) {
|
|
1399
|
+
this.url = new URL(e, this.url.href);
|
|
1400
|
+
}
|
|
1401
|
+
replace(e) {
|
|
1402
|
+
this.url = new URL(e, this.url.href);
|
|
1403
|
+
}
|
|
1404
|
+
reload() {}
|
|
1405
|
+
toString() {
|
|
1406
|
+
return this.url.href;
|
|
1407
|
+
}
|
|
1408
|
+
getHashPath() {
|
|
1409
|
+
return this.url.hash.slice(1);
|
|
1410
|
+
}
|
|
1411
|
+
getHrefWithoutHash() {
|
|
1412
|
+
let e = this.url;
|
|
1413
|
+
return `${e.origin}${e.pathname}${e.search}`;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
class J {
|
|
1418
|
+
windowRef;
|
|
1419
|
+
entries = [];
|
|
1420
|
+
index = 0;
|
|
1421
|
+
scrollRestoration = "auto";
|
|
1422
|
+
constructor(e) {
|
|
1423
|
+
this.windowRef = e, this.entries = [{ state: null, url: e.location.href }];
|
|
1424
|
+
}
|
|
1425
|
+
get length() {
|
|
1426
|
+
return this.entries.length;
|
|
1427
|
+
}
|
|
1428
|
+
get state() {
|
|
1429
|
+
return this.entries[this.index]?.state ?? null;
|
|
1430
|
+
}
|
|
1431
|
+
pushState(e, t, n) {
|
|
1432
|
+
let i = n ? new URL(n, this.windowRef.location.href).href : this.windowRef.location.href;
|
|
1433
|
+
this.entries = this.entries.slice(0, this.index + 1), this.entries.push({ state: e, url: i }), this.index = this.entries.length - 1, this.windowRef.setLocationUrl(i);
|
|
1434
|
+
}
|
|
1435
|
+
replaceState(e, t, n) {
|
|
1436
|
+
let i = n ? new URL(n, this.windowRef.location.href).href : this.windowRef.location.href;
|
|
1437
|
+
this.entries[this.index] = { state: e, url: i }, this.windowRef.setLocationUrl(i);
|
|
1438
|
+
}
|
|
1439
|
+
back() {
|
|
1440
|
+
this.go(-1);
|
|
1441
|
+
}
|
|
1442
|
+
forward() {
|
|
1443
|
+
this.go(1);
|
|
1444
|
+
}
|
|
1445
|
+
go(e = 0) {
|
|
1446
|
+
let t = this.index + e;
|
|
1447
|
+
if (t < 0 || t >= this.entries.length)
|
|
1448
|
+
return;
|
|
1449
|
+
this.index = t, this.windowRef.setLocationUrl(this.entries[t].url), this.windowRef.dispatchEvent(new c("popstate", { bubbles: false, cancelable: false }));
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
class ee {
|
|
1454
|
+
store = new Map;
|
|
1455
|
+
get length() {
|
|
1456
|
+
return this.store.size;
|
|
1457
|
+
}
|
|
1458
|
+
key(e) {
|
|
1459
|
+
return [...this.store.keys()][e] ?? null;
|
|
1460
|
+
}
|
|
1461
|
+
getItem(e) {
|
|
1462
|
+
return this.store.has(e) ? this.store.get(e) : null;
|
|
1463
|
+
}
|
|
1464
|
+
setItem(e, t) {
|
|
1465
|
+
this.store.set(e, String(t));
|
|
1466
|
+
}
|
|
1467
|
+
removeItem(e) {
|
|
1468
|
+
this.store.delete(e);
|
|
1469
|
+
}
|
|
1470
|
+
clear() {
|
|
1471
|
+
this.store.clear();
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
class te {
|
|
1476
|
+
userAgent = "TSone/0.2.1";
|
|
1477
|
+
platform = "TSone";
|
|
1478
|
+
language = "zh-CN";
|
|
1479
|
+
languages = ["zh-CN"];
|
|
1480
|
+
onLine = true;
|
|
1481
|
+
maxTouchPoints = 0;
|
|
1482
|
+
}
|
|
1483
|
+
function ge(e, t) {
|
|
1484
|
+
let n = new Set, i = false, r = { media: t, matches: false, onchange: null, addEventListener(s, l) {
|
|
1485
|
+
if (s === "change")
|
|
1486
|
+
n.add(l);
|
|
1487
|
+
}, removeEventListener(s, l) {
|
|
1488
|
+
if (s === "change")
|
|
1489
|
+
n.delete(l);
|
|
1490
|
+
}, addListener(s) {
|
|
1491
|
+
n.add(s);
|
|
1492
|
+
}, removeListener(s) {
|
|
1493
|
+
n.delete(s);
|
|
1494
|
+
}, dispatchEvent(s) {
|
|
1495
|
+
for (let l of [...n])
|
|
1496
|
+
if (typeof l === "function")
|
|
1497
|
+
l.call(r, s);
|
|
1498
|
+
else
|
|
1499
|
+
l.handleEvent(s);
|
|
1500
|
+
return true;
|
|
1501
|
+
} };
|
|
1502
|
+
return r;
|
|
1503
|
+
}
|
|
1504
|
+
var fe = ["window", "document", "Node", "Text", "Comment", "Element", "HTMLElement", "HTMLInputElement", "HTMLTextAreaElement", "HTMLSelectElement", "HTMLButtonElement", "HTMLOptionElement", "HTMLStyleElement", "HTMLAnchorElement", "DocumentFragment", "Document", "Event", "MouseEvent", "KeyboardEvent", "CustomEvent", "EventTarget", "DOMException", "history", "location", "navigator", "localStorage", "matchMedia", "getComputedStyle", "requestAnimationFrame", "cancelAnimationFrame", "ResizeObserver"];
|
|
1505
|
+
|
|
1506
|
+
class ne extends A {
|
|
1507
|
+
window = this;
|
|
1508
|
+
document;
|
|
1509
|
+
location;
|
|
1510
|
+
history;
|
|
1511
|
+
localStorage = new ee;
|
|
1512
|
+
navigator = new te;
|
|
1513
|
+
Node = b;
|
|
1514
|
+
Text = u;
|
|
1515
|
+
Comment = w;
|
|
1516
|
+
Element = M;
|
|
1517
|
+
HTMLElement = p;
|
|
1518
|
+
HTMLInputElement = U;
|
|
1519
|
+
HTMLTextAreaElement = B;
|
|
1520
|
+
HTMLSelectElement = P;
|
|
1521
|
+
HTMLButtonElement = W;
|
|
1522
|
+
HTMLOptionElement = k;
|
|
1523
|
+
HTMLStyleElement = z;
|
|
1524
|
+
HTMLAnchorElement = G;
|
|
1525
|
+
DocumentFragment = _;
|
|
1526
|
+
Document = S;
|
|
1527
|
+
Event = c;
|
|
1528
|
+
MouseEvent = O;
|
|
1529
|
+
KeyboardEvent = H;
|
|
1530
|
+
CustomEvent = I;
|
|
1531
|
+
EventTarget = A;
|
|
1532
|
+
DOMException = K;
|
|
1533
|
+
NodeList = f;
|
|
1534
|
+
constructor(e = {}) {
|
|
1535
|
+
super();
|
|
1536
|
+
let t = e.url ?? "http://localhost/";
|
|
1537
|
+
this.location = new Y(t), this.history = new J(this), this.document = new S, this.document.defaultView = this, Se(this.document);
|
|
1538
|
+
}
|
|
1539
|
+
matchMedia(e) {
|
|
1540
|
+
return ge(this, e);
|
|
1541
|
+
}
|
|
1542
|
+
getComputedStyle(e) {
|
|
1543
|
+
return e.style;
|
|
1544
|
+
}
|
|
1545
|
+
requestAnimationFrame(e) {
|
|
1546
|
+
return setTimeout(() => e(Date.now()), 0);
|
|
1547
|
+
}
|
|
1548
|
+
cancelAnimationFrame(e) {
|
|
1549
|
+
clearTimeout(e);
|
|
1550
|
+
}
|
|
1551
|
+
setLocationUrl(e) {
|
|
1552
|
+
this.location.href = e;
|
|
1553
|
+
}
|
|
1554
|
+
installKeys() {
|
|
1555
|
+
return [...fe];
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
function ke(e = {}) {
|
|
1559
|
+
return new ne(e);
|
|
1560
|
+
}
|
|
1561
|
+
function Pe(e, t = globalThis) {
|
|
1562
|
+
let n = new Map, i = e.installKeys();
|
|
1563
|
+
for (let r of i)
|
|
1564
|
+
n.set(r, Object.getOwnPropertyDescriptor(t, r));
|
|
1565
|
+
for (let r of i)
|
|
1566
|
+
Object.defineProperty(t, r, { configurable: true, enumerable: true, writable: true, value: e[r] });
|
|
1567
|
+
return Object.defineProperty(t, "window", { configurable: true, enumerable: true, writable: true, value: e }), () => {
|
|
1568
|
+
for (let r of i) {
|
|
1569
|
+
let s = n.get(r);
|
|
1570
|
+
if (s)
|
|
1571
|
+
Object.defineProperty(t, r, s);
|
|
1572
|
+
else
|
|
1573
|
+
Reflect.deleteProperty(t, r);
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
function ye(e, t) {
|
|
1578
|
+
let n = new _;
|
|
1579
|
+
if (t)
|
|
1580
|
+
n.ownerDocument = t;
|
|
1581
|
+
return Ee(n, e, t), [...n.childList];
|
|
1582
|
+
}
|
|
1583
|
+
function Ee(e, t, n) {
|
|
1584
|
+
let i = [], r = e, s = 0, l = t.length, a = (o) => {
|
|
1585
|
+
if (o.ownerDocument === null)
|
|
1586
|
+
o.ownerDocument = n;
|
|
1587
|
+
r.appendChild(o);
|
|
1588
|
+
};
|
|
1589
|
+
while (s < l) {
|
|
1590
|
+
let o = t.indexOf("<", s);
|
|
1591
|
+
if (o < 0) {
|
|
1592
|
+
a(new u(t.slice(s)));
|
|
1593
|
+
break;
|
|
1594
|
+
}
|
|
1595
|
+
if (o > s)
|
|
1596
|
+
a(new u(t.slice(s, o)));
|
|
1597
|
+
if (t.startsWith("<!--", o)) {
|
|
1598
|
+
let d = t.indexOf("-->", o + 4), E = d < 0 ? l : d;
|
|
1599
|
+
a(new w(t.slice(o + 4, E))), s = d < 0 ? l : d + 3;
|
|
1600
|
+
continue;
|
|
1601
|
+
}
|
|
1602
|
+
let h = ve(t, o);
|
|
1603
|
+
if (h < 0) {
|
|
1604
|
+
a(new u(t.slice(o)));
|
|
1605
|
+
break;
|
|
1606
|
+
}
|
|
1607
|
+
let T = t.slice(o + 1, h).trim();
|
|
1608
|
+
if (T.startsWith("/")) {
|
|
1609
|
+
let d = T.slice(1).trim().toLowerCase();
|
|
1610
|
+
if (i.length > 0 && i[i.length - 1].localName === d)
|
|
1611
|
+
i.pop(), r = i[i.length - 1] ?? e;
|
|
1612
|
+
s = h + 1;
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
let ae = T.endsWith("/"), y = we(T.replace(/\/$/, "").trim());
|
|
1616
|
+
if (!y) {
|
|
1617
|
+
s = h + 1;
|
|
1618
|
+
continue;
|
|
1619
|
+
}
|
|
1620
|
+
let v = m(y.name, n);
|
|
1621
|
+
for (let d of y.attributes)
|
|
1622
|
+
v.setAttribute(d.name, d.value);
|
|
1623
|
+
if (a(v), ie.has(y.name) || ae) {
|
|
1624
|
+
s = h + 1;
|
|
1625
|
+
continue;
|
|
1626
|
+
}
|
|
1627
|
+
if (re.has(y.name)) {
|
|
1628
|
+
let d = `</${y.name}>`, E = t.toLowerCase().indexOf(d, h + 1), j = t.slice(h + 1, E < 0 ? l : E);
|
|
1629
|
+
v.appendChild(n?.createTextNode(j) ?? new u(j)), s = E < 0 ? l : E + d.length;
|
|
1630
|
+
continue;
|
|
1631
|
+
}
|
|
1632
|
+
i.push(v), r = v, s = h + 1;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
var ie = new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
|
|
1636
|
+
var re = new Set(["script", "style", "textarea", "title"]);
|
|
1637
|
+
function ve(e, t) {
|
|
1638
|
+
let n = null;
|
|
1639
|
+
for (let i = t + 1;i < e.length; i += 1) {
|
|
1640
|
+
let r = e[i];
|
|
1641
|
+
if (n) {
|
|
1642
|
+
if (r === n)
|
|
1643
|
+
n = null;
|
|
1644
|
+
continue;
|
|
1645
|
+
}
|
|
1646
|
+
if (r === '"' || r === "'") {
|
|
1647
|
+
n = r;
|
|
1648
|
+
continue;
|
|
1649
|
+
}
|
|
1650
|
+
if (r === ">")
|
|
1651
|
+
return i;
|
|
1652
|
+
}
|
|
1653
|
+
return -1;
|
|
1654
|
+
}
|
|
1655
|
+
function we(e) {
|
|
1656
|
+
let t = e.match(/^([a-zA-Z][a-zA-Z0-9-]*)\s*(.*)$/);
|
|
1657
|
+
if (!t)
|
|
1658
|
+
return null;
|
|
1659
|
+
let n = t[1].toLowerCase(), i = [], r = t[2], s = /([a-zA-Z_:][a-zA-Z0-9_:.-]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g, l;
|
|
1660
|
+
while ((l = s.exec(r)) !== null) {
|
|
1661
|
+
let a = l[1], o = l[2] ?? l[3] ?? l[4] ?? "";
|
|
1662
|
+
i.push({ name: a, value: Ne(o) });
|
|
1663
|
+
}
|
|
1664
|
+
return { name: n, attributes: i };
|
|
1665
|
+
}
|
|
1666
|
+
function Ne(e) {
|
|
1667
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/ /g, "\xA0");
|
|
1668
|
+
}
|
|
1669
|
+
function se(e) {
|
|
1670
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1671
|
+
}
|
|
1672
|
+
function F(e) {
|
|
1673
|
+
return se(e).replace(/"/g, """);
|
|
1674
|
+
}
|
|
1675
|
+
function le(e) {
|
|
1676
|
+
switch (e.nodeType) {
|
|
1677
|
+
case 3:
|
|
1678
|
+
return se(e.data);
|
|
1679
|
+
case 8:
|
|
1680
|
+
return `<!--${e.data}-->`;
|
|
1681
|
+
case 1:
|
|
1682
|
+
return Te(e);
|
|
1683
|
+
default:
|
|
1684
|
+
return "";
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
function Te(e) {
|
|
1688
|
+
let t = e.localName, n = [];
|
|
1689
|
+
for (let s of e.attributeEntries()) {
|
|
1690
|
+
if (s.name === "style")
|
|
1691
|
+
continue;
|
|
1692
|
+
n.push(`${s.name}="${F(s.value)}"`);
|
|
1693
|
+
}
|
|
1694
|
+
let i = e.inlineStyleText();
|
|
1695
|
+
if (i)
|
|
1696
|
+
n.push(`style="${F(i)}"`);
|
|
1697
|
+
let r = n.length > 0 ? ` ${n.join(" ")}` : "";
|
|
1698
|
+
if (ie.has(t))
|
|
1699
|
+
return `<${t}${r}>`;
|
|
1700
|
+
if (re.has(t))
|
|
1701
|
+
return `<${t}${r}>${e.textContent}</${t}>`;
|
|
1702
|
+
return `<${t}${r}>${oe(e)}</${t}>`;
|
|
1703
|
+
}
|
|
1704
|
+
function oe(e) {
|
|
1705
|
+
return e.childList.map((t) => le(t)).join("");
|
|
1706
|
+
}
|
|
1707
|
+
function xe(e) {
|
|
1708
|
+
return e.split(",").map((t) => {
|
|
1709
|
+
let n = [], i = 0;
|
|
1710
|
+
while (i < t.length) {
|
|
1711
|
+
while (i < t.length && t[i] === " ")
|
|
1712
|
+
i += 1;
|
|
1713
|
+
if (i >= t.length)
|
|
1714
|
+
break;
|
|
1715
|
+
if (t[i] === ">") {
|
|
1716
|
+
n.push({ type: "child" }), i += 1;
|
|
1717
|
+
continue;
|
|
1718
|
+
}
|
|
1719
|
+
let r = i;
|
|
1720
|
+
while (i < t.length && t[i] !== " " && t[i] !== ">")
|
|
1721
|
+
i += 1;
|
|
1722
|
+
n.push(Le(t.slice(r, i)));
|
|
1723
|
+
}
|
|
1724
|
+
return n;
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1727
|
+
function Le(e) {
|
|
1728
|
+
let t = [], n = 0;
|
|
1729
|
+
while (n < e.length) {
|
|
1730
|
+
let i = e[n];
|
|
1731
|
+
if (i === "*")
|
|
1732
|
+
t.push({ type: "universal" }), n += 1;
|
|
1733
|
+
else if (i === "#") {
|
|
1734
|
+
let r = V(e, n + 1);
|
|
1735
|
+
t.push({ type: "id", id: e.slice(n + 1, r) }), n = r;
|
|
1736
|
+
} else if (i === ".") {
|
|
1737
|
+
let r = V(e, n + 1);
|
|
1738
|
+
t.push({ type: "class", className: e.slice(n + 1, r) }), n = r;
|
|
1739
|
+
} else if (i === "[") {
|
|
1740
|
+
let r = e.indexOf("]", n), s = e.slice(n + 1, r < 0 ? e.length : r).trim(), l = s.match(/^([a-zA-Z_:][a-zA-Z0-9_:.-]*)(?:([~|^$*]?=)(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?$/);
|
|
1741
|
+
if (l)
|
|
1742
|
+
t.push({ type: "attribute", name: l[1], operator: l[2], value: l[3] ?? l[4] ?? l[5] });
|
|
1743
|
+
else
|
|
1744
|
+
t.push({ type: "attribute", name: s });
|
|
1745
|
+
n = r < 0 ? e.length : r + 1;
|
|
1746
|
+
} else if (/[a-zA-Z_]/.test(i)) {
|
|
1747
|
+
let r = V(e, n);
|
|
1748
|
+
t.push({ type: "tag", name: e.slice(n, r).toLowerCase() }), n = r;
|
|
1749
|
+
} else
|
|
1750
|
+
n += 1;
|
|
1751
|
+
}
|
|
1752
|
+
if (t.length === 1)
|
|
1753
|
+
return t[0];
|
|
1754
|
+
return { type: "compound", parts: t };
|
|
1755
|
+
}
|
|
1756
|
+
function V(e, t) {
|
|
1757
|
+
let n = t;
|
|
1758
|
+
while (n < e.length && /[a-zA-Z0-9:_-]/.test(e[n]))
|
|
1759
|
+
n += 1;
|
|
1760
|
+
return n;
|
|
1761
|
+
}
|
|
1762
|
+
function ue(e, t) {
|
|
1763
|
+
return xe(t).some((i) => De(e, i));
|
|
1764
|
+
}
|
|
1765
|
+
function De(e, t) {
|
|
1766
|
+
let n = t.length - 1;
|
|
1767
|
+
if (n < 0)
|
|
1768
|
+
return true;
|
|
1769
|
+
if (!D(e, t[n]))
|
|
1770
|
+
return false;
|
|
1771
|
+
if (n === 0)
|
|
1772
|
+
return true;
|
|
1773
|
+
let i = e.parentElement;
|
|
1774
|
+
n -= 1;
|
|
1775
|
+
while (i) {
|
|
1776
|
+
let r = t[n];
|
|
1777
|
+
if (!r)
|
|
1778
|
+
return true;
|
|
1779
|
+
if (r.type === "child") {
|
|
1780
|
+
let s = t[n - 1];
|
|
1781
|
+
if (!s || !D(i, s))
|
|
1782
|
+
return false;
|
|
1783
|
+
if (n -= 2, n < 0)
|
|
1784
|
+
return true;
|
|
1785
|
+
i = i.parentElement;
|
|
1786
|
+
continue;
|
|
1787
|
+
}
|
|
1788
|
+
if (D(i, r)) {
|
|
1789
|
+
if (n -= 1, n < 0)
|
|
1790
|
+
return true;
|
|
1791
|
+
}
|
|
1792
|
+
i = i.parentElement;
|
|
1793
|
+
}
|
|
1794
|
+
return false;
|
|
1795
|
+
}
|
|
1796
|
+
function D(e, t) {
|
|
1797
|
+
switch (t.type) {
|
|
1798
|
+
case "universal":
|
|
1799
|
+
return true;
|
|
1800
|
+
case "tag":
|
|
1801
|
+
return e.localName === t.name;
|
|
1802
|
+
case "id":
|
|
1803
|
+
return e.id === t.id;
|
|
1804
|
+
case "class":
|
|
1805
|
+
return e.classList.contains(t.className);
|
|
1806
|
+
case "attribute":
|
|
1807
|
+
return Ae(e, t);
|
|
1808
|
+
case "compound":
|
|
1809
|
+
return t.parts.every((n) => D(e, n));
|
|
1810
|
+
case "child":
|
|
1811
|
+
return false;
|
|
1812
|
+
default:
|
|
1813
|
+
return false;
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
function Ae(e, t) {
|
|
1817
|
+
let n = e.getAttribute(t.name);
|
|
1818
|
+
if (!t.operator)
|
|
1819
|
+
return n !== null;
|
|
1820
|
+
if (n === null)
|
|
1821
|
+
return false;
|
|
1822
|
+
let i = t.value ?? "";
|
|
1823
|
+
switch (t.operator) {
|
|
1824
|
+
case "=":
|
|
1825
|
+
return n === i;
|
|
1826
|
+
case "~=":
|
|
1827
|
+
return n.split(/\s+/).includes(i);
|
|
1828
|
+
case "|=":
|
|
1829
|
+
return n === i || n.startsWith(`${i}-`);
|
|
1830
|
+
case "^=":
|
|
1831
|
+
return n.startsWith(i);
|
|
1832
|
+
case "$=":
|
|
1833
|
+
return n.endsWith(i);
|
|
1834
|
+
case "*=":
|
|
1835
|
+
return n.includes(i);
|
|
1836
|
+
default:
|
|
1837
|
+
return false;
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
function C(e, t) {
|
|
1841
|
+
let n = [];
|
|
1842
|
+
return N(e, (i) => {
|
|
1843
|
+
if (i !== e && ue(i, t))
|
|
1844
|
+
n.push(i);
|
|
1845
|
+
}), new f(n);
|
|
1846
|
+
}
|
|
1847
|
+
function N(e, t) {
|
|
1848
|
+
for (let n of e.childList)
|
|
1849
|
+
if (n.nodeType === 1)
|
|
1850
|
+
t(n), N(n, t);
|
|
1851
|
+
}
|
|
1852
|
+
function m(e, t) {
|
|
1853
|
+
let n = e.toLowerCase(), i;
|
|
1854
|
+
if (n === "input")
|
|
1855
|
+
i = new U(n);
|
|
1856
|
+
else if (n === "textarea")
|
|
1857
|
+
i = new B(n);
|
|
1858
|
+
else if (n === "select")
|
|
1859
|
+
i = new P(n);
|
|
1860
|
+
else if (n === "option")
|
|
1861
|
+
i = new k(n);
|
|
1862
|
+
else if (n === "button")
|
|
1863
|
+
i = new W(n);
|
|
1864
|
+
else if (n === "style")
|
|
1865
|
+
i = new z(n);
|
|
1866
|
+
else if (n === "a")
|
|
1867
|
+
i = new G(n);
|
|
1868
|
+
else
|
|
1869
|
+
i = new p(n);
|
|
1870
|
+
return i.ownerDocument = t, i;
|
|
1871
|
+
}
|
|
1872
|
+
function Se(e) {
|
|
1873
|
+
let t = e.createElement("html");
|
|
1874
|
+
t.setAttribute("lang", "en"), e.appendChild(t);
|
|
1875
|
+
let n = e.createElement("head"), i = e.createElement("body");
|
|
1876
|
+
t.appendChild(n), t.appendChild(i);
|
|
1877
|
+
}
|
|
1878
|
+
function Ce(e) {
|
|
1879
|
+
return new Proxy({}, { get(n, i) {
|
|
1880
|
+
if (typeof i === "symbol")
|
|
1881
|
+
return;
|
|
1882
|
+
return e.getAttribute(`data-${g(i)}`) ?? "";
|
|
1883
|
+
}, set(n, i, r) {
|
|
1884
|
+
if (typeof i === "symbol")
|
|
1885
|
+
return true;
|
|
1886
|
+
if (r === "" || r === null || r === undefined)
|
|
1887
|
+
e.removeAttribute(`data-${g(i)}`);
|
|
1888
|
+
else
|
|
1889
|
+
e.setAttribute(`data-${g(i)}`, String(r));
|
|
1890
|
+
return true;
|
|
1891
|
+
}, deleteProperty(n, i) {
|
|
1892
|
+
if (typeof i !== "symbol")
|
|
1893
|
+
e.removeAttribute(`data-${g(i)}`);
|
|
1894
|
+
return true;
|
|
1895
|
+
}, has(n, i) {
|
|
1896
|
+
if (typeof i === "symbol")
|
|
1897
|
+
return false;
|
|
1898
|
+
return e.hasAttribute(`data-${g(i)}`);
|
|
1899
|
+
}, ownKeys() {
|
|
1900
|
+
let n = [];
|
|
1901
|
+
for (let i of e.attributeEntries())
|
|
1902
|
+
if (i.name.startsWith("data-"))
|
|
1903
|
+
n.push(Oe(i.name.slice(5)));
|
|
1904
|
+
return n;
|
|
1905
|
+
}, getOwnPropertyDescriptor(n, i) {
|
|
1906
|
+
if (typeof i === "symbol")
|
|
1907
|
+
return;
|
|
1908
|
+
if (e.hasAttribute(`data-${g(i)}`))
|
|
1909
|
+
return { configurable: true, enumerable: true, writable: true, value: e.getAttribute(`data-${g(i)}`) };
|
|
1910
|
+
return;
|
|
1911
|
+
} });
|
|
1912
|
+
}
|
|
1913
|
+
function g(e) {
|
|
1914
|
+
return e.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`);
|
|
1915
|
+
}
|
|
1916
|
+
function Oe(e) {
|
|
1917
|
+
return e.replace(/-([a-z])/g, (t, n) => n.toUpperCase());
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
// src/project.ts
|
|
1921
|
+
var PROJECT_GLOBAL_KEYS = [...fe, "__APP__"];
|
|
1922
|
+
var projectDomQueue = Promise.resolve();
|
|
1923
|
+
async function renderProjectHtml(config, options, entry = config.entry) {
|
|
1924
|
+
return withProjectDom(async () => {
|
|
1925
|
+
const module = await importProjectEntry(entry);
|
|
1926
|
+
const app = module.app;
|
|
1927
|
+
if (!app || typeof app.renderHtmlDocument !== "function") {
|
|
1928
|
+
throw new Error(`TSone entry ${entry} must export an app with renderHtmlDocument()`);
|
|
1929
|
+
}
|
|
1930
|
+
return app.renderHtmlDocument(options);
|
|
1931
|
+
});
|
|
1932
|
+
}
|
|
1933
|
+
async function withProjectDom(callback) {
|
|
1934
|
+
const task = projectDomQueue.then(() => runWithProjectDom(callback));
|
|
1935
|
+
projectDomQueue = task.then(() => {
|
|
1936
|
+
return;
|
|
1937
|
+
}, () => {
|
|
1938
|
+
return;
|
|
1939
|
+
});
|
|
1940
|
+
return task;
|
|
1941
|
+
}
|
|
1942
|
+
async function runWithProjectDom(callback) {
|
|
1943
|
+
const windowRef = ke({ url: "http://127.0.0.1/" });
|
|
1944
|
+
Object.assign(windowRef, {
|
|
1945
|
+
Error,
|
|
1946
|
+
EvalError,
|
|
1947
|
+
RangeError,
|
|
1948
|
+
ReferenceError,
|
|
1949
|
+
SyntaxError,
|
|
1950
|
+
TypeError,
|
|
1951
|
+
URIError
|
|
1952
|
+
});
|
|
1953
|
+
const descriptors = captureGlobalDescriptors();
|
|
1954
|
+
try {
|
|
1955
|
+
Pe(windowRef);
|
|
1956
|
+
return await callback();
|
|
1957
|
+
} finally {
|
|
1958
|
+
restoreGlobalDescriptors(descriptors);
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
var projectEntrySequence = 0;
|
|
1962
|
+
async function importProjectEntry(entry) {
|
|
1963
|
+
projectEntrySequence += 1;
|
|
1964
|
+
return await import(`${entry}?tsone_entry=${projectEntrySequence}`);
|
|
1965
|
+
}
|
|
1966
|
+
function captureGlobalDescriptors() {
|
|
1967
|
+
return new Map(PROJECT_GLOBAL_KEYS.map((key) => [
|
|
1968
|
+
key,
|
|
1969
|
+
Object.getOwnPropertyDescriptor(globalThis, key)
|
|
1970
|
+
]));
|
|
1971
|
+
}
|
|
1972
|
+
function restoreGlobalDescriptors(descriptors) {
|
|
1973
|
+
PROJECT_GLOBAL_KEYS.forEach((key) => {
|
|
1974
|
+
const descriptor = descriptors.get(key);
|
|
1975
|
+
if (descriptor) {
|
|
1976
|
+
Object.defineProperty(globalThis, key, descriptor);
|
|
1977
|
+
return;
|
|
1978
|
+
}
|
|
1979
|
+
delete globalThis[key];
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
// src/safe-path.ts
|
|
1984
|
+
import { lstat, realpath } from "fs/promises";
|
|
1985
|
+
import { dirname, isAbsolute, relative, resolve as resolve2, sep } from "path";
|
|
1986
|
+
async function assertSafeSubdirectory(root, path, errorMessage) {
|
|
1987
|
+
try {
|
|
1988
|
+
const canonicalRoot = await realpath(root);
|
|
1989
|
+
const canonicalPath = await canonicalizePotentialPath(path);
|
|
1990
|
+
if (!isStrictSubdirectory(canonicalRoot, canonicalPath)) {
|
|
1991
|
+
throw new Error(errorMessage);
|
|
1992
|
+
}
|
|
1993
|
+
} catch {
|
|
1994
|
+
throw new Error(errorMessage);
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
async function assertSafeSubdirectoryDoesNotContain(root, path, protectedPath, errorMessage) {
|
|
1998
|
+
try {
|
|
1999
|
+
const lexicalPath = resolve2(path);
|
|
2000
|
+
const lexicalProtectedPath = resolve2(protectedPath);
|
|
2001
|
+
const canonicalRoot = await realpath(root);
|
|
2002
|
+
const canonicalPath = await canonicalizePotentialPath(path);
|
|
2003
|
+
const canonicalProtectedPath = await realpath(protectedPath);
|
|
2004
|
+
if (!isStrictSubdirectory(canonicalRoot, canonicalPath) || isPathWithinOrEqual(lexicalPath, lexicalProtectedPath) || isPathWithinOrEqual(canonicalPath, canonicalProtectedPath)) {
|
|
2005
|
+
throw new Error(errorMessage);
|
|
2006
|
+
}
|
|
2007
|
+
} catch {
|
|
2008
|
+
throw new Error(errorMessage);
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
async function canonicalizePotentialPath(path) {
|
|
2012
|
+
const ancestor = await findExistingAncestor(path);
|
|
2013
|
+
const canonicalAncestor = await realpath(ancestor);
|
|
2014
|
+
return resolve2(canonicalAncestor, relative(ancestor, path));
|
|
2015
|
+
}
|
|
2016
|
+
async function findExistingAncestor(path) {
|
|
2017
|
+
let candidate = path;
|
|
2018
|
+
while (candidate !== dirname(candidate)) {
|
|
2019
|
+
try {
|
|
2020
|
+
await lstat(candidate);
|
|
2021
|
+
return candidate;
|
|
2022
|
+
} catch (error) {
|
|
2023
|
+
if (!isMissingPathError(error)) {
|
|
2024
|
+
throw error;
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
candidate = dirname(candidate);
|
|
2028
|
+
}
|
|
2029
|
+
await lstat(candidate);
|
|
2030
|
+
return candidate;
|
|
2031
|
+
}
|
|
2032
|
+
function isMissingPathError(error) {
|
|
2033
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
2034
|
+
}
|
|
2035
|
+
function isStrictSubdirectory(root, path) {
|
|
2036
|
+
const pathFromRoot = relative(root, path);
|
|
2037
|
+
return pathFromRoot !== "" && pathFromRoot !== ".." && !pathFromRoot.startsWith(`..${sep}`) && !isAbsolute(pathFromRoot);
|
|
2038
|
+
}
|
|
2039
|
+
function isPathWithinOrEqual(parent, candidate) {
|
|
2040
|
+
const pathFromParent = relative(parent, candidate);
|
|
2041
|
+
return pathFromParent === "" || pathFromParent !== ".." && !pathFromParent.startsWith(`..${sep}`) && !isAbsolute(pathFromParent);
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
// src/build.ts
|
|
2045
|
+
var INVALID_OUTPUT_DIRECTORY_MESSAGE = "Build output must be a subdirectory of the project root";
|
|
2046
|
+
async function build(options = {}) {
|
|
2047
|
+
const config = await resolveConfig(options);
|
|
2048
|
+
for (const entry of Object.values(config.pages)) {
|
|
2049
|
+
await assertSafeSubdirectoryDoesNotContain(config.root, config.build.outDir, entry, INVALID_OUTPUT_DIRECTORY_MESSAGE);
|
|
2050
|
+
}
|
|
2051
|
+
for (const entry of Object.values(config.pages)) {
|
|
2052
|
+
await renderProjectHtml(config, {}, entry);
|
|
2053
|
+
}
|
|
2054
|
+
await rm(config.build.outDir, { recursive: true, force: true });
|
|
2055
|
+
await mkdir(config.build.outDir, { recursive: true });
|
|
2056
|
+
const pages = [];
|
|
2057
|
+
const failures = [];
|
|
2058
|
+
for (const [route, entry] of Object.entries(config.pages)) {
|
|
2059
|
+
const built = await buildPage(config, route, entry);
|
|
2060
|
+
if (typeof built === "string") {
|
|
2061
|
+
failures.push(built);
|
|
2062
|
+
continue;
|
|
2063
|
+
}
|
|
2064
|
+
pages.push(built);
|
|
2065
|
+
}
|
|
2066
|
+
if (failures.length > 0) {
|
|
2067
|
+
throw buildFailure(failures);
|
|
2068
|
+
}
|
|
2069
|
+
const assetsBuilt = [];
|
|
2070
|
+
for (const page of pages) {
|
|
2071
|
+
const html = await renderProjectHtml(config, {
|
|
2072
|
+
head: page.stylesheetAssets.map((asset) => ({
|
|
2073
|
+
tag: "link",
|
|
2074
|
+
attributes: {
|
|
2075
|
+
rel: "stylesheet",
|
|
2076
|
+
href: toAssetUrl(config.build.outDir, htmlPath(config, page.route), asset)
|
|
2077
|
+
}
|
|
2078
|
+
})),
|
|
2079
|
+
scripts: page.javascriptAssets.map((asset) => ({
|
|
2080
|
+
type: "module",
|
|
2081
|
+
src: toAssetUrl(config.build.outDir, htmlPath(config, page.route), asset)
|
|
2082
|
+
}))
|
|
2083
|
+
}, page.entry);
|
|
2084
|
+
const pageHtmlPath = htmlPath(config, page.route);
|
|
2085
|
+
await mkdir(dirname2(pageHtmlPath), { recursive: true });
|
|
2086
|
+
await writeFile(pageHtmlPath, html);
|
|
2087
|
+
assetsBuilt.push(...page.assets, pageHtmlPath);
|
|
2088
|
+
}
|
|
2089
|
+
return {
|
|
2090
|
+
root: config.root,
|
|
2091
|
+
outDir: config.build.outDir,
|
|
2092
|
+
assetsBuilt
|
|
2093
|
+
};
|
|
2094
|
+
}
|
|
2095
|
+
async function buildPage(config, route, entry) {
|
|
2096
|
+
let result;
|
|
2097
|
+
try {
|
|
2098
|
+
result = await Bun.build({
|
|
2099
|
+
entrypoints: [entry],
|
|
2100
|
+
outdir: config.build.outDir,
|
|
2101
|
+
target: "browser",
|
|
2102
|
+
format: "esm",
|
|
2103
|
+
minify: process.env.TSONE_MINIFY !== "0",
|
|
2104
|
+
naming: { entry: "[name].[ext]", chunk: "[name]-[hash].[ext]" },
|
|
2105
|
+
throw: false
|
|
2106
|
+
});
|
|
2107
|
+
} catch (error) {
|
|
2108
|
+
return pageFailureReason(route, [errorMessage(error)]);
|
|
2109
|
+
}
|
|
2110
|
+
const assets = result.outputs.map((output) => resolve3(output.path));
|
|
2111
|
+
const javascriptAssets = result.outputs.filter(isEntryJavaScriptOutput).map((output) => resolve3(output.path));
|
|
2112
|
+
const stylesheetAssets = result.outputs.filter(isStylesheetOutput).map((output) => resolve3(output.path));
|
|
2113
|
+
if (!result.success || assets.length === 0 || javascriptAssets.length === 0) {
|
|
2114
|
+
return pageFailureReason(route, result.logs.map((log) => log.message), {
|
|
2115
|
+
success: result.success,
|
|
2116
|
+
hasOutput: assets.length > 0,
|
|
2117
|
+
hasJavaScript: javascriptAssets.length > 0
|
|
2118
|
+
});
|
|
2119
|
+
}
|
|
2120
|
+
return {
|
|
2121
|
+
route,
|
|
2122
|
+
entry,
|
|
2123
|
+
assets,
|
|
2124
|
+
javascriptAssets,
|
|
2125
|
+
stylesheetAssets
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2128
|
+
function pageFailureReason(route, logs, state) {
|
|
2129
|
+
const pageContext = route === "/" ? "" : `Page ${route}: `;
|
|
2130
|
+
const reasons = [
|
|
2131
|
+
state && !state.success ? "Bun build reported failure" : "",
|
|
2132
|
+
state && !state.hasOutput ? "Bun emitted no output files" : "",
|
|
2133
|
+
state && !state.hasJavaScript ? "Bun emitted no JavaScript output" : "",
|
|
2134
|
+
...logs
|
|
2135
|
+
].filter((reason) => reason !== "");
|
|
2136
|
+
return `${pageContext}${reasons.join(`
|
|
2137
|
+
`)}`;
|
|
2138
|
+
}
|
|
2139
|
+
function buildFailure(failures) {
|
|
2140
|
+
if (failures.length === 1) {
|
|
2141
|
+
return new Error(`Failed to build TSone application: ${failures[0]}`);
|
|
2142
|
+
}
|
|
2143
|
+
return new Error(`Failed to build TSone application:
|
|
2144
|
+
${failures.map((failure) => `- ${failure}`).join(`
|
|
2145
|
+
`)}`);
|
|
2146
|
+
}
|
|
2147
|
+
function htmlPath(config, route) {
|
|
2148
|
+
if (route === "/") {
|
|
2149
|
+
return resolve3(config.build.outDir, "index.html");
|
|
2150
|
+
}
|
|
2151
|
+
return resolve3(config.build.outDir, `${route.replace(/^\/+/, "")}.html`);
|
|
2152
|
+
}
|
|
2153
|
+
function toAssetUrl(outDir, fromHtmlFile, asset) {
|
|
2154
|
+
const fromOutDir = relative2(outDir, asset).split(sep2).join("/");
|
|
2155
|
+
if (fromOutDir === "" || fromOutDir === ".." || fromOutDir.startsWith("../") || isAbsolute2(fromOutDir)) {
|
|
2156
|
+
throw new Error(`Build asset must be inside the output directory: ${asset}`);
|
|
2157
|
+
}
|
|
2158
|
+
const fromHtmlDir = dirname2(fromHtmlFile);
|
|
2159
|
+
const assetPath = relative2(fromHtmlDir, asset).split(sep2).join("/");
|
|
2160
|
+
return `./${assetPath}`;
|
|
2161
|
+
}
|
|
2162
|
+
function errorMessage(error) {
|
|
2163
|
+
return error instanceof Error ? error.message : String(error);
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
// src/create.ts
|
|
2167
|
+
import { existsSync as existsSync2, mkdirSync, writeFileSync } from "fs";
|
|
2168
|
+
import { basename, join } from "path";
|
|
2169
|
+
var TSONE_FRAMEWORK_VERSION = "0.2.1";
|
|
2170
|
+
var TSONE_CLI_VERSION = "0.2.2";
|
|
2171
|
+
var GITHUB_URL = "https://github.com/geektech-team/tsone";
|
|
2172
|
+
function createProject(options = {}) {
|
|
2173
|
+
const root = options.root ?? process.cwd();
|
|
2174
|
+
const name = options.name ?? basename(root);
|
|
2175
|
+
const files = scaffoldFiles(name);
|
|
2176
|
+
const existing = files.filter((file) => existsSync2(join(root, file.path)));
|
|
2177
|
+
if (existing.length > 0) {
|
|
2178
|
+
throw new Error(`Refusing to overwrite existing TSone project files: ${existing.map((file) => file.path).join(", ")}`);
|
|
2179
|
+
}
|
|
2180
|
+
mkdirSync(join(root, "src"), { recursive: true });
|
|
2181
|
+
const created = [];
|
|
2182
|
+
for (const file of files) {
|
|
2183
|
+
writeFileSync(join(root, file.path), file.content, "utf8");
|
|
2184
|
+
created.push(file.path);
|
|
2185
|
+
}
|
|
2186
|
+
return { root, files: created };
|
|
2187
|
+
}
|
|
2188
|
+
function scaffoldFiles(name) {
|
|
2189
|
+
return [
|
|
2190
|
+
{
|
|
2191
|
+
path: "package.json",
|
|
2192
|
+
content: `${JSON.stringify({
|
|
2193
|
+
name,
|
|
2194
|
+
private: true,
|
|
2195
|
+
type: "module",
|
|
2196
|
+
scripts: {
|
|
2197
|
+
dev: "tsone dev",
|
|
2198
|
+
build: "tsone build",
|
|
2199
|
+
typecheck: "bunx tsc --noEmit"
|
|
2200
|
+
},
|
|
2201
|
+
dependencies: {
|
|
2202
|
+
"@geektech/tsone": `^${TSONE_FRAMEWORK_VERSION}`
|
|
2203
|
+
},
|
|
2204
|
+
devDependencies: {
|
|
2205
|
+
"@geektech/tsone-cli": `^${TSONE_CLI_VERSION}`
|
|
2206
|
+
}
|
|
2207
|
+
}, null, 2)}
|
|
2208
|
+
`
|
|
2209
|
+
},
|
|
2210
|
+
{
|
|
2211
|
+
path: "tsone.config.ts",
|
|
2212
|
+
content: `import { defineConfig } from '@geektech/tsone-cli';
|
|
2213
|
+
|
|
2214
|
+
export default defineConfig({
|
|
2215
|
+
entry: 'src/main.ts',
|
|
2216
|
+
});
|
|
2217
|
+
`
|
|
2218
|
+
},
|
|
2219
|
+
{
|
|
2220
|
+
path: "tsconfig.json",
|
|
2221
|
+
content: `${JSON.stringify({
|
|
2222
|
+
compilerOptions: {
|
|
2223
|
+
target: "ESNext",
|
|
2224
|
+
module: "ESNext",
|
|
2225
|
+
moduleResolution: "Bundler",
|
|
2226
|
+
lib: ["ESNext", "DOM", "DOM.Iterable"],
|
|
2227
|
+
strict: true,
|
|
2228
|
+
noEmit: true,
|
|
2229
|
+
skipLibCheck: true,
|
|
2230
|
+
verbatimModuleSyntax: true
|
|
2231
|
+
},
|
|
2232
|
+
include: ["src/**/*", "tsone.config.ts"]
|
|
2233
|
+
}, null, 2)}
|
|
2234
|
+
`
|
|
2235
|
+
},
|
|
2236
|
+
{
|
|
2237
|
+
path: ".gitignore",
|
|
2238
|
+
content: `node_modules/
|
|
2239
|
+
dist/
|
|
2240
|
+
.tsone/
|
|
2241
|
+
`
|
|
2242
|
+
},
|
|
2243
|
+
{
|
|
2244
|
+
path: "src/main.ts",
|
|
2245
|
+
content: `import { Component, createApp, h, type VNode } from '@geektech/tsone';
|
|
2246
|
+
|
|
2247
|
+
class App extends Component<object, object> {
|
|
2248
|
+
protected initState(): object {
|
|
2249
|
+
return {};
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
protected initStyles(): void {
|
|
2253
|
+
this.styleManager.addStyle('app-body', {
|
|
2254
|
+
selector: 'body',
|
|
2255
|
+
properties: {
|
|
2256
|
+
margin: 0,
|
|
2257
|
+
background: '#f7fbf6',
|
|
2258
|
+
color: '#142216',
|
|
2259
|
+
fontFamily:
|
|
2260
|
+
"ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif",
|
|
2261
|
+
},
|
|
2262
|
+
});
|
|
2263
|
+
this.styleManager.addStyle('app-shell', {
|
|
2264
|
+
selector: '.app-shell',
|
|
2265
|
+
properties: {
|
|
2266
|
+
alignItems: 'center',
|
|
2267
|
+
display: 'flex',
|
|
2268
|
+
flexDirection: 'column',
|
|
2269
|
+
gap: '14px',
|
|
2270
|
+
justifyContent: 'center',
|
|
2271
|
+
minHeight: '100vh',
|
|
2272
|
+
},
|
|
2273
|
+
});
|
|
2274
|
+
this.styleManager.addStyle('app-title', {
|
|
2275
|
+
selector: '.app-title',
|
|
2276
|
+
properties: {
|
|
2277
|
+
fontSize: '64px',
|
|
2278
|
+
letterSpacing: 0,
|
|
2279
|
+
lineHeight: 1.05,
|
|
2280
|
+
margin: 0,
|
|
2281
|
+
},
|
|
2282
|
+
});
|
|
2283
|
+
this.styleManager.addStyle('app-link', {
|
|
2284
|
+
selector: '.app-link',
|
|
2285
|
+
properties: {
|
|
2286
|
+
color: '#2f7c39',
|
|
2287
|
+
fontSize: '16px',
|
|
2288
|
+
textDecoration: 'none',
|
|
2289
|
+
},
|
|
2290
|
+
hover: {
|
|
2291
|
+
textDecoration: 'underline',
|
|
2292
|
+
},
|
|
2293
|
+
});
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
protected render(): VNode {
|
|
2297
|
+
return h('main', { className: 'app-shell' }, [
|
|
2298
|
+
h('h1', { className: 'app-title' }, ['TSone']),
|
|
2299
|
+
h(
|
|
2300
|
+
'a',
|
|
2301
|
+
{ className: 'app-link', href: '${GITHUB_URL}' },
|
|
2302
|
+
['GitHub']
|
|
2303
|
+
),
|
|
2304
|
+
]);
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
export const app = createApp({
|
|
2309
|
+
root: App,
|
|
2310
|
+
document: {
|
|
2311
|
+
lang: 'zh-CN',
|
|
2312
|
+
title: 'TSone',
|
|
2313
|
+
description: '\u8F7B\u91CF\u7EA7\u7EAF TypeScript \u524D\u7AEF\u6846\u67B6',
|
|
2314
|
+
},
|
|
2315
|
+
});
|
|
2316
|
+
|
|
2317
|
+
app.mount();
|
|
2318
|
+
`
|
|
2319
|
+
}
|
|
2320
|
+
];
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
// src/server.ts
|
|
2324
|
+
import { randomUUID } from "crypto";
|
|
2325
|
+
import {
|
|
2326
|
+
basename as basename2,
|
|
2327
|
+
extname,
|
|
2328
|
+
isAbsolute as isAbsolute4,
|
|
2329
|
+
relative as relative4,
|
|
2330
|
+
resolve as resolve4,
|
|
2331
|
+
sep as sep3
|
|
2332
|
+
} from "path";
|
|
2333
|
+
|
|
2334
|
+
// src/proxy.ts
|
|
2335
|
+
var HOP_BY_HOP_HEADERS = new Set([
|
|
2336
|
+
"connection",
|
|
2337
|
+
"keep-alive",
|
|
2338
|
+
"proxy-authenticate",
|
|
2339
|
+
"proxy-authorization",
|
|
2340
|
+
"te",
|
|
2341
|
+
"trailer",
|
|
2342
|
+
"transfer-encoding",
|
|
2343
|
+
"upgrade"
|
|
2344
|
+
]);
|
|
2345
|
+
function createProxyHandler(proxy) {
|
|
2346
|
+
const rules = Object.entries(proxy ?? {}).map(([prefix, options]) => toProxyRule(prefix, options)).sort((first, second) => second.prefix.length - first.prefix.length);
|
|
2347
|
+
return async (request) => {
|
|
2348
|
+
const sourceUrl = new URL(request.url);
|
|
2349
|
+
const rule = rules.find(({ prefix }) => sourceUrl.pathname.startsWith(prefix));
|
|
2350
|
+
if (!rule) {
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
2353
|
+
const target = createTargetUrl(rule, sourceUrl);
|
|
2354
|
+
const headers = createRequestHeaders(request, sourceUrl, rule, target);
|
|
2355
|
+
const body = request.method === "GET" || request.method === "HEAD" ? undefined : request.body;
|
|
2356
|
+
try {
|
|
2357
|
+
const upstream = await fetch(target, {
|
|
2358
|
+
method: request.method,
|
|
2359
|
+
headers,
|
|
2360
|
+
body,
|
|
2361
|
+
signal: request.signal,
|
|
2362
|
+
redirect: "manual"
|
|
2363
|
+
});
|
|
2364
|
+
return new Response(upstream.body, {
|
|
2365
|
+
status: upstream.status,
|
|
2366
|
+
statusText: upstream.statusText,
|
|
2367
|
+
headers: filterHeaders(upstream.headers)
|
|
2368
|
+
});
|
|
2369
|
+
} catch {
|
|
2370
|
+
return new Response("Bad Gateway", { status: 502 });
|
|
2371
|
+
}
|
|
2372
|
+
};
|
|
2373
|
+
}
|
|
2374
|
+
function toProxyRule(prefix, value) {
|
|
2375
|
+
const options = typeof value === "string" ? { target: value } : value;
|
|
2376
|
+
return {
|
|
2377
|
+
prefix,
|
|
2378
|
+
target: new URL(options.target),
|
|
2379
|
+
changeOrigin: options.changeOrigin ?? false,
|
|
2380
|
+
...options.rewrite === undefined ? {} : { rewrite: options.rewrite }
|
|
2381
|
+
};
|
|
2382
|
+
}
|
|
2383
|
+
function createTargetUrl(rule, sourceUrl) {
|
|
2384
|
+
const target = new URL(rule.target);
|
|
2385
|
+
const pathname = rule.rewrite?.(sourceUrl.pathname) ?? sourceUrl.pathname;
|
|
2386
|
+
target.pathname = joinPathnames(target.pathname, pathname);
|
|
2387
|
+
target.search = sourceUrl.search;
|
|
2388
|
+
return target;
|
|
2389
|
+
}
|
|
2390
|
+
function joinPathnames(basePathname, pathname) {
|
|
2391
|
+
const base = basePathname === "/" ? "" : basePathname.replace(/\/+$/, "");
|
|
2392
|
+
const path = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
2393
|
+
return `${base}${path}` || "/";
|
|
2394
|
+
}
|
|
2395
|
+
function createRequestHeaders(request, sourceUrl, rule, target) {
|
|
2396
|
+
const headers = filterHeaders(request.headers);
|
|
2397
|
+
const incomingHost = request.headers.get("host") ?? sourceUrl.host;
|
|
2398
|
+
headers.set("host", rule.changeOrigin ? target.host : incomingHost);
|
|
2399
|
+
return headers;
|
|
2400
|
+
}
|
|
2401
|
+
function filterHeaders(source) {
|
|
2402
|
+
const headers = new Headers(source);
|
|
2403
|
+
const connection = headers.get("connection");
|
|
2404
|
+
if (connection) {
|
|
2405
|
+
connection.split(",").forEach((header) => {
|
|
2406
|
+
const name = header.trim();
|
|
2407
|
+
if (name) {
|
|
2408
|
+
headers.delete(name);
|
|
2409
|
+
}
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
HOP_BY_HOP_HEADERS.forEach((header) => headers.delete(header));
|
|
2413
|
+
return headers;
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
// src/watch.ts
|
|
2417
|
+
import { watch } from "fs";
|
|
2418
|
+
import { readdir, stat } from "fs/promises";
|
|
2419
|
+
import { isAbsolute as isAbsolute3, join as join2, relative as relative3 } from "path";
|
|
2420
|
+
var RECURSIVE_WATCH_UNSUPPORTED_ERROR = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
|
|
2421
|
+
var DEFAULT_DEBOUNCE_MS = 100;
|
|
2422
|
+
var DEFAULT_POLL_INTERVAL_MS = 300;
|
|
2423
|
+
function createFileWatcher(options) {
|
|
2424
|
+
const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
2425
|
+
let timer;
|
|
2426
|
+
const disposers = [];
|
|
2427
|
+
const scheduleChange = (relativePath) => {
|
|
2428
|
+
if (timer) {
|
|
2429
|
+
clearTimeout(timer);
|
|
2430
|
+
}
|
|
2431
|
+
timer = setTimeout(() => {
|
|
2432
|
+
timer = undefined;
|
|
2433
|
+
options.onChange(relativePath);
|
|
2434
|
+
}, debounceMs);
|
|
2435
|
+
};
|
|
2436
|
+
disposers.push(() => {
|
|
2437
|
+
if (timer) {
|
|
2438
|
+
clearTimeout(timer);
|
|
2439
|
+
}
|
|
2440
|
+
});
|
|
2441
|
+
const nativeWatcher = tryCreateNativeWatcher(options.root, options.isRelevant, scheduleChange);
|
|
2442
|
+
if (nativeWatcher) {
|
|
2443
|
+
disposers.push(nativeWatcher);
|
|
2444
|
+
} else {
|
|
2445
|
+
disposers.push(createPollingWatcher(options.root, options.isRelevant, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS, scheduleChange));
|
|
2446
|
+
}
|
|
2447
|
+
return {
|
|
2448
|
+
dispose: () => {
|
|
2449
|
+
disposers.splice(0).reverse().forEach((dispose) => dispose());
|
|
2450
|
+
}
|
|
2451
|
+
};
|
|
2452
|
+
}
|
|
2453
|
+
function tryCreateNativeWatcher(root, isRelevant, onRelevantChange) {
|
|
2454
|
+
let watcher;
|
|
2455
|
+
try {
|
|
2456
|
+
watcher = watch(root, { recursive: true }, (_event, filename) => {
|
|
2457
|
+
if (typeof filename !== "string") {
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
const relativePath = toRelativePath(root, filename);
|
|
2461
|
+
if (relativePath === undefined || !isRelevant(relativePath)) {
|
|
2462
|
+
return;
|
|
2463
|
+
}
|
|
2464
|
+
onRelevantChange(relativePath);
|
|
2465
|
+
});
|
|
2466
|
+
} catch (error) {
|
|
2467
|
+
if (isRecursiveWatchUnsupported(error)) {
|
|
2468
|
+
return;
|
|
2469
|
+
}
|
|
2470
|
+
throw error;
|
|
2471
|
+
}
|
|
2472
|
+
return () => watcher.close();
|
|
2473
|
+
}
|
|
2474
|
+
function createPollingWatcher(root, isRelevant, intervalMs, onRelevantChange) {
|
|
2475
|
+
let running = true;
|
|
2476
|
+
let snapshot = new Map;
|
|
2477
|
+
let timer;
|
|
2478
|
+
const scan = async () => {
|
|
2479
|
+
if (!running) {
|
|
2480
|
+
return;
|
|
2481
|
+
}
|
|
2482
|
+
const next = new Map;
|
|
2483
|
+
try {
|
|
2484
|
+
await collectRelevantFiles(root, isRelevant, next);
|
|
2485
|
+
} catch {
|
|
2486
|
+
return;
|
|
2487
|
+
}
|
|
2488
|
+
let changedPath;
|
|
2489
|
+
for (const [relativePath, snapshotEntry] of next) {
|
|
2490
|
+
const previous = snapshot.get(relativePath);
|
|
2491
|
+
if (!previous || previous.mtimeMs !== snapshotEntry.mtimeMs || previous.size !== snapshotEntry.size) {
|
|
2492
|
+
changedPath = relativePath;
|
|
2493
|
+
break;
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
if (changedPath === undefined) {
|
|
2497
|
+
for (const relativePath of snapshot.keys()) {
|
|
2498
|
+
if (!next.has(relativePath)) {
|
|
2499
|
+
changedPath = relativePath;
|
|
2500
|
+
break;
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
snapshot = next;
|
|
2505
|
+
if (changedPath !== undefined) {
|
|
2506
|
+
onRelevantChange(changedPath);
|
|
2507
|
+
}
|
|
2508
|
+
};
|
|
2509
|
+
scan();
|
|
2510
|
+
timer = setInterval(() => {
|
|
2511
|
+
scan();
|
|
2512
|
+
}, intervalMs);
|
|
2513
|
+
if (typeof timer.unref === "function") {
|
|
2514
|
+
timer.unref();
|
|
2515
|
+
}
|
|
2516
|
+
return () => {
|
|
2517
|
+
running = false;
|
|
2518
|
+
if (timer) {
|
|
2519
|
+
clearInterval(timer);
|
|
2520
|
+
}
|
|
2521
|
+
};
|
|
2522
|
+
}
|
|
2523
|
+
async function collectRelevantFiles(root, isRelevant, output) {
|
|
2524
|
+
const pendingDirectories = [""];
|
|
2525
|
+
while (pendingDirectories.length > 0) {
|
|
2526
|
+
const relativeDirectory = pendingDirectories.pop();
|
|
2527
|
+
if (relativeDirectory === undefined) {
|
|
2528
|
+
break;
|
|
2529
|
+
}
|
|
2530
|
+
const absoluteDirectory = join2(root, relativeDirectory);
|
|
2531
|
+
let entries;
|
|
2532
|
+
try {
|
|
2533
|
+
entries = await readdir(absoluteDirectory, { withFileTypes: true });
|
|
2534
|
+
} catch {
|
|
2535
|
+
continue;
|
|
2536
|
+
}
|
|
2537
|
+
for (const entry of entries) {
|
|
2538
|
+
const relativePath = relativeDirectory === "" ? entry.name : `${relativeDirectory}/${entry.name}`;
|
|
2539
|
+
if (entry.isDirectory()) {
|
|
2540
|
+
pendingDirectories.push(relativePath);
|
|
2541
|
+
continue;
|
|
2542
|
+
}
|
|
2543
|
+
if (!entry.isFile() || !isRelevant(relativePath)) {
|
|
2544
|
+
continue;
|
|
2545
|
+
}
|
|
2546
|
+
try {
|
|
2547
|
+
const info = await stat(join2(root, relativePath));
|
|
2548
|
+
output.set(relativePath, { mtimeMs: info.mtimeMs, size: info.size });
|
|
2549
|
+
} catch {}
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
function toRelativePath(root, filename) {
|
|
2554
|
+
const relativePath = isAbsolute3(filename) ? relative3(root, filename) : filename.split("\\").join("/");
|
|
2555
|
+
if (relativePath === "" || relativePath === ".." || relativePath.startsWith("../")) {
|
|
2556
|
+
return;
|
|
2557
|
+
}
|
|
2558
|
+
return relativePath.split("\\").join("/");
|
|
2559
|
+
}
|
|
2560
|
+
function isRecursiveWatchUnsupported(error) {
|
|
2561
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === RECURSIVE_WATCH_UNSUPPORTED_ERROR;
|
|
2562
|
+
}
|
|
2563
|
+
|
|
2564
|
+
// src/server.ts
|
|
2565
|
+
var DEVELOPMENT_URL_PREFIX = "/dev";
|
|
2566
|
+
var INVALID_DEVELOPMENT_DIRECTORY_MESSAGE = "Development output must be a subdirectory of the project root";
|
|
2567
|
+
var LIVE_RELOAD_PATH = "/__tsone/reload";
|
|
2568
|
+
var WATCHED_EXTENSIONS = new Set([
|
|
2569
|
+
".ts",
|
|
2570
|
+
".js",
|
|
2571
|
+
".mjs",
|
|
2572
|
+
".cjs",
|
|
2573
|
+
".json",
|
|
2574
|
+
".css",
|
|
2575
|
+
".html"
|
|
2576
|
+
]);
|
|
2577
|
+
var IGNORED_WATCH_SEGMENTS = new Set([
|
|
2578
|
+
".tsone",
|
|
2579
|
+
"node_modules",
|
|
2580
|
+
".git",
|
|
2581
|
+
".worktrees"
|
|
2582
|
+
]);
|
|
2583
|
+
var LIVE_RELOAD_CLIENT_SCRIPT = [
|
|
2584
|
+
'<script type="module">',
|
|
2585
|
+
"const tsoneReloadSource=new EventSource(",
|
|
2586
|
+
JSON.stringify(LIVE_RELOAD_PATH),
|
|
2587
|
+
");",
|
|
2588
|
+
'tsoneReloadSource.addEventListener("reload",()=>location.reload());',
|
|
2589
|
+
"</script>"
|
|
2590
|
+
].join("");
|
|
2591
|
+
async function startDevServer(options = {}) {
|
|
2592
|
+
if (options.watch) {
|
|
2593
|
+
return startWatchingDevServer(options);
|
|
2594
|
+
}
|
|
2595
|
+
const instance = await createServerInstance(options, false);
|
|
2596
|
+
return instance.server;
|
|
2597
|
+
}
|
|
2598
|
+
async function startWatchingDevServer(options) {
|
|
2599
|
+
let instance = await createServerInstance(options, true);
|
|
2600
|
+
let watcher = createProjectWatcher(instance, onChange);
|
|
2601
|
+
async function onChange(changedPath) {
|
|
2602
|
+
const configFile = instance.config.configFile;
|
|
2603
|
+
const configRelativePath = configFile === undefined ? undefined : toRelativePath2(instance.config.root, configFile);
|
|
2604
|
+
if (configRelativePath === changedPath) {
|
|
2605
|
+
await restart();
|
|
2606
|
+
return;
|
|
2607
|
+
}
|
|
2608
|
+
await rebuildAndReload();
|
|
2609
|
+
}
|
|
2610
|
+
async function rebuildAndReload() {
|
|
2611
|
+
const routes = Object.keys(instance.config.pages);
|
|
2612
|
+
instance.markDirty(routes);
|
|
2613
|
+
for (const route of routes) {
|
|
2614
|
+
const bundle = await instance.getBundle(route);
|
|
2615
|
+
if (bundle instanceof Response) {
|
|
2616
|
+
console.error("TSone rebuild failed; keeping the last working page.");
|
|
2617
|
+
return;
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
instance.liveReload?.broadcast();
|
|
2621
|
+
}
|
|
2622
|
+
async function restart() {
|
|
2623
|
+
watcher.dispose();
|
|
2624
|
+
instance.server.stop(true);
|
|
2625
|
+
instance = await createServerInstance(options, true);
|
|
2626
|
+
watcher = createProjectWatcher(instance, onChange);
|
|
2627
|
+
console.log(`TSone dev server restarted at http://${instance.server.hostname}:${instance.server.port}`);
|
|
2628
|
+
}
|
|
2629
|
+
return createServerHandle(() => instance, () => watcher.dispose());
|
|
2630
|
+
}
|
|
2631
|
+
function createProjectWatcher(instance, onChange) {
|
|
2632
|
+
return createFileWatcher({
|
|
2633
|
+
root: instance.config.root,
|
|
2634
|
+
isRelevant: (relativePath) => isWatchedFile(instance, relativePath),
|
|
2635
|
+
onChange: (changedPath) => {
|
|
2636
|
+
onChange(changedPath);
|
|
2637
|
+
}
|
|
2638
|
+
});
|
|
2639
|
+
}
|
|
2640
|
+
async function createServerInstance(options, watch2) {
|
|
2641
|
+
const config = await resolveConfig(options);
|
|
2642
|
+
for (const entry of Object.values(config.pages)) {
|
|
2643
|
+
await renderProjectHtml(config, {}, entry);
|
|
2644
|
+
}
|
|
2645
|
+
const developmentOutDir = resolve4(config.root, ".tsone", "dev");
|
|
2646
|
+
await assertSafeSubdirectory(config.root, developmentOutDir, INVALID_DEVELOPMENT_DIRECTORY_MESSAGE);
|
|
2647
|
+
const proxy = createProxyHandler(config.server.proxy);
|
|
2648
|
+
const sessionId = createGenerationId();
|
|
2649
|
+
const sessionOutDir = resolve4(developmentOutDir, sessionId);
|
|
2650
|
+
const artifacts = new Map;
|
|
2651
|
+
const buildProject = createDevelopmentBuilder(config, sessionId, sessionOutDir);
|
|
2652
|
+
const liveReload = watch2 ? createLiveReloadHub() : undefined;
|
|
2653
|
+
const bundles = new Map;
|
|
2654
|
+
const dirtyRoutes = new Set;
|
|
2655
|
+
const getBundle = async (route) => {
|
|
2656
|
+
const cached = bundles.get(route);
|
|
2657
|
+
if (watch2 && cached !== undefined && !dirtyRoutes.has(route)) {
|
|
2658
|
+
return cached;
|
|
2659
|
+
}
|
|
2660
|
+
const bundle = await buildProject(route);
|
|
2661
|
+
if (bundle instanceof Response) {
|
|
2662
|
+
if (watch2) {
|
|
2663
|
+
dirtyRoutes.add(route);
|
|
2664
|
+
}
|
|
2665
|
+
return bundle;
|
|
2666
|
+
}
|
|
2667
|
+
if (watch2) {
|
|
2668
|
+
bundles.set(route, bundle);
|
|
2669
|
+
dirtyRoutes.delete(route);
|
|
2670
|
+
}
|
|
2671
|
+
return bundle;
|
|
2672
|
+
};
|
|
2673
|
+
const server = Bun.serve({
|
|
2674
|
+
hostname: config.server.host,
|
|
2675
|
+
port: config.server.port,
|
|
2676
|
+
fetch: async (request) => {
|
|
2677
|
+
const reloadResponse = liveReload?.handleRequest(request);
|
|
2678
|
+
if (reloadResponse) {
|
|
2679
|
+
return reloadResponse;
|
|
2680
|
+
}
|
|
2681
|
+
return await proxy(request) ?? serveProjectRequest(request, config, config.pages, getBundle, artifacts, liveReload);
|
|
2682
|
+
}
|
|
2683
|
+
});
|
|
2684
|
+
return {
|
|
2685
|
+
server,
|
|
2686
|
+
config,
|
|
2687
|
+
getBundle,
|
|
2688
|
+
markDirty: (routes) => {
|
|
2689
|
+
routes.forEach((route) => dirtyRoutes.add(route));
|
|
2690
|
+
},
|
|
2691
|
+
liveReload
|
|
2692
|
+
};
|
|
2693
|
+
}
|
|
2694
|
+
function createServerHandle(getInstance, disposeWatcher) {
|
|
2695
|
+
return new Proxy({}, {
|
|
2696
|
+
get(_target, property) {
|
|
2697
|
+
if (property === "stop") {
|
|
2698
|
+
return (closeActiveConnections) => {
|
|
2699
|
+
disposeWatcher();
|
|
2700
|
+
getInstance().server.stop(closeActiveConnections);
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
const server = getInstance().server;
|
|
2704
|
+
const value = server[property];
|
|
2705
|
+
return typeof value === "function" ? value.bind(server) : value;
|
|
2706
|
+
}
|
|
2707
|
+
});
|
|
2708
|
+
}
|
|
2709
|
+
async function serveProjectRequest(request, config, pages, getBundle, artifacts, liveReload) {
|
|
2710
|
+
const pathname = new URL(request.url).pathname;
|
|
2711
|
+
const route = pageRouteForPathname(pages, pathname);
|
|
2712
|
+
if (route !== undefined) {
|
|
2713
|
+
const bundle = await getBundle(route);
|
|
2714
|
+
if (bundle instanceof Response) {
|
|
2715
|
+
return bundle;
|
|
2716
|
+
}
|
|
2717
|
+
try {
|
|
2718
|
+
const html = await renderProjectHtml(config, {
|
|
2719
|
+
head: bundle.stylesheets.map(({ pathname: href }) => ({
|
|
2720
|
+
tag: "link",
|
|
2721
|
+
attributes: { rel: "stylesheet", href }
|
|
2722
|
+
})),
|
|
2723
|
+
scripts: [{ type: "module", src: bundle.entry.pathname }]
|
|
2724
|
+
}, pages[route]);
|
|
2725
|
+
publishDevelopmentBundle(bundle, artifacts);
|
|
2726
|
+
return new Response(liveReload ? injectLiveReloadScript(html) : html, {
|
|
2727
|
+
headers: {
|
|
2728
|
+
"content-type": "text/html; charset=utf-8",
|
|
2729
|
+
"cache-control": "no-store"
|
|
2730
|
+
}
|
|
2731
|
+
});
|
|
2732
|
+
} catch (error) {
|
|
2733
|
+
console.error(error);
|
|
2734
|
+
return buildFailureResponse();
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
if (pathname === "/bundle.js") {
|
|
2738
|
+
const bundle = await getBundle("/");
|
|
2739
|
+
if (bundle instanceof Response) {
|
|
2740
|
+
return bundle;
|
|
2741
|
+
}
|
|
2742
|
+
try {
|
|
2743
|
+
publishDevelopmentBundle(bundle, artifacts);
|
|
2744
|
+
return new Response(null, {
|
|
2745
|
+
status: 307,
|
|
2746
|
+
headers: {
|
|
2747
|
+
location: bundle.entry.pathname,
|
|
2748
|
+
"cache-control": "no-store"
|
|
2749
|
+
}
|
|
2750
|
+
});
|
|
2751
|
+
} catch (error) {
|
|
2752
|
+
console.error(error);
|
|
2753
|
+
return buildFailureResponse();
|
|
2754
|
+
}
|
|
2755
|
+
}
|
|
2756
|
+
const artifact = artifacts.get(pathname);
|
|
2757
|
+
if (artifact) {
|
|
2758
|
+
return new Response(Bun.file(artifact.filePath), {
|
|
2759
|
+
headers: {
|
|
2760
|
+
"content-type": artifact.type,
|
|
2761
|
+
"cache-control": "no-store"
|
|
2762
|
+
}
|
|
2763
|
+
});
|
|
2764
|
+
}
|
|
2765
|
+
return new Response("Not found", {
|
|
2766
|
+
status: 404,
|
|
2767
|
+
headers: { "cache-control": "no-store" }
|
|
2768
|
+
});
|
|
2769
|
+
}
|
|
2770
|
+
function pageRouteForPathname(pages, pathname) {
|
|
2771
|
+
if (pages[pathname] !== undefined) {
|
|
2772
|
+
return pathname;
|
|
2773
|
+
}
|
|
2774
|
+
if (pathname === "/index.html") {
|
|
2775
|
+
return "/";
|
|
2776
|
+
}
|
|
2777
|
+
const candidate = pathname.length > 1 && pathname.endsWith("/") ? pathname.replace(/\/+$/, "") : pathname;
|
|
2778
|
+
if (pages[candidate] !== undefined) {
|
|
2779
|
+
return candidate;
|
|
2780
|
+
}
|
|
2781
|
+
if (candidate.endsWith("/index.html")) {
|
|
2782
|
+
const base = candidate.slice(0, candidate.length - "/index.html".length);
|
|
2783
|
+
if (base === "") {
|
|
2784
|
+
return "/";
|
|
2785
|
+
}
|
|
2786
|
+
if (pages[base] !== undefined) {
|
|
2787
|
+
return base;
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
return;
|
|
2791
|
+
}
|
|
2792
|
+
function injectLiveReloadScript(html) {
|
|
2793
|
+
if (html.includes(LIVE_RELOAD_PATH)) {
|
|
2794
|
+
return html;
|
|
2795
|
+
}
|
|
2796
|
+
if (html.includes("</body>")) {
|
|
2797
|
+
return html.replace("</body>", `${LIVE_RELOAD_CLIENT_SCRIPT}</body>`);
|
|
2798
|
+
}
|
|
2799
|
+
return html + LIVE_RELOAD_CLIENT_SCRIPT;
|
|
2800
|
+
}
|
|
2801
|
+
var reloadEncoder = new TextEncoder;
|
|
2802
|
+
function createLiveReloadHub() {
|
|
2803
|
+
const controllers = new Set;
|
|
2804
|
+
function handleRequest(request) {
|
|
2805
|
+
if (new URL(request.url).pathname !== LIVE_RELOAD_PATH) {
|
|
2806
|
+
return;
|
|
2807
|
+
}
|
|
2808
|
+
let streamController;
|
|
2809
|
+
const stream = new ReadableStream({
|
|
2810
|
+
start: (controller) => {
|
|
2811
|
+
streamController = controller;
|
|
2812
|
+
controllers.add(controller);
|
|
2813
|
+
try {
|
|
2814
|
+
controller.enqueue(reloadEncoder.encode(`: connected
|
|
2815
|
+
|
|
2816
|
+
`));
|
|
2817
|
+
} catch {
|
|
2818
|
+
controllers.delete(controller);
|
|
2819
|
+
}
|
|
2820
|
+
},
|
|
2821
|
+
cancel: () => {
|
|
2822
|
+
if (streamController) {
|
|
2823
|
+
controllers.delete(streamController);
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
});
|
|
2827
|
+
return new Response(stream, {
|
|
2828
|
+
headers: {
|
|
2829
|
+
"content-type": "text/event-stream",
|
|
2830
|
+
"cache-control": "no-store"
|
|
2831
|
+
}
|
|
2832
|
+
});
|
|
2833
|
+
}
|
|
2834
|
+
function broadcast() {
|
|
2835
|
+
const message = reloadEncoder.encode(`event: reload
|
|
2836
|
+
data: {}
|
|
2837
|
+
|
|
2838
|
+
`);
|
|
2839
|
+
for (const controller of [...controllers]) {
|
|
2840
|
+
try {
|
|
2841
|
+
controller.enqueue(message);
|
|
2842
|
+
} catch {
|
|
2843
|
+
controllers.delete(controller);
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
return { handleRequest, broadcast };
|
|
2848
|
+
}
|
|
2849
|
+
function isWatchedFile(instance, relativePath) {
|
|
2850
|
+
if (relativePath === "" || relativePath.startsWith("..")) {
|
|
2851
|
+
return false;
|
|
2852
|
+
}
|
|
2853
|
+
const segments = relativePath.split("/");
|
|
2854
|
+
if (segments.some((segment) => IGNORED_WATCH_SEGMENTS.has(segment))) {
|
|
2855
|
+
return false;
|
|
2856
|
+
}
|
|
2857
|
+
const absolutePath = resolve4(instance.config.root, relativePath);
|
|
2858
|
+
if (isWithinOrEqual(instance.config.build.outDir, absolutePath)) {
|
|
2859
|
+
return false;
|
|
2860
|
+
}
|
|
2861
|
+
const base = basename2(absolutePath);
|
|
2862
|
+
if (base.startsWith(".") && absolutePath !== instance.config.configFile) {
|
|
2863
|
+
return false;
|
|
2864
|
+
}
|
|
2865
|
+
return WATCHED_EXTENSIONS.has(extname(base).toLowerCase());
|
|
2866
|
+
}
|
|
2867
|
+
function toRelativePath2(root, absolutePath) {
|
|
2868
|
+
return relative4(root, absolutePath).split(sep3).join("/");
|
|
2869
|
+
}
|
|
2870
|
+
function isWithinOrEqual(parent, candidate) {
|
|
2871
|
+
const pathFromParent = relative4(parent, candidate);
|
|
2872
|
+
return pathFromParent === "" || pathFromParent !== ".." && !pathFromParent.startsWith(`..${sep3}`) && !isAbsolute4(pathFromParent);
|
|
2873
|
+
}
|
|
2874
|
+
function createDevelopmentBuilder(config, sessionId, sessionOutDir) {
|
|
2875
|
+
let queue = Promise.resolve();
|
|
2876
|
+
return (route) => {
|
|
2877
|
+
const entry = config.pages[route];
|
|
2878
|
+
const result = queue.then(() => buildProjectBundle(entry, sessionId, sessionOutDir));
|
|
2879
|
+
queue = result.then(() => {
|
|
2880
|
+
return;
|
|
2881
|
+
}, () => {
|
|
2882
|
+
return;
|
|
2883
|
+
});
|
|
2884
|
+
return result;
|
|
2885
|
+
};
|
|
2886
|
+
}
|
|
2887
|
+
async function buildProjectBundle(entry, sessionId, sessionOutDir) {
|
|
2888
|
+
const generationId = createGenerationId();
|
|
2889
|
+
const generationOutDir = resolve4(sessionOutDir, generationId);
|
|
2890
|
+
const generationUrl = `${DEVELOPMENT_URL_PREFIX}/${sessionId}/${generationId}`;
|
|
2891
|
+
const buildOptions = {
|
|
2892
|
+
entrypoints: [entry],
|
|
2893
|
+
outdir: generationOutDir,
|
|
2894
|
+
target: "browser",
|
|
2895
|
+
format: "esm",
|
|
2896
|
+
sourcemap: "inline",
|
|
2897
|
+
write: true,
|
|
2898
|
+
throw: false,
|
|
2899
|
+
publicPath: `${generationUrl}/`,
|
|
2900
|
+
naming: {
|
|
2901
|
+
entry: "[name]-[hash].[ext]",
|
|
2902
|
+
chunk: "[name]-[hash].[ext]",
|
|
2903
|
+
asset: "assets/[name]-[hash].[ext]"
|
|
2904
|
+
}
|
|
2905
|
+
};
|
|
2906
|
+
try {
|
|
2907
|
+
const result = await Bun.build(buildOptions);
|
|
2908
|
+
const entryArtifact = result.outputs.find(isEntryJavaScriptOutput);
|
|
2909
|
+
if (!result.success || !entryArtifact) {
|
|
2910
|
+
result.logs.forEach((log) => console.error(log));
|
|
2911
|
+
if (!entryArtifact) {
|
|
2912
|
+
console.error("Failed to build project bundle: no JavaScript output");
|
|
2913
|
+
}
|
|
2914
|
+
return buildFailureResponse();
|
|
2915
|
+
}
|
|
2916
|
+
const pendingArtifacts = new Map;
|
|
2917
|
+
const outputs = new Map;
|
|
2918
|
+
for (const output of result.outputs) {
|
|
2919
|
+
const developmentOutput = createDevelopmentOutput(generationOutDir, generationUrl, output);
|
|
2920
|
+
if (pendingArtifacts.has(developmentOutput.pathname)) {
|
|
2921
|
+
throw new Error(`Development output URL collision: ${developmentOutput.pathname}`);
|
|
2922
|
+
}
|
|
2923
|
+
pendingArtifacts.set(developmentOutput.pathname, developmentOutput);
|
|
2924
|
+
outputs.set(output, developmentOutput);
|
|
2925
|
+
}
|
|
2926
|
+
const entry2 = outputs.get(entryArtifact);
|
|
2927
|
+
if (!entry2) {
|
|
2928
|
+
throw new Error("Development entry output was not indexed");
|
|
2929
|
+
}
|
|
2930
|
+
return {
|
|
2931
|
+
entry: entry2,
|
|
2932
|
+
stylesheets: result.outputs.filter(isStylesheetOutput).map((output) => outputs.get(output)).filter((output) => output !== undefined),
|
|
2933
|
+
artifacts: pendingArtifacts
|
|
2934
|
+
};
|
|
2935
|
+
} catch (error) {
|
|
2936
|
+
console.error(error);
|
|
2937
|
+
return buildFailureResponse();
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
function publishDevelopmentBundle(bundle, artifacts) {
|
|
2941
|
+
for (const [pathname, output] of bundle.artifacts) {
|
|
2942
|
+
const existing = artifacts.get(pathname);
|
|
2943
|
+
if (existing) {
|
|
2944
|
+
if (existing.filePath === output.filePath) {
|
|
2945
|
+
continue;
|
|
2946
|
+
}
|
|
2947
|
+
throw new Error(`Development output URL collision: ${pathname}`);
|
|
2948
|
+
}
|
|
2949
|
+
artifacts.set(pathname, output);
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
function createDevelopmentOutput(generationOutDir, generationUrl, output) {
|
|
2953
|
+
const filePath = resolve4(output.path);
|
|
2954
|
+
const pathFromGeneration = relative4(generationOutDir, filePath);
|
|
2955
|
+
if (pathFromGeneration === "" || pathFromGeneration === ".." || pathFromGeneration.startsWith(`..${sep3}`) || isAbsolute4(pathFromGeneration)) {
|
|
2956
|
+
throw new Error(`Development output must not escape outside its generation directory: ${output.path}`);
|
|
2957
|
+
}
|
|
2958
|
+
const urlPath = pathFromGeneration.split(sep3).map((segment) => encodeURIComponent(segment)).join("/");
|
|
2959
|
+
return {
|
|
2960
|
+
filePath,
|
|
2961
|
+
pathname: `${generationUrl}/${urlPath}`,
|
|
2962
|
+
type: output.type
|
|
2963
|
+
};
|
|
2964
|
+
}
|
|
2965
|
+
function createGenerationId() {
|
|
2966
|
+
return randomUUID().replace(/-/g, "");
|
|
2967
|
+
}
|
|
2968
|
+
function buildFailureResponse() {
|
|
2969
|
+
return new Response("Failed to build project bundle", {
|
|
2970
|
+
status: 500,
|
|
2971
|
+
headers: { "cache-control": "no-store" }
|
|
2972
|
+
});
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2975
|
+
export { defineConfig, resolveConfig, build, createProject, startDevServer };
|
|
2976
|
+
|
|
2977
|
+
//# debugId=948B20A93B1A828264756E2164756E21
|
|
2978
|
+
//# sourceMappingURL=index-r68229k4.js.map
|