hono 4.1.7 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/cjs/helper/ssg/ssg.js +17 -14
  2. package/dist/cjs/jsx/dom/index.js +3 -0
  3. package/dist/cjs/jsx/hooks/index.js +4 -0
  4. package/dist/cjs/jsx/index.js +3 -0
  5. package/dist/cjs/middleware/basic-auth/index.js +22 -9
  6. package/dist/cjs/middleware/bearer-auth/index.js +4 -2
  7. package/dist/cjs/middleware/cache/index.js +22 -3
  8. package/dist/cjs/middleware/cors/index.js +1 -1
  9. package/dist/cjs/middleware/jwt/index.js +12 -6
  10. package/dist/cjs/middleware/method-override/index.js +106 -0
  11. package/dist/cjs/middleware/trailing-slash/index.js +49 -0
  12. package/dist/cjs/request.js +13 -4
  13. package/dist/cjs/test-utils/setup-vitest.js +5 -2
  14. package/dist/cjs/utils/jwt/index.js +2 -7
  15. package/dist/cjs/utils/jwt/jwa.js +43 -0
  16. package/dist/cjs/utils/jwt/jws.js +212 -0
  17. package/dist/cjs/utils/jwt/jwt.js +26 -72
  18. package/dist/cjs/utils/jwt/types.js +21 -8
  19. package/dist/cjs/utils/jwt/utf8.js +31 -0
  20. package/dist/cjs/validator/validator.js +2 -27
  21. package/dist/helper/ssg/ssg.js +16 -14
  22. package/dist/jsx/dom/index.js +3 -0
  23. package/dist/jsx/hooks/index.js +3 -0
  24. package/dist/jsx/index.js +3 -0
  25. package/dist/middleware/basic-auth/index.js +22 -9
  26. package/dist/middleware/bearer-auth/index.js +4 -2
  27. package/dist/middleware/cache/index.js +22 -3
  28. package/dist/middleware/cors/index.js +1 -1
  29. package/dist/middleware/jwt/index.js +12 -6
  30. package/dist/middleware/method-override/index.js +83 -0
  31. package/dist/middleware/trailing-slash/index.js +25 -0
  32. package/dist/request.js +13 -4
  33. package/dist/test-utils/setup-vitest.js +5 -2
  34. package/dist/types/helper/ssg/ssg.d.ts +3 -1
  35. package/dist/types/helper.d.ts +12 -0
  36. package/dist/types/jsx/dom/index.d.ts +3 -2
  37. package/dist/types/jsx/hooks/index.d.ts +1 -0
  38. package/dist/types/jsx/index.d.ts +3 -2
  39. package/dist/types/middleware/basic-auth/index.d.ts +9 -2
  40. package/dist/types/middleware/bearer-auth/index.d.ts +10 -2
  41. package/dist/types/middleware/cache/index.d.ts +1 -0
  42. package/dist/types/middleware/cors/index.d.ts +2 -1
  43. package/dist/types/middleware/jwt/index.d.ts +4 -3
  44. package/dist/types/middleware/method-override/index.d.ts +36 -0
  45. package/dist/types/middleware/trailing-slash/index.d.ts +13 -0
  46. package/dist/types/utils/jwt/index.d.ts +8 -1
  47. package/dist/types/utils/jwt/jwa.d.ts +16 -0
  48. package/dist/types/utils/jwt/jws.d.ts +4 -0
  49. package/dist/types/utils/jwt/jwt.d.ts +10 -5
  50. package/dist/types/utils/jwt/types.d.ts +30 -4
  51. package/dist/types/utils/jwt/utf8.d.ts +2 -0
  52. package/dist/utils/jwt/index.js +2 -1
  53. package/dist/utils/jwt/jwa.js +20 -0
  54. package/dist/utils/jwt/jws.js +188 -0
  55. package/dist/utils/jwt/jwt.js +24 -53
  56. package/dist/utils/jwt/types.js +19 -7
  57. package/dist/utils/jwt/utf8.js +7 -0
  58. package/dist/validator/validator.js +2 -27
  59. package/package.json +14 -1
@@ -4,7 +4,7 @@ import { timingSafeEqual } from "../../utils/buffer.js";
4
4
  var TOKEN_STRINGS = "[A-Za-z0-9._~+/-]+=*";
5
5
  var PREFIX = "Bearer";
6
6
  var bearerAuth = (options) => {
7
- if (!options.token) {
7
+ if (!("token" in options || "verifyToken" in options)) {
8
8
  throw new Error('bearer auth middleware requires options for "token"');
9
9
  }
10
10
  if (!options.realm) {
@@ -37,7 +37,9 @@ var bearerAuth = (options) => {
37
37
  throw new HTTPException(400, { res });
38
38
  } else {
39
39
  let equal = false;
40
- if (typeof options.token === "string") {
40
+ if ("verifyToken" in options) {
41
+ equal = await options.verifyToken(match[1], c);
42
+ } else if (typeof options.token === "string") {
41
43
  equal = await timingSafeEqual(options.token, match[1], options.hashFunction);
42
44
  } else if (Array.isArray(options.token) && options.token.length > 0) {
43
45
  for (const token of options.token) {
@@ -7,11 +7,17 @@ var cache = (options) => {
7
7
  if (options.wait === void 0) {
8
8
  options.wait = false;
9
9
  }
10
- const directives = options.cacheControl?.split(",").map((directive) => directive.toLowerCase());
10
+ const cacheControlDirectives = options.cacheControl?.split(",").map((directive) => directive.toLowerCase());
11
+ const varyDirectives = Array.isArray(options.vary) ? options.vary : options.vary?.split(",").map((directive) => directive.trim());
12
+ if (options.vary?.includes("*")) {
13
+ throw new Error(
14
+ 'Middleware vary configuration cannot include "*", as it disallows effective caching.'
15
+ );
16
+ }
11
17
  const addHeader = (c) => {
12
- if (directives) {
18
+ if (cacheControlDirectives) {
13
19
  const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0]) ?? [];
14
- for (const directive of directives) {
20
+ for (const directive of cacheControlDirectives) {
15
21
  let [name, value] = directive.trim().split("=", 2);
16
22
  name = name.toLowerCase();
17
23
  if (!existingDirectives.includes(name)) {
@@ -19,6 +25,19 @@ var cache = (options) => {
19
25
  }
20
26
  }
21
27
  }
28
+ if (varyDirectives) {
29
+ const existingDirectives = c.res.headers.get("Vary")?.split(",").map((d) => d.trim()) ?? [];
30
+ const vary = Array.from(
31
+ new Set(
32
+ [...existingDirectives, ...varyDirectives].map((directive) => directive.toLowerCase())
33
+ )
34
+ ).sort();
35
+ if (vary.includes("*")) {
36
+ c.header("Vary", "*");
37
+ } else {
38
+ c.header("Vary", vary.join(", "));
39
+ }
40
+ }
22
41
  };
23
42
  return async function cache2(c, next) {
24
43
  const key = c.req.url;
@@ -23,7 +23,7 @@ var cors = (options) => {
23
23
  function set(key, value) {
24
24
  c.res.headers.set(key, value);
25
25
  }
26
- const allowOrigin = findAllowOrigin(c.req.header("origin") || "");
26
+ const allowOrigin = findAllowOrigin(c.req.header("origin") || "", c);
27
27
  if (allowOrigin) {
28
28
  set("Access-Control-Allow-Origin", allowOrigin);
29
29
  }
@@ -16,11 +16,13 @@ var jwt = (options) => {
16
16
  if (credentials) {
17
17
  const parts = credentials.split(/\s+/);
18
18
  if (parts.length !== 2) {
19
+ const errDescription = "invalid credentials structure";
19
20
  throw new HTTPException(401, {
21
+ message: errDescription,
20
22
  res: unauthorizedResponse({
21
23
  ctx,
22
24
  error: "invalid_request",
23
- errDescription: "invalid credentials structure"
25
+ errDescription
24
26
  })
25
27
  });
26
28
  } else {
@@ -30,29 +32,33 @@ var jwt = (options) => {
30
32
  token = getCookie(ctx)[options.cookie];
31
33
  }
32
34
  if (!token) {
35
+ const errDescription = "no authorization included in request";
33
36
  throw new HTTPException(401, {
37
+ message: errDescription,
34
38
  res: unauthorizedResponse({
35
39
  ctx,
36
40
  error: "invalid_request",
37
- errDescription: "no authorization included in request"
41
+ errDescription
38
42
  })
39
43
  });
40
44
  }
41
45
  let payload;
42
- let msg = "";
46
+ let cause;
43
47
  try {
44
48
  payload = await Jwt.verify(token, options.secret, options.alg);
45
49
  } catch (e) {
46
- msg = `${e}`;
50
+ cause = e;
47
51
  }
48
52
  if (!payload) {
49
53
  throw new HTTPException(401, {
54
+ message: "Unauthorized",
50
55
  res: unauthorizedResponse({
51
56
  ctx,
52
57
  error: "invalid_token",
53
- statusText: msg,
58
+ statusText: "Unauthorized",
54
59
  errDescription: "token verification failure"
55
- })
60
+ }),
61
+ cause
56
62
  });
57
63
  }
58
64
  ctx.set("jwtPayload", payload);
@@ -0,0 +1,83 @@
1
+ // src/middleware/method-override/index.ts
2
+ import { URLSearchParams } from "url";
3
+ import { parseBody } from "../../utils/body.js";
4
+ var DEFAULT_METHOD_FORM_NAME = "_method";
5
+ var methodOverride = (options) => async function methodOverride2(c, next) {
6
+ if (c.req.method === "GET") {
7
+ return await next();
8
+ }
9
+ const app = options.app;
10
+ if (!(options.header || options.query)) {
11
+ const contentType = c.req.header("content-type");
12
+ const methodFormName = options.form || DEFAULT_METHOD_FORM_NAME;
13
+ const clonedRequest = c.req.raw.clone();
14
+ const newRequest = clonedRequest.clone();
15
+ if (contentType?.startsWith("multipart/form-data")) {
16
+ const form = await clonedRequest.formData();
17
+ const method = form.get(methodFormName);
18
+ if (method) {
19
+ const newForm = await newRequest.formData();
20
+ newForm.delete(methodFormName);
21
+ const newHeaders = new Headers(clonedRequest.headers);
22
+ newHeaders.delete("content-type");
23
+ newHeaders.delete("content-length");
24
+ const request = new Request(c.req.url, {
25
+ body: newForm,
26
+ headers: newHeaders,
27
+ method
28
+ });
29
+ return app.fetch(request, c.env, getExecutionCtx(c));
30
+ }
31
+ }
32
+ if (contentType === "application/x-www-form-urlencoded") {
33
+ const params = await parseBody(clonedRequest);
34
+ const method = params[methodFormName];
35
+ if (method) {
36
+ delete params[methodFormName];
37
+ const newParams = new URLSearchParams(params);
38
+ const request = new Request(newRequest, {
39
+ body: newParams,
40
+ method
41
+ });
42
+ return app.fetch(request, c.env, getExecutionCtx(c));
43
+ }
44
+ }
45
+ } else if (options.header) {
46
+ const headerName = options.header;
47
+ const method = c.req.header(headerName);
48
+ if (method) {
49
+ const newHeaders = new Headers(c.req.raw.headers);
50
+ newHeaders.delete(headerName);
51
+ const request = new Request(c.req.raw, {
52
+ headers: newHeaders,
53
+ method
54
+ });
55
+ return app.fetch(request, c.env, getExecutionCtx(c));
56
+ }
57
+ } else if (options.query) {
58
+ const queryName = options.query;
59
+ const method = c.req.query(queryName);
60
+ if (method) {
61
+ const url = new URL(c.req.url);
62
+ url.searchParams.delete(queryName);
63
+ const request = new Request(url.toString(), {
64
+ body: c.req.raw.body,
65
+ headers: c.req.raw.headers,
66
+ method
67
+ });
68
+ return app.fetch(request, c.env, getExecutionCtx(c));
69
+ }
70
+ }
71
+ await next();
72
+ };
73
+ var getExecutionCtx = (c) => {
74
+ let executionCtx;
75
+ try {
76
+ executionCtx = c.executionCtx;
77
+ } catch {
78
+ }
79
+ return executionCtx;
80
+ };
81
+ export {
82
+ methodOverride
83
+ };
@@ -0,0 +1,25 @@
1
+ // src/middleware/trailing-slash/index.ts
2
+ var trimTrailingSlash = () => {
3
+ return async function trimTrailingSlash2(c, next) {
4
+ await next();
5
+ if (c.res.status === 404 && c.req.method === "GET" && c.req.path !== "/" && c.req.path[c.req.path.length - 1] === "/") {
6
+ const url = new URL(c.req.url);
7
+ url.pathname = url.pathname.substring(0, url.pathname.length - 1);
8
+ c.res = c.redirect(url.toString(), 301);
9
+ }
10
+ };
11
+ };
12
+ var appendTrailingSlash = () => {
13
+ return async function appendTrailingSlash2(c, next) {
14
+ await next();
15
+ if (c.res.status === 404 && c.req.method === "GET" && c.req.path[c.req.path.length - 1] !== "/") {
16
+ const url = new URL(c.req.url);
17
+ url.pathname += "/";
18
+ c.res = c.redirect(url.toString(), 301);
19
+ }
20
+ };
21
+ };
22
+ export {
23
+ appendTrailingSlash,
24
+ trimTrailingSlash
25
+ };
package/dist/request.js CHANGED
@@ -66,10 +66,19 @@ var HonoRequest = class {
66
66
  if (cachedBody) {
67
67
  return cachedBody;
68
68
  }
69
- if (bodyCache.arrayBuffer) {
70
- return (async () => {
71
- return await new Response(bodyCache.arrayBuffer)[key]();
72
- })();
69
+ if (!bodyCache[key]) {
70
+ for (const keyOfBodyCache of Object.keys(bodyCache)) {
71
+ if (keyOfBodyCache === "parsedBody") {
72
+ continue;
73
+ }
74
+ return (async () => {
75
+ let body = await bodyCache[keyOfBodyCache];
76
+ if (keyOfBodyCache === "json") {
77
+ body = JSON.stringify(body);
78
+ }
79
+ return await new Response(body)[key]();
80
+ })();
81
+ }
73
82
  }
74
83
  return bodyCache[key] = raw[key]();
75
84
  };
@@ -1,7 +1,10 @@
1
1
  // src/test-utils/setup-vitest.ts
2
- import crypto from "node:crypto";
2
+ import * as nodeCrypto from "node:crypto";
3
3
  import { vi } from "vitest";
4
- vi.stubGlobal("crypto", crypto);
4
+ if (!globalThis.crypto) {
5
+ vi.stubGlobal("crypto", nodeCrypto);
6
+ vi.stubGlobal("CryptoKey", nodeCrypto.webcrypto.CryptoKey);
7
+ }
5
8
  var MockCache = class {
6
9
  name;
7
10
  store;
@@ -21,6 +21,7 @@ export interface ToSSGResult {
21
21
  files: string[];
22
22
  error?: Error;
23
23
  }
24
+ export declare const defaultExtensionMap: Record<string, string>;
24
25
  export type BeforeRequestHook = (req: Request) => Request | false | Promise<Request | false>;
25
26
  export type AfterResponseHook = (res: Response) => Response | false | Promise<Response | false>;
26
27
  export type AfterGenerateHook = (result: ToSSGResult) => void | Promise<void>;
@@ -30,6 +31,7 @@ export interface ToSSGOptions {
30
31
  afterResponseHook?: AfterResponseHook;
31
32
  afterGenerateHook?: AfterGenerateHook;
32
33
  concurrency?: number;
34
+ extensionMap?: Record<string, string>;
33
35
  }
34
36
  /**
35
37
  * @experimental
@@ -45,7 +47,7 @@ export declare const saveContentToFile: (data: Promise<{
45
47
  routePath: string;
46
48
  content: string | ArrayBuffer;
47
49
  mimeType: string;
48
- } | undefined>, fsModule: FileSystemModule, outDir: string) => Promise<string | undefined>;
50
+ } | undefined>, fsModule: FileSystemModule, outDir: string, extensionMap?: Record<string, string>) => Promise<string | undefined>;
49
51
  /**
50
52
  * @experimental
51
53
  * `ToSSGInterface` is an experimental feature.
@@ -0,0 +1,12 @@
1
+ export * from './helper/accepts';
2
+ export * from './helper/adapter';
3
+ export * from './helper/cookie';
4
+ export * from './helper/css';
5
+ export * from './helper/factory';
6
+ export * from './helper/html';
7
+ export * from './helper/streaming';
8
+ export * from './helper/testing';
9
+ export * from './helper/dev';
10
+ export * from './adapter/deno/ssg';
11
+ export * from './adapter/deno/websocket';
12
+ export { decode as jwtDecode, sign as jwtSign, verify as jwtVerify } from './middleware/jwt';
@@ -1,13 +1,13 @@
1
1
  import type { Props, Child, JSXNode } from '../base';
2
2
  import { memo, isValidElement } from '../base';
3
3
  import { useContext } from '../context';
4
- import { useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useDebugValue } from '../hooks';
4
+ import { useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useId, useDebugValue } from '../hooks';
5
5
  import { Suspense, ErrorBoundary } from './components';
6
6
  import { createContext } from './context';
7
7
  export { render } from './render';
8
8
  declare const createElement: (tag: string | ((props: Props) => JSXNode), props: Props, ...children: Child[]) => JSXNode;
9
9
  declare const cloneElement: <T extends JSXNode | JSX.Element>(element: T, props: Props, ...children: Child[]) => T;
10
- export { createElement as jsx, useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useDebugValue, Suspense, ErrorBoundary, createContext, useContext, memo, isValidElement, createElement, cloneElement, };
10
+ export { createElement as jsx, useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useId, useDebugValue, Suspense, ErrorBoundary, createContext, useContext, memo, isValidElement, createElement, cloneElement, };
11
11
  declare const _default: {
12
12
  useState: <T>(initialState: T | (() => T)) => [T, (newState: T | ((currentState: T) => T)) => void];
13
13
  useEffect: (effect: () => void | (() => void), deps?: readonly unknown[] | undefined) => void;
@@ -22,6 +22,7 @@ declare const _default: {
22
22
  useMemo: <T_5>(factory: () => T_5, deps: readonly unknown[]) => T_5;
23
23
  useLayoutEffect: (effect: () => void | (() => void), deps?: readonly unknown[] | undefined) => void;
24
24
  useReducer: <T_6, A>(reducer: (state: T_6, action: A) => T_6, initialArg: T_6, init?: ((initialState: T_6) => T_6) | undefined) => [T_6, (action: A) => void];
25
+ useId: () => string;
25
26
  useDebugValue: (_value: unknown, _formatter?: ((value: unknown) => string) | undefined) => void;
26
27
  Suspense: import("../base").FC<import("..").PropsWithChildren<{
27
28
  fallback: any;
@@ -25,5 +25,6 @@ export type RefObject<T> = {
25
25
  export declare const useRef: <T>(initialValue: T | null) => RefObject<T>;
26
26
  export declare const use: <T>(promise: Promise<T>) => T;
27
27
  export declare const useMemo: <T>(factory: () => T, deps: readonly unknown[]) => T;
28
+ export declare const useId: () => string;
28
29
  export declare const useDebugValue: (_value: unknown, _formatter?: ((value: unknown) => string) | undefined) => void;
29
30
  export {};
@@ -1,9 +1,9 @@
1
1
  import { jsx, memo, Fragment, isValidElement, cloneElement } from './base';
2
2
  import { ErrorBoundary } from './components';
3
3
  import { createContext, useContext } from './context';
4
- import { useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useDebugValue } from './hooks';
4
+ import { useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useId, useDebugValue } from './hooks';
5
5
  import { Suspense } from './streaming';
6
- export { jsx, memo, Fragment, isValidElement, jsx as createElement, cloneElement, ErrorBoundary, createContext, useContext, useState, useEffect, useRef, useCallback, useReducer, useDebugValue, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, Suspense, };
6
+ export { jsx, memo, Fragment, isValidElement, jsx as createElement, cloneElement, ErrorBoundary, createContext, useContext, useState, useEffect, useRef, useCallback, useReducer, useId, useDebugValue, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, Suspense, };
7
7
  declare const _default: {
8
8
  memo: <T>(component: import("./base").FC<T>, propsAreEqual?: (prevProps: Readonly<T>, nextProps: Readonly<T>) => boolean) => import("./base").FC<T>;
9
9
  Fragment: ({ children, }: {
@@ -25,6 +25,7 @@ declare const _default: {
25
25
  useRef: <T_5>(initialValue: T_5 | null) => import("./hooks").RefObject<T_5>;
26
26
  useCallback: <T_6 extends (...args: unknown[]) => unknown>(callback: T_6, deps: readonly unknown[]) => T_6;
27
27
  useReducer: <T_7, A>(reducer: (state: T_7, action: A) => T_7, initialArg: T_7, init?: ((initialState: T_7) => T_7) | undefined) => [T_7, (action: A) => void];
28
+ useId: () => string;
28
29
  useDebugValue: (_value: unknown, _formatter?: ((value: unknown) => string) | undefined) => void;
29
30
  use: <T_8>(promise: Promise<T_8>) => T_8;
30
31
  startTransition: (callback: () => void) => void;
@@ -1,10 +1,17 @@
1
+ import type { Context } from '../../context';
1
2
  import type { MiddlewareHandler } from '../../types';
2
- export declare const basicAuth: (options: {
3
+ type BasicAuthOptions = {
3
4
  username: string;
4
5
  password: string;
5
6
  realm?: string;
6
7
  hashFunction?: Function;
7
- }, ...users: {
8
+ } | {
9
+ verifyUser: (username: string, password: string, c: Context) => boolean | Promise<boolean>;
10
+ realm?: string;
11
+ hashFunction?: Function;
12
+ };
13
+ export declare const basicAuth: (options: BasicAuthOptions, ...users: {
8
14
  username: string;
9
15
  password: string;
10
16
  }[]) => MiddlewareHandler;
17
+ export {};
@@ -1,7 +1,15 @@
1
+ import type { Context } from '../../context';
1
2
  import type { MiddlewareHandler } from '../../types';
2
- export declare const bearerAuth: (options: {
3
+ type BearerAuthOptions = {
3
4
  token: string | string[];
4
5
  realm?: string;
5
6
  prefix?: string;
6
7
  hashFunction?: Function;
7
- }) => MiddlewareHandler;
8
+ } | {
9
+ realm?: string;
10
+ prefix?: string;
11
+ verifyToken: (token: string, c: Context) => boolean | Promise<boolean>;
12
+ hashFunction?: Function;
13
+ };
14
+ export declare const bearerAuth: (options: BearerAuthOptions) => MiddlewareHandler;
15
+ export {};
@@ -3,4 +3,5 @@ export declare const cache: (options: {
3
3
  cacheName: string;
4
4
  wait?: boolean;
5
5
  cacheControl?: string;
6
+ vary?: string | string[];
6
7
  }) => MiddlewareHandler;
@@ -1,6 +1,7 @@
1
+ import type { Context } from '../../context';
1
2
  import type { MiddlewareHandler } from '../../types';
2
3
  type CORSOptions = {
3
- origin: string | string[] | ((origin: string) => string | undefined | null);
4
+ origin: string | string[] | ((origin: string, c: Context) => string | undefined | null);
4
5
  allowMethods?: string[];
5
6
  allowHeaders?: string[];
6
7
  maxAge?: number;
@@ -1,5 +1,6 @@
1
1
  import type { MiddlewareHandler } from '../../types';
2
2
  import '../../context';
3
+ import type { SignatureAlgorithm } from '../../utils/jwt/jwa';
3
4
  declare module '../../context' {
4
5
  interface ContextVariableMap {
5
6
  jwtPayload: any;
@@ -8,11 +9,11 @@ declare module '../../context' {
8
9
  export declare const jwt: (options: {
9
10
  secret: string;
10
11
  cookie?: string;
11
- alg?: string;
12
+ alg?: SignatureAlgorithm;
12
13
  }) => MiddlewareHandler;
13
- export declare const verify: (token: string, secret: string, alg?: "HS256" | "HS384" | "HS512") => Promise<any>;
14
+ export declare const verify: (token: string, publicKey: import("../../utils/jwt/jws").SignatureKey, alg?: "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "ES512" | "EdDSA") => Promise<any>;
14
15
  export declare const decode: (token: string) => {
15
16
  header: any;
16
17
  payload: any;
17
18
  };
18
- export declare const sign: (payload: unknown, secret: string, alg?: "HS256" | "HS384" | "HS512") => Promise<string>;
19
+ export declare const sign: (payload: import("../../utils/jwt/types").JWTPayload, privateKey: import("../../utils/jwt/jws").SignatureKey, alg?: "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "ES512" | "EdDSA") => Promise<string>;
@@ -0,0 +1,36 @@
1
+ import type { Hono } from '../../hono';
2
+ import type { MiddlewareHandler } from '../../types';
3
+ type MethodOverrideOptions = {
4
+ app: Hono<any, any, any>;
5
+ } & ({
6
+ form?: string;
7
+ header?: never;
8
+ query?: never;
9
+ } | {
10
+ form?: never;
11
+ header: string;
12
+ query?: never;
13
+ } | {
14
+ form?: never;
15
+ header?: never;
16
+ query: string;
17
+ });
18
+ /**
19
+ * Method Override Middleware
20
+ *
21
+ * @example
22
+ * // with form input method
23
+ * const app = new Hono()
24
+ * app.use('/books/*', methodOverride({ app })) // the default `form` value is `_method`
25
+ * app.use('/authors/*', methodOverride({ app, form: 'method' }))
26
+ *
27
+ * @example
28
+ * // with custom header
29
+ * app.use('/books/*', methodOverride({ app, header: 'X-HTTP-METHOD-OVERRIDE' }))
30
+ *
31
+ * @example
32
+ * // with query parameter
33
+ * app.use('/books/*', methodOverride({ app, query: '_method' }))
34
+ */
35
+ export declare const methodOverride: (options: MethodOverrideOptions) => MiddlewareHandler;
36
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { MiddlewareHandler } from '../../types';
2
+ /**
3
+ * Trim the trailing slash from the URL if it does have one. For example, `/path/to/page/` will be redirected to `/path/to/page`.
4
+ * @access public
5
+ * @example app.use(trimTrailingSlash())
6
+ */
7
+ export declare const trimTrailingSlash: () => MiddlewareHandler;
8
+ /**
9
+ * Append a trailing slash to the URL if it doesn't have one. For example, `/path/to/page` will be redirected to `/path/to/page/`.
10
+ * @access public
11
+ * @example app.use(appendTrailingSlash())
12
+ */
13
+ export declare const appendTrailingSlash: () => MiddlewareHandler;
@@ -1 +1,8 @@
1
- export * as Jwt from './jwt';
1
+ export declare const Jwt: {
2
+ sign: (payload: import("./types").JWTPayload, privateKey: import("./jws").SignatureKey, alg?: "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "ES512" | "EdDSA") => Promise<string>;
3
+ verify: (token: string, publicKey: import("./jws").SignatureKey, alg?: "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "ES512" | "EdDSA") => Promise<any>;
4
+ decode: (token: string) => {
5
+ header: any;
6
+ payload: any;
7
+ };
8
+ };
@@ -0,0 +1,16 @@
1
+ export declare enum AlgorithmTypes {
2
+ HS256 = "HS256",
3
+ HS384 = "HS384",
4
+ HS512 = "HS512",
5
+ RS256 = "RS256",
6
+ RS384 = "RS384",
7
+ RS512 = "RS512",
8
+ PS256 = "PS256",
9
+ PS384 = "PS384",
10
+ PS512 = "PS512",
11
+ ES256 = "ES256",
12
+ ES384 = "ES384",
13
+ ES512 = "ES512",
14
+ EdDSA = "EdDSA"
15
+ }
16
+ export type SignatureAlgorithm = keyof typeof AlgorithmTypes;
@@ -0,0 +1,4 @@
1
+ import type { SignatureAlgorithm } from './jwa';
2
+ export type SignatureKey = string | JsonWebKey | CryptoKey;
3
+ export declare function signing(privateKey: SignatureKey, alg: SignatureAlgorithm, data: BufferSource): Promise<ArrayBuffer>;
4
+ export declare function verifying(publicKey: SignatureKey, alg: SignatureAlgorithm, signature: BufferSource, data: BufferSource): Promise<boolean>;
@@ -1,9 +1,14 @@
1
- import type { AlgorithmTypes } from './types';
2
- type AlgorithmTypeName = keyof typeof AlgorithmTypes;
3
- export declare const sign: (payload: unknown, secret: string, alg?: AlgorithmTypeName) => Promise<string>;
4
- export declare const verify: (token: string, secret: string, alg?: AlgorithmTypeName) => Promise<any>;
1
+ import type { SignatureAlgorithm } from './jwa';
2
+ import type { SignatureKey } from './jws';
3
+ import { type JWTPayload } from './types';
4
+ export interface TokenHeader {
5
+ alg: SignatureAlgorithm;
6
+ typ: 'JWT';
7
+ }
8
+ export declare function isTokenHeader(obj: any): obj is TokenHeader;
9
+ export declare const sign: (payload: JWTPayload, privateKey: SignatureKey, alg?: SignatureAlgorithm) => Promise<string>;
10
+ export declare const verify: (token: string, publicKey: SignatureKey, alg?: SignatureAlgorithm) => Promise<any>;
5
11
  export declare const decode: (token: string) => {
6
12
  header: any;
7
13
  payload: any;
8
14
  };
9
- export {};
@@ -13,11 +13,37 @@ export declare class JwtTokenExpired extends Error {
13
13
  export declare class JwtTokenIssuedAt extends Error {
14
14
  constructor(currentTimestamp: number, iat: number);
15
15
  }
16
+ export declare class JwtHeaderInvalid extends Error {
17
+ constructor(header: object);
18
+ }
16
19
  export declare class JwtTokenSignatureMismatched extends Error {
17
20
  constructor(token: string);
18
21
  }
19
- export declare enum AlgorithmTypes {
20
- HS256 = "HS256",
21
- HS384 = "HS384",
22
- HS512 = "HS512"
22
+ export declare enum CryptoKeyUsage {
23
+ Encrypt = "encrypt",
24
+ Decrypt = "decrypt",
25
+ Sign = "sign",
26
+ Verify = "verify",
27
+ DeriveKey = "deriveKey",
28
+ DeriveBits = "deriveBits",
29
+ WrapKey = "wrapKey",
30
+ UnwrapKey = "unwrapKey"
23
31
  }
32
+ /**
33
+ * JWT Payload
34
+ */
35
+ export type JWTPayload = (unknown & {}) | {
36
+ [key: string]: unknown;
37
+ /**
38
+ * The token is checked to ensure it has not expired.
39
+ */
40
+ exp?: number;
41
+ /**
42
+ * The token is checked to ensure it is not being used before a specified time.
43
+ */
44
+ nbf?: number;
45
+ /**
46
+ * The token is checked to ensure it is not issued in the future.
47
+ */
48
+ iat?: number;
49
+ };
@@ -0,0 +1,2 @@
1
+ export declare const utf8Encoder: TextEncoder;
2
+ export declare const utf8Decoder: TextDecoder;
@@ -1,5 +1,6 @@
1
1
  // src/utils/jwt/index.ts
2
- import * as Jwt from "./jwt.js";
2
+ import { sign, verify, decode } from "./jwt.js";
3
+ var Jwt = { sign, verify, decode };
3
4
  export {
4
5
  Jwt
5
6
  };
@@ -0,0 +1,20 @@
1
+ // src/utils/jwt/jwa.ts
2
+ var AlgorithmTypes = /* @__PURE__ */ ((AlgorithmTypes2) => {
3
+ AlgorithmTypes2["HS256"] = "HS256";
4
+ AlgorithmTypes2["HS384"] = "HS384";
5
+ AlgorithmTypes2["HS512"] = "HS512";
6
+ AlgorithmTypes2["RS256"] = "RS256";
7
+ AlgorithmTypes2["RS384"] = "RS384";
8
+ AlgorithmTypes2["RS512"] = "RS512";
9
+ AlgorithmTypes2["PS256"] = "PS256";
10
+ AlgorithmTypes2["PS384"] = "PS384";
11
+ AlgorithmTypes2["PS512"] = "PS512";
12
+ AlgorithmTypes2["ES256"] = "ES256";
13
+ AlgorithmTypes2["ES384"] = "ES384";
14
+ AlgorithmTypes2["ES512"] = "ES512";
15
+ AlgorithmTypes2["EdDSA"] = "EdDSA";
16
+ return AlgorithmTypes2;
17
+ })(AlgorithmTypes || {});
18
+ export {
19
+ AlgorithmTypes
20
+ };