shokupan 0.15.1 → 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.
Files changed (26) hide show
  1. package/dist/{index-5vGQaaL5.cjs → index-B-bQ7kZy.cjs} +123 -36
  2. package/dist/index-B-bQ7kZy.cjs.map +1 -0
  3. package/dist/{index-Da50R4Vm.js → index-BsMp6pBd.js} +119 -32
  4. package/dist/index-BsMp6pBd.js.map +1 -0
  5. package/dist/index.cjs +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/{knex-Cy3JHwDL.js → knex-CnHqFsjZ.js} +2 -2
  8. package/dist/{knex-Cy3JHwDL.js.map → knex-CnHqFsjZ.js.map} +1 -1
  9. package/dist/{knex-CDjnrxdn.cjs → knex-DYPtgZG5.cjs} +2 -2
  10. package/dist/{knex-CDjnrxdn.cjs.map → knex-DYPtgZG5.cjs.map} +1 -1
  11. package/dist/{level--l_261kz.js → level-BH1qmHgY.js} +2 -2
  12. package/dist/{level--l_261kz.js.map → level-BH1qmHgY.js.map} +1 -1
  13. package/dist/{level-dUQVvWkh.cjs → level-C8w1C6JX.cjs} +2 -2
  14. package/dist/{level-dUQVvWkh.cjs.map → level-C8w1C6JX.cjs.map} +1 -1
  15. package/dist/{sqlite-DdGPsbUB.cjs → sqlite-Bf3Y44PF.cjs} +2 -2
  16. package/dist/{sqlite-DdGPsbUB.cjs.map → sqlite-Bf3Y44PF.cjs.map} +1 -1
  17. package/dist/{sqlite-DOyRAxVq.js → sqlite-C2dVWOnw.js} +2 -2
  18. package/dist/{sqlite-DOyRAxVq.js.map → sqlite-C2dVWOnw.js.map} +1 -1
  19. package/dist/{surreal-BHXu9CVo.js → surreal-C6kHsjO6.js} +2 -2
  20. package/dist/{surreal-BHXu9CVo.js.map → surreal-C6kHsjO6.js.map} +1 -1
  21. package/dist/{surreal-p1skSyYf.cjs → surreal-Ctjsrb6S.cjs} +2 -2
  22. package/dist/{surreal-p1skSyYf.cjs.map → surreal-Ctjsrb6S.cjs.map} +1 -1
  23. package/dist/util/env-loader.d.ts +2 -0
  24. package/package.json +1 -1
  25. package/dist/index-5vGQaaL5.cjs.map +0 -1
  26. package/dist/index-Da50R4Vm.js.map +0 -1
@@ -121,6 +121,11 @@ class BodyParser {
121
121
  * Content-Length header.
122
122
  */
123
123
  static async parseFormData(req, maxBodySize) {
124
+ if (!req.headers.has("content-length") && req.headers.get("transfer-encoding") !== "chunked") {
125
+ const err = new Error("Length Required");
126
+ err.status = 411;
127
+ throw err;
128
+ }
124
129
  const rawBuffer = await BodyParser.readRawBufferBody(req, maxBodySize);
125
130
  const syntheticReq = new Request("http://localhost", {
126
131
  method: "POST",
@@ -2827,7 +2832,12 @@ function serveStatic(config, prefix) {
2827
2832
  const normalizedPrefix = prefix.endsWith("/") && prefix !== "/" ? prefix.slice(0, -1) : prefix;
2828
2833
  const isEtag = !!config.etag;
2829
2834
  const extensions = config.extensions || ["html", "htm", "htmx"];
2835
+ const cacheEnabled = config.useCache !== false;
2830
2836
  const FILES = {};
2837
+ let _resolveReady;
2838
+ const _ready = new Promise((resolve2) => {
2839
+ _resolveReady = resolve2;
2840
+ });
2831
2841
  function toHeaders(name, stats, isEtag2) {
2832
2842
  const ctype = mrmime.lookup(name) || "application/octet-stream";
2833
2843
  const headers = {
@@ -2843,7 +2853,7 @@ function serveStatic(config, prefix) {
2843
2853
  }
2844
2854
  return headers;
2845
2855
  }
2846
- if (!config.useCache) {
2856
+ if (cacheEnabled) {
2847
2857
  async function walk(dir) {
2848
2858
  const entries = await promises$1.readdir(dir, { withFileTypes: true });
2849
2859
  for (const entry of entries) {
@@ -2858,10 +2868,15 @@ function serveStatic(config, prefix) {
2858
2868
  }
2859
2869
  }
2860
2870
  }
2861
- walk(rootPath).catch(console.error);
2871
+ walk(rootPath).then(_resolveReady).catch((err) => {
2872
+ console.error("[serveStatic] Cache population error:", err);
2873
+ _resolveReady();
2874
+ });
2875
+ } else {
2876
+ _resolveReady();
2862
2877
  }
2863
2878
  const serveStaticMiddleware = async (ctx) => {
2864
- let reqPath = ctx.path.slice(normalizedPrefix.length);
2879
+ let reqPath = ctx.params?.["*"] ?? ctx.path.slice(normalizedPrefix.length);
2865
2880
  if (!reqPath.startsWith("/")) reqPath = "/" + reqPath;
2866
2881
  try {
2867
2882
  reqPath = decodeURIComponent(reqPath);
@@ -2872,7 +2887,7 @@ function serveStatic(config, prefix) {
2872
2887
  return ctx.json({ error: "Forbidden" }, 403);
2873
2888
  }
2874
2889
  let file;
2875
- if (!config.useCache) {
2890
+ if (cacheEnabled) {
2876
2891
  file = FILES[reqPath];
2877
2892
  if (!file) {
2878
2893
  for (const ext of extensions) {
@@ -2949,7 +2964,7 @@ function serveStatic(config, prefix) {
2949
2964
  <li><a href="../">../</a></li>
2950
2965
  <% } %>
2951
2966
  <% it.files.forEach(function(f) { %>
2952
- <li><a href="<%= f %>"><%= f %></a></li>
2967
+ <li><a href="<%= encodeURIComponent(f) %>"><%= f %></a></li>
2953
2968
  <% }) %>
2954
2969
  </ul>
2955
2970
  </body>
@@ -3007,6 +3022,7 @@ function serveStatic(config, prefix) {
3007
3022
  };
3008
3023
  serveStaticMiddleware.isBuiltin = true;
3009
3024
  serveStaticMiddleware.pluginName = "ServeStatic";
3025
+ serveStaticMiddleware.ready = _ready;
3010
3026
  return serveStaticMiddleware;
3011
3027
  }
3012
3028
  class OpenTelemetryPlugin {
@@ -3721,14 +3737,21 @@ class RouterTrie {
3721
3737
  delete params[node.paramChild.paramName];
3722
3738
  }
3723
3739
  if (node.wildcardChild) {
3740
+ params["*"] = segment;
3724
3741
  const result = this.findNode(node.wildcardChild, segments, index + 1, params);
3725
3742
  if (result) return result;
3743
+ delete params["*"];
3726
3744
  }
3727
3745
  if (node.recursiveChild) {
3728
3746
  const remaining = segments.length - index;
3729
3747
  for (let k = 0; k <= remaining; k++) {
3748
+ const matchedSegments = segments.slice(index, index + k).join("/");
3749
+ params["*"] = matchedSegments;
3750
+ params["**"] = matchedSegments;
3730
3751
  const result = this.findNode(node.recursiveChild, segments, index + k, params);
3731
3752
  if (result) return result;
3753
+ delete params["*"];
3754
+ delete params["**"];
3732
3755
  }
3733
3756
  }
3734
3757
  return null;
@@ -4203,13 +4226,13 @@ class ShokupanRouter {
4203
4226
  }
4204
4227
  return ctx.upgrade({
4205
4228
  open: async (ctx2, ws) => {
4229
+ ctx2[$ws] = ws;
4206
4230
  if (handlers.onOpen) {
4207
4231
  const sessionData = await handlers.onOpen(ctx2, ws);
4208
4232
  if (sessionData !== void 0) {
4209
4233
  ws.data = sessionData;
4210
4234
  ctx2.state = sessionData;
4211
4235
  }
4212
- ctx2[$ws] = ws;
4213
4236
  }
4214
4237
  if (!ctx2[$wsMessages]) ctx2[$wsMessages] = [];
4215
4238
  const originalSend = ws.send.bind(ws);
@@ -4317,6 +4340,7 @@ class ShokupanRouter {
4317
4340
  }
4318
4341
  return ctx.upgrade({
4319
4342
  open: async (ctx2, ws) => {
4343
+ ctx2[$ws] = ws;
4320
4344
  if (openMethodName) {
4321
4345
  const openMethod = instance[openMethodName];
4322
4346
  if (openMethod) {
@@ -4645,13 +4669,17 @@ class ShokupanRouter {
4645
4669
  find(method, path2) {
4646
4670
  let result = this.trie.search(method, path2);
4647
4671
  if (result) {
4648
- result.handler = this.wrapHandlerWithMiddleware(result.handler);
4672
+ if (!this[$isApplication]) {
4673
+ result.handler = this.wrapHandlerWithMiddleware(result.handler);
4674
+ }
4649
4675
  return result;
4650
4676
  }
4651
4677
  if (method === "HEAD") {
4652
4678
  result = this.trie.search("GET", path2);
4653
4679
  if (result) {
4654
- result.handler = this.wrapHandlerWithMiddleware(result.handler);
4680
+ if (!this[$isApplication]) {
4681
+ result.handler = this.wrapHandlerWithMiddleware(result.handler);
4682
+ }
4655
4683
  return result;
4656
4684
  }
4657
4685
  }
@@ -5950,29 +5978,29 @@ class Shokupan extends ShokupanRouter {
5950
5978
  try {
5951
5979
  switch (adapterName) {
5952
5980
  case "sqlite": {
5953
- const { SqliteAdapter } = await Promise.resolve().then(() => require("./sqlite-DdGPsbUB.cjs"));
5981
+ const { SqliteAdapter } = await Promise.resolve().then(() => require("./sqlite-Bf3Y44PF.cjs"));
5954
5982
  this.datastore = new SqliteAdapter(options);
5955
5983
  break;
5956
5984
  }
5957
5985
  case "level": {
5958
- const { LevelAdapter } = await Promise.resolve().then(() => require("./level-dUQVvWkh.cjs"));
5986
+ const { LevelAdapter } = await Promise.resolve().then(() => require("./level-C8w1C6JX.cjs"));
5959
5987
  this.datastore = new LevelAdapter(options);
5960
5988
  break;
5961
5989
  }
5962
5990
  case "surrealdb": {
5963
- const { SurrealAdapter } = await Promise.resolve().then(() => require("./surreal-p1skSyYf.cjs"));
5991
+ const { SurrealAdapter } = await Promise.resolve().then(() => require("./surreal-Ctjsrb6S.cjs"));
5964
5992
  const legacyConfig = this.applicationConfig.surreal || {};
5965
5993
  const effectiveOptions = { ...legacyConfig, ...options };
5966
5994
  this.datastore = new SurrealAdapter(effectiveOptions);
5967
5995
  break;
5968
5996
  }
5969
5997
  case "knex": {
5970
- const { KnexAdapter } = await Promise.resolve().then(() => require("./knex-CDjnrxdn.cjs"));
5998
+ const { KnexAdapter } = await Promise.resolve().then(() => require("./knex-DYPtgZG5.cjs"));
5971
5999
  this.datastore = new KnexAdapter(options || {});
5972
6000
  break;
5973
6001
  }
5974
6002
  default: {
5975
- const { SurrealAdapter } = await Promise.resolve().then(() => require("./surreal-p1skSyYf.cjs"));
6003
+ const { SurrealAdapter } = await Promise.resolve().then(() => require("./surreal-Ctjsrb6S.cjs"));
5976
6004
  const legacy = this.applicationConfig.surreal;
5977
6005
  this.datastore = new SurrealAdapter(options || legacy || {});
5978
6006
  }
@@ -6927,7 +6955,7 @@ class ApiExplorerPlugin extends ShokupanRouter {
6927
6955
  }
6928
6956
  }
6929
6957
  static getBasePath() {
6930
- 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-5vGQaaL5.cjs", document.baseURI).href));
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));
6931
6959
  if (dir.endsWith("dist")) {
6932
6960
  return dir + "/plugins/application/api-explorer";
6933
6961
  }
@@ -7600,7 +7628,7 @@ class AsyncApiPlugin extends ShokupanRouter {
7600
7628
  this.init();
7601
7629
  }
7602
7630
  static getBasePath() {
7603
- 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-5vGQaaL5.cjs", document.baseURI).href));
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));
7604
7632
  if (dir.endsWith("dist")) {
7605
7633
  return dir + "/plugins/application/asyncapi";
7606
7634
  }
@@ -8242,7 +8270,7 @@ function Card({ title, contentId }) {
8242
8270
  /* @__PURE__ */ jsxRuntime.jsx("div", { id: contentId })
8243
8271
  ] });
8244
8272
  }
8245
- const require$1 = node_module.createRequire(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-5vGQaaL5.cjs", document.baseURI).href);
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);
8246
8274
  const http = require$1("node:http");
8247
8275
  const https = require$1("node:https");
8248
8276
  class FetchInterceptor {
@@ -8846,7 +8874,7 @@ class Dashboard {
8846
8874
  }
8847
8875
  // Get base path for dashboard files - works in both dev (src/) and production (dist/)
8848
8876
  static getBasePath() {
8849
- 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-5vGQaaL5.cjs", document.baseURI).href));
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));
8850
8878
  if (dir.endsWith("dist")) {
8851
8879
  return dir + "/plugins/application/dashboard";
8852
8880
  }
@@ -11255,14 +11283,29 @@ function Compression(options = {}) {
11255
11283
  }
11256
11284
  const acceptEncoding = ctx.headers.get("accept-encoding") || "";
11257
11285
  let method = null;
11258
- if (acceptEncoding.includes("br")) method = "br";
11259
- else if (acceptEncoding.includes("zstd")) {
11260
- if (typeof Bun === "undefined") {
11261
- throw new Error("zstd compression is only available in Bun runtime. Client requested zstd but server is running on Node.js.");
11262
- }
11263
- method = "zstd";
11264
- } else if (acceptEncoding.includes("gzip")) method = "gzip";
11265
- else if (acceptEncoding.includes("deflate")) method = "deflate";
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
+ }
11266
11309
  if (!method) return next();
11267
11310
  if (!allowedAlgorithms.has(method)) {
11268
11311
  return next();
@@ -11639,10 +11682,21 @@ function validate(config) {
11639
11682
  let validQuery;
11640
11683
  if (validators.query && queryObj) {
11641
11684
  validQuery = await validators.query(queryObj);
11685
+ Object.defineProperty(ctx, "query", {
11686
+ value: validQuery,
11687
+ writable: true,
11688
+ configurable: true
11689
+ });
11642
11690
  }
11691
+ let validHeaders;
11643
11692
  if (validators.headers) {
11644
11693
  const headersObj = Object.fromEntries(ctx.req.headers.entries());
11645
- 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
+ });
11646
11700
  }
11647
11701
  let validBody;
11648
11702
  if (validators.body) {
@@ -11660,6 +11714,7 @@ function validate(config) {
11660
11714
  const validatedData = { ...dataToValidate };
11661
11715
  if (config.params) validatedData.params = ctx.params;
11662
11716
  if (config.query) validatedData.query = validQuery;
11717
+ if (config.headers) validatedData.headers = validHeaders;
11663
11718
  if (config.body) validatedData.body = validBody;
11664
11719
  await ctx.app.runHooks("afterValidate", ctx, validatedData);
11665
11720
  return next();
@@ -11900,7 +11955,7 @@ function Proxy$1(options) {
11900
11955
  if (!["http:", "https:"].includes(url.protocol)) {
11901
11956
  return ctx.text("Invalid protocol in proxied URL", 400);
11902
11957
  }
11903
- if (!options.allowedHosts?.includes(url.hostname)) {
11958
+ if (options.allowedHosts && !options.allowedHosts.includes(url.hostname)) {
11904
11959
  return ctx.text("Proxied hostname not in allowlist", 403);
11905
11960
  }
11906
11961
  const headers = new Headers(req.headers);
@@ -11997,8 +12052,15 @@ function handleWSDrain(ws) {
11997
12052
  function SecurityHeaders(options = {}) {
11998
12053
  const securityHeadersMiddleware = async function SecurityHeadersMiddleware(ctx, next) {
11999
12054
  const response = await next();
12000
- if (!(response instanceof Response)) return response;
12001
- const set = (k, v) => response.headers.set(k, v);
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
+ };
12002
12064
  if (options.dnsPrefetchControl !== false) {
12003
12065
  const allow = options.dnsPrefetchControl?.allow;
12004
12066
  set("X-DNS-Prefetch-Control", allow ? "on" : "off");
@@ -12053,7 +12115,13 @@ function SecurityHeaders(options = {}) {
12053
12115
  }
12054
12116
  }
12055
12117
  if (options.hidePoweredBy !== false) {
12056
- response.headers.delete("X-Powered-By");
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");
12057
12125
  }
12058
12126
  return response;
12059
12127
  };
@@ -12061,6 +12129,8 @@ function SecurityHeaders(options = {}) {
12061
12129
  securityHeadersMiddleware.pluginName = "SecurityHeaders";
12062
12130
  return securityHeadersMiddleware;
12063
12131
  }
12132
+ const $isDirty = /* @__PURE__ */ Symbol("isDirty");
12133
+ const $resetDirty = /* @__PURE__ */ Symbol("resetDirty");
12064
12134
  class Cookie {
12065
12135
  maxAge;
12066
12136
  signed;
@@ -12270,7 +12340,25 @@ function Session(options) {
12270
12340
  sessObj.cookie.expires = new Date(Date.now() + (sessObj.cookie.maxAge || 0));
12271
12341
  if (store.touch) store.touch(sessObj.id, sessObj);
12272
12342
  };
12273
- return sessObj;
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;
12274
12362
  };
12275
12363
  let sessionData = null;
12276
12364
  if (!isNew && sessionID) {
@@ -12293,17 +12381,15 @@ function Session(options) {
12293
12381
  ctx.session = sess;
12294
12382
  ctx.sessionID = sessionID;
12295
12383
  ctx.sessionStore = store;
12296
- const originalHash = JSON.stringify(sess);
12297
12384
  const result = await next();
12298
- const currentHash = JSON.stringify(sess);
12299
- const isModified = originalHash !== currentHash;
12385
+ const isModified = sess[$isDirty]?.() ?? false;
12300
12386
  if (!sessionID) return result;
12301
12387
  let shouldSave = false;
12302
12388
  if (isModified) {
12303
12389
  shouldSave = true;
12304
12390
  } else if (isNew && saveUninitialized) {
12305
12391
  shouldSave = true;
12306
- } else if (!isNew && resave) {
12392
+ } else if (!isNew && resave && isModified) {
12307
12393
  shouldSave = true;
12308
12394
  }
12309
12395
  if (shouldSave) {
@@ -12340,6 +12426,7 @@ function Static(options, prefix = "/") {
12340
12426
  try {
12341
12427
  const result = await staticMiddleware(ctx, next);
12342
12428
  if (result instanceof Response && result.status === 404) {
12429
+ ctx.response.status = 200;
12343
12430
  return next();
12344
12431
  }
12345
12432
  return result;
@@ -12491,4 +12578,4 @@ exports.traceMiddleware = traceMiddleware;
12491
12578
  exports.useExpress = useExpress;
12492
12579
  exports.valibot = valibot;
12493
12580
  exports.validate = validate;
12494
- //# sourceMappingURL=index-5vGQaaL5.cjs.map
12581
+ //# sourceMappingURL=index-B-bQ7kZy.cjs.map