shokupan 0.15.0 → 0.15.2
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/{index-46Z4ASUY.cjs → index-B-bQ7kZy.cjs} +232 -79
- package/dist/index-B-bQ7kZy.cjs.map +1 -0
- package/dist/{index-MDmdOQNV.js → index-BsMp6pBd.js} +229 -76
- package/dist/index-BsMp6pBd.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{knex-BbK40SH3.js → knex-CnHqFsjZ.js} +2 -2
- package/dist/{knex-BbK40SH3.js.map → knex-CnHqFsjZ.js.map} +1 -1
- package/dist/{knex-CIS1IT0Y.cjs → knex-DYPtgZG5.cjs} +2 -2
- package/dist/{knex-CIS1IT0Y.cjs.map → knex-DYPtgZG5.cjs.map} +1 -1
- package/dist/{level-Dhm9CiBU.js → level-BH1qmHgY.js} +2 -2
- package/dist/{level-Dhm9CiBU.js.map → level-BH1qmHgY.js.map} +1 -1
- package/dist/{level-B0zBSwWA.cjs → level-C8w1C6JX.cjs} +2 -2
- package/dist/{level-B0zBSwWA.cjs.map → level-C8w1C6JX.cjs.map} +1 -1
- package/dist/plugins/application/api-explorer/plugin.d.ts +9 -0
- package/dist/plugins/middleware/cors.d.ts +11 -0
- package/dist/{sqlite-sfDxgiji.cjs → sqlite-Bf3Y44PF.cjs} +2 -2
- package/dist/{sqlite-sfDxgiji.cjs.map → sqlite-Bf3Y44PF.cjs.map} +1 -1
- package/dist/{sqlite-CY-WyaJ5.js → sqlite-C2dVWOnw.js} +2 -2
- package/dist/{sqlite-CY-WyaJ5.js.map → sqlite-C2dVWOnw.js.map} +1 -1
- package/dist/{surreal-D1txBCZb.js → surreal-C6kHsjO6.js} +2 -2
- package/dist/{surreal-D1txBCZb.js.map → surreal-C6kHsjO6.js.map} +1 -1
- package/dist/{surreal-DiEl_VJL.cjs → surreal-Ctjsrb6S.cjs} +2 -2
- package/dist/{surreal-DiEl_VJL.cjs.map → surreal-Ctjsrb6S.cjs.map} +1 -1
- package/dist/util/body-parser.d.ts +7 -0
- package/dist/util/env-loader.d.ts +2 -0
- package/package.json +1 -1
- package/dist/index-46Z4ASUY.cjs.map +0 -1
- package/dist/index-MDmdOQNV.js.map +0 -1
|
@@ -116,26 +116,63 @@ class BodyParser {
|
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
118
|
* Parsing helper for FormData
|
|
119
|
+
* Security: Enforces maxBodySize by reading the raw body stream before
|
|
120
|
+
* handing it to formData(), so the limit cannot be bypassed via a spoofed
|
|
121
|
+
* Content-Length header.
|
|
119
122
|
*/
|
|
120
123
|
static async parseFormData(req, maxBodySize) {
|
|
121
|
-
|
|
122
|
-
if (!clHeader) {
|
|
124
|
+
if (!req.headers.has("content-length") && req.headers.get("transfer-encoding") !== "chunked") {
|
|
123
125
|
const err = new Error("Length Required");
|
|
124
126
|
err.status = 411;
|
|
125
127
|
throw err;
|
|
126
128
|
}
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
const rawBuffer = await BodyParser.readRawBufferBody(req, maxBodySize);
|
|
130
|
+
const syntheticReq = new Request("http://localhost", {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers: req.headers,
|
|
133
|
+
body: rawBuffer.buffer
|
|
134
|
+
});
|
|
135
|
+
return syntheticReq.formData();
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Reads raw body as Uint8Array with size enforcement (used by parseFormData).
|
|
139
|
+
*/
|
|
140
|
+
static async readRawBufferBody(req, maxBodySize) {
|
|
141
|
+
if (typeof req.body === "string") {
|
|
142
|
+
const enc = new TextEncoder().encode(req.body);
|
|
143
|
+
if (enc.byteLength > maxBodySize) {
|
|
144
|
+
const err = new Error("Payload Too Large");
|
|
145
|
+
err.status = 413;
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
148
|
+
return enc;
|
|
132
149
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
150
|
+
const reader = req.body?.getReader();
|
|
151
|
+
if (!reader) return new Uint8Array(0);
|
|
152
|
+
const chunks = [];
|
|
153
|
+
let totalSize = 0;
|
|
154
|
+
try {
|
|
155
|
+
while (true) {
|
|
156
|
+
const { done, value } = await reader.read();
|
|
157
|
+
if (done) break;
|
|
158
|
+
totalSize += value.length;
|
|
159
|
+
if (totalSize > maxBodySize) {
|
|
160
|
+
const err = new Error("Payload Too Large");
|
|
161
|
+
err.status = 413;
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
164
|
+
chunks.push(value);
|
|
165
|
+
}
|
|
166
|
+
} finally {
|
|
167
|
+
reader.releaseLock();
|
|
137
168
|
}
|
|
138
|
-
|
|
169
|
+
const result = new Uint8Array(totalSize);
|
|
170
|
+
let offset = 0;
|
|
171
|
+
for (const chunk of chunks) {
|
|
172
|
+
result.set(chunk, offset);
|
|
173
|
+
offset += chunk.length;
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
139
176
|
}
|
|
140
177
|
/**
|
|
141
178
|
* Reads raw body as string with size enforcement
|
|
@@ -1383,7 +1420,7 @@ class ShokupanContext {
|
|
|
1383
1420
|
}
|
|
1384
1421
|
function RateLimitMiddleware(options = {}) {
|
|
1385
1422
|
const windowMs = options.windowMs || 60 * 1e3;
|
|
1386
|
-
const max = options.limit || options.max ||
|
|
1423
|
+
const max = options.limit || options.max || 100;
|
|
1387
1424
|
const message = options.message || "Too many requests, please try again later.";
|
|
1388
1425
|
const statusCode = options.statusCode || 429;
|
|
1389
1426
|
const headers = options.headers !== false;
|
|
@@ -1412,9 +1449,7 @@ function RateLimitMiddleware(options = {}) {
|
|
|
1412
1449
|
const hits = /* @__PURE__ */ new Map();
|
|
1413
1450
|
const interval = setInterval(() => {
|
|
1414
1451
|
const now = Date.now();
|
|
1415
|
-
const
|
|
1416
|
-
for (let i = 0; i < entries.length; i++) {
|
|
1417
|
-
const [key, record] = entries[i];
|
|
1452
|
+
for (const [key, record] of hits) {
|
|
1418
1453
|
if (record.resetTime <= now) {
|
|
1419
1454
|
hits.delete(key);
|
|
1420
1455
|
}
|
|
@@ -2797,7 +2832,12 @@ function serveStatic(config, prefix) {
|
|
|
2797
2832
|
const normalizedPrefix = prefix.endsWith("/") && prefix !== "/" ? prefix.slice(0, -1) : prefix;
|
|
2798
2833
|
const isEtag = !!config.etag;
|
|
2799
2834
|
const extensions = config.extensions || ["html", "htm", "htmx"];
|
|
2835
|
+
const cacheEnabled = config.useCache !== false;
|
|
2800
2836
|
const FILES = {};
|
|
2837
|
+
let _resolveReady;
|
|
2838
|
+
const _ready = new Promise((resolve2) => {
|
|
2839
|
+
_resolveReady = resolve2;
|
|
2840
|
+
});
|
|
2801
2841
|
function toHeaders(name, stats, isEtag2) {
|
|
2802
2842
|
const ctype = mrmime.lookup(name) || "application/octet-stream";
|
|
2803
2843
|
const headers = {
|
|
@@ -2813,7 +2853,7 @@ function serveStatic(config, prefix) {
|
|
|
2813
2853
|
}
|
|
2814
2854
|
return headers;
|
|
2815
2855
|
}
|
|
2816
|
-
if (
|
|
2856
|
+
if (cacheEnabled) {
|
|
2817
2857
|
async function walk(dir) {
|
|
2818
2858
|
const entries = await promises$1.readdir(dir, { withFileTypes: true });
|
|
2819
2859
|
for (const entry of entries) {
|
|
@@ -2828,10 +2868,15 @@ function serveStatic(config, prefix) {
|
|
|
2828
2868
|
}
|
|
2829
2869
|
}
|
|
2830
2870
|
}
|
|
2831
|
-
walk(rootPath).catch(
|
|
2871
|
+
walk(rootPath).then(_resolveReady).catch((err) => {
|
|
2872
|
+
console.error("[serveStatic] Cache population error:", err);
|
|
2873
|
+
_resolveReady();
|
|
2874
|
+
});
|
|
2875
|
+
} else {
|
|
2876
|
+
_resolveReady();
|
|
2832
2877
|
}
|
|
2833
2878
|
const serveStaticMiddleware = async (ctx) => {
|
|
2834
|
-
let reqPath = ctx.path.slice(normalizedPrefix.length);
|
|
2879
|
+
let reqPath = ctx.params?.["*"] ?? ctx.path.slice(normalizedPrefix.length);
|
|
2835
2880
|
if (!reqPath.startsWith("/")) reqPath = "/" + reqPath;
|
|
2836
2881
|
try {
|
|
2837
2882
|
reqPath = decodeURIComponent(reqPath);
|
|
@@ -2842,7 +2887,7 @@ function serveStatic(config, prefix) {
|
|
|
2842
2887
|
return ctx.json({ error: "Forbidden" }, 403);
|
|
2843
2888
|
}
|
|
2844
2889
|
let file;
|
|
2845
|
-
if (
|
|
2890
|
+
if (cacheEnabled) {
|
|
2846
2891
|
file = FILES[reqPath];
|
|
2847
2892
|
if (!file) {
|
|
2848
2893
|
for (const ext of extensions) {
|
|
@@ -2919,7 +2964,7 @@ function serveStatic(config, prefix) {
|
|
|
2919
2964
|
<li><a href="../">../</a></li>
|
|
2920
2965
|
<% } %>
|
|
2921
2966
|
<% it.files.forEach(function(f) { %>
|
|
2922
|
-
<li><a href="<%= f %>"><%= f %></a></li>
|
|
2967
|
+
<li><a href="<%= encodeURIComponent(f) %>"><%= f %></a></li>
|
|
2923
2968
|
<% }) %>
|
|
2924
2969
|
</ul>
|
|
2925
2970
|
</body>
|
|
@@ -2977,6 +3022,7 @@ function serveStatic(config, prefix) {
|
|
|
2977
3022
|
};
|
|
2978
3023
|
serveStaticMiddleware.isBuiltin = true;
|
|
2979
3024
|
serveStaticMiddleware.pluginName = "ServeStatic";
|
|
3025
|
+
serveStaticMiddleware.ready = _ready;
|
|
2980
3026
|
return serveStaticMiddleware;
|
|
2981
3027
|
}
|
|
2982
3028
|
class OpenTelemetryPlugin {
|
|
@@ -3691,14 +3737,21 @@ class RouterTrie {
|
|
|
3691
3737
|
delete params[node.paramChild.paramName];
|
|
3692
3738
|
}
|
|
3693
3739
|
if (node.wildcardChild) {
|
|
3740
|
+
params["*"] = segment;
|
|
3694
3741
|
const result = this.findNode(node.wildcardChild, segments, index + 1, params);
|
|
3695
3742
|
if (result) return result;
|
|
3743
|
+
delete params["*"];
|
|
3696
3744
|
}
|
|
3697
3745
|
if (node.recursiveChild) {
|
|
3698
3746
|
const remaining = segments.length - index;
|
|
3699
3747
|
for (let k = 0; k <= remaining; k++) {
|
|
3748
|
+
const matchedSegments = segments.slice(index, index + k).join("/");
|
|
3749
|
+
params["*"] = matchedSegments;
|
|
3750
|
+
params["**"] = matchedSegments;
|
|
3700
3751
|
const result = this.findNode(node.recursiveChild, segments, index + k, params);
|
|
3701
3752
|
if (result) return result;
|
|
3753
|
+
delete params["*"];
|
|
3754
|
+
delete params["**"];
|
|
3702
3755
|
}
|
|
3703
3756
|
}
|
|
3704
3757
|
return null;
|
|
@@ -4173,13 +4226,13 @@ class ShokupanRouter {
|
|
|
4173
4226
|
}
|
|
4174
4227
|
return ctx.upgrade({
|
|
4175
4228
|
open: async (ctx2, ws) => {
|
|
4229
|
+
ctx2[$ws] = ws;
|
|
4176
4230
|
if (handlers.onOpen) {
|
|
4177
4231
|
const sessionData = await handlers.onOpen(ctx2, ws);
|
|
4178
4232
|
if (sessionData !== void 0) {
|
|
4179
4233
|
ws.data = sessionData;
|
|
4180
4234
|
ctx2.state = sessionData;
|
|
4181
4235
|
}
|
|
4182
|
-
ctx2[$ws] = ws;
|
|
4183
4236
|
}
|
|
4184
4237
|
if (!ctx2[$wsMessages]) ctx2[$wsMessages] = [];
|
|
4185
4238
|
const originalSend = ws.send.bind(ws);
|
|
@@ -4287,6 +4340,7 @@ class ShokupanRouter {
|
|
|
4287
4340
|
}
|
|
4288
4341
|
return ctx.upgrade({
|
|
4289
4342
|
open: async (ctx2, ws) => {
|
|
4343
|
+
ctx2[$ws] = ws;
|
|
4290
4344
|
if (openMethodName) {
|
|
4291
4345
|
const openMethod = instance[openMethodName];
|
|
4292
4346
|
if (openMethod) {
|
|
@@ -4615,13 +4669,17 @@ class ShokupanRouter {
|
|
|
4615
4669
|
find(method, path2) {
|
|
4616
4670
|
let result = this.trie.search(method, path2);
|
|
4617
4671
|
if (result) {
|
|
4618
|
-
|
|
4672
|
+
if (!this[$isApplication]) {
|
|
4673
|
+
result.handler = this.wrapHandlerWithMiddleware(result.handler);
|
|
4674
|
+
}
|
|
4619
4675
|
return result;
|
|
4620
4676
|
}
|
|
4621
4677
|
if (method === "HEAD") {
|
|
4622
4678
|
result = this.trie.search("GET", path2);
|
|
4623
4679
|
if (result) {
|
|
4624
|
-
|
|
4680
|
+
if (!this[$isApplication]) {
|
|
4681
|
+
result.handler = this.wrapHandlerWithMiddleware(result.handler);
|
|
4682
|
+
}
|
|
4625
4683
|
return result;
|
|
4626
4684
|
}
|
|
4627
4685
|
}
|
|
@@ -5920,29 +5978,29 @@ class Shokupan extends ShokupanRouter {
|
|
|
5920
5978
|
try {
|
|
5921
5979
|
switch (adapterName) {
|
|
5922
5980
|
case "sqlite": {
|
|
5923
|
-
const { SqliteAdapter } = await Promise.resolve().then(() => require("./sqlite-
|
|
5981
|
+
const { SqliteAdapter } = await Promise.resolve().then(() => require("./sqlite-Bf3Y44PF.cjs"));
|
|
5924
5982
|
this.datastore = new SqliteAdapter(options);
|
|
5925
5983
|
break;
|
|
5926
5984
|
}
|
|
5927
5985
|
case "level": {
|
|
5928
|
-
const { LevelAdapter } = await Promise.resolve().then(() => require("./level-
|
|
5986
|
+
const { LevelAdapter } = await Promise.resolve().then(() => require("./level-C8w1C6JX.cjs"));
|
|
5929
5987
|
this.datastore = new LevelAdapter(options);
|
|
5930
5988
|
break;
|
|
5931
5989
|
}
|
|
5932
5990
|
case "surrealdb": {
|
|
5933
|
-
const { SurrealAdapter } = await Promise.resolve().then(() => require("./surreal-
|
|
5991
|
+
const { SurrealAdapter } = await Promise.resolve().then(() => require("./surreal-Ctjsrb6S.cjs"));
|
|
5934
5992
|
const legacyConfig = this.applicationConfig.surreal || {};
|
|
5935
5993
|
const effectiveOptions = { ...legacyConfig, ...options };
|
|
5936
5994
|
this.datastore = new SurrealAdapter(effectiveOptions);
|
|
5937
5995
|
break;
|
|
5938
5996
|
}
|
|
5939
5997
|
case "knex": {
|
|
5940
|
-
const { KnexAdapter } = await Promise.resolve().then(() => require("./knex-
|
|
5998
|
+
const { KnexAdapter } = await Promise.resolve().then(() => require("./knex-DYPtgZG5.cjs"));
|
|
5941
5999
|
this.datastore = new KnexAdapter(options || {});
|
|
5942
6000
|
break;
|
|
5943
6001
|
}
|
|
5944
6002
|
default: {
|
|
5945
|
-
const { SurrealAdapter } = await Promise.resolve().then(() => require("./surreal-
|
|
6003
|
+
const { SurrealAdapter } = await Promise.resolve().then(() => require("./surreal-Ctjsrb6S.cjs"));
|
|
5946
6004
|
const legacy = this.applicationConfig.surreal;
|
|
5947
6005
|
this.datastore = new SurrealAdapter(options || legacy || {});
|
|
5948
6006
|
}
|
|
@@ -6897,7 +6955,7 @@ class ApiExplorerPlugin extends ShokupanRouter {
|
|
|
6897
6955
|
}
|
|
6898
6956
|
}
|
|
6899
6957
|
static getBasePath() {
|
|
6900
|
-
const dir = path$1.dirname(node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-
|
|
6958
|
+
const dir = path$1.dirname(node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-B-bQ7kZy.cjs", document.baseURI).href));
|
|
6901
6959
|
if (dir.endsWith("dist")) {
|
|
6902
6960
|
return dir + "/plugins/application/api-explorer";
|
|
6903
6961
|
}
|
|
@@ -6926,22 +6984,26 @@ class ApiExplorerPlugin extends ShokupanRouter {
|
|
|
6926
6984
|
this.get("/style.css", (ctx) => serveFile(ctx, "style.css", "text/css"));
|
|
6927
6985
|
this.get("/theme.css", (ctx) => serveFile(ctx, "theme.css", "text/css"));
|
|
6928
6986
|
this.get("/explorer-client.mjs", (ctx) => serveFile(ctx, "explorer-client.mjs", "application/javascript"));
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6987
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
6988
|
+
const sourceViewEnabled = this.pluginOptions.enableSourceView ?? !isProduction;
|
|
6989
|
+
if (sourceViewEnabled) {
|
|
6990
|
+
this.get("/_source", async (ctx) => {
|
|
6991
|
+
const file = ctx.query["file"];
|
|
6992
|
+
if (!file) return ctx.text("Missing file parameter", 400);
|
|
6993
|
+
const { resolve } = await import("node:path");
|
|
6994
|
+
const cwd = process.cwd();
|
|
6995
|
+
const resolvedPath = resolve(cwd, file);
|
|
6996
|
+
if (!resolvedPath.startsWith(cwd + "/") && resolvedPath !== cwd) {
|
|
6997
|
+
return ctx.text("Forbidden: File must be within project root", 403);
|
|
6998
|
+
}
|
|
6999
|
+
try {
|
|
7000
|
+
const content = await promises$1.readFile(resolvedPath, "utf-8");
|
|
7001
|
+
return ctx.text(content);
|
|
7002
|
+
} catch (err) {
|
|
7003
|
+
return ctx.text("File not found", 404);
|
|
7004
|
+
}
|
|
7005
|
+
});
|
|
7006
|
+
}
|
|
6945
7007
|
this.get("/openapi.json", async (ctx) => {
|
|
6946
7008
|
const spec = this.root.openApiSpec ? structuredClone(this.root.openApiSpec) : await (this.root || this).generateApiSpec();
|
|
6947
7009
|
return ctx.json(stripSourceCode(spec));
|
|
@@ -7566,7 +7628,7 @@ class AsyncApiPlugin extends ShokupanRouter {
|
|
|
7566
7628
|
this.init();
|
|
7567
7629
|
}
|
|
7568
7630
|
static getBasePath() {
|
|
7569
|
-
const dir = path$1.dirname(node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-
|
|
7631
|
+
const dir = path$1.dirname(node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-B-bQ7kZy.cjs", document.baseURI).href));
|
|
7570
7632
|
if (dir.endsWith("dist")) {
|
|
7571
7633
|
return dir + "/plugins/application/asyncapi";
|
|
7572
7634
|
}
|
|
@@ -7822,7 +7884,16 @@ class AuthPlugin extends ShokupanRouter {
|
|
|
7822
7884
|
};
|
|
7823
7885
|
} else if (provider === "apple") {
|
|
7824
7886
|
if (idToken) {
|
|
7825
|
-
const
|
|
7887
|
+
const { createRemoteJWKSet, jwtVerify } = this.jose;
|
|
7888
|
+
if (!this._appleJwks) {
|
|
7889
|
+
this._appleJwks = createRemoteJWKSet(
|
|
7890
|
+
new URL("https://appleid.apple.com/auth/keys")
|
|
7891
|
+
);
|
|
7892
|
+
}
|
|
7893
|
+
const { payload } = await jwtVerify(idToken, this._appleJwks, {
|
|
7894
|
+
issuer: "https://appleid.apple.com",
|
|
7895
|
+
audience: this.authConfig.providers.apple?.clientId
|
|
7896
|
+
});
|
|
7826
7897
|
user = {
|
|
7827
7898
|
id: payload.sub,
|
|
7828
7899
|
email: payload["email"],
|
|
@@ -8199,7 +8270,7 @@ function Card({ title, contentId }) {
|
|
|
8199
8270
|
/* @__PURE__ */ jsxRuntime.jsx("div", { id: contentId })
|
|
8200
8271
|
] });
|
|
8201
8272
|
}
|
|
8202
|
-
const require$1 = node_module.createRequire(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-
|
|
8273
|
+
const require$1 = node_module.createRequire(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-B-bQ7kZy.cjs", document.baseURI).href);
|
|
8203
8274
|
const http = require$1("node:http");
|
|
8204
8275
|
const https = require$1("node:https");
|
|
8205
8276
|
class FetchInterceptor {
|
|
@@ -8803,7 +8874,7 @@ class Dashboard {
|
|
|
8803
8874
|
}
|
|
8804
8875
|
// Get base path for dashboard files - works in both dev (src/) and production (dist/)
|
|
8805
8876
|
static getBasePath() {
|
|
8806
|
-
const dir = path$1.dirname(node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-
|
|
8877
|
+
const dir = path$1.dirname(node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-B-bQ7kZy.cjs", document.baseURI).href));
|
|
8807
8878
|
if (dir.endsWith("dist")) {
|
|
8808
8879
|
return dir + "/plugins/application/dashboard";
|
|
8809
8880
|
}
|
|
@@ -11212,14 +11283,29 @@ function Compression(options = {}) {
|
|
|
11212
11283
|
}
|
|
11213
11284
|
const acceptEncoding = ctx.headers.get("accept-encoding") || "";
|
|
11214
11285
|
let method = null;
|
|
11215
|
-
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11220
|
-
|
|
11221
|
-
|
|
11222
|
-
|
|
11286
|
+
const encodings = acceptEncoding.split(",");
|
|
11287
|
+
for (let i = 0; i < encodings.length; i++) {
|
|
11288
|
+
const enc = encodings[i].split(";")[0].trim().toLowerCase();
|
|
11289
|
+
if (enc === "br" && allowedAlgorithms.has("br")) {
|
|
11290
|
+
method = "br";
|
|
11291
|
+
break;
|
|
11292
|
+
}
|
|
11293
|
+
if (enc === "zstd" && allowedAlgorithms.has("zstd")) {
|
|
11294
|
+
if (typeof Bun !== "undefined") {
|
|
11295
|
+
method = "zstd";
|
|
11296
|
+
break;
|
|
11297
|
+
}
|
|
11298
|
+
continue;
|
|
11299
|
+
}
|
|
11300
|
+
if (enc === "gzip" && allowedAlgorithms.has("gzip")) {
|
|
11301
|
+
method = "gzip";
|
|
11302
|
+
break;
|
|
11303
|
+
}
|
|
11304
|
+
if (enc === "deflate" && allowedAlgorithms.has("deflate")) {
|
|
11305
|
+
method = "deflate";
|
|
11306
|
+
break;
|
|
11307
|
+
}
|
|
11308
|
+
}
|
|
11223
11309
|
if (!method) return next();
|
|
11224
11310
|
if (!allowedAlgorithms.has(method)) {
|
|
11225
11311
|
return next();
|
|
@@ -11306,6 +11392,11 @@ function Cors(options = {}) {
|
|
|
11306
11392
|
optionsSuccessStatus: 204
|
|
11307
11393
|
};
|
|
11308
11394
|
const opts = { ...defaults2, ...options };
|
|
11395
|
+
if (opts.credentials && opts.origin === "*") {
|
|
11396
|
+
throw new Error(
|
|
11397
|
+
'CORS misconfiguration: `credentials: true` is incompatible with `origin: "*"`. Specify an explicit origin or array of origins instead.'
|
|
11398
|
+
);
|
|
11399
|
+
}
|
|
11309
11400
|
const corsMiddleware = async function CorsMiddleware(ctx, next) {
|
|
11310
11401
|
const headers = {};
|
|
11311
11402
|
const origin = ctx.headers.get("origin");
|
|
@@ -11591,10 +11682,21 @@ function validate(config) {
|
|
|
11591
11682
|
let validQuery;
|
|
11592
11683
|
if (validators.query && queryObj) {
|
|
11593
11684
|
validQuery = await validators.query(queryObj);
|
|
11685
|
+
Object.defineProperty(ctx, "query", {
|
|
11686
|
+
value: validQuery,
|
|
11687
|
+
writable: true,
|
|
11688
|
+
configurable: true
|
|
11689
|
+
});
|
|
11594
11690
|
}
|
|
11691
|
+
let validHeaders;
|
|
11595
11692
|
if (validators.headers) {
|
|
11596
11693
|
const headersObj = Object.fromEntries(ctx.req.headers.entries());
|
|
11597
|
-
await validators.headers(headersObj);
|
|
11694
|
+
validHeaders = await validators.headers(headersObj);
|
|
11695
|
+
Object.defineProperty(ctx, "headers", {
|
|
11696
|
+
value: new Headers(validHeaders),
|
|
11697
|
+
writable: true,
|
|
11698
|
+
configurable: true
|
|
11699
|
+
});
|
|
11598
11700
|
}
|
|
11599
11701
|
let validBody;
|
|
11600
11702
|
if (validators.body) {
|
|
@@ -11612,6 +11714,7 @@ function validate(config) {
|
|
|
11612
11714
|
const validatedData = { ...dataToValidate };
|
|
11613
11715
|
if (config.params) validatedData.params = ctx.params;
|
|
11614
11716
|
if (config.query) validatedData.query = validQuery;
|
|
11717
|
+
if (config.headers) validatedData.headers = validHeaders;
|
|
11615
11718
|
if (config.body) validatedData.body = validBody;
|
|
11616
11719
|
await ctx.app.runHooks("afterValidate", ctx, validatedData);
|
|
11617
11720
|
return next();
|
|
@@ -11852,6 +11955,9 @@ function Proxy$1(options) {
|
|
|
11852
11955
|
if (!["http:", "https:"].includes(url.protocol)) {
|
|
11853
11956
|
return ctx.text("Invalid protocol in proxied URL", 400);
|
|
11854
11957
|
}
|
|
11958
|
+
if (options.allowedHosts && !options.allowedHosts.includes(url.hostname)) {
|
|
11959
|
+
return ctx.text("Proxied hostname not in allowlist", 403);
|
|
11960
|
+
}
|
|
11855
11961
|
const headers = new Headers(req.headers);
|
|
11856
11962
|
if (options.changeOrigin) {
|
|
11857
11963
|
headers.set("host", targetUrl.host);
|
|
@@ -11945,7 +12051,16 @@ function handleWSDrain(ws) {
|
|
|
11945
12051
|
}
|
|
11946
12052
|
function SecurityHeaders(options = {}) {
|
|
11947
12053
|
const securityHeadersMiddleware = async function SecurityHeadersMiddleware(ctx, next) {
|
|
11948
|
-
const
|
|
12054
|
+
const response = await next();
|
|
12055
|
+
const set = (k, v) => {
|
|
12056
|
+
if (response instanceof Response) {
|
|
12057
|
+
try {
|
|
12058
|
+
response.headers.set(k, v);
|
|
12059
|
+
} catch (e) {
|
|
12060
|
+
}
|
|
12061
|
+
}
|
|
12062
|
+
ctx.response.headers.set(k, v);
|
|
12063
|
+
};
|
|
11949
12064
|
if (options.dnsPrefetchControl !== false) {
|
|
11950
12065
|
const allow = options.dnsPrefetchControl?.allow;
|
|
11951
12066
|
set("X-DNS-Prefetch-Control", allow ? "on" : "off");
|
|
@@ -11956,7 +12071,7 @@ function SecurityHeaders(options = {}) {
|
|
|
11956
12071
|
if (action === "sameorigin") set("X-Frame-Options", "SAMEORIGIN");
|
|
11957
12072
|
else if (action === "deny") set("X-Frame-Options", "DENY");
|
|
11958
12073
|
}
|
|
11959
|
-
if (options.hsts !== false) {
|
|
12074
|
+
if (options.hsts !== false && ctx.secure === true) {
|
|
11960
12075
|
const opt = options.hsts || {};
|
|
11961
12076
|
const maxAge = opt.maxAge || 15552e3;
|
|
11962
12077
|
let header = `max-age=${maxAge}`;
|
|
@@ -11983,20 +12098,39 @@ function SecurityHeaders(options = {}) {
|
|
|
11983
12098
|
if (opt === void 0 || opt === true) {
|
|
11984
12099
|
set("Content-Security-Policy", "default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests");
|
|
11985
12100
|
} else if (typeof opt === "object") {
|
|
11986
|
-
const
|
|
11987
|
-
for (
|
|
11988
|
-
|
|
12101
|
+
const parts = [];
|
|
12102
|
+
for (const [key, val] of Object.entries(opt)) {
|
|
12103
|
+
if (val === false) continue;
|
|
12104
|
+
const directive = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
12105
|
+
if (val === true) {
|
|
12106
|
+
parts.push(directive);
|
|
12107
|
+
} else {
|
|
12108
|
+
const sources = Array.isArray(val) ? val.join(" ") : String(val);
|
|
12109
|
+
parts.push(`${directive} ${sources}`);
|
|
12110
|
+
}
|
|
12111
|
+
}
|
|
12112
|
+
if (parts.length > 0) {
|
|
12113
|
+
set("Content-Security-Policy", parts.join(";"));
|
|
11989
12114
|
}
|
|
11990
12115
|
}
|
|
11991
12116
|
}
|
|
11992
|
-
if (options.hidePoweredBy !== false)
|
|
11993
|
-
|
|
12117
|
+
if (options.hidePoweredBy !== false) {
|
|
12118
|
+
if (response instanceof Response) {
|
|
12119
|
+
try {
|
|
12120
|
+
response.headers.delete("X-Powered-By");
|
|
12121
|
+
} catch (e) {
|
|
12122
|
+
}
|
|
12123
|
+
}
|
|
12124
|
+
ctx.response.headers.delete("X-Powered-By");
|
|
12125
|
+
}
|
|
11994
12126
|
return response;
|
|
11995
12127
|
};
|
|
11996
12128
|
securityHeadersMiddleware.isBuiltin = true;
|
|
11997
12129
|
securityHeadersMiddleware.pluginName = "SecurityHeaders";
|
|
11998
12130
|
return securityHeadersMiddleware;
|
|
11999
12131
|
}
|
|
12132
|
+
const $isDirty = /* @__PURE__ */ Symbol("isDirty");
|
|
12133
|
+
const $resetDirty = /* @__PURE__ */ Symbol("resetDirty");
|
|
12000
12134
|
class Cookie {
|
|
12001
12135
|
maxAge;
|
|
12002
12136
|
signed;
|
|
@@ -12103,7 +12237,7 @@ function unsign(input, secret) {
|
|
|
12103
12237
|
Buffer.from(expectedInput).copy(paddedExpected);
|
|
12104
12238
|
Buffer.from(input).copy(paddedInput);
|
|
12105
12239
|
try {
|
|
12106
|
-
const valid =
|
|
12240
|
+
const valid = crypto.timingSafeEqual(paddedExpected, paddedInput);
|
|
12107
12241
|
return valid ? tentValue : false;
|
|
12108
12242
|
} catch {
|
|
12109
12243
|
return false;
|
|
@@ -12122,10 +12256,14 @@ function Session(options) {
|
|
|
12122
12256
|
const cookies = ctx.cookies;
|
|
12123
12257
|
const rawCookie = cookies[name];
|
|
12124
12258
|
if (rawCookie) {
|
|
12125
|
-
if (rawCookie.
|
|
12126
|
-
const
|
|
12127
|
-
|
|
12128
|
-
|
|
12259
|
+
if (rawCookie.slice(0, 2) === "s:") {
|
|
12260
|
+
const signed = rawCookie.slice(2);
|
|
12261
|
+
for (let i = 0; i < secrets.length; i++) {
|
|
12262
|
+
const val = unsign(signed, secrets[i]);
|
|
12263
|
+
if (val !== false) {
|
|
12264
|
+
reqSessionId = val;
|
|
12265
|
+
break;
|
|
12266
|
+
}
|
|
12129
12267
|
}
|
|
12130
12268
|
} else {
|
|
12131
12269
|
reqSessionId = rawCookie;
|
|
@@ -12181,8 +12319,6 @@ function Session(options) {
|
|
|
12181
12319
|
});
|
|
12182
12320
|
});
|
|
12183
12321
|
};
|
|
12184
|
-
sessObj.undefined = () => {
|
|
12185
|
-
};
|
|
12186
12322
|
sessObj.reload = () => {
|
|
12187
12323
|
return new Promise((resolve, reject) => {
|
|
12188
12324
|
store.get(sessObj.id, (err, sess2) => {
|
|
@@ -12204,7 +12340,25 @@ function Session(options) {
|
|
|
12204
12340
|
sessObj.cookie.expires = new Date(Date.now() + (sessObj.cookie.maxAge || 0));
|
|
12205
12341
|
if (store.touch) store.touch(sessObj.id, sessObj);
|
|
12206
12342
|
};
|
|
12207
|
-
|
|
12343
|
+
let _dirty = false;
|
|
12344
|
+
const skippedKeys = /* @__PURE__ */ new Set(["id", "save", "destroy", "regenerate", "reload", "touch"]);
|
|
12345
|
+
const proxy = new Proxy(sessObj, {
|
|
12346
|
+
set(target, prop, value, receiver) {
|
|
12347
|
+
if (typeof prop !== "symbol" && !skippedKeys.has(prop)) {
|
|
12348
|
+
_dirty = true;
|
|
12349
|
+
}
|
|
12350
|
+
return Reflect.set(target, prop, value, receiver);
|
|
12351
|
+
},
|
|
12352
|
+
deleteProperty(target, prop) {
|
|
12353
|
+
if (typeof prop !== "symbol" && !skippedKeys.has(prop)) _dirty = true;
|
|
12354
|
+
return Reflect.deleteProperty(target, prop);
|
|
12355
|
+
}
|
|
12356
|
+
});
|
|
12357
|
+
proxy[$isDirty] = () => _dirty;
|
|
12358
|
+
proxy[$resetDirty] = () => {
|
|
12359
|
+
_dirty = false;
|
|
12360
|
+
};
|
|
12361
|
+
return proxy;
|
|
12208
12362
|
};
|
|
12209
12363
|
let sessionData = null;
|
|
12210
12364
|
if (!isNew && sessionID) {
|
|
@@ -12227,17 +12381,15 @@ function Session(options) {
|
|
|
12227
12381
|
ctx.session = sess;
|
|
12228
12382
|
ctx.sessionID = sessionID;
|
|
12229
12383
|
ctx.sessionStore = store;
|
|
12230
|
-
const originalHash = JSON.stringify(sess);
|
|
12231
12384
|
const result = await next();
|
|
12232
|
-
const
|
|
12233
|
-
const isModified = originalHash !== currentHash;
|
|
12385
|
+
const isModified = sess[$isDirty]?.() ?? false;
|
|
12234
12386
|
if (!sessionID) return result;
|
|
12235
12387
|
let shouldSave = false;
|
|
12236
12388
|
if (isModified) {
|
|
12237
12389
|
shouldSave = true;
|
|
12238
12390
|
} else if (isNew && saveUninitialized) {
|
|
12239
12391
|
shouldSave = true;
|
|
12240
|
-
} else if (!isNew && resave) {
|
|
12392
|
+
} else if (!isNew && resave && isModified) {
|
|
12241
12393
|
shouldSave = true;
|
|
12242
12394
|
}
|
|
12243
12395
|
if (shouldSave) {
|
|
@@ -12274,6 +12426,7 @@ function Static(options, prefix = "/") {
|
|
|
12274
12426
|
try {
|
|
12275
12427
|
const result = await staticMiddleware(ctx, next);
|
|
12276
12428
|
if (result instanceof Response && result.status === 404) {
|
|
12429
|
+
ctx.response.status = 200;
|
|
12277
12430
|
return next();
|
|
12278
12431
|
}
|
|
12279
12432
|
return result;
|
|
@@ -12425,4 +12578,4 @@ exports.traceMiddleware = traceMiddleware;
|
|
|
12425
12578
|
exports.useExpress = useExpress;
|
|
12426
12579
|
exports.valibot = valibot;
|
|
12427
12580
|
exports.validate = validate;
|
|
12428
|
-
//# sourceMappingURL=index-
|
|
12581
|
+
//# sourceMappingURL=index-B-bQ7kZy.cjs.map
|