@orieljs/framework 0.1.0-alpha.10 → 0.1.0-alpha.12
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/dist/{chunk-VOYW3R5J.js → chunk-24673JQF.js} +3 -3
- package/dist/{chunk-OXAATQA6.js → chunk-7NA4HALO.js} +432 -89
- package/dist/chunk-7NA4HALO.js.map +1 -0
- package/dist/{chunk-GVNLZZTN.js → chunk-HTJKT2R2.js} +3 -1
- package/dist/chunk-HTJKT2R2.js.map +1 -0
- package/dist/{chunk-7ZQZYDOC.js → chunk-MURTCTRH.js} +2 -2
- package/dist/contracts.d.ts +12 -1
- package/dist/contracts.js +3 -1
- package/dist/index.d.ts +121 -4
- package/dist/index.js +296 -56
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/testing.js +3 -3
- package/docs/console.md +2 -0
- package/docs/deployment.md +95 -0
- package/docs/export.md +93 -0
- package/docs/installation.md +10 -0
- package/docs/middleware.md +1 -0
- package/docs/navigation.json +4 -0
- package/docs/starter-kits.md +3 -0
- package/docs/vite.md +106 -0
- package/package.json +32 -30
- package/dist/chunk-GVNLZZTN.js.map +0 -1
- package/dist/chunk-OXAATQA6.js.map +0 -1
- /package/dist/{chunk-VOYW3R5J.js.map → chunk-24673JQF.js.map} +0 -0
- /package/dist/{chunk-7ZQZYDOC.js.map → chunk-MURTCTRH.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
Arr,
|
|
3
3
|
ClassRegistry as ClassRegistry2,
|
|
4
4
|
Collection,
|
|
5
|
-
Container,
|
|
5
|
+
Container as Container2,
|
|
6
6
|
ContainerNotAvailableError,
|
|
7
7
|
ServiceProvider,
|
|
8
8
|
Str,
|
|
@@ -10,14 +10,16 @@ import {
|
|
|
10
10
|
facade,
|
|
11
11
|
fileType_exports,
|
|
12
12
|
inject
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-MURTCTRH.js";
|
|
14
14
|
import {
|
|
15
15
|
Application,
|
|
16
16
|
AuthFactory,
|
|
17
17
|
BusDispatcher,
|
|
18
|
+
ClassNames,
|
|
18
19
|
ClassRegistry,
|
|
19
20
|
ConfigRepository,
|
|
20
21
|
ConsoleKernel,
|
|
22
|
+
Container,
|
|
21
23
|
CookieJar,
|
|
22
24
|
CurrentRoute,
|
|
23
25
|
DatabaseManager,
|
|
@@ -45,7 +47,7 @@ import {
|
|
|
45
47
|
ValidationFactory,
|
|
46
48
|
ViewFactory,
|
|
47
49
|
token
|
|
48
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-HTJKT2R2.js";
|
|
49
51
|
|
|
50
52
|
// ../Config/dist/index.js
|
|
51
53
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -177,8 +179,137 @@ async function loadConfiguration(configPath) {
|
|
|
177
179
|
import { join as join3 } from "path";
|
|
178
180
|
import { isAbsolute, join as join4 } from "path";
|
|
179
181
|
import { existsSync as existsSync3, readFileSync as readFileSync2, statSync } from "fs";
|
|
182
|
+
|
|
183
|
+
// ../Obfuscate/dist/index.js
|
|
184
|
+
var FIRST = "abcdefghijklmnopqrstuvwxyz";
|
|
185
|
+
var REST = `${FIRST}0123456789`;
|
|
186
|
+
var CLASS_ATTRIBUTE = /^(class|o:[^\s=]*-class[^\s=]*)$/i;
|
|
187
|
+
var RAW_TEXT = /* @__PURE__ */ new Set(["script", "style", "textarea", "title", "xmp", "noembed", "noframes"]);
|
|
188
|
+
function rewriteHtml(html, map) {
|
|
189
|
+
if (Object.keys(map).length === 0) return html;
|
|
190
|
+
return replaceHtmlClasses(html, (token2) => map[decodeEntities(token2)] ?? token2);
|
|
191
|
+
}
|
|
192
|
+
function replaceHtmlClasses(html, replace) {
|
|
193
|
+
let out = "";
|
|
194
|
+
let last = 0;
|
|
195
|
+
let i = 0;
|
|
196
|
+
while (i < html.length) {
|
|
197
|
+
const open = html.indexOf("<", i);
|
|
198
|
+
if (open === -1) break;
|
|
199
|
+
if (html.startsWith("<!--", open)) {
|
|
200
|
+
const close = html.indexOf("-->", open + 4);
|
|
201
|
+
i = close === -1 ? html.length : close + 3;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const tag = /^<([a-zA-Z][^\s/>]*)/.exec(html.slice(open, open + 64));
|
|
205
|
+
if (tag === null) {
|
|
206
|
+
i = open + 1;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
let j = open + tag[0].length;
|
|
210
|
+
while (j < html.length && html[j] !== ">") {
|
|
211
|
+
if (/[\s/]/.test(html[j])) {
|
|
212
|
+
j++;
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
const nameEnd = attributeNameEnd(html, j);
|
|
216
|
+
const name = html.slice(j, nameEnd);
|
|
217
|
+
j = nameEnd;
|
|
218
|
+
while (/\s/.test(html[j] ?? "")) j++;
|
|
219
|
+
if (html[j] !== "=") continue;
|
|
220
|
+
j++;
|
|
221
|
+
while (/\s/.test(html[j] ?? "")) j++;
|
|
222
|
+
const quote2 = html[j] === '"' || html[j] === "'" ? html[j] : "";
|
|
223
|
+
const valueStart = quote2 === "" ? j : j + 1;
|
|
224
|
+
const valueEnd = quote2 === "" ? unquotedEnd(html, valueStart) : indexOrEnd(html, quote2, valueStart);
|
|
225
|
+
if (CLASS_ATTRIBUTE.test(name)) {
|
|
226
|
+
const value = html.slice(valueStart, valueEnd);
|
|
227
|
+
const renamed = value.replace(/\S+/g, replace);
|
|
228
|
+
if (renamed !== value) {
|
|
229
|
+
out += html.slice(last, valueStart) + renamed;
|
|
230
|
+
last = valueEnd;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
j = quote2 === "" ? valueEnd : valueEnd + 1;
|
|
234
|
+
}
|
|
235
|
+
i = j + 1;
|
|
236
|
+
const element = tag[1].toLowerCase();
|
|
237
|
+
if (RAW_TEXT.has(element)) {
|
|
238
|
+
const close = new RegExp(`</${element}`, "gi");
|
|
239
|
+
close.lastIndex = i;
|
|
240
|
+
i = close.exec(html)?.index ?? html.length;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return out + html.slice(last);
|
|
244
|
+
}
|
|
245
|
+
function attributeNameEnd(html, i) {
|
|
246
|
+
let j = i + 1;
|
|
247
|
+
while (j < html.length && !/[\s/>=]/.test(html[j])) j++;
|
|
248
|
+
return j;
|
|
249
|
+
}
|
|
250
|
+
function unquotedEnd(html, i) {
|
|
251
|
+
let j = i;
|
|
252
|
+
while (j < html.length && !/[\s>]/.test(html[j])) j++;
|
|
253
|
+
return j;
|
|
254
|
+
}
|
|
255
|
+
function indexOrEnd(html, search, from) {
|
|
256
|
+
const index = html.indexOf(search, from);
|
|
257
|
+
return index === -1 ? html.length : index;
|
|
258
|
+
}
|
|
259
|
+
var NAMED = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: "\xA0" };
|
|
260
|
+
function decodeEntities(value) {
|
|
261
|
+
if (!value.includes("&")) return value;
|
|
262
|
+
return value.replace(/&(#x[0-9a-f]+|#\d+|[a-z]+);/gi, (entity, body) => {
|
|
263
|
+
if (body[0] === "#") return String.fromCodePoint(body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number(body.slice(1)));
|
|
264
|
+
return NAMED[body.toLowerCase()] ?? entity;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// ../Foundation/dist/index.js
|
|
269
|
+
import { existsSync as existsSync22, readFileSync as readFileSync22, statSync as statSync2 } from "fs";
|
|
180
270
|
import { createHash, randomBytes } from "crypto";
|
|
181
271
|
import { join as join22 } from "path";
|
|
272
|
+
var RAW_TEXT2 = /<(script|style|textarea|title|xmp|noembed|noframes)\b[^>]*>(?![\s\S]*<\/\1)/i;
|
|
273
|
+
var RenameClasses = class {
|
|
274
|
+
#container = inject(Container);
|
|
275
|
+
async handle(request2, next) {
|
|
276
|
+
const response2 = await next(request2);
|
|
277
|
+
if (response2.body === null || !/^text\/html\b/i.test(response2.headers.get("content-type") ?? "") || response2.headers.has("content-encoding")) return response2;
|
|
278
|
+
if (!this.#container.bound(ClassNames)) return response2;
|
|
279
|
+
const classNames = this.#container.make(ClassNames);
|
|
280
|
+
if (!classNames.active) return response2;
|
|
281
|
+
const headers = new Headers(response2.headers);
|
|
282
|
+
headers.delete("content-length");
|
|
283
|
+
return new Response(response2.body.pipeThrough(renamer((html) => classNames.html(html))), { status: response2.status, statusText: response2.statusText, headers });
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
function renamer(rename2) {
|
|
287
|
+
const decoder = new TextDecoder();
|
|
288
|
+
const encoder = new TextEncoder();
|
|
289
|
+
let carry = "";
|
|
290
|
+
return new TransformStream({
|
|
291
|
+
transform(chunk2, controller) {
|
|
292
|
+
const text = carry + decoder.decode(chunk2, { stream: true });
|
|
293
|
+
const cut = safeCut(text);
|
|
294
|
+
carry = text.slice(cut);
|
|
295
|
+
if (cut > 0) controller.enqueue(encoder.encode(rename2(text.slice(0, cut))));
|
|
296
|
+
},
|
|
297
|
+
flush(controller) {
|
|
298
|
+
const text = carry + decoder.decode();
|
|
299
|
+
if (text !== "") controller.enqueue(encoder.encode(rename2(text)));
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
function safeCut(text) {
|
|
304
|
+
let cut = text.lastIndexOf(">") + 1;
|
|
305
|
+
if (cut === 0) return 0;
|
|
306
|
+
const head = text.slice(0, cut);
|
|
307
|
+
const comment = head.lastIndexOf("<!--");
|
|
308
|
+
if (comment !== -1 && head.indexOf("-->", comment + 4) === -1) cut = comment;
|
|
309
|
+
const raw = RAW_TEXT2.exec(text.slice(0, cut));
|
|
310
|
+
if (raw !== null) cut = raw.index;
|
|
311
|
+
return cut;
|
|
312
|
+
}
|
|
182
313
|
var ApplicationBuilder = class {
|
|
183
314
|
constructor(app) {
|
|
184
315
|
this.app = app;
|
|
@@ -223,12 +354,48 @@ var ApplicationBuilder = class {
|
|
|
223
354
|
loadEnvironment(this.app.basePath());
|
|
224
355
|
this.app.instance(ConfigRepository, new Repository(await loadConfiguration(this.app.configPath())));
|
|
225
356
|
if (this.routing) this.app.instance(RoutingPaths, this.routing);
|
|
226
|
-
|
|
357
|
+
const middleware = [(m) => void m.prepend(RenameClasses), ...this.middleware];
|
|
358
|
+
this.app.instance(MiddlewareCallbacks, middleware);
|
|
227
359
|
this.app.instance(ExceptionCallbacks, this.exceptions);
|
|
228
360
|
for (const provider of this.providers) await this.app.register(provider);
|
|
229
361
|
return this.app;
|
|
230
362
|
}
|
|
231
363
|
};
|
|
364
|
+
var ClassNameMap = class {
|
|
365
|
+
constructor(app) {
|
|
366
|
+
this.app = app;
|
|
367
|
+
}
|
|
368
|
+
app;
|
|
369
|
+
#loaded;
|
|
370
|
+
/** The map, or undefined: no scrambled build, the dev server is running, or the app is running its tests. */
|
|
371
|
+
classes() {
|
|
372
|
+
if (this.#testing() || existsSync3(this.app.publicPath("hot"))) return void 0;
|
|
373
|
+
const file = this.app.bootstrapPath("cache/classes.json");
|
|
374
|
+
let modified;
|
|
375
|
+
try {
|
|
376
|
+
modified = statSync(file).mtimeMs;
|
|
377
|
+
} catch {
|
|
378
|
+
this.#loaded = void 0;
|
|
379
|
+
return void 0;
|
|
380
|
+
}
|
|
381
|
+
if (this.#loaded?.modified !== modified) {
|
|
382
|
+
const parsed = JSON.parse(readFileSync2(file, "utf8"));
|
|
383
|
+
this.#loaded = { modified, classes: parsed.classes ?? {} };
|
|
384
|
+
}
|
|
385
|
+
return Object.keys(this.#loaded.classes).length === 0 ? void 0 : this.#loaded.classes;
|
|
386
|
+
}
|
|
387
|
+
/** The app runs its tests: Oriel's TestCase sets APP_ENV=testing, which a test that switches app.env leaves set. */
|
|
388
|
+
#testing() {
|
|
389
|
+
return this.app.runningUnitTests() || process.env.APP_ENV === "testing";
|
|
390
|
+
}
|
|
391
|
+
get active() {
|
|
392
|
+
return this.classes() !== void 0;
|
|
393
|
+
}
|
|
394
|
+
html(html) {
|
|
395
|
+
const classes = this.classes();
|
|
396
|
+
return classes === void 0 ? html : rewriteHtml(html, classes);
|
|
397
|
+
}
|
|
398
|
+
};
|
|
232
399
|
var ProviderBootError = class extends Error {
|
|
233
400
|
constructor(provider, cause) {
|
|
234
401
|
super(`Service provider [${provider}] failed to boot: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
@@ -335,11 +502,11 @@ var Vite = class {
|
|
|
335
502
|
return this.#hotFile ?? this.app.publicPath("hot");
|
|
336
503
|
}
|
|
337
504
|
isRunningHot() {
|
|
338
|
-
return
|
|
505
|
+
return existsSync22(this.hotFile());
|
|
339
506
|
}
|
|
340
507
|
/** The dev server URL written by @orieljs/vite, or undefined when it isn't running. */
|
|
341
508
|
devServerUrl() {
|
|
342
|
-
return this.isRunningHot() ?
|
|
509
|
+
return this.isRunningHot() ? readFileSync22(this.hotFile(), "utf8").trimEnd() : void 0;
|
|
343
510
|
}
|
|
344
511
|
// Tags -----------------------------------------------------------------------------------------------------
|
|
345
512
|
/** Laravel's @vite([...]): preloads (styles first), then stylesheets, then scripts. */
|
|
@@ -408,25 +575,25 @@ var Vite = class {
|
|
|
408
575
|
content(path, buildDirectory = this.#buildDirectory) {
|
|
409
576
|
const chunk2 = this.#chunk(this.manifest(buildDirectory), path);
|
|
410
577
|
const file = this.app.publicPath(join22(buildDirectory, chunk2.file));
|
|
411
|
-
if (!
|
|
412
|
-
return
|
|
578
|
+
if (!existsSync22(file)) throw new ViteError(`Unable to locate file from Vite manifest: ${file}.`);
|
|
579
|
+
return readFileSync22(file, "utf8");
|
|
413
580
|
}
|
|
414
581
|
/** md5 of the manifest (a cache-busting asset version); undefined while hot or without a build. */
|
|
415
582
|
manifestHash(buildDirectory = this.#buildDirectory) {
|
|
416
583
|
if (this.isRunningHot()) return void 0;
|
|
417
584
|
const path = this.manifestPath(buildDirectory);
|
|
418
|
-
return
|
|
585
|
+
return existsSync22(path) ? createHash("md5").update(readFileSync22(path)).digest("hex") : void 0;
|
|
419
586
|
}
|
|
420
587
|
manifestPath(buildDirectory = this.#buildDirectory) {
|
|
421
588
|
return this.app.publicPath(join22(buildDirectory, this.#manifestFilename));
|
|
422
589
|
}
|
|
423
590
|
manifest(buildDirectory = this.#buildDirectory) {
|
|
424
591
|
const path = this.manifestPath(buildDirectory);
|
|
425
|
-
if (!
|
|
426
|
-
const { mtimeMs } =
|
|
592
|
+
if (!existsSync22(path)) throw new ViteError(`Vite manifest not found at: ${path}`);
|
|
593
|
+
const { mtimeMs } = statSync2(path);
|
|
427
594
|
const cached = manifests.get(path);
|
|
428
595
|
if (cached !== void 0 && cached.mtimeMs === mtimeMs) return cached.manifest;
|
|
429
|
-
const manifest = JSON.parse(
|
|
596
|
+
const manifest = JSON.parse(readFileSync22(path, "utf8"));
|
|
430
597
|
manifests.set(path, { mtimeMs, manifest });
|
|
431
598
|
return manifest;
|
|
432
599
|
}
|
|
@@ -521,18 +688,19 @@ function viteReactRefresh() {
|
|
|
521
688
|
return currentVite().reactRefresh();
|
|
522
689
|
}
|
|
523
690
|
var SHUTDOWN_TIMEOUT_MS = 1e4;
|
|
524
|
-
var Application2 = class _Application extends
|
|
691
|
+
var Application2 = class _Application extends Container2 {
|
|
525
692
|
constructor(base) {
|
|
526
693
|
super();
|
|
527
694
|
this.base = base;
|
|
528
|
-
|
|
695
|
+
Container2.setInstance(this);
|
|
529
696
|
this.instance(Application, this);
|
|
530
697
|
this.instance(_Application, this);
|
|
531
698
|
this.singleton(ClassRegistry, ClassRegistry2);
|
|
532
699
|
this.scoped(Vite, () => new Vite(this));
|
|
700
|
+
this.singleton(ClassNames, () => new ClassNameMap(this));
|
|
533
701
|
}
|
|
534
702
|
base;
|
|
535
|
-
version = "0.1.0-alpha.
|
|
703
|
+
version = "0.1.0-alpha.12";
|
|
536
704
|
providers = [];
|
|
537
705
|
bootingCallbacks = [];
|
|
538
706
|
bootedCallbacks = [];
|
|
@@ -663,7 +831,7 @@ var Application2 = class _Application extends Container {
|
|
|
663
831
|
return "done";
|
|
664
832
|
})();
|
|
665
833
|
let timer;
|
|
666
|
-
const deadline = new Promise((
|
|
834
|
+
const deadline = new Promise((resolve4) => timer = setTimeout(() => resolve4("timeout"), SHUTDOWN_TIMEOUT_MS));
|
|
667
835
|
const outcome = await Promise.race([run, deadline]);
|
|
668
836
|
clearTimeout(timer);
|
|
669
837
|
if (outcome === "timeout") {
|
|
@@ -710,21 +878,25 @@ import { basename } from "path";
|
|
|
710
878
|
import { Readable } from "stream";
|
|
711
879
|
import { readFile } from "fs/promises";
|
|
712
880
|
import { fileURLToPath } from "url";
|
|
881
|
+
import { existsSync as existsSync4, lstatSync, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
|
|
882
|
+
import { cp, mkdir, mkdtemp, rename, rm, writeFile } from "fs/promises";
|
|
883
|
+
import { basename as basename2, dirname, join as join5, resolve as resolve2 } from "path";
|
|
713
884
|
import { createReadStream as createReadStream2 } from "fs";
|
|
714
885
|
import { stat as stat2 } from "fs/promises";
|
|
715
886
|
import { Readable as Readable2 } from "stream";
|
|
716
887
|
import { relative, resolve, sep } from "path";
|
|
888
|
+
import { posix } from "path";
|
|
717
889
|
import { createServer } from "http";
|
|
718
890
|
import { Readable as Readable3 } from "stream";
|
|
719
891
|
import { pipeline } from "stream/promises";
|
|
720
|
-
import { existsSync as
|
|
721
|
-
import { mkdir, readFile as readFile2, writeFile } from "fs/promises";
|
|
722
|
-
import { dirname } from "path";
|
|
723
|
-
import { existsSync as
|
|
724
|
-
import { join as join5 } from "path";
|
|
725
|
-
import * as util from "util";
|
|
726
|
-
import { existsSync as existsSync22, statSync as statSync2, watch as watchPath } from "fs";
|
|
892
|
+
import { existsSync as existsSync42 } from "fs";
|
|
893
|
+
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
894
|
+
import { dirname as dirname2, resolve as resolve3 } from "path";
|
|
895
|
+
import { existsSync as existsSync23, readFileSync as readFileSync3 } from "fs";
|
|
727
896
|
import { join as join23 } from "path";
|
|
897
|
+
import * as util from "util";
|
|
898
|
+
import { existsSync as existsSync32, statSync as statSync22, watch as watchPath } from "fs";
|
|
899
|
+
import { join as join32 } from "path";
|
|
728
900
|
import { createServer as createServer2 } from "net";
|
|
729
901
|
import { spawn as spawnProcess } from "child_process";
|
|
730
902
|
var HttpException = class extends Error {
|
|
@@ -2250,6 +2422,131 @@ function exitOnSignals(close, closed, app) {
|
|
|
2250
2422
|
});
|
|
2251
2423
|
}
|
|
2252
2424
|
var displayHost = (hostname) => hostname.includes(":") ? `[${hostname}]` : hostname;
|
|
2425
|
+
var ANCHOR = /<a\b[^>]*?\shref\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+))/gi;
|
|
2426
|
+
var decode = (path) => {
|
|
2427
|
+
try {
|
|
2428
|
+
return decodeURIComponent(path);
|
|
2429
|
+
} catch {
|
|
2430
|
+
return path;
|
|
2431
|
+
}
|
|
2432
|
+
};
|
|
2433
|
+
function exportFileName(path, style) {
|
|
2434
|
+
const trimmed = decode(path).replace(/^\/+|\/+$/g, "");
|
|
2435
|
+
if (trimmed === "") return "index.html";
|
|
2436
|
+
if (posix.extname(trimmed) !== "") return trimmed;
|
|
2437
|
+
return style === "directory" ? `${trimmed}/index.html` : `${trimmed}.html`;
|
|
2438
|
+
}
|
|
2439
|
+
function sameSiteLinks(html, pageUrl, baseUrl) {
|
|
2440
|
+
const origin = new URL(baseUrl).origin;
|
|
2441
|
+
const found = [];
|
|
2442
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2443
|
+
for (const match of html.matchAll(ANCHOR)) {
|
|
2444
|
+
const href = (match[1] ?? match[2] ?? match[3] ?? "").trim();
|
|
2445
|
+
if (href === "" || href.startsWith("#")) continue;
|
|
2446
|
+
const path = sitePath(href, pageUrl, origin);
|
|
2447
|
+
if (path === void 0 || seen.has(path)) continue;
|
|
2448
|
+
seen.add(path);
|
|
2449
|
+
found.push(path);
|
|
2450
|
+
}
|
|
2451
|
+
return found;
|
|
2452
|
+
}
|
|
2453
|
+
function sitePath(href, pageUrl, origin) {
|
|
2454
|
+
let url2;
|
|
2455
|
+
try {
|
|
2456
|
+
url2 = new URL(href, pageUrl);
|
|
2457
|
+
} catch {
|
|
2458
|
+
return void 0;
|
|
2459
|
+
}
|
|
2460
|
+
if (url2.origin !== new URL(origin).origin) return void 0;
|
|
2461
|
+
return decode(url2.pathname.length > 1 ? url2.pathname.replace(/\/+$/, "") : url2.pathname);
|
|
2462
|
+
}
|
|
2463
|
+
var ExportError = class extends Error {
|
|
2464
|
+
constructor(path, status) {
|
|
2465
|
+
super(`[${path}] answered ${status}.`);
|
|
2466
|
+
this.path = path;
|
|
2467
|
+
this.status = status;
|
|
2468
|
+
}
|
|
2469
|
+
path;
|
|
2470
|
+
status;
|
|
2471
|
+
name = "ExportError";
|
|
2472
|
+
};
|
|
2473
|
+
var MARKER = ".oriel-export";
|
|
2474
|
+
var NOT_FOUND_PATH = "/__oriel-export-not-found__";
|
|
2475
|
+
async function exportSite(app, options) {
|
|
2476
|
+
const output = resolve2(options.output);
|
|
2477
|
+
const publicPath = options.publicPath === false ? void 0 : resolve2(options.publicPath);
|
|
2478
|
+
if (publicPath !== void 0 && existsSync4(join5(publicPath, "hot"))) {
|
|
2479
|
+
throw new Error("The Vite dev server is running (public/hot exists): stop `npm run dev`, build the assets with `npm run build`, then export.");
|
|
2480
|
+
}
|
|
2481
|
+
assertReplaceable(output);
|
|
2482
|
+
const staging = await mkdtemp(join5(dirname(output), `.${basename2(output)}-`));
|
|
2483
|
+
try {
|
|
2484
|
+
if (publicPath !== void 0 && existsSync4(publicPath)) {
|
|
2485
|
+
await cp(publicPath, staging, { recursive: true, filter: (source) => basename2(source) !== "hot" && !lstatSync(source).isSymbolicLink() });
|
|
2486
|
+
}
|
|
2487
|
+
const excluded = (path) => options.exclude.some((pattern) => wildcard(pattern).test(path));
|
|
2488
|
+
const isPublicFile = (path) => publicPath !== void 0 && path !== "/" && isFile(join5(publicPath, path));
|
|
2489
|
+
const queue = [.../* @__PURE__ */ new Set(["/", ...options.paths.map(rooted)])].filter((path) => path === "/" || !excluded(path));
|
|
2490
|
+
const seen = new Set(queue);
|
|
2491
|
+
const pages = [];
|
|
2492
|
+
const redirects = [];
|
|
2493
|
+
while (queue.length > 0) {
|
|
2494
|
+
const path = queue.shift();
|
|
2495
|
+
const url2 = new URL(path, options.baseUrl).href;
|
|
2496
|
+
const answer = await fetchPage(app, url2);
|
|
2497
|
+
if (answer.status >= 300 && answer.status < 400) {
|
|
2498
|
+
const location = new URL(answer.headers.get("location") ?? "/", url2).href;
|
|
2499
|
+
redirects.push({ path, location });
|
|
2500
|
+
const target2 = sitePath(location, url2, options.baseUrl);
|
|
2501
|
+
if (target2 !== void 0 && !seen.has(target2) && !excluded(target2) && !isPublicFile(target2)) {
|
|
2502
|
+
seen.add(target2);
|
|
2503
|
+
queue.push(target2);
|
|
2504
|
+
}
|
|
2505
|
+
continue;
|
|
2506
|
+
}
|
|
2507
|
+
if (answer.status >= 400) throw new ExportError(path, answer.status);
|
|
2508
|
+
await writeInto(staging, exportFileName(path, options.fileNames), answer.body);
|
|
2509
|
+
pages.push(path);
|
|
2510
|
+
if (!options.crawl || !isHtml(answer.headers)) continue;
|
|
2511
|
+
for (const link of sameSiteLinks(answer.body.toString("utf8"), url2, options.baseUrl)) {
|
|
2512
|
+
if (seen.has(link) || excluded(link) || isPublicFile(link)) continue;
|
|
2513
|
+
seen.add(link);
|
|
2514
|
+
queue.push(link);
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
const notFound = await fetchPage(app, new URL(NOT_FOUND_PATH, options.baseUrl).href);
|
|
2518
|
+
const notFoundPage = notFound.status === 404 && isHtml(notFound.headers);
|
|
2519
|
+
if (notFoundPage) await writeInto(staging, "404.html", notFound.body);
|
|
2520
|
+
await writeFile(join5(staging, MARKER), "");
|
|
2521
|
+
await rm(output, { recursive: true, force: true });
|
|
2522
|
+
await rename(staging, output);
|
|
2523
|
+
return { pages, redirects, notFoundPage };
|
|
2524
|
+
} catch (error) {
|
|
2525
|
+
await rm(staging, { recursive: true, force: true });
|
|
2526
|
+
throw error;
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
function assertReplaceable(output) {
|
|
2530
|
+
if (!existsSync4(output)) return;
|
|
2531
|
+
if (statSync3(output).isDirectory() && (existsSync4(join5(output, MARKER)) || readdirSync2(output).length === 0)) return;
|
|
2532
|
+
throw new Error(`[${output}] exists and wasn't made by oriel export: remove it, or export somewhere else with --output.`);
|
|
2533
|
+
}
|
|
2534
|
+
async function fetchPage(app, url2) {
|
|
2535
|
+
const request2 = new Request(url2, { headers: { accept: "text/html" } });
|
|
2536
|
+
const response2 = await handleSafely(app, request2);
|
|
2537
|
+
const body = Buffer.from(await response2.arrayBuffer());
|
|
2538
|
+
await terminateRequest(app, request2, response2);
|
|
2539
|
+
return { status: response2.status, headers: response2.headers, body };
|
|
2540
|
+
}
|
|
2541
|
+
async function writeInto(folder, file, body) {
|
|
2542
|
+
const path = join5(folder, file);
|
|
2543
|
+
await mkdir(dirname(path), { recursive: true });
|
|
2544
|
+
await writeFile(path, body);
|
|
2545
|
+
}
|
|
2546
|
+
var isHtml = (headers) => (headers.get("content-type") ?? "").includes("text/html");
|
|
2547
|
+
var rooted = (path) => path.startsWith("/") ? path : `/${path}`;
|
|
2548
|
+
var isFile = (path) => existsSync4(path) && statSync3(path).isFile();
|
|
2549
|
+
var wildcard = (pattern) => new RegExp(`^${rooted(pattern).replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*")}$`);
|
|
2253
2550
|
function bunRuntime() {
|
|
2254
2551
|
return globalThis.Bun;
|
|
2255
2552
|
}
|
|
@@ -2257,7 +2554,7 @@ async function serveBun(app, options) {
|
|
|
2257
2554
|
const bun = bunRuntime();
|
|
2258
2555
|
if (bun === void 0) throw new HttpServerError("Bun.serve is not available: the process is not running on Bun.");
|
|
2259
2556
|
let markClosed = () => void 0;
|
|
2260
|
-
const closed = new Promise((
|
|
2557
|
+
const closed = new Promise((resolve4) => markClosed = resolve4);
|
|
2261
2558
|
const server = bun.serve({
|
|
2262
2559
|
port: options.port,
|
|
2263
2560
|
hostname: options.hostname,
|
|
@@ -2275,8 +2572,8 @@ async function serveBun(app, options) {
|
|
|
2275
2572
|
let closing;
|
|
2276
2573
|
const close = () => closing ??= (async () => {
|
|
2277
2574
|
let timer;
|
|
2278
|
-
const forced = new Promise((
|
|
2279
|
-
timer = setTimeout(() => void Promise.resolve(server.stop(true)).then(
|
|
2575
|
+
const forced = new Promise((resolve4) => {
|
|
2576
|
+
timer = setTimeout(() => void Promise.resolve(server.stop(true)).then(resolve4), options.shutdownTimeout);
|
|
2280
2577
|
});
|
|
2281
2578
|
await Promise.race([Promise.resolve(server.stop(false)), forced]);
|
|
2282
2579
|
clearTimeout(timer);
|
|
@@ -2374,40 +2671,44 @@ async function writeResponse(res, response2) {
|
|
|
2374
2671
|
}
|
|
2375
2672
|
await pipeline(Readable3.fromWeb(response2.body), res);
|
|
2376
2673
|
}
|
|
2674
|
+
function nodeRequestHandler(app, options) {
|
|
2675
|
+
return async (req, res) => {
|
|
2676
|
+
let request2;
|
|
2677
|
+
try {
|
|
2678
|
+
request2 = toWebRequest(req, res, options.fallbackHost);
|
|
2679
|
+
} catch {
|
|
2680
|
+
res.statusCode = 400;
|
|
2681
|
+
res.end("Bad Request");
|
|
2682
|
+
return;
|
|
2683
|
+
}
|
|
2684
|
+
setClientAddress(request2, req.socket.remoteAddress);
|
|
2685
|
+
const response2 = await handleSafely(app, request2, options.publicPath);
|
|
2686
|
+
try {
|
|
2687
|
+
await writeResponse(res, response2);
|
|
2688
|
+
} catch {
|
|
2689
|
+
res.destroy();
|
|
2690
|
+
}
|
|
2691
|
+
await terminateRequest(app, request2, response2);
|
|
2692
|
+
};
|
|
2693
|
+
}
|
|
2377
2694
|
async function serveNode(app, options) {
|
|
2378
|
-
const
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
let request2;
|
|
2382
|
-
try {
|
|
2383
|
-
request2 = toWebRequest(req, res, fallbackHost);
|
|
2384
|
-
} catch {
|
|
2385
|
-
res.statusCode = 400;
|
|
2386
|
-
res.end("Bad Request");
|
|
2387
|
-
return;
|
|
2388
|
-
}
|
|
2389
|
-
setClientAddress(request2, req.socket.remoteAddress);
|
|
2390
|
-
const response2 = await handleSafely(app, request2, options.publicPath);
|
|
2391
|
-
try {
|
|
2392
|
-
await writeResponse(res, response2);
|
|
2393
|
-
} catch {
|
|
2394
|
-
res.destroy();
|
|
2395
|
-
}
|
|
2396
|
-
await terminateRequest(app, request2, response2);
|
|
2397
|
-
})();
|
|
2695
|
+
const handle = nodeRequestHandler(app, {
|
|
2696
|
+
...options.publicPath !== void 0 && { publicPath: options.publicPath },
|
|
2697
|
+
fallbackHost: `${displayHost(options.hostname)}:${options.port}`
|
|
2398
2698
|
});
|
|
2399
|
-
|
|
2699
|
+
const server = createServer((req, res) => void handle(req, res));
|
|
2700
|
+
await new Promise((resolve4, reject) => {
|
|
2400
2701
|
server.once("error", reject);
|
|
2401
2702
|
server.listen(options.port, options.hostname, () => {
|
|
2402
2703
|
server.off("error", reject);
|
|
2403
|
-
|
|
2704
|
+
resolve4();
|
|
2404
2705
|
});
|
|
2405
2706
|
});
|
|
2406
2707
|
const address = server.address();
|
|
2407
|
-
const closed = new Promise((
|
|
2708
|
+
const closed = new Promise((resolve4) => server.once("close", () => resolve4()));
|
|
2408
2709
|
let closing;
|
|
2409
2710
|
const close = () => closing ??= (async () => {
|
|
2410
|
-
const done = new Promise((
|
|
2711
|
+
const done = new Promise((resolve4) => server.close(() => resolve4()));
|
|
2411
2712
|
server.closeIdleConnections();
|
|
2412
2713
|
const idle = setInterval(() => server.closeIdleConnections(), 50);
|
|
2413
2714
|
const force = setTimeout(() => server.closeAllConnections(), options.shutdownTimeout);
|
|
@@ -2463,8 +2764,8 @@ function serverEnvironment(options = {}) {
|
|
|
2463
2764
|
if (typeof parseEnv2 !== "function") return env2;
|
|
2464
2765
|
const cwd = options.cwd ?? process.cwd();
|
|
2465
2766
|
for (const name of BUN_ENV_FILES) {
|
|
2466
|
-
const file =
|
|
2467
|
-
if (!
|
|
2767
|
+
const file = join23(cwd, name);
|
|
2768
|
+
if (!existsSync23(file)) continue;
|
|
2468
2769
|
let values;
|
|
2469
2770
|
try {
|
|
2470
2771
|
values = parseEnv2(readFileSync3(file, "utf8"));
|
|
@@ -2508,7 +2809,7 @@ function watchFiles(basePath, onChange, options = {}) {
|
|
|
2508
2809
|
const reportedLate = (path) => {
|
|
2509
2810
|
if (Date.now() - startedAt >= settle) return false;
|
|
2510
2811
|
try {
|
|
2511
|
-
const modified =
|
|
2812
|
+
const modified = statSync22(join32(basePath, path), { throwIfNoEntry: false })?.mtimeMs;
|
|
2512
2813
|
return modified === void 0 || modified < startedAt + 1;
|
|
2513
2814
|
} catch {
|
|
2514
2815
|
return false;
|
|
@@ -2527,7 +2828,7 @@ function watchFiles(basePath, onChange, options = {}) {
|
|
|
2527
2828
|
const handles = [];
|
|
2528
2829
|
const start = (folder, recursive, toPath) => {
|
|
2529
2830
|
try {
|
|
2530
|
-
const handle = watch(folder === "." ? basePath :
|
|
2831
|
+
const handle = watch(folder === "." ? basePath : join32(basePath, folder), { recursive }, (_event, file) => {
|
|
2531
2832
|
const path = toPath(file);
|
|
2532
2833
|
if (path !== void 0) record(path);
|
|
2533
2834
|
});
|
|
@@ -2539,7 +2840,7 @@ function watchFiles(basePath, onChange, options = {}) {
|
|
|
2539
2840
|
};
|
|
2540
2841
|
start(".", false, (file) => file === null ? void 0 : toSlashes(file));
|
|
2541
2842
|
for (const folder of WATCHED_FOLDERS) {
|
|
2542
|
-
if (
|
|
2843
|
+
if (existsSync32(join32(basePath, folder))) start(folder, true, (file) => `${folder}/${file === null ? "" : toSlashes(file)}`);
|
|
2543
2844
|
}
|
|
2544
2845
|
return {
|
|
2545
2846
|
close() {
|
|
@@ -2550,13 +2851,13 @@ function watchFiles(basePath, onChange, options = {}) {
|
|
|
2550
2851
|
};
|
|
2551
2852
|
}
|
|
2552
2853
|
function claimPort(hostname, port) {
|
|
2553
|
-
return new Promise((
|
|
2854
|
+
return new Promise((resolve4, reject) => {
|
|
2554
2855
|
const server = createServer2();
|
|
2555
2856
|
server.once("error", reject);
|
|
2556
2857
|
try {
|
|
2557
2858
|
server.listen({ port, host: hostname, exclusive: true }, () => {
|
|
2558
2859
|
const { port: claimed } = server.address();
|
|
2559
|
-
server.close(() =>
|
|
2860
|
+
server.close(() => resolve4(claimed));
|
|
2560
2861
|
});
|
|
2561
2862
|
} catch (error) {
|
|
2562
2863
|
reject(error);
|
|
@@ -2584,7 +2885,7 @@ var WatchedServer = class {
|
|
|
2584
2885
|
};
|
|
2585
2886
|
/** Starts the server and keeps it current until stopped. Resolves 0 once the last server has exited. */
|
|
2586
2887
|
run() {
|
|
2587
|
-
const done = new Promise((
|
|
2888
|
+
const done = new Promise((resolve4) => this.finish = resolve4);
|
|
2588
2889
|
const stopListening = this.listenForSignals();
|
|
2589
2890
|
const watcher = this.options.watch((files) => void this.changed(files));
|
|
2590
2891
|
this.start();
|
|
@@ -2623,14 +2924,14 @@ var WatchedServer = class {
|
|
|
2623
2924
|
stdio: ["ignore", "inherit", "inherit"]
|
|
2624
2925
|
});
|
|
2625
2926
|
const running = { child, stopping: false, killed: false, exited: Promise.resolve() };
|
|
2626
|
-
running.exited = new Promise((
|
|
2927
|
+
running.exited = new Promise((resolve4) => {
|
|
2627
2928
|
let settled = false;
|
|
2628
2929
|
const settle = (report) => {
|
|
2629
2930
|
if (settled) return;
|
|
2630
2931
|
settled = true;
|
|
2631
2932
|
if (this.running === running) this.running = void 0;
|
|
2632
2933
|
if (!running.stopping && !this.stopping) this.options.error(`${report}. Waiting for changes before restarting...`);
|
|
2633
|
-
|
|
2934
|
+
resolve4();
|
|
2634
2935
|
};
|
|
2635
2936
|
child.once("exit", (code, signal) => settle(signal !== null ? `The server stopped (signal ${signal})` : `The server stopped (exit code ${code})`));
|
|
2636
2937
|
child.once("error", (error) => {
|
|
@@ -2766,6 +3067,38 @@ async function serveWatching(app, out, port, run) {
|
|
|
2766
3067
|
error: (message) => out.error(message)
|
|
2767
3068
|
});
|
|
2768
3069
|
}
|
|
3070
|
+
async function exportCommand(app, out) {
|
|
3071
|
+
const config = (key2, fallback) => app.bound(ConfigRepository) ? app.make(ConfigRepository).get(key2, fallback) : fallback;
|
|
3072
|
+
const fileNames = config("export.file_names", "html");
|
|
3073
|
+
if (fileNames !== "html" && fileNames !== "directory") {
|
|
3074
|
+
out.error(`export.file_names is "html" or "directory", not "${fileNames}".`);
|
|
3075
|
+
return 1;
|
|
3076
|
+
}
|
|
3077
|
+
const output = out.option("output") ?? config("export.output", "dist");
|
|
3078
|
+
const baseUrl = config("app.url", "http://localhost");
|
|
3079
|
+
const started = performance.now();
|
|
3080
|
+
try {
|
|
3081
|
+
const result = await exportSite(app, {
|
|
3082
|
+
output: resolve3(app.basePath(), output),
|
|
3083
|
+
baseUrl,
|
|
3084
|
+
crawl: config("export.crawl", true),
|
|
3085
|
+
paths: config("export.paths", []),
|
|
3086
|
+
exclude: config("export.exclude", []),
|
|
3087
|
+
fileNames,
|
|
3088
|
+
publicPath: app.publicPath()
|
|
3089
|
+
});
|
|
3090
|
+
const origin = new URL(baseUrl).origin;
|
|
3091
|
+
for (const { path, location } of result.redirects) {
|
|
3092
|
+
out.line(`Redirect ${path} \u2192 ${location.startsWith(origin) ? location.slice(origin.length) || "/" : location}, not written.`);
|
|
3093
|
+
}
|
|
3094
|
+
const pages = result.pages.length === 1 ? "1 page" : `${result.pages.length} pages`;
|
|
3095
|
+
out.info(`Exported ${pages} to [${output}] in ${Math.round(performance.now() - started)} ms.`);
|
|
3096
|
+
return 0;
|
|
3097
|
+
} catch (error) {
|
|
3098
|
+
out.error(error instanceof ExportError ? error.message : error instanceof Error ? error.message : String(error));
|
|
3099
|
+
return 1;
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
2769
3102
|
function registerHttpCommands(kernel, app, options = {}) {
|
|
2770
3103
|
const serveApp = options.serve ?? serve;
|
|
2771
3104
|
const terminalWidth = options.terminalWidth ?? (() => process.stdout.columns ?? 120);
|
|
@@ -2824,25 +3157,28 @@ function registerHttpCommands(kernel, app, options = {}) {
|
|
|
2824
3157
|
return 0;
|
|
2825
3158
|
}
|
|
2826
3159
|
).purpose("List all registered routes");
|
|
3160
|
+
kernel.command("export {--output= : The folder to write the site to (default: config export.output, else dist)}", function() {
|
|
3161
|
+
return exportCommand(app, io(this));
|
|
3162
|
+
}).purpose("Export the application's pages as static files");
|
|
2827
3163
|
kernel.command("install:api {--force : Overwrite any existing API routes file}", async function() {
|
|
2828
3164
|
const out = io(this);
|
|
2829
3165
|
const routesFile = app.basePath("routes/api.ts");
|
|
2830
|
-
if (
|
|
3166
|
+
if (existsSync42(routesFile) && !out.flag("force")) {
|
|
2831
3167
|
out.error("API routes file already exists.");
|
|
2832
3168
|
} else {
|
|
2833
|
-
await
|
|
2834
|
-
await
|
|
3169
|
+
await mkdir2(dirname2(routesFile), { recursive: true });
|
|
3170
|
+
await writeFile2(routesFile, API_ROUTES_STUB);
|
|
2835
3171
|
out.info("Published API routes file.");
|
|
2836
3172
|
}
|
|
2837
3173
|
const bootstrapFile = app.bootstrapPath("app.ts");
|
|
2838
|
-
const source =
|
|
3174
|
+
const source = existsSync42(bootstrapFile) ? await readFile2(bootstrapFile, "utf8") : void 0;
|
|
2839
3175
|
const updated = source === void 0 ? void 0 : addApiRouting(source);
|
|
2840
3176
|
if (updated === void 0) {
|
|
2841
3177
|
out.warn(
|
|
2842
3178
|
"Unable to automatically add API route definition to bootstrap file. Add api: 'routes/api.ts' to withRouting() in bootstrap/app.ts."
|
|
2843
3179
|
);
|
|
2844
3180
|
} else if (updated !== source) {
|
|
2845
|
-
await
|
|
3181
|
+
await writeFile2(bootstrapFile, updated);
|
|
2846
3182
|
}
|
|
2847
3183
|
out.info("API scaffolding installed.");
|
|
2848
3184
|
return 0;
|
|
@@ -2885,13 +3221,13 @@ import { isDeepStrictEqual } from "util";
|
|
|
2885
3221
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
2886
3222
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
2887
3223
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
2888
|
-
import { existsSync as existsSync5, readdirSync as
|
|
3224
|
+
import { existsSync as existsSync5, readdirSync as readdirSync3 } from "fs";
|
|
2889
3225
|
import { join as join6, relative as relative2, sep as sep2 } from "path";
|
|
2890
3226
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
2891
3227
|
import { AsyncLocalStorage } from "async_hooks";
|
|
2892
|
-
import { existsSync as
|
|
2893
|
-
import { mkdir as
|
|
2894
|
-
import { dirname as
|
|
3228
|
+
import { existsSync as existsSync24 } from "fs";
|
|
3229
|
+
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
3230
|
+
import { dirname as dirname3, join as join24, relative as relative22, sep as sep22 } from "path";
|
|
2895
3231
|
var LiveError = class extends Error {
|
|
2896
3232
|
name = "LiveError";
|
|
2897
3233
|
kind = "Server";
|
|
@@ -3505,7 +3841,7 @@ function stripTags(html) {
|
|
|
3505
3841
|
return html.replace(/<[^>]*>/g, "");
|
|
3506
3842
|
}
|
|
3507
3843
|
var VOID = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "source", "track", "wbr"]);
|
|
3508
|
-
var
|
|
3844
|
+
var RAW_TEXT3 = /* @__PURE__ */ new Set(["script", "style", "textarea", "title"]);
|
|
3509
3845
|
var TOKEN = /<\/([A-Za-z][\w:-]*)\s*>|<([A-Za-z][\w:-]*)(?:\s+[^\s"'<>/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'=<>`]+))?)*\s*(\/?)>/g;
|
|
3510
3846
|
function rootTag(html, component) {
|
|
3511
3847
|
const fail22 = () => {
|
|
@@ -3527,7 +3863,7 @@ function rootTag(html, component) {
|
|
|
3527
3863
|
if (depth === 0) rootEnd = match.index + token2.length;
|
|
3528
3864
|
continue;
|
|
3529
3865
|
}
|
|
3530
|
-
if (
|
|
3866
|
+
if (RAW_TEXT3.has(tag)) {
|
|
3531
3867
|
const closer = new RegExp(`</${tag}`, "gi");
|
|
3532
3868
|
closer.lastIndex = TOKEN.lastIndex;
|
|
3533
3869
|
const end = closer.exec(source);
|
|
@@ -3785,7 +4121,7 @@ var fail = (message, actual, expected) => {
|
|
|
3785
4121
|
var getPath = (target2, path) => path.split(".").reduce((node, segment) => typeof node === "object" && node !== null ? node[segment] : void 0, target2);
|
|
3786
4122
|
var TestRequestScope = token("Testing.RequestScope");
|
|
3787
4123
|
function requestScope2() {
|
|
3788
|
-
const container2 = currentContainer() ??
|
|
4124
|
+
const container2 = currentContainer() ?? Container2.getInstance();
|
|
3789
4125
|
return container2?.bound(TestRequestScope) === true ? container2.make(TestRequestScope) : (run) => run();
|
|
3790
4126
|
}
|
|
3791
4127
|
function currentSession() {
|
|
@@ -4019,7 +4355,7 @@ function defaultName(cls) {
|
|
|
4019
4355
|
}
|
|
4020
4356
|
function componentFiles(directory) {
|
|
4021
4357
|
if (!existsSync5(directory)) return [];
|
|
4022
|
-
return
|
|
4358
|
+
return readdirSync3(directory, { recursive: true, encoding: "utf8" }).filter((file) => /\.(tsx|ts|jsx|js|mts|mjs)$/.test(file) && !/\.(test|spec|d)\.[^.]+$/.test(file)).map((file) => file.split(sep2).join("/")).sort();
|
|
4023
4359
|
}
|
|
4024
4360
|
async function discover(directory) {
|
|
4025
4361
|
const found = [];
|
|
@@ -4565,7 +4901,9 @@ var LiveComponentManager = class {
|
|
|
4565
4901
|
);
|
|
4566
4902
|
await hook2(instance, "rendered", html);
|
|
4567
4903
|
memo.children = context.children;
|
|
4568
|
-
|
|
4904
|
+
const container2 = this.container();
|
|
4905
|
+
const renamed = container2.bound(ClassNames) ? container2.make(ClassNames).html(html) : html;
|
|
4906
|
+
return { html: renamed.trim(), tag: rootTag(renamed, memo.name) };
|
|
4569
4907
|
}
|
|
4570
4908
|
/** The absolute URL of the page a memo path belongs to, on the current request's origin ('/' + path without one). */
|
|
4571
4909
|
pageUrl(path) {
|
|
@@ -4625,7 +4963,7 @@ test('{{ name }} renders', async () => {
|
|
|
4625
4963
|
`;
|
|
4626
4964
|
var CLASS_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
4627
4965
|
function importPath(from, to) {
|
|
4628
|
-
const path = relative22(
|
|
4966
|
+
const path = relative22(dirname3(from), to).split(sep22).join("/").replace(/\.tsx?$/, "");
|
|
4629
4967
|
return path.startsWith(".") ? path : `./${path}`;
|
|
4630
4968
|
}
|
|
4631
4969
|
function registerLiveCommands(kernel, app) {
|
|
@@ -4640,23 +4978,23 @@ function registerLiveCommands(kernel, app) {
|
|
|
4640
4978
|
const directory = config?.get("live.class_path") ?? app.appPath("Live");
|
|
4641
4979
|
const file = join24(directory, ...segments.slice(0, -1), `${className}.tsx`);
|
|
4642
4980
|
const force = this.option("force") === true;
|
|
4643
|
-
if (
|
|
4981
|
+
if (existsSync24(file) && !force) {
|
|
4644
4982
|
this.error(`Component [${relative22(app.basePath(), file)}] already exists.`);
|
|
4645
4983
|
return 1;
|
|
4646
4984
|
}
|
|
4647
|
-
await
|
|
4648
|
-
await
|
|
4985
|
+
await mkdir3(dirname3(file), { recursive: true });
|
|
4986
|
+
await writeFile3(file, COMPONENT_STUB.replace("{{ class }}", () => className));
|
|
4649
4987
|
this.info(`Component [${relative22(app.basePath(), file)}] created successfully.`);
|
|
4650
4988
|
if (this.option("test") === true) {
|
|
4651
4989
|
const testFile = app.basePath(join24("tests", "Feature", "Live", ...segments.slice(0, -1), `${className}.test.ts`));
|
|
4652
|
-
if (
|
|
4990
|
+
if (existsSync24(testFile) && !force) {
|
|
4653
4991
|
this.error(`Test [${relative22(app.basePath(), testFile)}] already exists.`);
|
|
4654
4992
|
return 1;
|
|
4655
4993
|
}
|
|
4656
4994
|
const name = segments.map((segment) => Str.kebab(segment)).join(".");
|
|
4657
4995
|
const test = TEST_STUB.replaceAll("{{ class }}", () => className).replace("{{ component }}", () => importPath(testFile, file)).replace("{{ testCase }}", () => importPath(testFile, app.basePath(join24("tests", "TestCase.ts")))).replace("{{ name }}", () => name);
|
|
4658
|
-
await
|
|
4659
|
-
await
|
|
4996
|
+
await mkdir3(dirname3(testFile), { recursive: true });
|
|
4997
|
+
await writeFile3(testFile, test);
|
|
4660
4998
|
this.info(`Test [${relative22(app.basePath(), testFile)}] created successfully.`);
|
|
4661
4999
|
}
|
|
4662
5000
|
return 0;
|
|
@@ -4743,7 +5081,7 @@ import { randomUUID } from "crypto";
|
|
|
4743
5081
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
4744
5082
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
4745
5083
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
4746
|
-
import { posix } from "path";
|
|
5084
|
+
import { posix as posix2 } from "path";
|
|
4747
5085
|
import { deflateSync } from "zlib";
|
|
4748
5086
|
var original;
|
|
4749
5087
|
var testNow;
|
|
@@ -5552,7 +5890,7 @@ function decryptCookie(encrypter, name, value) {
|
|
|
5552
5890
|
return void 0;
|
|
5553
5891
|
}
|
|
5554
5892
|
}
|
|
5555
|
-
var
|
|
5893
|
+
var decode2 = (text) => {
|
|
5556
5894
|
try {
|
|
5557
5895
|
return decodeURIComponent(text);
|
|
5558
5896
|
} catch {
|
|
@@ -5563,8 +5901,8 @@ function parseSetCookie(header) {
|
|
|
5563
5901
|
const [pair = "", ...attributes] = header.split(";");
|
|
5564
5902
|
const eq = pair.indexOf("=");
|
|
5565
5903
|
const cookie = {
|
|
5566
|
-
name:
|
|
5567
|
-
value:
|
|
5904
|
+
name: decode2(pair.slice(0, eq).trim()),
|
|
5905
|
+
value: decode2(pair.slice(eq + 1).trim().replace(/^"(.*)"$/, "$1")),
|
|
5568
5906
|
httpOnly: false,
|
|
5569
5907
|
secure: false
|
|
5570
5908
|
};
|
|
@@ -6518,8 +6856,8 @@ var InteractsWithApplication = class {
|
|
|
6518
6856
|
} finally {
|
|
6519
6857
|
this.destroying = [];
|
|
6520
6858
|
this.application = void 0;
|
|
6521
|
-
const global =
|
|
6522
|
-
if (global === app)
|
|
6859
|
+
const global = Container2.getInstance();
|
|
6860
|
+
if (global === app) Container2.setInstance(void 0);
|
|
6523
6861
|
}
|
|
6524
6862
|
}
|
|
6525
6863
|
/**
|
|
@@ -7823,7 +8161,7 @@ var FakeDisk = class {
|
|
|
7823
8161
|
async put(path, contents, options = {}) {
|
|
7824
8162
|
const key2 = normalize(path);
|
|
7825
8163
|
const bytes = typeof contents === "string" ? new TextEncoder().encode(contents) : contents instanceof Uint8Array ? contents.slice() : await collect(contents);
|
|
7826
|
-
this.write(key2, bytes, options.mimeType ?? diskType(
|
|
8164
|
+
this.write(key2, bytes, options.mimeType ?? diskType(posix2.extname(key2)), options);
|
|
7827
8165
|
return true;
|
|
7828
8166
|
}
|
|
7829
8167
|
putFile(directory, file, options = {}) {
|
|
@@ -8268,7 +8606,9 @@ export {
|
|
|
8268
8606
|
Config,
|
|
8269
8607
|
Repository,
|
|
8270
8608
|
env,
|
|
8609
|
+
RenameClasses,
|
|
8271
8610
|
ApplicationBuilder,
|
|
8611
|
+
ClassNameMap,
|
|
8272
8612
|
ProviderBootError,
|
|
8273
8613
|
ProviderRegisterError,
|
|
8274
8614
|
ViteError,
|
|
@@ -8329,10 +8669,13 @@ export {
|
|
|
8329
8669
|
ExceptionsConfiguration,
|
|
8330
8670
|
applyExceptionCallbacks,
|
|
8331
8671
|
servePublicFile,
|
|
8672
|
+
ExportError,
|
|
8673
|
+
exportSite,
|
|
8332
8674
|
bunRuntime,
|
|
8333
8675
|
serveBun,
|
|
8334
8676
|
toWebRequest,
|
|
8335
8677
|
writeResponse,
|
|
8678
|
+
nodeRequestHandler,
|
|
8336
8679
|
serveNode,
|
|
8337
8680
|
detectRuntime,
|
|
8338
8681
|
serve,
|
|
@@ -8430,4 +8773,4 @@ export {
|
|
|
8430
8773
|
StorageFake,
|
|
8431
8774
|
FakeFile
|
|
8432
8775
|
};
|
|
8433
|
-
//# sourceMappingURL=chunk-
|
|
8776
|
+
//# sourceMappingURL=chunk-7NA4HALO.js.map
|