@hyperspan/framework 0.4.3 → 0.4.5
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/assets.js +1 -1
- package/dist/middleware.js +3 -2
- package/dist/server.js +194 -241
- package/package.json +5 -5
- package/src/actions.test.ts +1 -1
- package/src/assets.ts +2 -2
- package/src/plugins.ts +3 -3
- package/tsconfig.json +5 -1
package/dist/assets.js
CHANGED
|
@@ -27,7 +27,7 @@ function renderClientJS(module, onLoad) {
|
|
|
27
27
|
throw new Error(`[Hyperspan] Client JS was not loaded by Hyperspan! Ensure the filename ends with .client.ts to use this render method.`);
|
|
28
28
|
}
|
|
29
29
|
return html.raw(module.__CLIENT_JS.renderScriptTag({
|
|
30
|
-
onLoad: onLoad ? functionToString(onLoad) : undefined
|
|
30
|
+
onLoad: onLoad ? typeof onLoad === "string" ? onLoad : functionToString(onLoad) : undefined
|
|
31
31
|
}));
|
|
32
32
|
}
|
|
33
33
|
function functionToString(fn) {
|
package/dist/middleware.js
CHANGED
|
@@ -78,7 +78,7 @@ var mergeBuffers = (buffer1, buffer2) => {
|
|
|
78
78
|
if (!buffer1) {
|
|
79
79
|
return buffer2;
|
|
80
80
|
}
|
|
81
|
-
const merged = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
|
|
81
|
+
const merged = new Uint8Array(new ArrayBuffer(buffer1.byteLength + buffer2.byteLength));
|
|
82
82
|
merged.set(new Uint8Array(buffer1), 0);
|
|
83
83
|
merged.set(buffer2, buffer1.byteLength);
|
|
84
84
|
return merged;
|
|
@@ -111,8 +111,9 @@ var RETAINED_304_HEADERS = [
|
|
|
111
111
|
"expires",
|
|
112
112
|
"vary"
|
|
113
113
|
];
|
|
114
|
+
var stripWeak = (tag) => tag.replace(/^W\//, "");
|
|
114
115
|
function etagMatches(etag2, ifNoneMatch) {
|
|
115
|
-
return ifNoneMatch != null && ifNoneMatch.split(/,\s*/).
|
|
116
|
+
return ifNoneMatch != null && ifNoneMatch.split(/,\s*/).some((t) => stripWeak(t) === stripWeak(etag2));
|
|
116
117
|
}
|
|
117
118
|
function initializeGenerator(generator) {
|
|
118
119
|
if (!generator) {
|
package/dist/server.js
CHANGED
|
@@ -16,7 +16,7 @@ async function clientJSPlugin(config) {
|
|
|
16
16
|
async setup(build) {
|
|
17
17
|
build.onLoad({ filter: /\.client\.ts$/ }, async (args) => {
|
|
18
18
|
const jsId = assetHash(args.path);
|
|
19
|
-
if (CLIENT_JS_CACHE.has(jsId)) {
|
|
19
|
+
if (IS_PROD && CLIENT_JS_CACHE.has(jsId)) {
|
|
20
20
|
return {
|
|
21
21
|
contents: CLIENT_JS_CACHE.get(jsId) || "",
|
|
22
22
|
loader: "js"
|
|
@@ -55,10 +55,9 @@ export const __CLIENT_JS = {
|
|
|
55
55
|
sourceFile: "${args.path}",
|
|
56
56
|
outputFile: "${result.outputs[0].path}",
|
|
57
57
|
renderScriptTag: ({ onLoad }) => {
|
|
58
|
-
const fn = onLoad ? functionToString(onLoad) :
|
|
58
|
+
const fn = onLoad ? (typeof onLoad === 'string' ? onLoad : \`const fn = \${functionToString(onLoad)}; fn(${fnArgs});\`) : '';
|
|
59
59
|
return \`<script type="module" data-source-id="${jsId}">import ${exports} from "${esmName}";
|
|
60
|
-
\${fn
|
|
61
|
-
fn(${fnArgs});\` : ''}</script>\`;
|
|
60
|
+
\${fn}</script>\`;
|
|
62
61
|
},
|
|
63
62
|
}
|
|
64
63
|
`;
|
|
@@ -75,10 +74,10 @@ fn(${fnArgs});\` : ''}</script>\`;
|
|
|
75
74
|
// src/server.ts
|
|
76
75
|
import { html, isHSHtml, renderStream, renderAsync, render } from "@hyperspan/html";
|
|
77
76
|
import { readdir } from "node:fs/promises";
|
|
78
|
-
import { basename, extname, join } from "node:path";
|
|
77
|
+
import { basename, extname, join as join2 } from "node:path";
|
|
79
78
|
|
|
80
79
|
// ../../node_modules/isbot/index.mjs
|
|
81
|
-
var fullPattern = " daum[ /]| deusu/|
|
|
80
|
+
var fullPattern = " daum[ /]| deusu/|(?:^|[^g])news(?!sapphire)|(?<! (?:channel/|google/))google(?!(app|/google| pixel))|(?<! cu)bots?(?:\\b|_)|(?<!(?:lib))http|(?<![hg]m)score|(?<!cam)scan|@[a-z][\\w-]+\\.|\\(\\)|\\.com\\b|\\btime/|\\||^<|^[\\w \\.\\-\\(?:\\):%]+(?:/v?\\d+(?:\\.\\d+)?(?:\\.\\d{1,10})*?)?(?:,|$)|^[^ ]{50,}$|^\\d+\\b|^\\w*search\\b|^\\w+/[\\w\\(\\)]*$|^active|^ad muncher|^amaya|^avsdevicesdk/|^azure|^biglotron|^bot|^bw/|^clamav[ /]|^client/|^cobweb/|^custom|^ddg[_-]android|^discourse|^dispatch/\\d|^downcast/|^duckduckgo|^email|^facebook|^getright/|^gozilla/|^hobbit|^hotzonu|^hwcdn/|^igetter/|^jeode/|^jetty/|^jigsaw|^microsoft bits|^movabletype|^mozilla/\\d\\.\\d\\s[\\w\\.-]+$|^mozilla/\\d\\.\\d\\s\\(compatible;?(?:\\s\\w+\\/\\d+\\.\\d+)?\\)$|^navermailapp|^netsurf|^offline|^openai/|^owler|^php|^postman|^python|^rank|^read|^reed|^rest|^rss|^snapchat|^space bison|^svn|^swcd |^taringa|^thumbor/|^track|^w3c|^webbandit/|^webcopier|^wget|^whatsapp|^wordpress|^xenu link sleuth|^yahoo|^yandex|^zdm/\\d|^zoom marketplace/|agent|analyzer|archive|ask jeeves/teoma|audit|bit\\.ly/|bluecoat drtr|browsex|burpcollaborator|capture|catch|check\\b|checker|chrome-lighthouse|chromeframe|classifier|cloudflare|convertify|crawl|cypress/|dareboost|datanyze|dejaclick|detect|dmbrowser|download|evc-batch/|exaleadcloudview|feed|fetcher|firephp|functionize|grab|headless|httrack|hubspot marketing grader|hydra|ibisbrowser|infrawatch|insight|inspect|iplabel|java(?!;)|library|linkcheck|mail\\.ru/|manager|measure|neustar wpm|node|nutch|offbyone|onetrust|optimize|pageburst|pagespeed|parser|perl|phantomjs|pingdom|powermarks|preview|proxy|ptst[ /]\\d|retriever|rexx;|rigor|rss\\b|scrape|server|sogou|sparkler/|speedcurve|spider|splash|statuscake|supercleaner|synapse|synthetic|tools|torrent|transcoder|url|validator|virtuoso|wappalyzer|webglance|webkit2png|whatcms/|xtate/";
|
|
82
81
|
var naivePattern = /bot|crawl|http|lighthouse|scan|search|spider/i;
|
|
83
82
|
var pattern;
|
|
84
83
|
function getPattern() {
|
|
@@ -140,6 +139,9 @@ var compose = (middleware, onError, onNotFound) => {
|
|
|
140
139
|
};
|
|
141
140
|
};
|
|
142
141
|
|
|
142
|
+
// ../../node_modules/hono/dist/request/constants.js
|
|
143
|
+
var GET_MATCH_RESULT = Symbol();
|
|
144
|
+
|
|
143
145
|
// ../../node_modules/hono/dist/utils/body.js
|
|
144
146
|
var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
|
|
145
147
|
const { all = false, dot = false } = options;
|
|
@@ -186,7 +188,11 @@ var handleParsingAllValues = (form, key, value) => {
|
|
|
186
188
|
form[key] = [form[key], value];
|
|
187
189
|
}
|
|
188
190
|
} else {
|
|
189
|
-
|
|
191
|
+
if (!key.endsWith("[]")) {
|
|
192
|
+
form[key] = value;
|
|
193
|
+
} else {
|
|
194
|
+
form[key] = [value];
|
|
195
|
+
}
|
|
190
196
|
}
|
|
191
197
|
};
|
|
192
198
|
var handleParsingNestedValues = (form, key, value) => {
|
|
@@ -273,7 +279,7 @@ var tryDecode = (str, decoder) => {
|
|
|
273
279
|
var tryDecodeURI = (str) => tryDecode(str, decodeURI);
|
|
274
280
|
var getPath = (request) => {
|
|
275
281
|
const url = request.url;
|
|
276
|
-
const start = url.indexOf("/", 8);
|
|
282
|
+
const start = url.indexOf("/", url.charCodeAt(9) === 58 ? 13 : 8);
|
|
277
283
|
let i = start;
|
|
278
284
|
for (;i < url.length; i++) {
|
|
279
285
|
const charCode = url.charCodeAt(i);
|
|
@@ -331,7 +337,7 @@ var _decodeURI = (value) => {
|
|
|
331
337
|
if (value.indexOf("+") !== -1) {
|
|
332
338
|
value = value.replace(/\+/g, " ");
|
|
333
339
|
}
|
|
334
|
-
return value.indexOf("%") !== -1 ?
|
|
340
|
+
return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
|
|
335
341
|
};
|
|
336
342
|
var _getQueryParam = (url, key, multiple) => {
|
|
337
343
|
let encoded;
|
|
@@ -473,7 +479,7 @@ var HonoRequest = class {
|
|
|
473
479
|
return bodyCache[key] = raw[key]();
|
|
474
480
|
};
|
|
475
481
|
json() {
|
|
476
|
-
return this.#cachedBody("
|
|
482
|
+
return this.#cachedBody("text").then((text) => JSON.parse(text));
|
|
477
483
|
}
|
|
478
484
|
text() {
|
|
479
485
|
return this.#cachedBody("text");
|
|
@@ -499,6 +505,9 @@ var HonoRequest = class {
|
|
|
499
505
|
get method() {
|
|
500
506
|
return this.raw.method;
|
|
501
507
|
}
|
|
508
|
+
get [GET_MATCH_RESULT]() {
|
|
509
|
+
return this.#matchResult;
|
|
510
|
+
}
|
|
502
511
|
get matchedRoutes() {
|
|
503
512
|
return this.#matchResult[0].map(([[, route]]) => route);
|
|
504
513
|
}
|
|
@@ -547,11 +556,11 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
|
|
|
547
556
|
|
|
548
557
|
// ../../node_modules/hono/dist/context.js
|
|
549
558
|
var TEXT_PLAIN = "text/plain; charset=UTF-8";
|
|
550
|
-
var
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
559
|
+
var setDefaultContentType = (contentType, headers) => {
|
|
560
|
+
return {
|
|
561
|
+
"Content-Type": contentType,
|
|
562
|
+
...headers
|
|
563
|
+
};
|
|
555
564
|
};
|
|
556
565
|
var Context = class {
|
|
557
566
|
#rawRequest;
|
|
@@ -560,15 +569,13 @@ var Context = class {
|
|
|
560
569
|
#var;
|
|
561
570
|
finalized = false;
|
|
562
571
|
error;
|
|
563
|
-
#status
|
|
572
|
+
#status;
|
|
564
573
|
#executionCtx;
|
|
565
|
-
#headers;
|
|
566
|
-
#preparedHeaders;
|
|
567
574
|
#res;
|
|
568
|
-
#isFresh = true;
|
|
569
575
|
#layout;
|
|
570
576
|
#renderer;
|
|
571
577
|
#notFoundHandler;
|
|
578
|
+
#preparedHeaders;
|
|
572
579
|
#matchResult;
|
|
573
580
|
#path;
|
|
574
581
|
constructor(req, options) {
|
|
@@ -600,11 +607,11 @@ var Context = class {
|
|
|
600
607
|
}
|
|
601
608
|
}
|
|
602
609
|
get res() {
|
|
603
|
-
this.#
|
|
604
|
-
|
|
610
|
+
return this.#res ||= new Response(null, {
|
|
611
|
+
headers: this.#preparedHeaders ??= new Headers
|
|
612
|
+
});
|
|
605
613
|
}
|
|
606
614
|
set res(_res) {
|
|
607
|
-
this.#isFresh = false;
|
|
608
615
|
if (this.#res && _res) {
|
|
609
616
|
_res = new Response(_res.body, _res);
|
|
610
617
|
for (const [k, v] of this.#res.headers.entries()) {
|
|
@@ -638,42 +645,16 @@ var Context = class {
|
|
|
638
645
|
if (this.finalized) {
|
|
639
646
|
this.#res = new Response(this.#res.body, this.#res);
|
|
640
647
|
}
|
|
648
|
+
const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers;
|
|
641
649
|
if (value === undefined) {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
delete this.#preparedHeaders[name.toLocaleLowerCase()];
|
|
646
|
-
}
|
|
647
|
-
if (this.finalized) {
|
|
648
|
-
this.res.headers.delete(name);
|
|
649
|
-
}
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
if (options?.append) {
|
|
653
|
-
if (!this.#headers) {
|
|
654
|
-
this.#isFresh = false;
|
|
655
|
-
this.#headers = new Headers(this.#preparedHeaders);
|
|
656
|
-
this.#preparedHeaders = {};
|
|
657
|
-
}
|
|
658
|
-
this.#headers.append(name, value);
|
|
650
|
+
headers.delete(name);
|
|
651
|
+
} else if (options?.append) {
|
|
652
|
+
headers.append(name, value);
|
|
659
653
|
} else {
|
|
660
|
-
|
|
661
|
-
this.#headers.set(name, value);
|
|
662
|
-
} else {
|
|
663
|
-
this.#preparedHeaders ??= {};
|
|
664
|
-
this.#preparedHeaders[name.toLowerCase()] = value;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
if (this.finalized) {
|
|
668
|
-
if (options?.append) {
|
|
669
|
-
this.res.headers.append(name, value);
|
|
670
|
-
} else {
|
|
671
|
-
this.res.headers.set(name, value);
|
|
672
|
-
}
|
|
654
|
+
headers.set(name, value);
|
|
673
655
|
}
|
|
674
656
|
};
|
|
675
657
|
status = (status) => {
|
|
676
|
-
this.#isFresh = false;
|
|
677
658
|
this.#status = status;
|
|
678
659
|
};
|
|
679
660
|
set = (key, value) => {
|
|
@@ -690,94 +671,47 @@ var Context = class {
|
|
|
690
671
|
return Object.fromEntries(this.#var);
|
|
691
672
|
}
|
|
692
673
|
#newResponse(data, arg, headers) {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
const header = new Headers(arg.headers);
|
|
700
|
-
if (this.#headers) {
|
|
701
|
-
this.#headers.forEach((v, k) => {
|
|
702
|
-
if (k === "set-cookie") {
|
|
703
|
-
header.append(k, v);
|
|
704
|
-
} else {
|
|
705
|
-
header.set(k, v);
|
|
706
|
-
}
|
|
707
|
-
});
|
|
708
|
-
}
|
|
709
|
-
const headers2 = setHeaders(header, this.#preparedHeaders);
|
|
710
|
-
return new Response(data, {
|
|
711
|
-
headers: headers2,
|
|
712
|
-
status: arg.status ?? this.#status
|
|
713
|
-
});
|
|
714
|
-
}
|
|
715
|
-
const status = typeof arg === "number" ? arg : this.#status;
|
|
716
|
-
this.#preparedHeaders ??= {};
|
|
717
|
-
this.#headers ??= new Headers;
|
|
718
|
-
setHeaders(this.#headers, this.#preparedHeaders);
|
|
719
|
-
if (this.#res) {
|
|
720
|
-
this.#res.headers.forEach((v, k) => {
|
|
721
|
-
if (k === "set-cookie") {
|
|
722
|
-
this.#headers?.append(k, v);
|
|
674
|
+
const responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers;
|
|
675
|
+
if (typeof arg === "object" && "headers" in arg) {
|
|
676
|
+
const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);
|
|
677
|
+
for (const [key, value] of argHeaders) {
|
|
678
|
+
if (key.toLowerCase() === "set-cookie") {
|
|
679
|
+
responseHeaders.append(key, value);
|
|
723
680
|
} else {
|
|
724
|
-
|
|
681
|
+
responseHeaders.set(key, value);
|
|
725
682
|
}
|
|
726
|
-
}
|
|
727
|
-
setHeaders(this.#headers, this.#preparedHeaders);
|
|
683
|
+
}
|
|
728
684
|
}
|
|
729
|
-
headers
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
685
|
+
if (headers) {
|
|
686
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
687
|
+
if (typeof v === "string") {
|
|
688
|
+
responseHeaders.set(k, v);
|
|
689
|
+
} else {
|
|
690
|
+
responseHeaders.delete(k);
|
|
691
|
+
for (const v2 of v) {
|
|
692
|
+
responseHeaders.append(k, v2);
|
|
693
|
+
}
|
|
737
694
|
}
|
|
738
695
|
}
|
|
739
696
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
headers: this.#headers
|
|
743
|
-
});
|
|
697
|
+
const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
|
|
698
|
+
return new Response(data, { status, headers: responseHeaders });
|
|
744
699
|
}
|
|
745
700
|
newResponse = (...args) => this.#newResponse(...args);
|
|
746
|
-
body = (data, arg, headers) =>
|
|
747
|
-
return typeof arg === "number" ? this.#newResponse(data, arg, headers) : this.#newResponse(data, arg);
|
|
748
|
-
};
|
|
701
|
+
body = (data, arg, headers) => this.#newResponse(data, arg, headers);
|
|
749
702
|
text = (text, arg, headers) => {
|
|
750
|
-
|
|
751
|
-
if (this.#isFresh && !headers && !arg) {
|
|
752
|
-
return new Response(text);
|
|
753
|
-
}
|
|
754
|
-
this.#preparedHeaders = {};
|
|
755
|
-
}
|
|
756
|
-
this.#preparedHeaders["content-type"] = TEXT_PLAIN;
|
|
757
|
-
if (typeof arg === "number") {
|
|
758
|
-
return this.#newResponse(text, arg, headers);
|
|
759
|
-
}
|
|
760
|
-
return this.#newResponse(text, arg);
|
|
703
|
+
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(text, arg, setDefaultContentType(TEXT_PLAIN, headers));
|
|
761
704
|
};
|
|
762
705
|
json = (object, arg, headers) => {
|
|
763
|
-
|
|
764
|
-
this.#preparedHeaders ??= {};
|
|
765
|
-
this.#preparedHeaders["content-type"] = "application/json";
|
|
766
|
-
return typeof arg === "number" ? this.#newResponse(body, arg, headers) : this.#newResponse(body, arg);
|
|
706
|
+
return this.#newResponse(JSON.stringify(object), arg, setDefaultContentType("application/json", headers));
|
|
767
707
|
};
|
|
768
708
|
html = (html, arg, headers) => {
|
|
769
|
-
this.#
|
|
770
|
-
|
|
771
|
-
if (typeof html === "object") {
|
|
772
|
-
return resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then((html2) => {
|
|
773
|
-
return typeof arg === "number" ? this.#newResponse(html2, arg, headers) : this.#newResponse(html2, arg);
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
return typeof arg === "number" ? this.#newResponse(html, arg, headers) : this.#newResponse(html, arg);
|
|
709
|
+
const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
|
|
710
|
+
return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
|
|
777
711
|
};
|
|
778
712
|
redirect = (location, status) => {
|
|
779
|
-
|
|
780
|
-
this
|
|
713
|
+
const locationString = String(location);
|
|
714
|
+
this.header("Location", !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString));
|
|
781
715
|
return this.newResponse(null, status ?? 302);
|
|
782
716
|
};
|
|
783
717
|
notFound = () => {
|
|
@@ -803,7 +737,8 @@ var notFoundHandler = (c) => {
|
|
|
803
737
|
};
|
|
804
738
|
var errorHandler = (err, c) => {
|
|
805
739
|
if ("getResponse" in err) {
|
|
806
|
-
|
|
740
|
+
const res = err.getResponse();
|
|
741
|
+
return c.newResponse(res.body, res);
|
|
807
742
|
}
|
|
808
743
|
console.error(err);
|
|
809
744
|
return c.text("Internal Server Error", 500);
|
|
@@ -951,7 +886,7 @@ var Hono = class {
|
|
|
951
886
|
#addRoute(method, path, handler) {
|
|
952
887
|
method = method.toUpperCase();
|
|
953
888
|
path = mergePath(this._basePath, path);
|
|
954
|
-
const r = { path, method, handler };
|
|
889
|
+
const r = { basePath: this._basePath, path, method, handler };
|
|
955
890
|
this.router.add(method, path, [handler, r]);
|
|
956
891
|
this.routes.push(r);
|
|
957
892
|
}
|
|
@@ -1062,6 +997,9 @@ var Node = class {
|
|
|
1062
997
|
const name = pattern2[1];
|
|
1063
998
|
let regexpStr = pattern2[2] || LABEL_REG_EXP_STR;
|
|
1064
999
|
if (name && pattern2[2]) {
|
|
1000
|
+
if (regexpStr === ".*") {
|
|
1001
|
+
throw PATH_ERROR;
|
|
1002
|
+
}
|
|
1065
1003
|
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
|
|
1066
1004
|
if (/\((?!\?:)/.test(regexpStr)) {
|
|
1067
1005
|
throw PATH_ERROR;
|
|
@@ -1437,11 +1375,10 @@ var Node2 = class {
|
|
|
1437
1375
|
const nextP = parts[i + 1];
|
|
1438
1376
|
const pattern2 = getPattern2(p, nextP);
|
|
1439
1377
|
const key = Array.isArray(pattern2) ? pattern2[0] : p;
|
|
1440
|
-
if (
|
|
1378
|
+
if (key in curNode.#children) {
|
|
1441
1379
|
curNode = curNode.#children[key];
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
possibleKeys.push(pattern22[1]);
|
|
1380
|
+
if (pattern2) {
|
|
1381
|
+
possibleKeys.push(pattern2[1]);
|
|
1445
1382
|
}
|
|
1446
1383
|
continue;
|
|
1447
1384
|
}
|
|
@@ -1452,14 +1389,13 @@ var Node2 = class {
|
|
|
1452
1389
|
}
|
|
1453
1390
|
curNode = curNode.#children[key];
|
|
1454
1391
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
curNode.#methods.push(m);
|
|
1392
|
+
curNode.#methods.push({
|
|
1393
|
+
[method]: {
|
|
1394
|
+
handler,
|
|
1395
|
+
possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
|
|
1396
|
+
score: this.#order
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1463
1399
|
return curNode;
|
|
1464
1400
|
}
|
|
1465
1401
|
#getHandlerSets(node, method, nodeParams, params) {
|
|
@@ -1520,10 +1456,10 @@ var Node2 = class {
|
|
|
1520
1456
|
}
|
|
1521
1457
|
continue;
|
|
1522
1458
|
}
|
|
1523
|
-
|
|
1459
|
+
const [key, name, matcher] = pattern2;
|
|
1460
|
+
if (!part && !(matcher instanceof RegExp)) {
|
|
1524
1461
|
continue;
|
|
1525
1462
|
}
|
|
1526
|
-
const [key, name, matcher] = pattern2;
|
|
1527
1463
|
const child = node.#children[key];
|
|
1528
1464
|
const restPathString = parts.slice(i).join("/");
|
|
1529
1465
|
if (matcher instanceof RegExp) {
|
|
@@ -1599,42 +1535,11 @@ var Hono2 = class extends Hono {
|
|
|
1599
1535
|
|
|
1600
1536
|
// ../../node_modules/hono/dist/adapter/bun/serve-static.js
|
|
1601
1537
|
import { stat } from "node:fs/promises";
|
|
1538
|
+
import { join } from "node:path";
|
|
1602
1539
|
|
|
1603
1540
|
// ../../node_modules/hono/dist/utils/compress.js
|
|
1604
1541
|
var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
|
|
1605
1542
|
|
|
1606
|
-
// ../../node_modules/hono/dist/utils/filepath.js
|
|
1607
|
-
var getFilePath = (options) => {
|
|
1608
|
-
let filename = options.filename;
|
|
1609
|
-
const defaultDocument = options.defaultDocument || "index.html";
|
|
1610
|
-
if (filename.endsWith("/")) {
|
|
1611
|
-
filename = filename.concat(defaultDocument);
|
|
1612
|
-
} else if (!filename.match(/\.[a-zA-Z0-9_-]+$/)) {
|
|
1613
|
-
filename = filename.concat("/" + defaultDocument);
|
|
1614
|
-
}
|
|
1615
|
-
const path = getFilePathWithoutDefaultDocument({
|
|
1616
|
-
root: options.root,
|
|
1617
|
-
filename
|
|
1618
|
-
});
|
|
1619
|
-
return path;
|
|
1620
|
-
};
|
|
1621
|
-
var getFilePathWithoutDefaultDocument = (options) => {
|
|
1622
|
-
let root = options.root || "";
|
|
1623
|
-
let filename = options.filename;
|
|
1624
|
-
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
|
1625
|
-
return;
|
|
1626
|
-
}
|
|
1627
|
-
filename = filename.replace(/^\.?[\/\\]/, "");
|
|
1628
|
-
filename = filename.replace(/\\/, "/");
|
|
1629
|
-
root = root.replace(/\/$/, "");
|
|
1630
|
-
let path = root ? root + "/" + filename : filename;
|
|
1631
|
-
path = path.replace(/^\.?\//, "");
|
|
1632
|
-
if (root[0] !== "/" && path[0] === "/") {
|
|
1633
|
-
return;
|
|
1634
|
-
}
|
|
1635
|
-
return path;
|
|
1636
|
-
};
|
|
1637
|
-
|
|
1638
1543
|
// ../../node_modules/hono/dist/utils/mime.js
|
|
1639
1544
|
var getMimeType = (filename, mimes = baseMimes) => {
|
|
1640
1545
|
const regexp = /\.([a-zA-Z0-9]+?)$/;
|
|
@@ -1694,6 +1599,7 @@ var _baseMimes = {
|
|
|
1694
1599
|
wasm: "application/wasm",
|
|
1695
1600
|
webm: "video/webm",
|
|
1696
1601
|
weba: "audio/webm",
|
|
1602
|
+
webmanifest: "application/manifest+json",
|
|
1697
1603
|
webp: "image/webp",
|
|
1698
1604
|
woff: "font/woff",
|
|
1699
1605
|
woff2: "font/woff2",
|
|
@@ -1707,6 +1613,22 @@ var _baseMimes = {
|
|
|
1707
1613
|
};
|
|
1708
1614
|
var baseMimes = _baseMimes;
|
|
1709
1615
|
|
|
1616
|
+
// ../../node_modules/hono/dist/middleware/serve-static/path.js
|
|
1617
|
+
var defaultJoin = (...paths) => {
|
|
1618
|
+
let result = paths.filter((p) => p !== "").join("/");
|
|
1619
|
+
result = result.replace(/(?<=\/)\/+/g, "");
|
|
1620
|
+
const segments = result.split("/");
|
|
1621
|
+
const resolved = [];
|
|
1622
|
+
for (const segment of segments) {
|
|
1623
|
+
if (segment === ".." && resolved.length > 0 && resolved.at(-1) !== "..") {
|
|
1624
|
+
resolved.pop();
|
|
1625
|
+
} else if (segment !== ".") {
|
|
1626
|
+
resolved.push(segment);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
return resolved.join("/") || ".";
|
|
1630
|
+
};
|
|
1631
|
+
|
|
1710
1632
|
// ../../node_modules/hono/dist/middleware/serve-static/index.js
|
|
1711
1633
|
var ENCODINGS = {
|
|
1712
1634
|
br: ".br",
|
|
@@ -1715,65 +1637,34 @@ var ENCODINGS = {
|
|
|
1715
1637
|
};
|
|
1716
1638
|
var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
|
|
1717
1639
|
var DEFAULT_DOCUMENT = "index.html";
|
|
1718
|
-
var defaultPathResolve = (path) => path;
|
|
1719
1640
|
var serveStatic = (options) => {
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
if (options.root.startsWith("/")) {
|
|
1724
|
-
isAbsoluteRoot = true;
|
|
1725
|
-
root = new URL(`file://${options.root}`).pathname;
|
|
1726
|
-
} else {
|
|
1727
|
-
root = options.root;
|
|
1728
|
-
}
|
|
1729
|
-
}
|
|
1641
|
+
const root = options.root ?? "./";
|
|
1642
|
+
const optionPath = options.path;
|
|
1643
|
+
const join = options.join ?? defaultJoin;
|
|
1730
1644
|
return async (c, next) => {
|
|
1731
1645
|
if (c.finalized) {
|
|
1732
|
-
|
|
1733
|
-
return;
|
|
1646
|
+
return next();
|
|
1734
1647
|
}
|
|
1735
|
-
let filename
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1648
|
+
let filename;
|
|
1649
|
+
if (options.path) {
|
|
1650
|
+
filename = options.path;
|
|
1651
|
+
} else {
|
|
1652
|
+
try {
|
|
1653
|
+
filename = decodeURIComponent(c.req.path);
|
|
1654
|
+
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
|
1655
|
+
throw new Error;
|
|
1656
|
+
}
|
|
1657
|
+
} catch {
|
|
1658
|
+
await options.onNotFound?.(c.req.path, c);
|
|
1659
|
+
return next();
|
|
1744
1660
|
}
|
|
1745
1661
|
}
|
|
1746
|
-
let path =
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
defaultDocument: DEFAULT_DOCUMENT
|
|
1750
|
-
});
|
|
1751
|
-
if (!path) {
|
|
1752
|
-
return await next();
|
|
1753
|
-
}
|
|
1754
|
-
if (isAbsoluteRoot) {
|
|
1755
|
-
path = "/" + path;
|
|
1662
|
+
let path = join(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename);
|
|
1663
|
+
if (options.isDir && await options.isDir(path)) {
|
|
1664
|
+
path = join(path, DEFAULT_DOCUMENT);
|
|
1756
1665
|
}
|
|
1757
1666
|
const getContent = options.getContent;
|
|
1758
|
-
const pathResolve = options.pathResolve ?? defaultPathResolve;
|
|
1759
|
-
path = pathResolve(path);
|
|
1760
1667
|
let content = await getContent(path, c);
|
|
1761
|
-
if (!content) {
|
|
1762
|
-
let pathWithoutDefaultDocument = getFilePathWithoutDefaultDocument({
|
|
1763
|
-
filename,
|
|
1764
|
-
root
|
|
1765
|
-
});
|
|
1766
|
-
if (!pathWithoutDefaultDocument) {
|
|
1767
|
-
return await next();
|
|
1768
|
-
}
|
|
1769
|
-
pathWithoutDefaultDocument = pathResolve(pathWithoutDefaultDocument);
|
|
1770
|
-
if (pathWithoutDefaultDocument !== path) {
|
|
1771
|
-
content = await getContent(pathWithoutDefaultDocument, c);
|
|
1772
|
-
if (content) {
|
|
1773
|
-
path = pathWithoutDefaultDocument;
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
1668
|
if (content instanceof Response) {
|
|
1778
1669
|
return c.newResponse(content.body, content);
|
|
1779
1670
|
}
|
|
@@ -1808,13 +1699,9 @@ var serveStatic = (options) => {
|
|
|
1808
1699
|
var serveStatic2 = (options) => {
|
|
1809
1700
|
return async function serveStatic2(c, next) {
|
|
1810
1701
|
const getContent = async (path) => {
|
|
1811
|
-
path = path.startsWith("/") ? path : `./${path}`;
|
|
1812
1702
|
const file = Bun.file(path);
|
|
1813
1703
|
return await file.exists() ? file : null;
|
|
1814
1704
|
};
|
|
1815
|
-
const pathResolve = (path) => {
|
|
1816
|
-
return path.startsWith("/") ? path : `./${path}`;
|
|
1817
|
-
};
|
|
1818
1705
|
const isDir = async (path) => {
|
|
1819
1706
|
let isDir2;
|
|
1820
1707
|
try {
|
|
@@ -1826,7 +1713,7 @@ var serveStatic2 = (options) => {
|
|
|
1826
1713
|
return serveStatic({
|
|
1827
1714
|
...options,
|
|
1828
1715
|
getContent,
|
|
1829
|
-
|
|
1716
|
+
join,
|
|
1830
1717
|
isDir
|
|
1831
1718
|
})(c, next);
|
|
1832
1719
|
};
|
|
@@ -1870,6 +1757,52 @@ var WSContext = class {
|
|
|
1870
1757
|
this.#init.close(code, reason);
|
|
1871
1758
|
}
|
|
1872
1759
|
};
|
|
1760
|
+
var defineWebSocketHelper = (handler) => {
|
|
1761
|
+
return (...args) => {
|
|
1762
|
+
if (typeof args[0] === "function") {
|
|
1763
|
+
const [createEvents, options] = args;
|
|
1764
|
+
return async function upgradeWebSocket(c, next) {
|
|
1765
|
+
const events = await createEvents(c);
|
|
1766
|
+
const result = await handler(c, events, options);
|
|
1767
|
+
if (result) {
|
|
1768
|
+
return result;
|
|
1769
|
+
}
|
|
1770
|
+
await next();
|
|
1771
|
+
};
|
|
1772
|
+
} else {
|
|
1773
|
+
const [c, events, options] = args;
|
|
1774
|
+
return (async () => {
|
|
1775
|
+
const upgraded = await handler(c, events, options);
|
|
1776
|
+
if (!upgraded) {
|
|
1777
|
+
throw new Error("Failed to upgrade WebSocket");
|
|
1778
|
+
}
|
|
1779
|
+
return upgraded;
|
|
1780
|
+
})();
|
|
1781
|
+
}
|
|
1782
|
+
};
|
|
1783
|
+
};
|
|
1784
|
+
|
|
1785
|
+
// ../../node_modules/hono/dist/adapter/bun/server.js
|
|
1786
|
+
var getBunServer = (c) => ("server" in c.env) ? c.env.server : c.env;
|
|
1787
|
+
|
|
1788
|
+
// ../../node_modules/hono/dist/adapter/bun/websocket.js
|
|
1789
|
+
var upgradeWebSocket = defineWebSocketHelper((c, events) => {
|
|
1790
|
+
const server = getBunServer(c);
|
|
1791
|
+
if (!server) {
|
|
1792
|
+
throw new TypeError("env has to include the 2nd argument of fetch.");
|
|
1793
|
+
}
|
|
1794
|
+
const upgradeResult = server.upgrade(c.req.raw, {
|
|
1795
|
+
data: {
|
|
1796
|
+
events,
|
|
1797
|
+
url: new URL(c.req.url),
|
|
1798
|
+
protocol: c.req.url
|
|
1799
|
+
}
|
|
1800
|
+
});
|
|
1801
|
+
if (upgradeResult) {
|
|
1802
|
+
return new Response(null);
|
|
1803
|
+
}
|
|
1804
|
+
return;
|
|
1805
|
+
});
|
|
1873
1806
|
|
|
1874
1807
|
// ../../node_modules/hono/dist/http-exception.js
|
|
1875
1808
|
var HTTPException = class extends Error {
|
|
@@ -1895,10 +1828,12 @@ var HTTPException = class extends Error {
|
|
|
1895
1828
|
};
|
|
1896
1829
|
|
|
1897
1830
|
// ../../node_modules/hono/dist/middleware/csrf/index.js
|
|
1831
|
+
var secFetchSiteValues = ["same-origin", "same-site", "none", "cross-site"];
|
|
1832
|
+
var isSecFetchSite = (value) => secFetchSiteValues.includes(value);
|
|
1898
1833
|
var isSafeMethodRe = /^(GET|HEAD)$/;
|
|
1899
1834
|
var isRequestedByFormElementRe = /^\b(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)\b/i;
|
|
1900
1835
|
var csrf = (options) => {
|
|
1901
|
-
const
|
|
1836
|
+
const originHandler = ((optsOrigin) => {
|
|
1902
1837
|
if (!optsOrigin) {
|
|
1903
1838
|
return (origin, c) => origin === new URL(c.req.url).origin;
|
|
1904
1839
|
} else if (typeof optsOrigin === "string") {
|
|
@@ -1913,13 +1848,31 @@ var csrf = (options) => {
|
|
|
1913
1848
|
if (origin === undefined) {
|
|
1914
1849
|
return false;
|
|
1915
1850
|
}
|
|
1916
|
-
return
|
|
1851
|
+
return originHandler(origin, c);
|
|
1852
|
+
};
|
|
1853
|
+
const secFetchSiteHandler = ((optsSecFetchSite) => {
|
|
1854
|
+
if (!optsSecFetchSite) {
|
|
1855
|
+
return (secFetchSite) => secFetchSite === "same-origin";
|
|
1856
|
+
} else if (typeof optsSecFetchSite === "string") {
|
|
1857
|
+
return (secFetchSite) => secFetchSite === optsSecFetchSite;
|
|
1858
|
+
} else if (typeof optsSecFetchSite === "function") {
|
|
1859
|
+
return optsSecFetchSite;
|
|
1860
|
+
} else {
|
|
1861
|
+
return (secFetchSite) => optsSecFetchSite.includes(secFetchSite);
|
|
1862
|
+
}
|
|
1863
|
+
})(options?.secFetchSite);
|
|
1864
|
+
const isAllowedSecFetchSite = (secFetchSite, c) => {
|
|
1865
|
+
if (secFetchSite === undefined) {
|
|
1866
|
+
return false;
|
|
1867
|
+
}
|
|
1868
|
+
if (!isSecFetchSite(secFetchSite)) {
|
|
1869
|
+
return false;
|
|
1870
|
+
}
|
|
1871
|
+
return secFetchSiteHandler(secFetchSite, c);
|
|
1917
1872
|
};
|
|
1918
1873
|
return async function csrf2(c, next) {
|
|
1919
|
-
if (!isSafeMethodRe.test(c.req.method) && isRequestedByFormElementRe.test(c.req.header("content-type") || "text/plain") && !isAllowedOrigin(c.req.header("origin"), c)) {
|
|
1920
|
-
const res = new Response("Forbidden", {
|
|
1921
|
-
status: 403
|
|
1922
|
-
});
|
|
1874
|
+
if (!isSafeMethodRe.test(c.req.method) && isRequestedByFormElementRe.test(c.req.header("content-type") || "text/plain") && !isAllowedSecFetchSite(c.req.header("sec-fetch-site"), c) && !isAllowedOrigin(c.req.header("origin"), c)) {
|
|
1875
|
+
const res = new Response("Forbidden", { status: 403 });
|
|
1923
1876
|
throw new HTTPException(403, { res });
|
|
1924
1877
|
}
|
|
1925
1878
|
await next();
|
|
@@ -2160,7 +2113,7 @@ async function showErrorReponse(context, err, responseOptions) {
|
|
|
2160
2113
|
}
|
|
2161
2114
|
var ROUTE_SEGMENT = /(\[[a-zA-Z_\.]+\])/g;
|
|
2162
2115
|
async function buildRoutes(config) {
|
|
2163
|
-
const routesDir =
|
|
2116
|
+
const routesDir = join2(config.appDir, "routes");
|
|
2164
2117
|
const files = await readdir(routesDir, { recursive: true });
|
|
2165
2118
|
const routes = [];
|
|
2166
2119
|
for (const file of files) {
|
|
@@ -2187,18 +2140,18 @@ async function buildRoutes(config) {
|
|
|
2187
2140
|
});
|
|
2188
2141
|
}
|
|
2189
2142
|
routes.push({
|
|
2190
|
-
file:
|
|
2143
|
+
file: join2("./", routesDir, file),
|
|
2191
2144
|
route: normalizePath(route || "/"),
|
|
2192
2145
|
params
|
|
2193
2146
|
});
|
|
2194
2147
|
}
|
|
2195
2148
|
return await Promise.all(routes.map(async (route) => {
|
|
2196
|
-
route.module = (await import(
|
|
2149
|
+
route.module = (await import(join2(CWD, route.file))).default;
|
|
2197
2150
|
return route;
|
|
2198
2151
|
}));
|
|
2199
2152
|
}
|
|
2200
2153
|
async function buildActions(config) {
|
|
2201
|
-
const routesDir =
|
|
2154
|
+
const routesDir = join2(config.appDir, "actions");
|
|
2202
2155
|
const files = await readdir(routesDir, { recursive: true });
|
|
2203
2156
|
const routes = [];
|
|
2204
2157
|
for (const file of files) {
|
|
@@ -2207,13 +2160,13 @@ async function buildActions(config) {
|
|
|
2207
2160
|
}
|
|
2208
2161
|
let route = assetHash("/" + file.replace(extname(file), ""));
|
|
2209
2162
|
routes.push({
|
|
2210
|
-
file:
|
|
2163
|
+
file: join2("./", routesDir, file),
|
|
2211
2164
|
route: `/__actions/${route}`,
|
|
2212
2165
|
params: []
|
|
2213
2166
|
});
|
|
2214
2167
|
}
|
|
2215
2168
|
return await Promise.all(routes.map(async (route) => {
|
|
2216
|
-
route.module = (await import(
|
|
2169
|
+
route.module = (await import(join2(CWD, route.file))).default;
|
|
2217
2170
|
route.route = route.module._route;
|
|
2218
2171
|
return route;
|
|
2219
2172
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperspan/framework",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "Hyperspan Web Framework",
|
|
5
5
|
"main": "dist/server.ts",
|
|
6
6
|
"types": "src/server.ts",
|
|
@@ -65,10 +65,10 @@
|
|
|
65
65
|
"typescript": "^5.8.3"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@hyperspan/html": "
|
|
69
|
-
"hono": "^4.
|
|
70
|
-
"isbot": "^5.1.
|
|
68
|
+
"@hyperspan/html": "0.1.7",
|
|
69
|
+
"hono": "^4.9.4",
|
|
70
|
+
"isbot": "^5.1.30",
|
|
71
71
|
"timestring": "^7.0.0",
|
|
72
|
-
"zod": "^
|
|
72
|
+
"zod": "^4.1.5"
|
|
73
73
|
}
|
|
74
74
|
}
|
package/src/actions.test.ts
CHANGED
|
@@ -61,7 +61,7 @@ describe('createAction', () => {
|
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
describe('when data is invalid', () => {
|
|
64
|
+
describe.skip('when data is invalid', () => {
|
|
65
65
|
it('should return the content of the form with error', async () => {
|
|
66
66
|
const schema = z.object({
|
|
67
67
|
name: z.string().nonempty(),
|
package/src/assets.ts
CHANGED
|
@@ -36,7 +36,7 @@ export async function buildClientJS() {
|
|
|
36
36
|
/**
|
|
37
37
|
* Render a client JS module as a script tag
|
|
38
38
|
*/
|
|
39
|
-
export function renderClientJS<T>(module: T, onLoad?: (module: T) => void) {
|
|
39
|
+
export function renderClientJS<T>(module: T, onLoad?: (module: T) => void | string) {
|
|
40
40
|
// @ts-ignore
|
|
41
41
|
if (!module.__CLIENT_JS) {
|
|
42
42
|
throw new Error(
|
|
@@ -47,7 +47,7 @@ export function renderClientJS<T>(module: T, onLoad?: (module: T) => void) {
|
|
|
47
47
|
return html.raw(
|
|
48
48
|
// @ts-ignore
|
|
49
49
|
module.__CLIENT_JS.renderScriptTag({
|
|
50
|
-
onLoad: onLoad ? functionToString(onLoad) : undefined,
|
|
50
|
+
onLoad: onLoad ? (typeof onLoad === 'string' ? onLoad : functionToString(onLoad)) : undefined,
|
|
51
51
|
})
|
|
52
52
|
);
|
|
53
53
|
}
|
package/src/plugins.ts
CHANGED
|
@@ -17,7 +17,7 @@ export async function clientJSPlugin(config: THSServerConfig) {
|
|
|
17
17
|
const jsId = assetHash(args.path);
|
|
18
18
|
|
|
19
19
|
// Cache: Avoid re-processing the same file
|
|
20
|
-
if (CLIENT_JS_CACHE.has(jsId)) {
|
|
20
|
+
if (IS_PROD && CLIENT_JS_CACHE.has(jsId)) {
|
|
21
21
|
return {
|
|
22
22
|
contents: CLIENT_JS_CACHE.get(jsId) || '',
|
|
23
23
|
loader: 'js',
|
|
@@ -72,8 +72,8 @@ export const __CLIENT_JS = {
|
|
|
72
72
|
sourceFile: "${args.path}",
|
|
73
73
|
outputFile: "${result.outputs[0].path}",
|
|
74
74
|
renderScriptTag: ({ onLoad }) => {
|
|
75
|
-
const fn = onLoad ? functionToString(onLoad) :
|
|
76
|
-
return \`<script type="module" data-source-id="${jsId}">import ${exports} from "${esmName}";\n\${fn
|
|
75
|
+
const fn = onLoad ? (typeof onLoad === 'string' ? onLoad : \`const fn = \${functionToString(onLoad)}; fn(${fnArgs});\`) : '';
|
|
76
|
+
return \`<script type="module" data-source-id="${jsId}">import ${exports} from "${esmName}";\n\${fn}</script>\`;
|
|
77
77
|
},
|
|
78
78
|
}
|
|
79
79
|
`;
|
package/tsconfig.json
CHANGED
|
@@ -19,7 +19,11 @@
|
|
|
19
19
|
"skipLibCheck": true,
|
|
20
20
|
"allowSyntheticDefaultImports": true,
|
|
21
21
|
"forceConsistentCasingInFileNames": true,
|
|
22
|
-
"allowJs": true
|
|
22
|
+
"allowJs": true,
|
|
23
|
+
"baseUrl": ".",
|
|
24
|
+
"paths": {
|
|
25
|
+
"@hyperspan/html": ["../html/src/html.ts"]
|
|
26
|
+
}
|
|
23
27
|
},
|
|
24
28
|
"exclude": ["node_modules", "__tests__", "*.test.ts"]
|
|
25
29
|
}
|