@shware/http 2.2.4 → 2.3.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/error/parse.ts"],"sourcesContent":["import { hasText } from '@shware/utils';\nimport { type BadRequest, DetailType } from './detail';\nimport type { ErrorBody } from './status';\nimport type { DefaultNamespace, Namespace, TFunction } from 'i18next';\n\nexport function getErrorReason(data: unknown) {\n if (typeof data !== 'object' || data === null || !('error' in data)) return 'UNKNOWN';\n const { error } = data as ErrorBody;\n const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n return errorInfo?.reason ?? 'UNKNOWN';\n}\n\n/**\n * @example For axios:\n *\n * const { t } = useTranslation('error');\n *\n * const { message } = getErrorMessage(error.response.data, t);\n * toast.error(message);\n */\nexport function getErrorMessage<Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n data: unknown,\n t: TFunction<Ns, KPrefix>\n): { reason: string; message: string } {\n // 0. unknown error\n if (typeof data !== 'object' || data === null || !('error' in data)) {\n console.error('Unknown API error:', data);\n return { reason: 'UNKNOWN', message: t('UNKNOWN') };\n }\n\n const { error } = data as ErrorBody;\n\n // 1. from server via Accept-Language header or lng param\n const localizedMessage = error?.details?.find((d) => d['@type'] === DetailType.LOCALIZED_MESSAGE);\n if (localizedMessage) return { reason: 'LOCALIZED_MESSAGE', message: localizedMessage.message };\n\n // 2. from business logic error\n const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n if (errorInfo) {\n return {\n reason: errorInfo.reason,\n message: t(errorInfo.reason, errorInfo.metadata),\n };\n }\n\n // 3. error message in english\n if (hasText(error.message)) return { reason: 'ERROR_MESSAGE', message: error.message };\n\n // 4. from server via status code\n if (error.status) return { reason: error.status, message: t(error.status) };\n\n // 5. unknown error\n console.error('Unknown API error:', data);\n return { reason: 'UNKNOWN', message: t('UNKNOWN') };\n}\n\n/**\n * @example For react-hook-form:\n *\n * const { setError } = useForm();\n * const fieldViolations = getFieldViolations(error.response.data);\n * fieldViolations.forEach((violation) => {\n * setError(violation.field, { message: violation.description });\n * });\n */\nexport function getFieldViolations(data: unknown): BadRequest['fieldViolations'] {\n if (typeof data !== 'object' || data === null || !('error' in data)) return [];\n const { error } = data as ErrorBody;\n const badRequest = error?.details?.find((d) => d['@type'] === DetailType.BAD_REQUEST);\n return badRequest?.fieldViolations ?? [];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAwB;AACxB,oBAA4C;AAIrC,SAAS,eAAe,MAAe;AAC5C,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO;AAC5E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW,UAAU;AAClF,SAAO,WAAW,UAAU;AAC9B;AAUO,SAAS,gBACd,MACA,GACqC;AAErC,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,OAAO;AACnE,YAAQ,MAAM,sBAAsB,IAAI;AACxC,WAAO,EAAE,QAAQ,WAAW,SAAS,EAAE,SAAS,EAAE;AAAA,EACpD;AAEA,QAAM,EAAE,MAAM,IAAI;AAGlB,QAAM,mBAAmB,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW,iBAAiB;AAChG,MAAI,iBAAkB,QAAO,EAAE,QAAQ,qBAAqB,SAAS,iBAAiB,QAAQ;AAG9F,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW,UAAU;AAClF,MAAI,WAAW;AACb,WAAO;AAAA,MACL,QAAQ,UAAU;AAAA,MAClB,SAAS,EAAE,UAAU,QAAQ,UAAU,QAAQ;AAAA,IACjD;AAAA,EACF;AAGA,UAAI,sBAAQ,MAAM,OAAO,EAAG,QAAO,EAAE,QAAQ,iBAAiB,SAAS,MAAM,QAAQ;AAGrF,MAAI,MAAM,OAAQ,QAAO,EAAE,QAAQ,MAAM,QAAQ,SAAS,EAAE,MAAM,MAAM,EAAE;AAG1E,UAAQ,MAAM,sBAAsB,IAAI;AACxC,SAAO,EAAE,QAAQ,WAAW,SAAS,EAAE,SAAS,EAAE;AACpD;AAWO,SAAS,mBAAmB,MAA8C;AAC/E,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO,CAAC;AAC7E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW,WAAW;AACpF,SAAO,YAAY,mBAAmB,CAAC;AACzC;","names":[]}
1
+ {"version":3,"sources":["../../src/error/parse.ts"],"sourcesContent":["import type { DefaultNamespace, Namespace, TFunction } from 'i18next';\nimport { hasText } from '@shware/utils';\nimport type { ErrorBody } from './status';\nimport { type BadRequest, DetailType } from './detail';\n\nexport function getErrorReason(data: unknown) {\n if (typeof data !== 'object' || data === null || !('error' in data)) return 'UNKNOWN';\n const { error } = data as ErrorBody;\n const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n return errorInfo?.reason ?? 'UNKNOWN';\n}\n\n/**\n * @example For axios:\n *\n * const { t } = useTranslation('error');\n *\n * const { message } = getErrorMessage(error.response.data, t);\n * toast.error(message);\n */\nexport function getErrorMessage<Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n data: unknown,\n t: TFunction<Ns, KPrefix>\n): { reason: string; message: string } {\n // 0. unknown error\n if (typeof data !== 'object' || data === null || !('error' in data)) {\n console.error('Unknown API error:', data);\n return { reason: 'UNKNOWN', message: t('UNKNOWN') };\n }\n\n const { error } = data as ErrorBody;\n\n // 1. from server via Accept-Language header or lng param\n const localizedMessage = error?.details?.find((d) => d['@type'] === DetailType.LOCALIZED_MESSAGE);\n if (localizedMessage) return { reason: 'LOCALIZED_MESSAGE', message: localizedMessage.message };\n\n // 2. from business logic error\n const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n if (errorInfo) {\n return {\n reason: errorInfo.reason,\n message: t(errorInfo.reason, errorInfo.metadata),\n };\n }\n\n // 3. error message in english\n if (hasText(error.message)) return { reason: 'ERROR_MESSAGE', message: error.message };\n\n // 4. from server via status code\n if (error.status) return { reason: error.status, message: t(error.status) };\n\n // 5. unknown error\n console.error('Unknown API error:', data);\n return { reason: 'UNKNOWN', message: t('UNKNOWN') };\n}\n\n/**\n * @example For react-hook-form:\n *\n * const { setError } = useForm();\n * const fieldViolations = getFieldViolations(error.response.data);\n * fieldViolations.forEach((violation) => {\n * setError(violation.field, { message: violation.description });\n * });\n */\nexport function getFieldViolations(data: unknown): BadRequest['fieldViolations'] {\n if (typeof data !== 'object' || data === null || !('error' in data)) return [];\n const { error } = data as ErrorBody;\n const badRequest = error?.details?.find((d) => d['@type'] === DetailType.BAD_REQUEST);\n return badRequest?.fieldViolations ?? [];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAwB;AAExB,oBAA4C;AAErC,SAAS,eAAe,MAAe;AAC5C,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO;AAC5E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW,UAAU;AAClF,SAAO,WAAW,UAAU;AAC9B;AAUO,SAAS,gBACd,MACA,GACqC;AAErC,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,OAAO;AACnE,YAAQ,MAAM,sBAAsB,IAAI;AACxC,WAAO,EAAE,QAAQ,WAAW,SAAS,EAAE,SAAS,EAAE;AAAA,EACpD;AAEA,QAAM,EAAE,MAAM,IAAI;AAGlB,QAAM,mBAAmB,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW,iBAAiB;AAChG,MAAI,iBAAkB,QAAO,EAAE,QAAQ,qBAAqB,SAAS,iBAAiB,QAAQ;AAG9F,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW,UAAU;AAClF,MAAI,WAAW;AACb,WAAO;AAAA,MACL,QAAQ,UAAU;AAAA,MAClB,SAAS,EAAE,UAAU,QAAQ,UAAU,QAAQ;AAAA,IACjD;AAAA,EACF;AAGA,UAAI,sBAAQ,MAAM,OAAO,EAAG,QAAO,EAAE,QAAQ,iBAAiB,SAAS,MAAM,QAAQ;AAGrF,MAAI,MAAM,OAAQ,QAAO,EAAE,QAAQ,MAAM,QAAQ,SAAS,EAAE,MAAM,MAAM,EAAE;AAG1E,UAAQ,MAAM,sBAAsB,IAAI;AACxC,SAAO,EAAE,QAAQ,WAAW,SAAS,EAAE,SAAS,EAAE;AACpD;AAWO,SAAS,mBAAmB,MAA8C;AAC/E,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO,CAAC;AAC7E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW,WAAW;AACpF,SAAO,YAAY,mBAAmB,CAAC;AACzC;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import { NetworkErrorReason, StatusErrorReason, AuthenticationErrorReason, ModerationErrorReason, MultipartErrorReason, AppErrorReason } from './reason.cjs';
2
- import { BadRequest } from './detail.cjs';
3
2
  import { Namespace, DefaultNamespace, TFunction } from 'i18next';
3
+ import { BadRequest } from './detail.cjs';
4
4
 
5
5
  declare function getErrorReason(data: unknown): (string & {}) | keyof NetworkErrorReason | keyof StatusErrorReason | keyof AuthenticationErrorReason | keyof ModerationErrorReason | keyof MultipartErrorReason | keyof AppErrorReason;
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import { NetworkErrorReason, StatusErrorReason, AuthenticationErrorReason, ModerationErrorReason, MultipartErrorReason, AppErrorReason } from './reason.js';
2
- import { BadRequest } from './detail.js';
3
2
  import { Namespace, DefaultNamespace, TFunction } from 'i18next';
3
+ import { BadRequest } from './detail.js';
4
4
 
5
5
  declare function getErrorReason(data: unknown): (string & {}) | keyof NetworkErrorReason | keyof StatusErrorReason | keyof AuthenticationErrorReason | keyof ModerationErrorReason | keyof MultipartErrorReason | keyof AppErrorReason;
6
6
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/error/parse.ts"],"sourcesContent":["import { hasText } from '@shware/utils';\nimport { type BadRequest, DetailType } from './detail';\nimport type { ErrorBody } from './status';\nimport type { DefaultNamespace, Namespace, TFunction } from 'i18next';\n\nexport function getErrorReason(data: unknown) {\n if (typeof data !== 'object' || data === null || !('error' in data)) return 'UNKNOWN';\n const { error } = data as ErrorBody;\n const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n return errorInfo?.reason ?? 'UNKNOWN';\n}\n\n/**\n * @example For axios:\n *\n * const { t } = useTranslation('error');\n *\n * const { message } = getErrorMessage(error.response.data, t);\n * toast.error(message);\n */\nexport function getErrorMessage<Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n data: unknown,\n t: TFunction<Ns, KPrefix>\n): { reason: string; message: string } {\n // 0. unknown error\n if (typeof data !== 'object' || data === null || !('error' in data)) {\n console.error('Unknown API error:', data);\n return { reason: 'UNKNOWN', message: t('UNKNOWN') };\n }\n\n const { error } = data as ErrorBody;\n\n // 1. from server via Accept-Language header or lng param\n const localizedMessage = error?.details?.find((d) => d['@type'] === DetailType.LOCALIZED_MESSAGE);\n if (localizedMessage) return { reason: 'LOCALIZED_MESSAGE', message: localizedMessage.message };\n\n // 2. from business logic error\n const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n if (errorInfo) {\n return {\n reason: errorInfo.reason,\n message: t(errorInfo.reason, errorInfo.metadata),\n };\n }\n\n // 3. error message in english\n if (hasText(error.message)) return { reason: 'ERROR_MESSAGE', message: error.message };\n\n // 4. from server via status code\n if (error.status) return { reason: error.status, message: t(error.status) };\n\n // 5. unknown error\n console.error('Unknown API error:', data);\n return { reason: 'UNKNOWN', message: t('UNKNOWN') };\n}\n\n/**\n * @example For react-hook-form:\n *\n * const { setError } = useForm();\n * const fieldViolations = getFieldViolations(error.response.data);\n * fieldViolations.forEach((violation) => {\n * setError(violation.field, { message: violation.description });\n * });\n */\nexport function getFieldViolations(data: unknown): BadRequest['fieldViolations'] {\n if (typeof data !== 'object' || data === null || !('error' in data)) return [];\n const { error } = data as ErrorBody;\n const badRequest = error?.details?.find((d) => d['@type'] === DetailType.BAD_REQUEST);\n return badRequest?.fieldViolations ?? [];\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,SAA0B,kBAAkB;AAIrC,SAAS,eAAe,MAAe;AAC5C,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO;AAC5E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,UAAU;AAClF,SAAO,WAAW,UAAU;AAC9B;AAUO,SAAS,gBACd,MACA,GACqC;AAErC,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,OAAO;AACnE,YAAQ,MAAM,sBAAsB,IAAI;AACxC,WAAO,EAAE,QAAQ,WAAW,SAAS,EAAE,SAAS,EAAE;AAAA,EACpD;AAEA,QAAM,EAAE,MAAM,IAAI;AAGlB,QAAM,mBAAmB,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,iBAAiB;AAChG,MAAI,iBAAkB,QAAO,EAAE,QAAQ,qBAAqB,SAAS,iBAAiB,QAAQ;AAG9F,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,UAAU;AAClF,MAAI,WAAW;AACb,WAAO;AAAA,MACL,QAAQ,UAAU;AAAA,MAClB,SAAS,EAAE,UAAU,QAAQ,UAAU,QAAQ;AAAA,IACjD;AAAA,EACF;AAGA,MAAI,QAAQ,MAAM,OAAO,EAAG,QAAO,EAAE,QAAQ,iBAAiB,SAAS,MAAM,QAAQ;AAGrF,MAAI,MAAM,OAAQ,QAAO,EAAE,QAAQ,MAAM,QAAQ,SAAS,EAAE,MAAM,MAAM,EAAE;AAG1E,UAAQ,MAAM,sBAAsB,IAAI;AACxC,SAAO,EAAE,QAAQ,WAAW,SAAS,EAAE,SAAS,EAAE;AACpD;AAWO,SAAS,mBAAmB,MAA8C;AAC/E,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO,CAAC;AAC7E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,WAAW;AACpF,SAAO,YAAY,mBAAmB,CAAC;AACzC;","names":[]}
1
+ {"version":3,"sources":["../../src/error/parse.ts"],"sourcesContent":["import type { DefaultNamespace, Namespace, TFunction } from 'i18next';\nimport { hasText } from '@shware/utils';\nimport type { ErrorBody } from './status';\nimport { type BadRequest, DetailType } from './detail';\n\nexport function getErrorReason(data: unknown) {\n if (typeof data !== 'object' || data === null || !('error' in data)) return 'UNKNOWN';\n const { error } = data as ErrorBody;\n const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n return errorInfo?.reason ?? 'UNKNOWN';\n}\n\n/**\n * @example For axios:\n *\n * const { t } = useTranslation('error');\n *\n * const { message } = getErrorMessage(error.response.data, t);\n * toast.error(message);\n */\nexport function getErrorMessage<Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n data: unknown,\n t: TFunction<Ns, KPrefix>\n): { reason: string; message: string } {\n // 0. unknown error\n if (typeof data !== 'object' || data === null || !('error' in data)) {\n console.error('Unknown API error:', data);\n return { reason: 'UNKNOWN', message: t('UNKNOWN') };\n }\n\n const { error } = data as ErrorBody;\n\n // 1. from server via Accept-Language header or lng param\n const localizedMessage = error?.details?.find((d) => d['@type'] === DetailType.LOCALIZED_MESSAGE);\n if (localizedMessage) return { reason: 'LOCALIZED_MESSAGE', message: localizedMessage.message };\n\n // 2. from business logic error\n const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n if (errorInfo) {\n return {\n reason: errorInfo.reason,\n message: t(errorInfo.reason, errorInfo.metadata),\n };\n }\n\n // 3. error message in english\n if (hasText(error.message)) return { reason: 'ERROR_MESSAGE', message: error.message };\n\n // 4. from server via status code\n if (error.status) return { reason: error.status, message: t(error.status) };\n\n // 5. unknown error\n console.error('Unknown API error:', data);\n return { reason: 'UNKNOWN', message: t('UNKNOWN') };\n}\n\n/**\n * @example For react-hook-form:\n *\n * const { setError } = useForm();\n * const fieldViolations = getFieldViolations(error.response.data);\n * fieldViolations.forEach((violation) => {\n * setError(violation.field, { message: violation.description });\n * });\n */\nexport function getFieldViolations(data: unknown): BadRequest['fieldViolations'] {\n if (typeof data !== 'object' || data === null || !('error' in data)) return [];\n const { error } = data as ErrorBody;\n const badRequest = error?.details?.find((d) => d['@type'] === DetailType.BAD_REQUEST);\n return badRequest?.fieldViolations ?? [];\n}\n"],"mappings":";AACA,SAAS,eAAe;AAExB,SAA0B,kBAAkB;AAErC,SAAS,eAAe,MAAe;AAC5C,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO;AAC5E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,UAAU;AAClF,SAAO,WAAW,UAAU;AAC9B;AAUO,SAAS,gBACd,MACA,GACqC;AAErC,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,OAAO;AACnE,YAAQ,MAAM,sBAAsB,IAAI;AACxC,WAAO,EAAE,QAAQ,WAAW,SAAS,EAAE,SAAS,EAAE;AAAA,EACpD;AAEA,QAAM,EAAE,MAAM,IAAI;AAGlB,QAAM,mBAAmB,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,iBAAiB;AAChG,MAAI,iBAAkB,QAAO,EAAE,QAAQ,qBAAqB,SAAS,iBAAiB,QAAQ;AAG9F,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,UAAU;AAClF,MAAI,WAAW;AACb,WAAO;AAAA,MACL,QAAQ,UAAU;AAAA,MAClB,SAAS,EAAE,UAAU,QAAQ,UAAU,QAAQ;AAAA,IACjD;AAAA,EACF;AAGA,MAAI,QAAQ,MAAM,OAAO,EAAG,QAAO,EAAE,QAAQ,iBAAiB,SAAS,MAAM,QAAQ;AAGrF,MAAI,MAAM,OAAQ,QAAO,EAAE,QAAQ,MAAM,QAAQ,SAAS,EAAE,MAAM,MAAM,EAAE;AAG1E,UAAQ,MAAM,sBAAsB,IAAI;AACxC,SAAO,EAAE,QAAQ,WAAW,SAAS,EAAE,SAAS,EAAE;AACpD;AAWO,SAAS,mBAAmB,MAA8C;AAC/E,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO,CAAC;AAC7E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,WAAW;AACpF,SAAO,YAAY,mBAAmB,CAAC;AACzC;","names":[]}
@@ -23,25 +23,41 @@ __export(google_one_tap_exports, {
23
23
  prompt: () => prompt
24
24
  });
25
25
  module.exports = __toCommonJS(google_one_tap_exports);
26
- function prompt({ clientId, callback }) {
27
- const scriptId = "google-one-tap";
28
- const script = document.createElement("script");
29
- script.id = scriptId;
30
- script.async = true;
31
- script.defer = true;
32
- script.src = "https://accounts.google.com/gsi/client";
33
- script.onload = () => {
26
+ var script = null;
27
+ function prompt({
28
+ client_id,
29
+ auto_select = false,
30
+ use_fedcm_for_prompt = true,
31
+ cancel_on_tap_outside = false,
32
+ callback
33
+ }) {
34
+ const initializeAndPrompt = () => {
34
35
  window.google.accounts.id.initialize({
35
36
  ux_mode: "popup",
36
37
  context: "signin",
37
- auto_select: false,
38
- client_id: clientId,
39
- use_fedcm_for_prompt: true,
40
- cancel_on_tap_outside: false,
41
- callback
38
+ auto_select,
39
+ client_id,
40
+ use_fedcm_for_prompt,
41
+ cancel_on_tap_outside,
42
+ callback,
43
+ native_callback: callback
42
44
  });
43
45
  window.google?.accounts?.id?.prompt();
44
46
  };
47
+ if (script) {
48
+ if (window.google?.accounts?.id) {
49
+ initializeAndPrompt();
50
+ } else {
51
+ script.addEventListener("load", initializeAndPrompt);
52
+ }
53
+ return;
54
+ }
55
+ script = document.createElement("script");
56
+ script.id = "google-one-tap";
57
+ script.async = true;
58
+ script.defer = true;
59
+ script.src = "https://accounts.google.com/gsi/client";
60
+ script.onload = initializeAndPrompt;
45
61
  document.head.appendChild(script);
46
62
  }
47
63
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/google-one-tap/index.ts"],"sourcesContent":["import type { CredentialResponse, GoogleAccounts } from './types';\n\ndeclare global {\n interface Window {\n google: {\n accounts: GoogleAccounts;\n };\n }\n}\n\nexport type Props = {\n clientId: string;\n callback: (response: CredentialResponse) => void | Promise<void>;\n};\n\n/** debug: chrome://settings/content/federatedIdentityApi */\nexport function prompt({ clientId, callback }: Props) {\n const scriptId = 'google-one-tap';\n const script = document.createElement('script');\n script.id = scriptId;\n script.async = true;\n script.defer = true;\n script.src = 'https://accounts.google.com/gsi/client';\n script.onload = () => {\n window.google.accounts.id.initialize({\n ux_mode: 'popup',\n context: 'signin',\n auto_select: false,\n client_id: clientId,\n use_fedcm_for_prompt: true,\n cancel_on_tap_outside: false,\n callback,\n });\n window.google?.accounts?.id?.prompt();\n };\n\n document.head.appendChild(script);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBO,SAAS,OAAO,EAAE,UAAU,SAAS,GAAU;AACpD,QAAM,WAAW;AACjB,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,KAAK;AACZ,SAAO,QAAQ;AACf,SAAO,QAAQ;AACf,SAAO,MAAM;AACb,SAAO,SAAS,MAAM;AACpB,WAAO,OAAO,SAAS,GAAG,WAAW;AAAA,MACnC,SAAS;AAAA,MACT,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,MACX,sBAAsB;AAAA,MACtB,uBAAuB;AAAA,MACvB;AAAA,IACF,CAAC;AACD,WAAO,QAAQ,UAAU,IAAI,OAAO;AAAA,EACtC;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;","names":[]}
1
+ {"version":3,"sources":["../../src/google-one-tap/index.ts"],"sourcesContent":["import type { CredentialResponse, GoogleAccounts } from './types';\n\ndeclare global {\n interface Window {\n google: {\n accounts: GoogleAccounts;\n };\n }\n}\n\nexport type Props = {\n client_id: string;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n use_fedcm_for_prompt?: boolean;\n callback: (response: CredentialResponse) => void | Promise<void>;\n};\n\nlet script: HTMLScriptElement | null = null;\n\n/** debug: chrome://settings/content/federatedIdentityApi */\nexport function prompt({\n client_id,\n auto_select = false,\n use_fedcm_for_prompt = true,\n cancel_on_tap_outside = false,\n callback,\n}: Props) {\n const initializeAndPrompt = () => {\n window.google.accounts.id.initialize({\n ux_mode: 'popup',\n context: 'signin',\n auto_select,\n client_id,\n use_fedcm_for_prompt,\n cancel_on_tap_outside,\n callback,\n native_callback: callback,\n });\n window.google?.accounts?.id?.prompt();\n };\n\n if (script) {\n if (window.google?.accounts?.id) {\n initializeAndPrompt();\n } else {\n script.addEventListener('load', initializeAndPrompt);\n }\n return;\n }\n\n script = document.createElement('script');\n script.id = 'google-one-tap';\n script.async = true;\n script.defer = true;\n script.src = 'https://accounts.google.com/gsi/client';\n script.onload = initializeAndPrompt;\n\n document.head.appendChild(script);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBA,IAAI,SAAmC;AAGhC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB;AACF,GAAU;AACR,QAAM,sBAAsB,MAAM;AAChC,WAAO,OAAO,SAAS,GAAG,WAAW;AAAA,MACnC,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,IACnB,CAAC;AACD,WAAO,QAAQ,UAAU,IAAI,OAAO;AAAA,EACtC;AAEA,MAAI,QAAQ;AACV,QAAI,OAAO,QAAQ,UAAU,IAAI;AAC/B,0BAAoB;AAAA,IACtB,OAAO;AACL,aAAO,iBAAiB,QAAQ,mBAAmB;AAAA,IACrD;AACA;AAAA,EACF;AAEA,WAAS,SAAS,cAAc,QAAQ;AACxC,SAAO,KAAK;AACZ,SAAO,QAAQ;AACf,SAAO,QAAQ;AACf,SAAO,MAAM;AACb,SAAO,SAAS;AAEhB,WAAS,KAAK,YAAY,MAAM;AAClC;","names":[]}
@@ -8,10 +8,13 @@ declare global {
8
8
  }
9
9
  }
10
10
  type Props = {
11
- clientId: string;
11
+ client_id: string;
12
+ auto_select?: boolean;
13
+ cancel_on_tap_outside?: boolean;
14
+ use_fedcm_for_prompt?: boolean;
12
15
  callback: (response: CredentialResponse) => void | Promise<void>;
13
16
  };
14
17
  /** debug: chrome://settings/content/federatedIdentityApi */
15
- declare function prompt({ clientId, callback }: Props): void;
18
+ declare function prompt({ client_id, auto_select, use_fedcm_for_prompt, cancel_on_tap_outside, callback, }: Props): void;
16
19
 
17
20
  export { type Props, prompt };
@@ -8,10 +8,13 @@ declare global {
8
8
  }
9
9
  }
10
10
  type Props = {
11
- clientId: string;
11
+ client_id: string;
12
+ auto_select?: boolean;
13
+ cancel_on_tap_outside?: boolean;
14
+ use_fedcm_for_prompt?: boolean;
12
15
  callback: (response: CredentialResponse) => void | Promise<void>;
13
16
  };
14
17
  /** debug: chrome://settings/content/federatedIdentityApi */
15
- declare function prompt({ clientId, callback }: Props): void;
18
+ declare function prompt({ client_id, auto_select, use_fedcm_for_prompt, cancel_on_tap_outside, callback, }: Props): void;
16
19
 
17
20
  export { type Props, prompt };
@@ -1,23 +1,39 @@
1
1
  // src/google-one-tap/index.ts
2
- function prompt({ clientId, callback }) {
3
- const scriptId = "google-one-tap";
4
- const script = document.createElement("script");
5
- script.id = scriptId;
6
- script.async = true;
7
- script.defer = true;
8
- script.src = "https://accounts.google.com/gsi/client";
9
- script.onload = () => {
2
+ var script = null;
3
+ function prompt({
4
+ client_id,
5
+ auto_select = false,
6
+ use_fedcm_for_prompt = true,
7
+ cancel_on_tap_outside = false,
8
+ callback
9
+ }) {
10
+ const initializeAndPrompt = () => {
10
11
  window.google.accounts.id.initialize({
11
12
  ux_mode: "popup",
12
13
  context: "signin",
13
- auto_select: false,
14
- client_id: clientId,
15
- use_fedcm_for_prompt: true,
16
- cancel_on_tap_outside: false,
17
- callback
14
+ auto_select,
15
+ client_id,
16
+ use_fedcm_for_prompt,
17
+ cancel_on_tap_outside,
18
+ callback,
19
+ native_callback: callback
18
20
  });
19
21
  window.google?.accounts?.id?.prompt();
20
22
  };
23
+ if (script) {
24
+ if (window.google?.accounts?.id) {
25
+ initializeAndPrompt();
26
+ } else {
27
+ script.addEventListener("load", initializeAndPrompt);
28
+ }
29
+ return;
30
+ }
31
+ script = document.createElement("script");
32
+ script.id = "google-one-tap";
33
+ script.async = true;
34
+ script.defer = true;
35
+ script.src = "https://accounts.google.com/gsi/client";
36
+ script.onload = initializeAndPrompt;
21
37
  document.head.appendChild(script);
22
38
  }
23
39
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/google-one-tap/index.ts"],"sourcesContent":["import type { CredentialResponse, GoogleAccounts } from './types';\n\ndeclare global {\n interface Window {\n google: {\n accounts: GoogleAccounts;\n };\n }\n}\n\nexport type Props = {\n clientId: string;\n callback: (response: CredentialResponse) => void | Promise<void>;\n};\n\n/** debug: chrome://settings/content/federatedIdentityApi */\nexport function prompt({ clientId, callback }: Props) {\n const scriptId = 'google-one-tap';\n const script = document.createElement('script');\n script.id = scriptId;\n script.async = true;\n script.defer = true;\n script.src = 'https://accounts.google.com/gsi/client';\n script.onload = () => {\n window.google.accounts.id.initialize({\n ux_mode: 'popup',\n context: 'signin',\n auto_select: false,\n client_id: clientId,\n use_fedcm_for_prompt: true,\n cancel_on_tap_outside: false,\n callback,\n });\n window.google?.accounts?.id?.prompt();\n };\n\n document.head.appendChild(script);\n}\n"],"mappings":";AAgBO,SAAS,OAAO,EAAE,UAAU,SAAS,GAAU;AACpD,QAAM,WAAW;AACjB,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,KAAK;AACZ,SAAO,QAAQ;AACf,SAAO,QAAQ;AACf,SAAO,MAAM;AACb,SAAO,SAAS,MAAM;AACpB,WAAO,OAAO,SAAS,GAAG,WAAW;AAAA,MACnC,SAAS;AAAA,MACT,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,MACX,sBAAsB;AAAA,MACtB,uBAAuB;AAAA,MACvB;AAAA,IACF,CAAC;AACD,WAAO,QAAQ,UAAU,IAAI,OAAO;AAAA,EACtC;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;","names":[]}
1
+ {"version":3,"sources":["../../src/google-one-tap/index.ts"],"sourcesContent":["import type { CredentialResponse, GoogleAccounts } from './types';\n\ndeclare global {\n interface Window {\n google: {\n accounts: GoogleAccounts;\n };\n }\n}\n\nexport type Props = {\n client_id: string;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n use_fedcm_for_prompt?: boolean;\n callback: (response: CredentialResponse) => void | Promise<void>;\n};\n\nlet script: HTMLScriptElement | null = null;\n\n/** debug: chrome://settings/content/federatedIdentityApi */\nexport function prompt({\n client_id,\n auto_select = false,\n use_fedcm_for_prompt = true,\n cancel_on_tap_outside = false,\n callback,\n}: Props) {\n const initializeAndPrompt = () => {\n window.google.accounts.id.initialize({\n ux_mode: 'popup',\n context: 'signin',\n auto_select,\n client_id,\n use_fedcm_for_prompt,\n cancel_on_tap_outside,\n callback,\n native_callback: callback,\n });\n window.google?.accounts?.id?.prompt();\n };\n\n if (script) {\n if (window.google?.accounts?.id) {\n initializeAndPrompt();\n } else {\n script.addEventListener('load', initializeAndPrompt);\n }\n return;\n }\n\n script = document.createElement('script');\n script.id = 'google-one-tap';\n script.async = true;\n script.defer = true;\n script.src = 'https://accounts.google.com/gsi/client';\n script.onload = initializeAndPrompt;\n\n document.head.appendChild(script);\n}\n"],"mappings":";AAkBA,IAAI,SAAmC;AAGhC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB;AACF,GAAU;AACR,QAAM,sBAAsB,MAAM;AAChC,WAAO,OAAO,SAAS,GAAG,WAAW;AAAA,MACnC,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,IACnB,CAAC;AACD,WAAO,QAAQ,UAAU,IAAI,OAAO;AAAA,EACtC;AAEA,MAAI,QAAQ;AACV,QAAI,OAAO,QAAQ,UAAU,IAAI;AAC/B,0BAAoB;AAAA,IACtB,OAAO;AACL,aAAO,iBAAiB,QAAQ,mBAAmB;AAAA,IACrD;AACA;AAAA,EACF;AAEA,WAAS,SAAS,cAAc,QAAQ;AACxC,SAAO,KAAK;AACZ,SAAO,QAAQ;AACf,SAAO,QAAQ;AACf,SAAO,MAAM;AACb,SAAO,SAAS;AAEhB,WAAS,KAAK,YAAY,MAAM;AAClC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/authorizer.ts"],"sourcesContent":["import { METHOD_NAME_ALL } from 'hono/router';\nimport { RegExpRouter } from 'hono/router/reg-exp-router';\nimport { SmartRouter } from 'hono/router/smart-router';\nimport { TrieRouter } from 'hono/router/trie-router';\nimport { Status } from '../error/status';\nimport type { MiddlewareHandler } from 'hono';\n\ntype Methods = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\ntype Auth = { isAuthenticated: (request: Request) => Promise<boolean> };\n\nexport type AuthRule = string | { path: string; methods?: [Methods, ...Methods[]] };\n\nexport interface AuthorizerConfig {\n auth: Auth;\n errorMessage?: string;\n rules?: AuthRule[];\n}\n\nexport function authorizer({\n auth,\n errorMessage = 'Unauthorized, please login to continue.',\n rules = [],\n}: AuthorizerConfig): MiddlewareHandler {\n const router = new SmartRouter<null>({ routers: [new RegExpRouter(), new TrieRouter()] });\n\n for (const rule of rules) {\n if (typeof rule === 'string') {\n router.add(METHOD_NAME_ALL, rule, null);\n } else if (rule.methods && rule.methods.length > 0) {\n for (const method of rule.methods) {\n router.add(method, rule.path, null);\n }\n } else {\n router.add(METHOD_NAME_ALL, rule.path, null);\n }\n }\n\n return async (c, next) => {\n if (c.req.method === 'OPTIONS') {\n await next();\n return;\n }\n\n const [matched] = router.match(c.req.method, c.req.path);\n if (matched.length === 0) {\n await next();\n return;\n }\n\n const authenticated = await auth.isAuthenticated(c.req.raw);\n if (!authenticated) throw Status.unauthorized(errorMessage).error();\n await next();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAgC;AAChC,4BAA6B;AAC7B,0BAA4B;AAC5B,yBAA2B;AAC3B,oBAAuB;AAehB,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,eAAe;AAAA,EACf,QAAQ,CAAC;AACX,GAAwC;AACtC,QAAM,SAAS,IAAI,gCAAkB,EAAE,SAAS,CAAC,IAAI,mCAAa,GAAG,IAAI,8BAAW,CAAC,EAAE,CAAC;AAExF,aAAW,QAAQ,OAAO;AACxB,QAAI,OAAO,SAAS,UAAU;AAC5B,aAAO,IAAI,+BAAiB,MAAM,IAAI;AAAA,IACxC,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAClD,iBAAW,UAAU,KAAK,SAAS;AACjC,eAAO,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,MACpC;AAAA,IACF,OAAO;AACL,aAAO,IAAI,+BAAiB,KAAK,MAAM,IAAI;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO,OAAO,GAAG,SAAS;AACxB,QAAI,EAAE,IAAI,WAAW,WAAW;AAC9B,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,CAAC,OAAO,IAAI,OAAO,MAAM,EAAE,IAAI,QAAQ,EAAE,IAAI,IAAI;AACvD,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,KAAK,gBAAgB,EAAE,IAAI,GAAG;AAC1D,QAAI,CAAC,cAAe,OAAM,qBAAO,aAAa,YAAY,EAAE,MAAM;AAClE,UAAM,KAAK;AAAA,EACb;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/authorizer.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono';\nimport { METHOD_NAME_ALL } from 'hono/router';\nimport { RegExpRouter } from 'hono/router/reg-exp-router';\nimport { SmartRouter } from 'hono/router/smart-router';\nimport { TrieRouter } from 'hono/router/trie-router';\nimport { Status } from '../error/status';\n\ntype Methods = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\ntype Auth = { isAuthenticated: (request: Request) => Promise<boolean> };\n\nexport type AuthRule = string | { path: string; methods?: [Methods, ...Methods[]] };\n\nexport interface AuthorizerConfig {\n auth: Auth;\n errorMessage?: string;\n rules?: AuthRule[];\n}\n\nexport function authorizer({\n auth,\n errorMessage = 'Unauthorized, please login to continue.',\n rules = [],\n}: AuthorizerConfig): MiddlewareHandler {\n const router = new SmartRouter<null>({ routers: [new RegExpRouter(), new TrieRouter()] });\n\n for (const rule of rules) {\n if (typeof rule === 'string') {\n router.add(METHOD_NAME_ALL, rule, null);\n } else if (rule.methods && rule.methods.length > 0) {\n for (const method of rule.methods) {\n router.add(method, rule.path, null);\n }\n } else {\n router.add(METHOD_NAME_ALL, rule.path, null);\n }\n }\n\n return async (c, next) => {\n if (c.req.method === 'OPTIONS') {\n await next();\n return;\n }\n\n const [matched] = router.match(c.req.method, c.req.path);\n if (matched.length === 0) {\n await next();\n return;\n }\n\n const authenticated = await auth.isAuthenticated(c.req.raw);\n if (!authenticated) throw Status.unauthorized(errorMessage).error();\n await next();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAAgC;AAChC,4BAA6B;AAC7B,0BAA4B;AAC5B,yBAA2B;AAC3B,oBAAuB;AAchB,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,eAAe;AAAA,EACf,QAAQ,CAAC;AACX,GAAwC;AACtC,QAAM,SAAS,IAAI,gCAAkB,EAAE,SAAS,CAAC,IAAI,mCAAa,GAAG,IAAI,8BAAW,CAAC,EAAE,CAAC;AAExF,aAAW,QAAQ,OAAO;AACxB,QAAI,OAAO,SAAS,UAAU;AAC5B,aAAO,IAAI,+BAAiB,MAAM,IAAI;AAAA,IACxC,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAClD,iBAAW,UAAU,KAAK,SAAS;AACjC,eAAO,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,MACpC;AAAA,IACF,OAAO;AACL,aAAO,IAAI,+BAAiB,KAAK,MAAM,IAAI;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO,OAAO,GAAG,SAAS;AACxB,QAAI,EAAE,IAAI,WAAW,WAAW;AAC9B,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,CAAC,OAAO,IAAI,OAAO,MAAM,EAAE,IAAI,QAAQ,EAAE,IAAI,IAAI;AACvD,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,KAAK,gBAAgB,EAAE,IAAI,GAAG;AAC1D,QAAI,CAAC,cAAe,OAAM,qBAAO,aAAa,YAAY,EAAE,MAAM;AAClE,UAAM,KAAK;AAAA,EACb;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/authorizer.ts"],"sourcesContent":["import { METHOD_NAME_ALL } from 'hono/router';\nimport { RegExpRouter } from 'hono/router/reg-exp-router';\nimport { SmartRouter } from 'hono/router/smart-router';\nimport { TrieRouter } from 'hono/router/trie-router';\nimport { Status } from '../error/status';\nimport type { MiddlewareHandler } from 'hono';\n\ntype Methods = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\ntype Auth = { isAuthenticated: (request: Request) => Promise<boolean> };\n\nexport type AuthRule = string | { path: string; methods?: [Methods, ...Methods[]] };\n\nexport interface AuthorizerConfig {\n auth: Auth;\n errorMessage?: string;\n rules?: AuthRule[];\n}\n\nexport function authorizer({\n auth,\n errorMessage = 'Unauthorized, please login to continue.',\n rules = [],\n}: AuthorizerConfig): MiddlewareHandler {\n const router = new SmartRouter<null>({ routers: [new RegExpRouter(), new TrieRouter()] });\n\n for (const rule of rules) {\n if (typeof rule === 'string') {\n router.add(METHOD_NAME_ALL, rule, null);\n } else if (rule.methods && rule.methods.length > 0) {\n for (const method of rule.methods) {\n router.add(method, rule.path, null);\n }\n } else {\n router.add(METHOD_NAME_ALL, rule.path, null);\n }\n }\n\n return async (c, next) => {\n if (c.req.method === 'OPTIONS') {\n await next();\n return;\n }\n\n const [matched] = router.match(c.req.method, c.req.path);\n if (matched.length === 0) {\n await next();\n return;\n }\n\n const authenticated = await auth.isAuthenticated(c.req.raw);\n if (!authenticated) throw Status.unauthorized(errorMessage).error();\n await next();\n };\n}\n"],"mappings":";AAAA,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AAehB,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,eAAe;AAAA,EACf,QAAQ,CAAC;AACX,GAAwC;AACtC,QAAM,SAAS,IAAI,YAAkB,EAAE,SAAS,CAAC,IAAI,aAAa,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC;AAExF,aAAW,QAAQ,OAAO;AACxB,QAAI,OAAO,SAAS,UAAU;AAC5B,aAAO,IAAI,iBAAiB,MAAM,IAAI;AAAA,IACxC,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAClD,iBAAW,UAAU,KAAK,SAAS;AACjC,eAAO,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,MACpC;AAAA,IACF,OAAO;AACL,aAAO,IAAI,iBAAiB,KAAK,MAAM,IAAI;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO,OAAO,GAAG,SAAS;AACxB,QAAI,EAAE,IAAI,WAAW,WAAW;AAC9B,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,CAAC,OAAO,IAAI,OAAO,MAAM,EAAE,IAAI,QAAQ,EAAE,IAAI,IAAI;AACvD,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,KAAK,gBAAgB,EAAE,IAAI,GAAG;AAC1D,QAAI,CAAC,cAAe,OAAM,OAAO,aAAa,YAAY,EAAE,MAAM;AAClE,UAAM,KAAK;AAAA,EACb;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/authorizer.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono';\nimport { METHOD_NAME_ALL } from 'hono/router';\nimport { RegExpRouter } from 'hono/router/reg-exp-router';\nimport { SmartRouter } from 'hono/router/smart-router';\nimport { TrieRouter } from 'hono/router/trie-router';\nimport { Status } from '../error/status';\n\ntype Methods = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\ntype Auth = { isAuthenticated: (request: Request) => Promise<boolean> };\n\nexport type AuthRule = string | { path: string; methods?: [Methods, ...Methods[]] };\n\nexport interface AuthorizerConfig {\n auth: Auth;\n errorMessage?: string;\n rules?: AuthRule[];\n}\n\nexport function authorizer({\n auth,\n errorMessage = 'Unauthorized, please login to continue.',\n rules = [],\n}: AuthorizerConfig): MiddlewareHandler {\n const router = new SmartRouter<null>({ routers: [new RegExpRouter(), new TrieRouter()] });\n\n for (const rule of rules) {\n if (typeof rule === 'string') {\n router.add(METHOD_NAME_ALL, rule, null);\n } else if (rule.methods && rule.methods.length > 0) {\n for (const method of rule.methods) {\n router.add(method, rule.path, null);\n }\n } else {\n router.add(METHOD_NAME_ALL, rule.path, null);\n }\n }\n\n return async (c, next) => {\n if (c.req.method === 'OPTIONS') {\n await next();\n return;\n }\n\n const [matched] = router.match(c.req.method, c.req.path);\n if (matched.length === 0) {\n await next();\n return;\n }\n\n const authenticated = await auth.isAuthenticated(c.req.raw);\n if (!authenticated) throw Status.unauthorized(errorMessage).error();\n await next();\n };\n}\n"],"mappings":";AACA,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AAchB,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,eAAe;AAAA,EACf,QAAQ,CAAC;AACX,GAAwC;AACtC,QAAM,SAAS,IAAI,YAAkB,EAAE,SAAS,CAAC,IAAI,aAAa,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC;AAExF,aAAW,QAAQ,OAAO;AACxB,QAAI,OAAO,SAAS,UAAU;AAC5B,aAAO,IAAI,iBAAiB,MAAM,IAAI;AAAA,IACxC,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAClD,iBAAW,UAAU,KAAK,SAAS;AACjC,eAAO,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,MACpC;AAAA,IACF,OAAO;AACL,aAAO,IAAI,iBAAiB,KAAK,MAAM,IAAI;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO,OAAO,GAAG,SAAS;AACxB,QAAI,EAAE,IAAI,WAAW,WAAW;AAC9B,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,CAAC,OAAO,IAAI,OAAO,MAAM,EAAE,IAAI,QAAQ,EAAE,IAAI,IAAI;AACvD,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,KAAK,gBAAgB,EAAE,IAAI,GAAG;AAC1D,QAAI,CAAC,cAAe,OAAM,OAAO,aAAa,YAAY,EAAE,MAAM;AAClE,UAAM,KAAK;AAAA,EACb;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/csrf.ts"],"sourcesContent":["import { timingSafeEqual } from 'crypto';\nimport { getCookie } from 'hono/cookie';\nimport { METHOD_NAME_ALL } from 'hono/router';\nimport { RegExpRouter } from 'hono/router/reg-exp-router';\nimport { SmartRouter } from 'hono/router/smart-router';\nimport { TrieRouter } from 'hono/router/trie-router';\nimport { Status } from '../error/status';\nimport type { MiddlewareHandler } from 'hono';\n\ntype HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';\n\nexport type CSRFIgnoreRule = string | { path: string; methods?: [HTTPMethod, ...HTTPMethod[]] };\n\nexport interface CSRFConfig {\n /**\n * Cookie name for CSRF token\n * @default 'XSRF-TOKEN'\n */\n cookieName?: string;\n\n /**\n * Header name for CSRF token\n * @default 'X-XSRF-TOKEN'\n */\n headerName?: string;\n\n /**\n * Ignore rules for specific paths and methods\n * @example\n * [\n * { path: '/api/webhook/*', methods: ['POST'] },\n * { path: '/auth/apple/callback' }, // ignores all methods\n * ]\n */\n ignores?: CSRFIgnoreRule[];\n\n /**\n * Skip CSRF check for these methods\n * @default ['GET', 'HEAD', 'OPTIONS']\n */\n safeMethods?: HTTPMethod[];\n\n /**\n * Origin allowed to bypass CSRF check\n * @default undefined\n */\n origin?: string[];\n\n /**\n * Sec-Fetch-Site allowed to bypass CSRF check\n * @default undefined\n */\n secFetchSite?: Array<'same-origin' | 'same-site' | 'none' | 'cross-origin'>;\n\n /**\n * Custom error message\n * @default 'CSRF token validation failed'\n */\n errorMessage?: string;\n}\n\n/** use timing safe compare to prevent timing attack */\nfunction safeCompare(a: string, b: string): boolean {\n if (typeof a !== 'string' || typeof b !== 'string') return false;\n if (a.length === 0 || b.length === 0) return false;\n\n const bufferA = Buffer.from(a, 'utf-8');\n const bufferB = Buffer.from(b, 'utf-8');\n if (bufferA.length !== bufferB.length) return false;\n return timingSafeEqual(bufferA, bufferB);\n}\n\n/**\n * Create CSRF protection middleware\n *\n * @example\n * ```ts\n * import { Hono } from 'hono';\n * import { csrf } from '@shware/http/hono';\n *\n * const app = new Hono();\n *\n * // basic usage\n * app.use(csrf());\n *\n * // with configuration\n * app.use(csrf({\n * cookieName: 'csrf-token',\n * headerName: 'X-CSRF-Token',\n * ignores: [\n * { path: '/api/webhook/*', methods: ['POST'] },\n * { path: '/auth/apple/callback' },\n * ]\n * }));\n * ```\n */\nexport function csrf(config: CSRFConfig = {}): MiddlewareHandler {\n const cookieName = config.cookieName ?? 'XSRF-TOKEN';\n const headerName = config.headerName ?? 'X-XSRF-TOKEN';\n const safeMethods = new Set(config.safeMethods ?? ['GET', 'HEAD', 'OPTIONS']);\n const errorMessage = config.errorMessage ?? 'CSRF token validation failed';\n\n // initialize router for matching ignore rules\n const router = new SmartRouter<boolean>({\n routers: [new RegExpRouter(), new TrieRouter()],\n });\n\n // register ignore rules\n if (config.ignores) {\n for (const rule of config.ignores) {\n if (typeof rule === 'string') {\n router.add(METHOD_NAME_ALL, rule, true);\n } else if (rule.methods && rule.methods.length > 0) {\n for (const method of rule.methods) {\n router.add(method, rule.path, true);\n }\n } else {\n // if no methods are specified, ignore all methods\n router.add(METHOD_NAME_ALL, rule.path, true);\n }\n }\n }\n\n // return middleware\n return async (c, next) => {\n const method = c.req.method;\n const path = c.req.path;\n\n // check if the request should be ignored\n // 1. ignore safe methods\n if (safeMethods.has(method)) {\n await next();\n return;\n }\n\n // 2. ignore configured origin\n if (config.origin && config.origin.includes(c.req.header('origin') ?? '')) {\n await next();\n return;\n }\n\n // 3. ignore configured secFetchSite\n if (\n config.secFetchSite &&\n config.secFetchSite.includes((c.req.header('sec-fetch-site') ?? '') as never)\n ) {\n await next();\n return;\n }\n\n // 4. ignore configured ignore rules\n const [matched] = router.match(method, path);\n if (matched.length > 0) {\n await next();\n return;\n }\n\n const cookieToken = getCookie(c, cookieName);\n const headerToken = c.req.header(headerName);\n\n if (!cookieToken || !headerToken) {\n throw Status.permissionDenied(errorMessage).error();\n }\n\n if (!safeCompare(cookieToken, headerToken)) {\n throw Status.permissionDenied(errorMessage).error();\n }\n\n await next();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAgC;AAChC,oBAA0B;AAC1B,oBAAgC;AAChC,4BAA6B;AAC7B,0BAA4B;AAC5B,yBAA2B;AAC3B,oBAAuB;AAwDvB,SAAS,YAAY,GAAW,GAAoB;AAClD,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO;AAC3D,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAE7C,QAAM,UAAU,OAAO,KAAK,GAAG,OAAO;AACtC,QAAM,UAAU,OAAO,KAAK,GAAG,OAAO;AACtC,MAAI,QAAQ,WAAW,QAAQ,OAAQ,QAAO;AAC9C,aAAO,+BAAgB,SAAS,OAAO;AACzC;AA0BO,SAAS,KAAK,SAAqB,CAAC,GAAsB;AAC/D,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,cAAc,IAAI,IAAI,OAAO,eAAe,CAAC,OAAO,QAAQ,SAAS,CAAC;AAC5E,QAAM,eAAe,OAAO,gBAAgB;AAG5C,QAAM,SAAS,IAAI,gCAAqB;AAAA,IACtC,SAAS,CAAC,IAAI,mCAAa,GAAG,IAAI,8BAAW,CAAC;AAAA,EAChD,CAAC;AAGD,MAAI,OAAO,SAAS;AAClB,eAAW,QAAQ,OAAO,SAAS;AACjC,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO,IAAI,+BAAiB,MAAM,IAAI;AAAA,MACxC,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAClD,mBAAW,UAAU,KAAK,SAAS;AACjC,iBAAO,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,QACpC;AAAA,MACF,OAAO;AAEL,eAAO,IAAI,+BAAiB,KAAK,MAAM,IAAI;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAGA,SAAO,OAAO,GAAG,SAAS;AACxB,UAAM,SAAS,EAAE,IAAI;AACrB,UAAM,OAAO,EAAE,IAAI;AAInB,QAAI,YAAY,IAAI,MAAM,GAAG;AAC3B,YAAM,KAAK;AACX;AAAA,IACF;AAGA,QAAI,OAAO,UAAU,OAAO,OAAO,SAAS,EAAE,IAAI,OAAO,QAAQ,KAAK,EAAE,GAAG;AACzE,YAAM,KAAK;AACX;AAAA,IACF;AAGA,QACE,OAAO,gBACP,OAAO,aAAa,SAAU,EAAE,IAAI,OAAO,gBAAgB,KAAK,EAAY,GAC5E;AACA,YAAM,KAAK;AACX;AAAA,IACF;AAGA,UAAM,CAAC,OAAO,IAAI,OAAO,MAAM,QAAQ,IAAI;AAC3C,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,kBAAc,yBAAU,GAAG,UAAU;AAC3C,UAAM,cAAc,EAAE,IAAI,OAAO,UAAU;AAE3C,QAAI,CAAC,eAAe,CAAC,aAAa;AAChC,YAAM,qBAAO,iBAAiB,YAAY,EAAE,MAAM;AAAA,IACpD;AAEA,QAAI,CAAC,YAAY,aAAa,WAAW,GAAG;AAC1C,YAAM,qBAAO,iBAAiB,YAAY,EAAE,MAAM;AAAA,IACpD;AAEA,UAAM,KAAK;AAAA,EACb;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/csrf.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono';\nimport { timingSafeEqual } from 'crypto';\nimport { getCookie } from 'hono/cookie';\nimport { METHOD_NAME_ALL } from 'hono/router';\nimport { RegExpRouter } from 'hono/router/reg-exp-router';\nimport { SmartRouter } from 'hono/router/smart-router';\nimport { TrieRouter } from 'hono/router/trie-router';\nimport { Status } from '../error/status';\n\ntype HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';\n\nexport type CSRFIgnoreRule = string | { path: string; methods?: [HTTPMethod, ...HTTPMethod[]] };\n\nexport interface CSRFConfig {\n /**\n * Cookie name for CSRF token\n * @default 'XSRF-TOKEN'\n */\n cookieName?: string;\n\n /**\n * Header name for CSRF token\n * @default 'X-XSRF-TOKEN'\n */\n headerName?: string;\n\n /**\n * Ignore rules for specific paths and methods\n * @example\n * [\n * { path: '/api/webhook/*', methods: ['POST'] },\n * { path: '/auth/apple/callback' }, // ignores all methods\n * ]\n */\n ignores?: CSRFIgnoreRule[];\n\n /**\n * Skip CSRF check for these methods\n * @default ['GET', 'HEAD', 'OPTIONS']\n */\n safeMethods?: HTTPMethod[];\n\n /**\n * Origin allowed to bypass CSRF check\n * @default undefined\n */\n origin?: string[];\n\n /**\n * Sec-Fetch-Site allowed to bypass CSRF check\n * @default undefined\n */\n secFetchSite?: Array<'same-origin' | 'same-site' | 'none' | 'cross-origin'>;\n\n /**\n * Custom error message\n * @default 'CSRF token validation failed'\n */\n errorMessage?: string;\n}\n\n/** use timing safe compare to prevent timing attack */\nfunction safeCompare(a: string, b: string): boolean {\n if (typeof a !== 'string' || typeof b !== 'string') return false;\n if (a.length === 0 || b.length === 0) return false;\n\n const bufferA = Buffer.from(a, 'utf-8');\n const bufferB = Buffer.from(b, 'utf-8');\n if (bufferA.length !== bufferB.length) return false;\n return timingSafeEqual(bufferA, bufferB);\n}\n\n/**\n * Create CSRF protection middleware\n *\n * @example\n * ```ts\n * import { Hono } from 'hono';\n * import { csrf } from '@shware/http/hono';\n *\n * const app = new Hono();\n *\n * // basic usage\n * app.use(csrf());\n *\n * // with configuration\n * app.use(csrf({\n * cookieName: 'csrf-token',\n * headerName: 'X-CSRF-Token',\n * ignores: [\n * { path: '/api/webhook/*', methods: ['POST'] },\n * { path: '/auth/apple/callback' },\n * ]\n * }));\n * ```\n */\nexport function csrf(config: CSRFConfig = {}): MiddlewareHandler {\n const cookieName = config.cookieName ?? 'XSRF-TOKEN';\n const headerName = config.headerName ?? 'X-XSRF-TOKEN';\n const safeMethods = new Set(config.safeMethods ?? ['GET', 'HEAD', 'OPTIONS']);\n const errorMessage = config.errorMessage ?? 'CSRF token validation failed';\n\n // initialize router for matching ignore rules\n const router = new SmartRouter<boolean>({\n routers: [new RegExpRouter(), new TrieRouter()],\n });\n\n // register ignore rules\n if (config.ignores) {\n for (const rule of config.ignores) {\n if (typeof rule === 'string') {\n router.add(METHOD_NAME_ALL, rule, true);\n } else if (rule.methods && rule.methods.length > 0) {\n for (const method of rule.methods) {\n router.add(method, rule.path, true);\n }\n } else {\n // if no methods are specified, ignore all methods\n router.add(METHOD_NAME_ALL, rule.path, true);\n }\n }\n }\n\n // return middleware\n return async (c, next) => {\n const method = c.req.method;\n const path = c.req.path;\n\n // check if the request should be ignored\n // 1. ignore safe methods\n if (safeMethods.has(method)) {\n await next();\n return;\n }\n\n // 2. ignore configured origin\n if (config.origin && config.origin.includes(c.req.header('origin') ?? '')) {\n await next();\n return;\n }\n\n // 3. ignore configured secFetchSite\n if (\n config.secFetchSite &&\n config.secFetchSite.includes((c.req.header('sec-fetch-site') ?? '') as never)\n ) {\n await next();\n return;\n }\n\n // 4. ignore configured ignore rules\n const [matched] = router.match(method, path);\n if (matched.length > 0) {\n await next();\n return;\n }\n\n const cookieToken = getCookie(c, cookieName);\n const headerToken = c.req.header(headerName);\n\n if (!cookieToken || !headerToken) {\n throw Status.permissionDenied(errorMessage).error();\n }\n\n if (!safeCompare(cookieToken, headerToken)) {\n throw Status.permissionDenied(errorMessage).error();\n }\n\n await next();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAAgC;AAChC,oBAA0B;AAC1B,oBAAgC;AAChC,4BAA6B;AAC7B,0BAA4B;AAC5B,yBAA2B;AAC3B,oBAAuB;AAuDvB,SAAS,YAAY,GAAW,GAAoB;AAClD,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO;AAC3D,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAE7C,QAAM,UAAU,OAAO,KAAK,GAAG,OAAO;AACtC,QAAM,UAAU,OAAO,KAAK,GAAG,OAAO;AACtC,MAAI,QAAQ,WAAW,QAAQ,OAAQ,QAAO;AAC9C,aAAO,+BAAgB,SAAS,OAAO;AACzC;AA0BO,SAAS,KAAK,SAAqB,CAAC,GAAsB;AAC/D,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,cAAc,IAAI,IAAI,OAAO,eAAe,CAAC,OAAO,QAAQ,SAAS,CAAC;AAC5E,QAAM,eAAe,OAAO,gBAAgB;AAG5C,QAAM,SAAS,IAAI,gCAAqB;AAAA,IACtC,SAAS,CAAC,IAAI,mCAAa,GAAG,IAAI,8BAAW,CAAC;AAAA,EAChD,CAAC;AAGD,MAAI,OAAO,SAAS;AAClB,eAAW,QAAQ,OAAO,SAAS;AACjC,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO,IAAI,+BAAiB,MAAM,IAAI;AAAA,MACxC,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAClD,mBAAW,UAAU,KAAK,SAAS;AACjC,iBAAO,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,QACpC;AAAA,MACF,OAAO;AAEL,eAAO,IAAI,+BAAiB,KAAK,MAAM,IAAI;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAGA,SAAO,OAAO,GAAG,SAAS;AACxB,UAAM,SAAS,EAAE,IAAI;AACrB,UAAM,OAAO,EAAE,IAAI;AAInB,QAAI,YAAY,IAAI,MAAM,GAAG;AAC3B,YAAM,KAAK;AACX;AAAA,IACF;AAGA,QAAI,OAAO,UAAU,OAAO,OAAO,SAAS,EAAE,IAAI,OAAO,QAAQ,KAAK,EAAE,GAAG;AACzE,YAAM,KAAK;AACX;AAAA,IACF;AAGA,QACE,OAAO,gBACP,OAAO,aAAa,SAAU,EAAE,IAAI,OAAO,gBAAgB,KAAK,EAAY,GAC5E;AACA,YAAM,KAAK;AACX;AAAA,IACF;AAGA,UAAM,CAAC,OAAO,IAAI,OAAO,MAAM,QAAQ,IAAI;AAC3C,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,kBAAc,yBAAU,GAAG,UAAU;AAC3C,UAAM,cAAc,EAAE,IAAI,OAAO,UAAU;AAE3C,QAAI,CAAC,eAAe,CAAC,aAAa;AAChC,YAAM,qBAAO,iBAAiB,YAAY,EAAE,MAAM;AAAA,IACpD;AAEA,QAAI,CAAC,YAAY,aAAa,WAAW,GAAG;AAC1C,YAAM,qBAAO,iBAAiB,YAAY,EAAE,MAAM;AAAA,IACpD;AAEA,UAAM,KAAK;AAAA,EACb;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/csrf.ts"],"sourcesContent":["import { timingSafeEqual } from 'crypto';\nimport { getCookie } from 'hono/cookie';\nimport { METHOD_NAME_ALL } from 'hono/router';\nimport { RegExpRouter } from 'hono/router/reg-exp-router';\nimport { SmartRouter } from 'hono/router/smart-router';\nimport { TrieRouter } from 'hono/router/trie-router';\nimport { Status } from '../error/status';\nimport type { MiddlewareHandler } from 'hono';\n\ntype HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';\n\nexport type CSRFIgnoreRule = string | { path: string; methods?: [HTTPMethod, ...HTTPMethod[]] };\n\nexport interface CSRFConfig {\n /**\n * Cookie name for CSRF token\n * @default 'XSRF-TOKEN'\n */\n cookieName?: string;\n\n /**\n * Header name for CSRF token\n * @default 'X-XSRF-TOKEN'\n */\n headerName?: string;\n\n /**\n * Ignore rules for specific paths and methods\n * @example\n * [\n * { path: '/api/webhook/*', methods: ['POST'] },\n * { path: '/auth/apple/callback' }, // ignores all methods\n * ]\n */\n ignores?: CSRFIgnoreRule[];\n\n /**\n * Skip CSRF check for these methods\n * @default ['GET', 'HEAD', 'OPTIONS']\n */\n safeMethods?: HTTPMethod[];\n\n /**\n * Origin allowed to bypass CSRF check\n * @default undefined\n */\n origin?: string[];\n\n /**\n * Sec-Fetch-Site allowed to bypass CSRF check\n * @default undefined\n */\n secFetchSite?: Array<'same-origin' | 'same-site' | 'none' | 'cross-origin'>;\n\n /**\n * Custom error message\n * @default 'CSRF token validation failed'\n */\n errorMessage?: string;\n}\n\n/** use timing safe compare to prevent timing attack */\nfunction safeCompare(a: string, b: string): boolean {\n if (typeof a !== 'string' || typeof b !== 'string') return false;\n if (a.length === 0 || b.length === 0) return false;\n\n const bufferA = Buffer.from(a, 'utf-8');\n const bufferB = Buffer.from(b, 'utf-8');\n if (bufferA.length !== bufferB.length) return false;\n return timingSafeEqual(bufferA, bufferB);\n}\n\n/**\n * Create CSRF protection middleware\n *\n * @example\n * ```ts\n * import { Hono } from 'hono';\n * import { csrf } from '@shware/http/hono';\n *\n * const app = new Hono();\n *\n * // basic usage\n * app.use(csrf());\n *\n * // with configuration\n * app.use(csrf({\n * cookieName: 'csrf-token',\n * headerName: 'X-CSRF-Token',\n * ignores: [\n * { path: '/api/webhook/*', methods: ['POST'] },\n * { path: '/auth/apple/callback' },\n * ]\n * }));\n * ```\n */\nexport function csrf(config: CSRFConfig = {}): MiddlewareHandler {\n const cookieName = config.cookieName ?? 'XSRF-TOKEN';\n const headerName = config.headerName ?? 'X-XSRF-TOKEN';\n const safeMethods = new Set(config.safeMethods ?? ['GET', 'HEAD', 'OPTIONS']);\n const errorMessage = config.errorMessage ?? 'CSRF token validation failed';\n\n // initialize router for matching ignore rules\n const router = new SmartRouter<boolean>({\n routers: [new RegExpRouter(), new TrieRouter()],\n });\n\n // register ignore rules\n if (config.ignores) {\n for (const rule of config.ignores) {\n if (typeof rule === 'string') {\n router.add(METHOD_NAME_ALL, rule, true);\n } else if (rule.methods && rule.methods.length > 0) {\n for (const method of rule.methods) {\n router.add(method, rule.path, true);\n }\n } else {\n // if no methods are specified, ignore all methods\n router.add(METHOD_NAME_ALL, rule.path, true);\n }\n }\n }\n\n // return middleware\n return async (c, next) => {\n const method = c.req.method;\n const path = c.req.path;\n\n // check if the request should be ignored\n // 1. ignore safe methods\n if (safeMethods.has(method)) {\n await next();\n return;\n }\n\n // 2. ignore configured origin\n if (config.origin && config.origin.includes(c.req.header('origin') ?? '')) {\n await next();\n return;\n }\n\n // 3. ignore configured secFetchSite\n if (\n config.secFetchSite &&\n config.secFetchSite.includes((c.req.header('sec-fetch-site') ?? '') as never)\n ) {\n await next();\n return;\n }\n\n // 4. ignore configured ignore rules\n const [matched] = router.match(method, path);\n if (matched.length > 0) {\n await next();\n return;\n }\n\n const cookieToken = getCookie(c, cookieName);\n const headerToken = c.req.header(headerName);\n\n if (!cookieToken || !headerToken) {\n throw Status.permissionDenied(errorMessage).error();\n }\n\n if (!safeCompare(cookieToken, headerToken)) {\n throw Status.permissionDenied(errorMessage).error();\n }\n\n await next();\n };\n}\n"],"mappings":";AAAA,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AAwDvB,SAAS,YAAY,GAAW,GAAoB;AAClD,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO;AAC3D,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAE7C,QAAM,UAAU,OAAO,KAAK,GAAG,OAAO;AACtC,QAAM,UAAU,OAAO,KAAK,GAAG,OAAO;AACtC,MAAI,QAAQ,WAAW,QAAQ,OAAQ,QAAO;AAC9C,SAAO,gBAAgB,SAAS,OAAO;AACzC;AA0BO,SAAS,KAAK,SAAqB,CAAC,GAAsB;AAC/D,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,cAAc,IAAI,IAAI,OAAO,eAAe,CAAC,OAAO,QAAQ,SAAS,CAAC;AAC5E,QAAM,eAAe,OAAO,gBAAgB;AAG5C,QAAM,SAAS,IAAI,YAAqB;AAAA,IACtC,SAAS,CAAC,IAAI,aAAa,GAAG,IAAI,WAAW,CAAC;AAAA,EAChD,CAAC;AAGD,MAAI,OAAO,SAAS;AAClB,eAAW,QAAQ,OAAO,SAAS;AACjC,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO,IAAI,iBAAiB,MAAM,IAAI;AAAA,MACxC,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAClD,mBAAW,UAAU,KAAK,SAAS;AACjC,iBAAO,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,QACpC;AAAA,MACF,OAAO;AAEL,eAAO,IAAI,iBAAiB,KAAK,MAAM,IAAI;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAGA,SAAO,OAAO,GAAG,SAAS;AACxB,UAAM,SAAS,EAAE,IAAI;AACrB,UAAM,OAAO,EAAE,IAAI;AAInB,QAAI,YAAY,IAAI,MAAM,GAAG;AAC3B,YAAM,KAAK;AACX;AAAA,IACF;AAGA,QAAI,OAAO,UAAU,OAAO,OAAO,SAAS,EAAE,IAAI,OAAO,QAAQ,KAAK,EAAE,GAAG;AACzE,YAAM,KAAK;AACX;AAAA,IACF;AAGA,QACE,OAAO,gBACP,OAAO,aAAa,SAAU,EAAE,IAAI,OAAO,gBAAgB,KAAK,EAAY,GAC5E;AACA,YAAM,KAAK;AACX;AAAA,IACF;AAGA,UAAM,CAAC,OAAO,IAAI,OAAO,MAAM,QAAQ,IAAI;AAC3C,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,cAAc,UAAU,GAAG,UAAU;AAC3C,UAAM,cAAc,EAAE,IAAI,OAAO,UAAU;AAE3C,QAAI,CAAC,eAAe,CAAC,aAAa;AAChC,YAAM,OAAO,iBAAiB,YAAY,EAAE,MAAM;AAAA,IACpD;AAEA,QAAI,CAAC,YAAY,aAAa,WAAW,GAAG;AAC1C,YAAM,OAAO,iBAAiB,YAAY,EAAE,MAAM;AAAA,IACpD;AAEA,UAAM,KAAK;AAAA,EACb;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/csrf.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono';\nimport { timingSafeEqual } from 'crypto';\nimport { getCookie } from 'hono/cookie';\nimport { METHOD_NAME_ALL } from 'hono/router';\nimport { RegExpRouter } from 'hono/router/reg-exp-router';\nimport { SmartRouter } from 'hono/router/smart-router';\nimport { TrieRouter } from 'hono/router/trie-router';\nimport { Status } from '../error/status';\n\ntype HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';\n\nexport type CSRFIgnoreRule = string | { path: string; methods?: [HTTPMethod, ...HTTPMethod[]] };\n\nexport interface CSRFConfig {\n /**\n * Cookie name for CSRF token\n * @default 'XSRF-TOKEN'\n */\n cookieName?: string;\n\n /**\n * Header name for CSRF token\n * @default 'X-XSRF-TOKEN'\n */\n headerName?: string;\n\n /**\n * Ignore rules for specific paths and methods\n * @example\n * [\n * { path: '/api/webhook/*', methods: ['POST'] },\n * { path: '/auth/apple/callback' }, // ignores all methods\n * ]\n */\n ignores?: CSRFIgnoreRule[];\n\n /**\n * Skip CSRF check for these methods\n * @default ['GET', 'HEAD', 'OPTIONS']\n */\n safeMethods?: HTTPMethod[];\n\n /**\n * Origin allowed to bypass CSRF check\n * @default undefined\n */\n origin?: string[];\n\n /**\n * Sec-Fetch-Site allowed to bypass CSRF check\n * @default undefined\n */\n secFetchSite?: Array<'same-origin' | 'same-site' | 'none' | 'cross-origin'>;\n\n /**\n * Custom error message\n * @default 'CSRF token validation failed'\n */\n errorMessage?: string;\n}\n\n/** use timing safe compare to prevent timing attack */\nfunction safeCompare(a: string, b: string): boolean {\n if (typeof a !== 'string' || typeof b !== 'string') return false;\n if (a.length === 0 || b.length === 0) return false;\n\n const bufferA = Buffer.from(a, 'utf-8');\n const bufferB = Buffer.from(b, 'utf-8');\n if (bufferA.length !== bufferB.length) return false;\n return timingSafeEqual(bufferA, bufferB);\n}\n\n/**\n * Create CSRF protection middleware\n *\n * @example\n * ```ts\n * import { Hono } from 'hono';\n * import { csrf } from '@shware/http/hono';\n *\n * const app = new Hono();\n *\n * // basic usage\n * app.use(csrf());\n *\n * // with configuration\n * app.use(csrf({\n * cookieName: 'csrf-token',\n * headerName: 'X-CSRF-Token',\n * ignores: [\n * { path: '/api/webhook/*', methods: ['POST'] },\n * { path: '/auth/apple/callback' },\n * ]\n * }));\n * ```\n */\nexport function csrf(config: CSRFConfig = {}): MiddlewareHandler {\n const cookieName = config.cookieName ?? 'XSRF-TOKEN';\n const headerName = config.headerName ?? 'X-XSRF-TOKEN';\n const safeMethods = new Set(config.safeMethods ?? ['GET', 'HEAD', 'OPTIONS']);\n const errorMessage = config.errorMessage ?? 'CSRF token validation failed';\n\n // initialize router for matching ignore rules\n const router = new SmartRouter<boolean>({\n routers: [new RegExpRouter(), new TrieRouter()],\n });\n\n // register ignore rules\n if (config.ignores) {\n for (const rule of config.ignores) {\n if (typeof rule === 'string') {\n router.add(METHOD_NAME_ALL, rule, true);\n } else if (rule.methods && rule.methods.length > 0) {\n for (const method of rule.methods) {\n router.add(method, rule.path, true);\n }\n } else {\n // if no methods are specified, ignore all methods\n router.add(METHOD_NAME_ALL, rule.path, true);\n }\n }\n }\n\n // return middleware\n return async (c, next) => {\n const method = c.req.method;\n const path = c.req.path;\n\n // check if the request should be ignored\n // 1. ignore safe methods\n if (safeMethods.has(method)) {\n await next();\n return;\n }\n\n // 2. ignore configured origin\n if (config.origin && config.origin.includes(c.req.header('origin') ?? '')) {\n await next();\n return;\n }\n\n // 3. ignore configured secFetchSite\n if (\n config.secFetchSite &&\n config.secFetchSite.includes((c.req.header('sec-fetch-site') ?? '') as never)\n ) {\n await next();\n return;\n }\n\n // 4. ignore configured ignore rules\n const [matched] = router.match(method, path);\n if (matched.length > 0) {\n await next();\n return;\n }\n\n const cookieToken = getCookie(c, cookieName);\n const headerToken = c.req.header(headerName);\n\n if (!cookieToken || !headerToken) {\n throw Status.permissionDenied(errorMessage).error();\n }\n\n if (!safeCompare(cookieToken, headerToken)) {\n throw Status.permissionDenied(errorMessage).error();\n }\n\n await next();\n };\n}\n"],"mappings":";AACA,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AAuDvB,SAAS,YAAY,GAAW,GAAoB;AAClD,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO;AAC3D,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAE7C,QAAM,UAAU,OAAO,KAAK,GAAG,OAAO;AACtC,QAAM,UAAU,OAAO,KAAK,GAAG,OAAO;AACtC,MAAI,QAAQ,WAAW,QAAQ,OAAQ,QAAO;AAC9C,SAAO,gBAAgB,SAAS,OAAO;AACzC;AA0BO,SAAS,KAAK,SAAqB,CAAC,GAAsB;AAC/D,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,cAAc,IAAI,IAAI,OAAO,eAAe,CAAC,OAAO,QAAQ,SAAS,CAAC;AAC5E,QAAM,eAAe,OAAO,gBAAgB;AAG5C,QAAM,SAAS,IAAI,YAAqB;AAAA,IACtC,SAAS,CAAC,IAAI,aAAa,GAAG,IAAI,WAAW,CAAC;AAAA,EAChD,CAAC;AAGD,MAAI,OAAO,SAAS;AAClB,eAAW,QAAQ,OAAO,SAAS;AACjC,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO,IAAI,iBAAiB,MAAM,IAAI;AAAA,MACxC,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAClD,mBAAW,UAAU,KAAK,SAAS;AACjC,iBAAO,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,QACpC;AAAA,MACF,OAAO;AAEL,eAAO,IAAI,iBAAiB,KAAK,MAAM,IAAI;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAGA,SAAO,OAAO,GAAG,SAAS;AACxB,UAAM,SAAS,EAAE,IAAI;AACrB,UAAM,OAAO,EAAE,IAAI;AAInB,QAAI,YAAY,IAAI,MAAM,GAAG;AAC3B,YAAM,KAAK;AACX;AAAA,IACF;AAGA,QAAI,OAAO,UAAU,OAAO,OAAO,SAAS,EAAE,IAAI,OAAO,QAAQ,KAAK,EAAE,GAAG;AACzE,YAAM,KAAK;AACX;AAAA,IACF;AAGA,QACE,OAAO,gBACP,OAAO,aAAa,SAAU,EAAE,IAAI,OAAO,gBAAgB,KAAK,EAAY,GAC5E;AACA,YAAM,KAAK;AACX;AAAA,IACF;AAGA,UAAM,CAAC,OAAO,IAAI,OAAO,MAAM,QAAQ,IAAI;AAC3C,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,UAAM,cAAc,UAAU,GAAG,UAAU;AAC3C,UAAM,cAAc,EAAE,IAAI,OAAO,UAAU;AAE3C,QAAI,CAAC,eAAe,CAAC,aAAa;AAChC,YAAM,OAAO,iBAAiB,YAAY,EAAE,MAAM;AAAA,IACpD;AAEA,QAAI,CAAC,YAAY,aAAa,WAAW,GAAG;AAC1C,YAAM,OAAO,iBAAiB,YAAY,EAAE,MAAM;AAAA,IACpD;AAEA,UAAM,KAAK;AAAA,EACb;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/geolocation.ts"],"sourcesContent":["import { getRuntimeKey } from 'hono/adapter';\nimport { extractIpAddress } from '../utils/ip';\nimport type { Context } from 'hono';\n\nexport type Geolocation = {\n ip_address?: string;\n city?: string;\n country?: string; // ISO 3166-1 alpha-2\n continent?: string;\n longitude?: number;\n latitude?: number;\n region?: string; // ISO 3166-2\n metro_code?: string;\n postal_code?: string;\n time_zone?: string;\n};\n\n/** reference: https://developers.cloudflare.com/rules/transform/managed-transforms/reference/#add-visitor-location-headers */\nfunction getGeolocationFromCloudflareWorker(c: Context): Geolocation {\n return {\n ip_address: c.req.header('true-client-ip') ?? c.req.header('cf-connecting-ip'),\n city: c.req.header('cf-ipcity'),\n country: c.req.header('cf-ipcountry'),\n continent: c.req.header('cf-ipcontinent'),\n longitude: c.req.header('cf-iplongitude') ? Number(c.req.header('cf-iplongitude')) : undefined,\n latitude: c.req.header('cf-iplatitude') ? Number(c.req.header('cf-iplatitude')) : undefined,\n region: c.req.header('cf-region-code'),\n metro_code: c.req.header('cf-metro-code'),\n postal_code: c.req.header('cf-postal-code'),\n time_zone: c.req.header('cf-timezone'),\n };\n}\n\n/** https://github.com/vercel/vercel/blob/main/packages/functions/src/headers.ts */\nfunction getGeolocationFromVercel(c: Context): Geolocation {\n return {\n ip_address: c.req.header('x-real-ip'),\n city: c.req.header('x-vercel-ip-city'),\n country: c.req.header('x-vercel-ip-country'),\n continent: c.req.header('x-vercel-ip-continent'),\n longitude: c.req.header('x-vercel-ip-longitude')\n ? Number(c.req.header('x-vercel-ip-longitude'))\n : undefined,\n latitude: c.req.header('x-vercel-ip-latitude')\n ? Number(c.req.header('x-vercel-ip-latitude'))\n : undefined,\n region: c.req.header('x-vercel-ip-country-region'),\n metro_code: undefined,\n postal_code: c.req.header('x-vercel-ip-postal-code'),\n time_zone: undefined,\n };\n}\n\n/** ref: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html#cloudfront-headers-viewer-location */\nfunction getGeolocationFromCloudfront(c: Context): Geolocation {\n return {\n ip_address: extractIpAddress(c.req.header('CloudFront-Viewer-Address')) ?? undefined,\n city: c.req.header('CloudFront-Viewer-City'),\n country: c.req.header('CloudFront-Viewer-Country'),\n continent: undefined,\n longitude: c.req.header('CloudFront-Viewer-Longitude')\n ? Number(c.req.header('CloudFront-Viewer-Longitude'))\n : undefined,\n latitude: c.req.header('CloudFront-Viewer-Latitude')\n ? Number(c.req.header('CloudFront-Viewer-Latitude'))\n : undefined,\n region: c.req.header('CloudFront-Viewer-Country-Region'),\n metro_code: c.req.header('CloudFront-Viewer-Metro-Code'),\n postal_code: c.req.header('CloudFront-Viewer-Postal-Code'),\n time_zone: c.req.header('CloudFront-Viewer-Time-Zone'),\n };\n}\n\nexport function geolocation(c: Context): Geolocation {\n if (getRuntimeKey() === 'workerd') return getGeolocationFromCloudflareWorker(c);\n if (c.req.header('x-vercel-id')) return getGeolocationFromVercel(c);\n return getGeolocationFromCloudfront(c);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA8B;AAC9B,gBAAiC;AAiBjC,SAAS,mCAAmC,GAAyB;AACnE,SAAO;AAAA,IACL,YAAY,EAAE,IAAI,OAAO,gBAAgB,KAAK,EAAE,IAAI,OAAO,kBAAkB;AAAA,IAC7E,MAAM,EAAE,IAAI,OAAO,WAAW;AAAA,IAC9B,SAAS,EAAE,IAAI,OAAO,cAAc;AAAA,IACpC,WAAW,EAAE,IAAI,OAAO,gBAAgB;AAAA,IACxC,WAAW,EAAE,IAAI,OAAO,gBAAgB,IAAI,OAAO,EAAE,IAAI,OAAO,gBAAgB,CAAC,IAAI;AAAA,IACrF,UAAU,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,EAAE,IAAI,OAAO,eAAe,CAAC,IAAI;AAAA,IAClF,QAAQ,EAAE,IAAI,OAAO,gBAAgB;AAAA,IACrC,YAAY,EAAE,IAAI,OAAO,eAAe;AAAA,IACxC,aAAa,EAAE,IAAI,OAAO,gBAAgB;AAAA,IAC1C,WAAW,EAAE,IAAI,OAAO,aAAa;AAAA,EACvC;AACF;AAGA,SAAS,yBAAyB,GAAyB;AACzD,SAAO;AAAA,IACL,YAAY,EAAE,IAAI,OAAO,WAAW;AAAA,IACpC,MAAM,EAAE,IAAI,OAAO,kBAAkB;AAAA,IACrC,SAAS,EAAE,IAAI,OAAO,qBAAqB;AAAA,IAC3C,WAAW,EAAE,IAAI,OAAO,uBAAuB;AAAA,IAC/C,WAAW,EAAE,IAAI,OAAO,uBAAuB,IAC3C,OAAO,EAAE,IAAI,OAAO,uBAAuB,CAAC,IAC5C;AAAA,IACJ,UAAU,EAAE,IAAI,OAAO,sBAAsB,IACzC,OAAO,EAAE,IAAI,OAAO,sBAAsB,CAAC,IAC3C;AAAA,IACJ,QAAQ,EAAE,IAAI,OAAO,4BAA4B;AAAA,IACjD,YAAY;AAAA,IACZ,aAAa,EAAE,IAAI,OAAO,yBAAyB;AAAA,IACnD,WAAW;AAAA,EACb;AACF;AAGA,SAAS,6BAA6B,GAAyB;AAC7D,SAAO;AAAA,IACL,gBAAY,4BAAiB,EAAE,IAAI,OAAO,2BAA2B,CAAC,KAAK;AAAA,IAC3E,MAAM,EAAE,IAAI,OAAO,wBAAwB;AAAA,IAC3C,SAAS,EAAE,IAAI,OAAO,2BAA2B;AAAA,IACjD,WAAW;AAAA,IACX,WAAW,EAAE,IAAI,OAAO,6BAA6B,IACjD,OAAO,EAAE,IAAI,OAAO,6BAA6B,CAAC,IAClD;AAAA,IACJ,UAAU,EAAE,IAAI,OAAO,4BAA4B,IAC/C,OAAO,EAAE,IAAI,OAAO,4BAA4B,CAAC,IACjD;AAAA,IACJ,QAAQ,EAAE,IAAI,OAAO,kCAAkC;AAAA,IACvD,YAAY,EAAE,IAAI,OAAO,8BAA8B;AAAA,IACvD,aAAa,EAAE,IAAI,OAAO,+BAA+B;AAAA,IACzD,WAAW,EAAE,IAAI,OAAO,6BAA6B;AAAA,EACvD;AACF;AAEO,SAAS,YAAY,GAAyB;AACnD,UAAI,8BAAc,MAAM,UAAW,QAAO,mCAAmC,CAAC;AAC9E,MAAI,EAAE,IAAI,OAAO,aAAa,EAAG,QAAO,yBAAyB,CAAC;AAClE,SAAO,6BAA6B,CAAC;AACvC;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/geolocation.ts"],"sourcesContent":["import type { Context } from 'hono';\nimport { getRuntimeKey } from 'hono/adapter';\nimport { extractIpAddress } from '../utils/ip';\n\nexport type Geolocation = {\n ip_address?: string;\n city?: string;\n country?: string; // ISO 3166-1 alpha-2\n continent?: string;\n longitude?: number;\n latitude?: number;\n region?: string; // ISO 3166-2\n metro_code?: string;\n postal_code?: string;\n time_zone?: string;\n};\n\n/** reference: https://developers.cloudflare.com/rules/transform/managed-transforms/reference/#add-visitor-location-headers */\nfunction getGeolocationFromCloudflareWorker(c: Context): Geolocation {\n return {\n ip_address: c.req.header('true-client-ip') ?? c.req.header('cf-connecting-ip'),\n city: c.req.header('cf-ipcity'),\n country: c.req.header('cf-ipcountry'),\n continent: c.req.header('cf-ipcontinent'),\n longitude: c.req.header('cf-iplongitude') ? Number(c.req.header('cf-iplongitude')) : undefined,\n latitude: c.req.header('cf-iplatitude') ? Number(c.req.header('cf-iplatitude')) : undefined,\n region: c.req.header('cf-region-code'),\n metro_code: c.req.header('cf-metro-code'),\n postal_code: c.req.header('cf-postal-code'),\n time_zone: c.req.header('cf-timezone'),\n };\n}\n\n/** https://github.com/vercel/vercel/blob/main/packages/functions/src/headers.ts */\nfunction getGeolocationFromVercel(c: Context): Geolocation {\n return {\n ip_address: c.req.header('x-real-ip'),\n city: c.req.header('x-vercel-ip-city'),\n country: c.req.header('x-vercel-ip-country'),\n continent: c.req.header('x-vercel-ip-continent'),\n longitude: c.req.header('x-vercel-ip-longitude')\n ? Number(c.req.header('x-vercel-ip-longitude'))\n : undefined,\n latitude: c.req.header('x-vercel-ip-latitude')\n ? Number(c.req.header('x-vercel-ip-latitude'))\n : undefined,\n region: c.req.header('x-vercel-ip-country-region'),\n metro_code: undefined,\n postal_code: c.req.header('x-vercel-ip-postal-code'),\n time_zone: undefined,\n };\n}\n\n/** ref: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html#cloudfront-headers-viewer-location */\nfunction getGeolocationFromCloudfront(c: Context): Geolocation {\n return {\n ip_address: extractIpAddress(c.req.header('CloudFront-Viewer-Address')) ?? undefined,\n city: c.req.header('CloudFront-Viewer-City'),\n country: c.req.header('CloudFront-Viewer-Country'),\n continent: undefined,\n longitude: c.req.header('CloudFront-Viewer-Longitude')\n ? Number(c.req.header('CloudFront-Viewer-Longitude'))\n : undefined,\n latitude: c.req.header('CloudFront-Viewer-Latitude')\n ? Number(c.req.header('CloudFront-Viewer-Latitude'))\n : undefined,\n region: c.req.header('CloudFront-Viewer-Country-Region'),\n metro_code: c.req.header('CloudFront-Viewer-Metro-Code'),\n postal_code: c.req.header('CloudFront-Viewer-Postal-Code'),\n time_zone: c.req.header('CloudFront-Viewer-Time-Zone'),\n };\n}\n\nexport function geolocation(c: Context): Geolocation {\n if (getRuntimeKey() === 'workerd') return getGeolocationFromCloudflareWorker(c);\n if (c.req.header('x-vercel-id')) return getGeolocationFromVercel(c);\n return getGeolocationFromCloudfront(c);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA8B;AAC9B,gBAAiC;AAgBjC,SAAS,mCAAmC,GAAyB;AACnE,SAAO;AAAA,IACL,YAAY,EAAE,IAAI,OAAO,gBAAgB,KAAK,EAAE,IAAI,OAAO,kBAAkB;AAAA,IAC7E,MAAM,EAAE,IAAI,OAAO,WAAW;AAAA,IAC9B,SAAS,EAAE,IAAI,OAAO,cAAc;AAAA,IACpC,WAAW,EAAE,IAAI,OAAO,gBAAgB;AAAA,IACxC,WAAW,EAAE,IAAI,OAAO,gBAAgB,IAAI,OAAO,EAAE,IAAI,OAAO,gBAAgB,CAAC,IAAI;AAAA,IACrF,UAAU,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,EAAE,IAAI,OAAO,eAAe,CAAC,IAAI;AAAA,IAClF,QAAQ,EAAE,IAAI,OAAO,gBAAgB;AAAA,IACrC,YAAY,EAAE,IAAI,OAAO,eAAe;AAAA,IACxC,aAAa,EAAE,IAAI,OAAO,gBAAgB;AAAA,IAC1C,WAAW,EAAE,IAAI,OAAO,aAAa;AAAA,EACvC;AACF;AAGA,SAAS,yBAAyB,GAAyB;AACzD,SAAO;AAAA,IACL,YAAY,EAAE,IAAI,OAAO,WAAW;AAAA,IACpC,MAAM,EAAE,IAAI,OAAO,kBAAkB;AAAA,IACrC,SAAS,EAAE,IAAI,OAAO,qBAAqB;AAAA,IAC3C,WAAW,EAAE,IAAI,OAAO,uBAAuB;AAAA,IAC/C,WAAW,EAAE,IAAI,OAAO,uBAAuB,IAC3C,OAAO,EAAE,IAAI,OAAO,uBAAuB,CAAC,IAC5C;AAAA,IACJ,UAAU,EAAE,IAAI,OAAO,sBAAsB,IACzC,OAAO,EAAE,IAAI,OAAO,sBAAsB,CAAC,IAC3C;AAAA,IACJ,QAAQ,EAAE,IAAI,OAAO,4BAA4B;AAAA,IACjD,YAAY;AAAA,IACZ,aAAa,EAAE,IAAI,OAAO,yBAAyB;AAAA,IACnD,WAAW;AAAA,EACb;AACF;AAGA,SAAS,6BAA6B,GAAyB;AAC7D,SAAO;AAAA,IACL,gBAAY,4BAAiB,EAAE,IAAI,OAAO,2BAA2B,CAAC,KAAK;AAAA,IAC3E,MAAM,EAAE,IAAI,OAAO,wBAAwB;AAAA,IAC3C,SAAS,EAAE,IAAI,OAAO,2BAA2B;AAAA,IACjD,WAAW;AAAA,IACX,WAAW,EAAE,IAAI,OAAO,6BAA6B,IACjD,OAAO,EAAE,IAAI,OAAO,6BAA6B,CAAC,IAClD;AAAA,IACJ,UAAU,EAAE,IAAI,OAAO,4BAA4B,IAC/C,OAAO,EAAE,IAAI,OAAO,4BAA4B,CAAC,IACjD;AAAA,IACJ,QAAQ,EAAE,IAAI,OAAO,kCAAkC;AAAA,IACvD,YAAY,EAAE,IAAI,OAAO,8BAA8B;AAAA,IACvD,aAAa,EAAE,IAAI,OAAO,+BAA+B;AAAA,IACzD,WAAW,EAAE,IAAI,OAAO,6BAA6B;AAAA,EACvD;AACF;AAEO,SAAS,YAAY,GAAyB;AACnD,UAAI,8BAAc,MAAM,UAAW,QAAO,mCAAmC,CAAC;AAC9E,MAAI,EAAE,IAAI,OAAO,aAAa,EAAG,QAAO,yBAAyB,CAAC;AAClE,SAAO,6BAA6B,CAAC;AACvC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/geolocation.ts"],"sourcesContent":["import { getRuntimeKey } from 'hono/adapter';\nimport { extractIpAddress } from '../utils/ip';\nimport type { Context } from 'hono';\n\nexport type Geolocation = {\n ip_address?: string;\n city?: string;\n country?: string; // ISO 3166-1 alpha-2\n continent?: string;\n longitude?: number;\n latitude?: number;\n region?: string; // ISO 3166-2\n metro_code?: string;\n postal_code?: string;\n time_zone?: string;\n};\n\n/** reference: https://developers.cloudflare.com/rules/transform/managed-transforms/reference/#add-visitor-location-headers */\nfunction getGeolocationFromCloudflareWorker(c: Context): Geolocation {\n return {\n ip_address: c.req.header('true-client-ip') ?? c.req.header('cf-connecting-ip'),\n city: c.req.header('cf-ipcity'),\n country: c.req.header('cf-ipcountry'),\n continent: c.req.header('cf-ipcontinent'),\n longitude: c.req.header('cf-iplongitude') ? Number(c.req.header('cf-iplongitude')) : undefined,\n latitude: c.req.header('cf-iplatitude') ? Number(c.req.header('cf-iplatitude')) : undefined,\n region: c.req.header('cf-region-code'),\n metro_code: c.req.header('cf-metro-code'),\n postal_code: c.req.header('cf-postal-code'),\n time_zone: c.req.header('cf-timezone'),\n };\n}\n\n/** https://github.com/vercel/vercel/blob/main/packages/functions/src/headers.ts */\nfunction getGeolocationFromVercel(c: Context): Geolocation {\n return {\n ip_address: c.req.header('x-real-ip'),\n city: c.req.header('x-vercel-ip-city'),\n country: c.req.header('x-vercel-ip-country'),\n continent: c.req.header('x-vercel-ip-continent'),\n longitude: c.req.header('x-vercel-ip-longitude')\n ? Number(c.req.header('x-vercel-ip-longitude'))\n : undefined,\n latitude: c.req.header('x-vercel-ip-latitude')\n ? Number(c.req.header('x-vercel-ip-latitude'))\n : undefined,\n region: c.req.header('x-vercel-ip-country-region'),\n metro_code: undefined,\n postal_code: c.req.header('x-vercel-ip-postal-code'),\n time_zone: undefined,\n };\n}\n\n/** ref: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html#cloudfront-headers-viewer-location */\nfunction getGeolocationFromCloudfront(c: Context): Geolocation {\n return {\n ip_address: extractIpAddress(c.req.header('CloudFront-Viewer-Address')) ?? undefined,\n city: c.req.header('CloudFront-Viewer-City'),\n country: c.req.header('CloudFront-Viewer-Country'),\n continent: undefined,\n longitude: c.req.header('CloudFront-Viewer-Longitude')\n ? Number(c.req.header('CloudFront-Viewer-Longitude'))\n : undefined,\n latitude: c.req.header('CloudFront-Viewer-Latitude')\n ? Number(c.req.header('CloudFront-Viewer-Latitude'))\n : undefined,\n region: c.req.header('CloudFront-Viewer-Country-Region'),\n metro_code: c.req.header('CloudFront-Viewer-Metro-Code'),\n postal_code: c.req.header('CloudFront-Viewer-Postal-Code'),\n time_zone: c.req.header('CloudFront-Viewer-Time-Zone'),\n };\n}\n\nexport function geolocation(c: Context): Geolocation {\n if (getRuntimeKey() === 'workerd') return getGeolocationFromCloudflareWorker(c);\n if (c.req.header('x-vercel-id')) return getGeolocationFromVercel(c);\n return getGeolocationFromCloudfront(c);\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AAiBjC,SAAS,mCAAmC,GAAyB;AACnE,SAAO;AAAA,IACL,YAAY,EAAE,IAAI,OAAO,gBAAgB,KAAK,EAAE,IAAI,OAAO,kBAAkB;AAAA,IAC7E,MAAM,EAAE,IAAI,OAAO,WAAW;AAAA,IAC9B,SAAS,EAAE,IAAI,OAAO,cAAc;AAAA,IACpC,WAAW,EAAE,IAAI,OAAO,gBAAgB;AAAA,IACxC,WAAW,EAAE,IAAI,OAAO,gBAAgB,IAAI,OAAO,EAAE,IAAI,OAAO,gBAAgB,CAAC,IAAI;AAAA,IACrF,UAAU,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,EAAE,IAAI,OAAO,eAAe,CAAC,IAAI;AAAA,IAClF,QAAQ,EAAE,IAAI,OAAO,gBAAgB;AAAA,IACrC,YAAY,EAAE,IAAI,OAAO,eAAe;AAAA,IACxC,aAAa,EAAE,IAAI,OAAO,gBAAgB;AAAA,IAC1C,WAAW,EAAE,IAAI,OAAO,aAAa;AAAA,EACvC;AACF;AAGA,SAAS,yBAAyB,GAAyB;AACzD,SAAO;AAAA,IACL,YAAY,EAAE,IAAI,OAAO,WAAW;AAAA,IACpC,MAAM,EAAE,IAAI,OAAO,kBAAkB;AAAA,IACrC,SAAS,EAAE,IAAI,OAAO,qBAAqB;AAAA,IAC3C,WAAW,EAAE,IAAI,OAAO,uBAAuB;AAAA,IAC/C,WAAW,EAAE,IAAI,OAAO,uBAAuB,IAC3C,OAAO,EAAE,IAAI,OAAO,uBAAuB,CAAC,IAC5C;AAAA,IACJ,UAAU,EAAE,IAAI,OAAO,sBAAsB,IACzC,OAAO,EAAE,IAAI,OAAO,sBAAsB,CAAC,IAC3C;AAAA,IACJ,QAAQ,EAAE,IAAI,OAAO,4BAA4B;AAAA,IACjD,YAAY;AAAA,IACZ,aAAa,EAAE,IAAI,OAAO,yBAAyB;AAAA,IACnD,WAAW;AAAA,EACb;AACF;AAGA,SAAS,6BAA6B,GAAyB;AAC7D,SAAO;AAAA,IACL,YAAY,iBAAiB,EAAE,IAAI,OAAO,2BAA2B,CAAC,KAAK;AAAA,IAC3E,MAAM,EAAE,IAAI,OAAO,wBAAwB;AAAA,IAC3C,SAAS,EAAE,IAAI,OAAO,2BAA2B;AAAA,IACjD,WAAW;AAAA,IACX,WAAW,EAAE,IAAI,OAAO,6BAA6B,IACjD,OAAO,EAAE,IAAI,OAAO,6BAA6B,CAAC,IAClD;AAAA,IACJ,UAAU,EAAE,IAAI,OAAO,4BAA4B,IAC/C,OAAO,EAAE,IAAI,OAAO,4BAA4B,CAAC,IACjD;AAAA,IACJ,QAAQ,EAAE,IAAI,OAAO,kCAAkC;AAAA,IACvD,YAAY,EAAE,IAAI,OAAO,8BAA8B;AAAA,IACvD,aAAa,EAAE,IAAI,OAAO,+BAA+B;AAAA,IACzD,WAAW,EAAE,IAAI,OAAO,6BAA6B;AAAA,EACvD;AACF;AAEO,SAAS,YAAY,GAAyB;AACnD,MAAI,cAAc,MAAM,UAAW,QAAO,mCAAmC,CAAC;AAC9E,MAAI,EAAE,IAAI,OAAO,aAAa,EAAG,QAAO,yBAAyB,CAAC;AAClE,SAAO,6BAA6B,CAAC;AACvC;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/geolocation.ts"],"sourcesContent":["import type { Context } from 'hono';\nimport { getRuntimeKey } from 'hono/adapter';\nimport { extractIpAddress } from '../utils/ip';\n\nexport type Geolocation = {\n ip_address?: string;\n city?: string;\n country?: string; // ISO 3166-1 alpha-2\n continent?: string;\n longitude?: number;\n latitude?: number;\n region?: string; // ISO 3166-2\n metro_code?: string;\n postal_code?: string;\n time_zone?: string;\n};\n\n/** reference: https://developers.cloudflare.com/rules/transform/managed-transforms/reference/#add-visitor-location-headers */\nfunction getGeolocationFromCloudflareWorker(c: Context): Geolocation {\n return {\n ip_address: c.req.header('true-client-ip') ?? c.req.header('cf-connecting-ip'),\n city: c.req.header('cf-ipcity'),\n country: c.req.header('cf-ipcountry'),\n continent: c.req.header('cf-ipcontinent'),\n longitude: c.req.header('cf-iplongitude') ? Number(c.req.header('cf-iplongitude')) : undefined,\n latitude: c.req.header('cf-iplatitude') ? Number(c.req.header('cf-iplatitude')) : undefined,\n region: c.req.header('cf-region-code'),\n metro_code: c.req.header('cf-metro-code'),\n postal_code: c.req.header('cf-postal-code'),\n time_zone: c.req.header('cf-timezone'),\n };\n}\n\n/** https://github.com/vercel/vercel/blob/main/packages/functions/src/headers.ts */\nfunction getGeolocationFromVercel(c: Context): Geolocation {\n return {\n ip_address: c.req.header('x-real-ip'),\n city: c.req.header('x-vercel-ip-city'),\n country: c.req.header('x-vercel-ip-country'),\n continent: c.req.header('x-vercel-ip-continent'),\n longitude: c.req.header('x-vercel-ip-longitude')\n ? Number(c.req.header('x-vercel-ip-longitude'))\n : undefined,\n latitude: c.req.header('x-vercel-ip-latitude')\n ? Number(c.req.header('x-vercel-ip-latitude'))\n : undefined,\n region: c.req.header('x-vercel-ip-country-region'),\n metro_code: undefined,\n postal_code: c.req.header('x-vercel-ip-postal-code'),\n time_zone: undefined,\n };\n}\n\n/** ref: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html#cloudfront-headers-viewer-location */\nfunction getGeolocationFromCloudfront(c: Context): Geolocation {\n return {\n ip_address: extractIpAddress(c.req.header('CloudFront-Viewer-Address')) ?? undefined,\n city: c.req.header('CloudFront-Viewer-City'),\n country: c.req.header('CloudFront-Viewer-Country'),\n continent: undefined,\n longitude: c.req.header('CloudFront-Viewer-Longitude')\n ? Number(c.req.header('CloudFront-Viewer-Longitude'))\n : undefined,\n latitude: c.req.header('CloudFront-Viewer-Latitude')\n ? Number(c.req.header('CloudFront-Viewer-Latitude'))\n : undefined,\n region: c.req.header('CloudFront-Viewer-Country-Region'),\n metro_code: c.req.header('CloudFront-Viewer-Metro-Code'),\n postal_code: c.req.header('CloudFront-Viewer-Postal-Code'),\n time_zone: c.req.header('CloudFront-Viewer-Time-Zone'),\n };\n}\n\nexport function geolocation(c: Context): Geolocation {\n if (getRuntimeKey() === 'workerd') return getGeolocationFromCloudflareWorker(c);\n if (c.req.header('x-vercel-id')) return getGeolocationFromVercel(c);\n return getGeolocationFromCloudfront(c);\n}\n"],"mappings":";AACA,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AAgBjC,SAAS,mCAAmC,GAAyB;AACnE,SAAO;AAAA,IACL,YAAY,EAAE,IAAI,OAAO,gBAAgB,KAAK,EAAE,IAAI,OAAO,kBAAkB;AAAA,IAC7E,MAAM,EAAE,IAAI,OAAO,WAAW;AAAA,IAC9B,SAAS,EAAE,IAAI,OAAO,cAAc;AAAA,IACpC,WAAW,EAAE,IAAI,OAAO,gBAAgB;AAAA,IACxC,WAAW,EAAE,IAAI,OAAO,gBAAgB,IAAI,OAAO,EAAE,IAAI,OAAO,gBAAgB,CAAC,IAAI;AAAA,IACrF,UAAU,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,EAAE,IAAI,OAAO,eAAe,CAAC,IAAI;AAAA,IAClF,QAAQ,EAAE,IAAI,OAAO,gBAAgB;AAAA,IACrC,YAAY,EAAE,IAAI,OAAO,eAAe;AAAA,IACxC,aAAa,EAAE,IAAI,OAAO,gBAAgB;AAAA,IAC1C,WAAW,EAAE,IAAI,OAAO,aAAa;AAAA,EACvC;AACF;AAGA,SAAS,yBAAyB,GAAyB;AACzD,SAAO;AAAA,IACL,YAAY,EAAE,IAAI,OAAO,WAAW;AAAA,IACpC,MAAM,EAAE,IAAI,OAAO,kBAAkB;AAAA,IACrC,SAAS,EAAE,IAAI,OAAO,qBAAqB;AAAA,IAC3C,WAAW,EAAE,IAAI,OAAO,uBAAuB;AAAA,IAC/C,WAAW,EAAE,IAAI,OAAO,uBAAuB,IAC3C,OAAO,EAAE,IAAI,OAAO,uBAAuB,CAAC,IAC5C;AAAA,IACJ,UAAU,EAAE,IAAI,OAAO,sBAAsB,IACzC,OAAO,EAAE,IAAI,OAAO,sBAAsB,CAAC,IAC3C;AAAA,IACJ,QAAQ,EAAE,IAAI,OAAO,4BAA4B;AAAA,IACjD,YAAY;AAAA,IACZ,aAAa,EAAE,IAAI,OAAO,yBAAyB;AAAA,IACnD,WAAW;AAAA,EACb;AACF;AAGA,SAAS,6BAA6B,GAAyB;AAC7D,SAAO;AAAA,IACL,YAAY,iBAAiB,EAAE,IAAI,OAAO,2BAA2B,CAAC,KAAK;AAAA,IAC3E,MAAM,EAAE,IAAI,OAAO,wBAAwB;AAAA,IAC3C,SAAS,EAAE,IAAI,OAAO,2BAA2B;AAAA,IACjD,WAAW;AAAA,IACX,WAAW,EAAE,IAAI,OAAO,6BAA6B,IACjD,OAAO,EAAE,IAAI,OAAO,6BAA6B,CAAC,IAClD;AAAA,IACJ,UAAU,EAAE,IAAI,OAAO,4BAA4B,IAC/C,OAAO,EAAE,IAAI,OAAO,4BAA4B,CAAC,IACjD;AAAA,IACJ,QAAQ,EAAE,IAAI,OAAO,kCAAkC;AAAA,IACvD,YAAY,EAAE,IAAI,OAAO,8BAA8B;AAAA,IACvD,aAAa,EAAE,IAAI,OAAO,+BAA+B;AAAA,IACzD,WAAW,EAAE,IAAI,OAAO,6BAA6B;AAAA,EACvD;AACF;AAEO,SAAS,YAAY,GAAyB;AACnD,MAAI,cAAc,MAAM,UAAW,QAAO,mCAAmC,CAAC;AAC9E,MAAI,EAAE,IAAI,OAAO,aAAa,EAAG,QAAO,yBAAyB,CAAC;AAClE,SAAO,6BAA6B,CAAC;AACvC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/handler.ts"],"sourcesContent":["import { DetailType, Details } from '../error/detail';\nimport { Status, StatusError } from '../error/status';\nimport type { Context } from 'hono';\nimport type { RequestIdVariables } from 'hono/request-id';\nimport type { Bindings, HTTPResponseError } from 'hono/types';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\n\nexport type Env = {\n Variables: RequestIdVariables;\n Bindings?: Bindings;\n};\n\ntype AxiosError = {\n code?: string;\n cause?: unknown;\n status?: number;\n message?: string;\n isAxiosError: boolean;\n response?: {\n data: unknown;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n };\n config?: { url?: string; data?: unknown; method?: string; headers?: Record<string, string> };\n};\n\nexport function isAxiosError(payload: unknown): payload is AxiosError {\n return (\n payload !== null &&\n typeof payload === 'object' &&\n 'isAxiosError' in payload &&\n payload.isAxiosError === true\n );\n}\n\nexport function errorHandler<E extends Env = never>(\n error: Error | HTTPResponseError,\n c: Context<E>\n): Response | Promise<Response> {\n const requestId = c.get('requestId');\n const servingData = `${c.req.method}: ${c.req.path}`;\n const details = Details.new().requestInfo({ requestId, servingData });\n\n if (error instanceof StatusError) {\n error.body?.error?.details?.push(...details.list);\n const badRequest = error.body?.error?.details.find(\n (d) => d['@type'] === DetailType.BAD_REQUEST\n );\n if (badRequest) console.warn(servingData, badRequest);\n return c.json(error.body, error.status as ContentfulStatusCode);\n }\n\n if (error instanceof SyntaxError) {\n if (/^Cannot convert .* to a BigInt$/.test(error.message)) {\n return Status.invalidArgument(`Invalid number. ${error.message}`).response(details);\n }\n }\n\n if (isAxiosError(error)) {\n console.error({\n status: error.status,\n message: error.message,\n request: {\n method: error.config?.method,\n url: error.config?.url,\n data: error.config?.data,\n },\n response: { data: error.response?.data },\n });\n return Status.internal('Axios error').response(details);\n }\n\n console.error(`Unknown error: ${servingData}`, error);\n return Status.internal('Unknown error').response(details);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAoC;AACpC,oBAAoC;AA0B7B,SAAS,aAAa,SAAyC;AACpE,SACE,YAAY,QACZ,OAAO,YAAY,YACnB,kBAAkB,WAClB,QAAQ,iBAAiB;AAE7B;AAEO,SAAS,aACd,OACA,GAC8B;AAC9B,QAAM,YAAY,EAAE,IAAI,WAAW;AACnC,QAAM,cAAc,GAAG,EAAE,IAAI,MAAM,KAAK,EAAE,IAAI,IAAI;AAClD,QAAM,UAAU,sBAAQ,IAAI,EAAE,YAAY,EAAE,WAAW,YAAY,CAAC;AAEpE,MAAI,iBAAiB,2BAAa;AAChC,UAAM,MAAM,OAAO,SAAS,KAAK,GAAG,QAAQ,IAAI;AAChD,UAAM,aAAa,MAAM,MAAM,OAAO,QAAQ;AAAA,MAC5C,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW;AAAA,IACnC;AACA,QAAI,WAAY,SAAQ,KAAK,aAAa,UAAU;AACpD,WAAO,EAAE,KAAK,MAAM,MAAM,MAAM,MAA8B;AAAA,EAChE;AAEA,MAAI,iBAAiB,aAAa;AAChC,QAAI,kCAAkC,KAAK,MAAM,OAAO,GAAG;AACzD,aAAO,qBAAO,gBAAgB,mBAAmB,MAAM,OAAO,EAAE,EAAE,SAAS,OAAO;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,GAAG;AACvB,YAAQ,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,MACd,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,QACP,QAAQ,MAAM,QAAQ;AAAA,QACtB,KAAK,MAAM,QAAQ;AAAA,QACnB,MAAM,MAAM,QAAQ;AAAA,MACtB;AAAA,MACA,UAAU,EAAE,MAAM,MAAM,UAAU,KAAK;AAAA,IACzC,CAAC;AACD,WAAO,qBAAO,SAAS,aAAa,EAAE,SAAS,OAAO;AAAA,EACxD;AAEA,UAAQ,MAAM,kBAAkB,WAAW,IAAI,KAAK;AACpD,SAAO,qBAAO,SAAS,eAAe,EAAE,SAAS,OAAO;AAC1D;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/handler.ts"],"sourcesContent":["import type { Context } from 'hono';\nimport type { RequestIdVariables } from 'hono/request-id';\nimport type { Bindings, HTTPResponseError } from 'hono/types';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { DetailType, Details } from '../error/detail';\nimport { Status, StatusError } from '../error/status';\n\nexport type Env = {\n Variables: RequestIdVariables;\n Bindings?: Bindings;\n};\n\ntype AxiosError = {\n code?: string;\n cause?: unknown;\n status?: number;\n message?: string;\n isAxiosError: boolean;\n response?: {\n data: unknown;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n };\n config?: { url?: string; data?: unknown; method?: string; headers?: Record<string, string> };\n};\n\nexport function isAxiosError(payload: unknown): payload is AxiosError {\n return (\n payload !== null &&\n typeof payload === 'object' &&\n 'isAxiosError' in payload &&\n payload.isAxiosError === true\n );\n}\n\nexport function errorHandler<E extends Env = never>(\n error: Error | HTTPResponseError,\n c: Context<E>\n): Response | Promise<Response> {\n const requestId = c.get('requestId');\n const servingData = `${c.req.method}: ${c.req.path}`;\n const details = Details.new().requestInfo({ requestId, servingData });\n\n if (error instanceof StatusError) {\n error.body?.error?.details?.push(...details.list);\n const badRequest = error.body?.error?.details.find(\n (d) => d['@type'] === DetailType.BAD_REQUEST\n );\n if (badRequest) console.warn(servingData, badRequest);\n return c.json(error.body, error.status as ContentfulStatusCode);\n }\n\n if (error instanceof SyntaxError) {\n if (/^Cannot convert .* to a BigInt$/.test(error.message)) {\n return Status.invalidArgument(`Invalid number. ${error.message}`).response(details);\n }\n }\n\n if (isAxiosError(error)) {\n console.error({\n status: error.status,\n message: error.message,\n request: {\n method: error.config?.method,\n url: error.config?.url,\n data: error.config?.data,\n },\n response: { data: error.response?.data },\n });\n return Status.internal('Axios error').response(details);\n }\n\n console.error(`Unknown error: ${servingData}`, error);\n return Status.internal('Unknown error').response(details);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,oBAAoC;AACpC,oBAAoC;AAsB7B,SAAS,aAAa,SAAyC;AACpE,SACE,YAAY,QACZ,OAAO,YAAY,YACnB,kBAAkB,WAClB,QAAQ,iBAAiB;AAE7B;AAEO,SAAS,aACd,OACA,GAC8B;AAC9B,QAAM,YAAY,EAAE,IAAI,WAAW;AACnC,QAAM,cAAc,GAAG,EAAE,IAAI,MAAM,KAAK,EAAE,IAAI,IAAI;AAClD,QAAM,UAAU,sBAAQ,IAAI,EAAE,YAAY,EAAE,WAAW,YAAY,CAAC;AAEpE,MAAI,iBAAiB,2BAAa;AAChC,UAAM,MAAM,OAAO,SAAS,KAAK,GAAG,QAAQ,IAAI;AAChD,UAAM,aAAa,MAAM,MAAM,OAAO,QAAQ;AAAA,MAC5C,CAAC,MAAM,EAAE,OAAO,MAAM,yBAAW;AAAA,IACnC;AACA,QAAI,WAAY,SAAQ,KAAK,aAAa,UAAU;AACpD,WAAO,EAAE,KAAK,MAAM,MAAM,MAAM,MAA8B;AAAA,EAChE;AAEA,MAAI,iBAAiB,aAAa;AAChC,QAAI,kCAAkC,KAAK,MAAM,OAAO,GAAG;AACzD,aAAO,qBAAO,gBAAgB,mBAAmB,MAAM,OAAO,EAAE,EAAE,SAAS,OAAO;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,GAAG;AACvB,YAAQ,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,MACd,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,QACP,QAAQ,MAAM,QAAQ;AAAA,QACtB,KAAK,MAAM,QAAQ;AAAA,QACnB,MAAM,MAAM,QAAQ;AAAA,MACtB;AAAA,MACA,UAAU,EAAE,MAAM,MAAM,UAAU,KAAK;AAAA,IACzC,CAAC;AACD,WAAO,qBAAO,SAAS,aAAa,EAAE,SAAS,OAAO;AAAA,EACxD;AAEA,UAAQ,MAAM,kBAAkB,WAAW,IAAI,KAAK;AACpD,SAAO,qBAAO,SAAS,eAAe,EAAE,SAAS,OAAO;AAC1D;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/handler.ts"],"sourcesContent":["import { DetailType, Details } from '../error/detail';\nimport { Status, StatusError } from '../error/status';\nimport type { Context } from 'hono';\nimport type { RequestIdVariables } from 'hono/request-id';\nimport type { Bindings, HTTPResponseError } from 'hono/types';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\n\nexport type Env = {\n Variables: RequestIdVariables;\n Bindings?: Bindings;\n};\n\ntype AxiosError = {\n code?: string;\n cause?: unknown;\n status?: number;\n message?: string;\n isAxiosError: boolean;\n response?: {\n data: unknown;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n };\n config?: { url?: string; data?: unknown; method?: string; headers?: Record<string, string> };\n};\n\nexport function isAxiosError(payload: unknown): payload is AxiosError {\n return (\n payload !== null &&\n typeof payload === 'object' &&\n 'isAxiosError' in payload &&\n payload.isAxiosError === true\n );\n}\n\nexport function errorHandler<E extends Env = never>(\n error: Error | HTTPResponseError,\n c: Context<E>\n): Response | Promise<Response> {\n const requestId = c.get('requestId');\n const servingData = `${c.req.method}: ${c.req.path}`;\n const details = Details.new().requestInfo({ requestId, servingData });\n\n if (error instanceof StatusError) {\n error.body?.error?.details?.push(...details.list);\n const badRequest = error.body?.error?.details.find(\n (d) => d['@type'] === DetailType.BAD_REQUEST\n );\n if (badRequest) console.warn(servingData, badRequest);\n return c.json(error.body, error.status as ContentfulStatusCode);\n }\n\n if (error instanceof SyntaxError) {\n if (/^Cannot convert .* to a BigInt$/.test(error.message)) {\n return Status.invalidArgument(`Invalid number. ${error.message}`).response(details);\n }\n }\n\n if (isAxiosError(error)) {\n console.error({\n status: error.status,\n message: error.message,\n request: {\n method: error.config?.method,\n url: error.config?.url,\n data: error.config?.data,\n },\n response: { data: error.response?.data },\n });\n return Status.internal('Axios error').response(details);\n }\n\n console.error(`Unknown error: ${servingData}`, error);\n return Status.internal('Unknown error').response(details);\n}\n"],"mappings":";AAAA,SAAS,YAAY,eAAe;AACpC,SAAS,QAAQ,mBAAmB;AA0B7B,SAAS,aAAa,SAAyC;AACpE,SACE,YAAY,QACZ,OAAO,YAAY,YACnB,kBAAkB,WAClB,QAAQ,iBAAiB;AAE7B;AAEO,SAAS,aACd,OACA,GAC8B;AAC9B,QAAM,YAAY,EAAE,IAAI,WAAW;AACnC,QAAM,cAAc,GAAG,EAAE,IAAI,MAAM,KAAK,EAAE,IAAI,IAAI;AAClD,QAAM,UAAU,QAAQ,IAAI,EAAE,YAAY,EAAE,WAAW,YAAY,CAAC;AAEpE,MAAI,iBAAiB,aAAa;AAChC,UAAM,MAAM,OAAO,SAAS,KAAK,GAAG,QAAQ,IAAI;AAChD,UAAM,aAAa,MAAM,MAAM,OAAO,QAAQ;AAAA,MAC5C,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW;AAAA,IACnC;AACA,QAAI,WAAY,SAAQ,KAAK,aAAa,UAAU;AACpD,WAAO,EAAE,KAAK,MAAM,MAAM,MAAM,MAA8B;AAAA,EAChE;AAEA,MAAI,iBAAiB,aAAa;AAChC,QAAI,kCAAkC,KAAK,MAAM,OAAO,GAAG;AACzD,aAAO,OAAO,gBAAgB,mBAAmB,MAAM,OAAO,EAAE,EAAE,SAAS,OAAO;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,GAAG;AACvB,YAAQ,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,MACd,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,QACP,QAAQ,MAAM,QAAQ;AAAA,QACtB,KAAK,MAAM,QAAQ;AAAA,QACnB,MAAM,MAAM,QAAQ;AAAA,MACtB;AAAA,MACA,UAAU,EAAE,MAAM,MAAM,UAAU,KAAK;AAAA,IACzC,CAAC;AACD,WAAO,OAAO,SAAS,aAAa,EAAE,SAAS,OAAO;AAAA,EACxD;AAEA,UAAQ,MAAM,kBAAkB,WAAW,IAAI,KAAK;AACpD,SAAO,OAAO,SAAS,eAAe,EAAE,SAAS,OAAO;AAC1D;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/handler.ts"],"sourcesContent":["import type { Context } from 'hono';\nimport type { RequestIdVariables } from 'hono/request-id';\nimport type { Bindings, HTTPResponseError } from 'hono/types';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { DetailType, Details } from '../error/detail';\nimport { Status, StatusError } from '../error/status';\n\nexport type Env = {\n Variables: RequestIdVariables;\n Bindings?: Bindings;\n};\n\ntype AxiosError = {\n code?: string;\n cause?: unknown;\n status?: number;\n message?: string;\n isAxiosError: boolean;\n response?: {\n data: unknown;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n };\n config?: { url?: string; data?: unknown; method?: string; headers?: Record<string, string> };\n};\n\nexport function isAxiosError(payload: unknown): payload is AxiosError {\n return (\n payload !== null &&\n typeof payload === 'object' &&\n 'isAxiosError' in payload &&\n payload.isAxiosError === true\n );\n}\n\nexport function errorHandler<E extends Env = never>(\n error: Error | HTTPResponseError,\n c: Context<E>\n): Response | Promise<Response> {\n const requestId = c.get('requestId');\n const servingData = `${c.req.method}: ${c.req.path}`;\n const details = Details.new().requestInfo({ requestId, servingData });\n\n if (error instanceof StatusError) {\n error.body?.error?.details?.push(...details.list);\n const badRequest = error.body?.error?.details.find(\n (d) => d['@type'] === DetailType.BAD_REQUEST\n );\n if (badRequest) console.warn(servingData, badRequest);\n return c.json(error.body, error.status as ContentfulStatusCode);\n }\n\n if (error instanceof SyntaxError) {\n if (/^Cannot convert .* to a BigInt$/.test(error.message)) {\n return Status.invalidArgument(`Invalid number. ${error.message}`).response(details);\n }\n }\n\n if (isAxiosError(error)) {\n console.error({\n status: error.status,\n message: error.message,\n request: {\n method: error.config?.method,\n url: error.config?.url,\n data: error.config?.data,\n },\n response: { data: error.response?.data },\n });\n return Status.internal('Axios error').response(details);\n }\n\n console.error(`Unknown error: ${servingData}`, error);\n return Status.internal('Unknown error').response(details);\n}\n"],"mappings":";AAIA,SAAS,YAAY,eAAe;AACpC,SAAS,QAAQ,mBAAmB;AAsB7B,SAAS,aAAa,SAAyC;AACpE,SACE,YAAY,QACZ,OAAO,YAAY,YACnB,kBAAkB,WAClB,QAAQ,iBAAiB;AAE7B;AAEO,SAAS,aACd,OACA,GAC8B;AAC9B,QAAM,YAAY,EAAE,IAAI,WAAW;AACnC,QAAM,cAAc,GAAG,EAAE,IAAI,MAAM,KAAK,EAAE,IAAI,IAAI;AAClD,QAAM,UAAU,QAAQ,IAAI,EAAE,YAAY,EAAE,WAAW,YAAY,CAAC;AAEpE,MAAI,iBAAiB,aAAa;AAChC,UAAM,MAAM,OAAO,SAAS,KAAK,GAAG,QAAQ,IAAI;AAChD,UAAM,aAAa,MAAM,MAAM,OAAO,QAAQ;AAAA,MAC5C,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW;AAAA,IACnC;AACA,QAAI,WAAY,SAAQ,KAAK,aAAa,UAAU;AACpD,WAAO,EAAE,KAAK,MAAM,MAAM,MAAM,MAA8B;AAAA,EAChE;AAEA,MAAI,iBAAiB,aAAa;AAChC,QAAI,kCAAkC,KAAK,MAAM,OAAO,GAAG;AACzD,aAAO,OAAO,gBAAgB,mBAAmB,MAAM,OAAO,EAAE,EAAE,SAAS,OAAO;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,GAAG;AACvB,YAAQ,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,MACd,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,QACP,QAAQ,MAAM,QAAQ;AAAA,QACtB,KAAK,MAAM,QAAQ;AAAA,QACnB,MAAM,MAAM,QAAQ;AAAA,MACtB;AAAA,MACA,UAAU,EAAE,MAAM,MAAM,UAAU,KAAK;AAAA,IACzC,CAAC;AACD,WAAO,OAAO,SAAS,aAAa,EAAE,SAAS,OAAO;AAAA,EACxD;AAEA,UAAQ,MAAM,kBAAkB,WAAW,IAAI,KAAK;AACpD,SAAO,OAAO,SAAS,eAAe,EAAE,SAAS,OAAO;AAC1D;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import { validator } from 'hono/validator';\nimport {\n NEVER,\n type ZodMiniType,\n type output as outputMini,\n pipe,\n string,\n transform,\n} from 'zod/mini';\nimport { type BadRequest, Details } from '../error/detail';\nimport { Status } from '../error/status';\nimport type { ValidationTargets } from 'hono';\nimport type { ZodType, output as outputV4 } from 'zod';\n\nexport function zValidator<S extends ZodType | ZodMiniType>(\n target: keyof ValidationTargets,\n schema: S\n) {\n return validator(target, async (value) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return result.data as S extends ZodType ? outputV4<S> : outputMini<S>;\n\n const fieldViolations: BadRequest['fieldViolations'] = result.error.issues.map(\n ({ code, path, message }) => ({\n field: path.join('.'),\n description: message,\n reason: code?.toUpperCase() ?? 'INVALID_ARGUMENT',\n localizedMessage: { locale: 'en-US', message: message },\n })\n );\n const details = Details.new().badRequest({ fieldViolations });\n throw Status.invalidArgument().error(details);\n });\n}\n\nexport const bigintId = pipe(\n string(),\n transform((input, ctx) => {\n if (!/^(0|[1-9]\\d{0,19})$/.test(input)) {\n const message = `Invalid bigint id: ${input}`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n try {\n return BigInt(input);\n } catch {\n const message = `Parse bigint id: ${input} failed`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n })\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAA0B;AAC1B,kBAOO;AACP,oBAAyC;AACzC,oBAAuB;AAIhB,SAAS,WACd,QACA,QACA;AACA,aAAO,4BAAU,QAAQ,OAAO,UAAU;AACxC,UAAM,SAAS,MAAM,OAAO,eAAe,KAAK;AAChD,QAAI,OAAO,QAAS,QAAO,OAAO;AAElC,UAAM,kBAAiD,OAAO,MAAM,OAAO;AAAA,MACzE,CAAC,EAAE,MAAM,MAAM,QAAQ,OAAO;AAAA,QAC5B,OAAO,KAAK,KAAK,GAAG;AAAA,QACpB,aAAa;AAAA,QACb,QAAQ,MAAM,YAAY,KAAK;AAAA,QAC/B,kBAAkB,EAAE,QAAQ,SAAS,QAAiB;AAAA,MACxD;AAAA,IACF;AACA,UAAM,UAAU,sBAAQ,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC;AAC5D,UAAM,qBAAO,gBAAgB,EAAE,MAAM,OAAO;AAAA,EAC9C,CAAC;AACH;AAEO,IAAM,eAAW;AAAA,MACtB,oBAAO;AAAA,MACP,uBAAU,CAAC,OAAO,QAAQ;AACxB,QAAI,CAAC,sBAAsB,KAAK,KAAK,GAAG;AACtC,YAAM,UAAU,sBAAsB,KAAK;AAC3C,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AACA,QAAI;AACF,aAAO,OAAO,KAAK;AAAA,IACrB,QAAQ;AACN,YAAM,UAAU,oBAAoB,KAAK;AACzC,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import type { ValidationTargets } from 'hono';\nimport type { ZodType, output as outputV4 } from 'zod';\nimport { validator } from 'hono/validator';\nimport {\n NEVER,\n type ZodMiniType,\n type output as outputMini,\n pipe,\n string,\n transform,\n} from 'zod/mini';\nimport { type BadRequest, Details } from '../error/detail';\nimport { Status } from '../error/status';\n\nexport function zValidator<S extends ZodType | ZodMiniType>(\n target: keyof ValidationTargets,\n schema: S\n) {\n return validator(target, async (value) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return result.data as S extends ZodType ? outputV4<S> : outputMini<S>;\n\n const fieldViolations: BadRequest['fieldViolations'] = result.error.issues.map(\n ({ code, path, message }) => ({\n field: path.join('.'),\n description: message,\n reason: code?.toUpperCase() ?? 'INVALID_ARGUMENT',\n localizedMessage: { locale: 'en-US', message: message },\n })\n );\n const details = Details.new().badRequest({ fieldViolations });\n throw Status.invalidArgument().error(details);\n });\n}\n\nexport const bigintId = pipe(\n string(),\n transform((input, ctx) => {\n if (!/^(0|[1-9]\\d{0,19})$/.test(input)) {\n const message = `Invalid bigint id: ${input}`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n try {\n return BigInt(input);\n } catch {\n const message = `Parse bigint id: ${input} failed`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n })\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,uBAA0B;AAC1B,kBAOO;AACP,oBAAyC;AACzC,oBAAuB;AAEhB,SAAS,WACd,QACA,QACA;AACA,aAAO,4BAAU,QAAQ,OAAO,UAAU;AACxC,UAAM,SAAS,MAAM,OAAO,eAAe,KAAK;AAChD,QAAI,OAAO,QAAS,QAAO,OAAO;AAElC,UAAM,kBAAiD,OAAO,MAAM,OAAO;AAAA,MACzE,CAAC,EAAE,MAAM,MAAM,QAAQ,OAAO;AAAA,QAC5B,OAAO,KAAK,KAAK,GAAG;AAAA,QACpB,aAAa;AAAA,QACb,QAAQ,MAAM,YAAY,KAAK;AAAA,QAC/B,kBAAkB,EAAE,QAAQ,SAAS,QAAiB;AAAA,MACxD;AAAA,IACF;AACA,UAAM,UAAU,sBAAQ,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC;AAC5D,UAAM,qBAAO,gBAAgB,EAAE,MAAM,OAAO;AAAA,EAC9C,CAAC;AACH;AAEO,IAAM,eAAW;AAAA,MACtB,oBAAO;AAAA,MACP,uBAAU,CAAC,OAAO,QAAQ;AACxB,QAAI,CAAC,sBAAsB,KAAK,KAAK,GAAG;AACtC,YAAM,UAAU,sBAAsB,KAAK;AAC3C,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AACA,QAAI;AACF,aAAO,OAAO,KAAK;AAAA,IACrB,QAAQ;AACN,YAAM,UAAU,oBAAoB,KAAK;AACzC,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
@@ -1,12 +1,12 @@
1
1
  import * as zod_mini from 'zod/mini';
2
- import { ZodMiniType, output } from 'zod/mini';
2
+ import { ZodMiniType } from 'zod/mini';
3
3
  import * as hono_utils_http_status from 'hono/utils/http-status';
4
4
  import * as hono_validator from 'hono/validator';
5
5
  import * as hono_types from 'hono/types';
6
6
  import * as hono from 'hono';
7
7
  import { ValidationTargets } from 'hono';
8
8
  import * as zod_v4_core from 'zod/v4/core';
9
- import { ZodType } from 'zod';
9
+ import { ZodType, output } from 'zod';
10
10
 
11
11
  declare function zValidator<S extends ZodType | ZodMiniType>(target: keyof ValidationTargets, schema: S): hono.MiddlewareHandler<any, string, {
12
12
  in: {
@@ -1,12 +1,12 @@
1
1
  import * as zod_mini from 'zod/mini';
2
- import { ZodMiniType, output } from 'zod/mini';
2
+ import { ZodMiniType } from 'zod/mini';
3
3
  import * as hono_utils_http_status from 'hono/utils/http-status';
4
4
  import * as hono_validator from 'hono/validator';
5
5
  import * as hono_types from 'hono/types';
6
6
  import * as hono from 'hono';
7
7
  import { ValidationTargets } from 'hono';
8
8
  import * as zod_v4_core from 'zod/v4/core';
9
- import { ZodType } from 'zod';
9
+ import { ZodType, output } from 'zod';
10
10
 
11
11
  declare function zValidator<S extends ZodType | ZodMiniType>(target: keyof ValidationTargets, schema: S): hono.MiddlewareHandler<any, string, {
12
12
  in: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import { validator } from 'hono/validator';\nimport {\n NEVER,\n type ZodMiniType,\n type output as outputMini,\n pipe,\n string,\n transform,\n} from 'zod/mini';\nimport { type BadRequest, Details } from '../error/detail';\nimport { Status } from '../error/status';\nimport type { ValidationTargets } from 'hono';\nimport type { ZodType, output as outputV4 } from 'zod';\n\nexport function zValidator<S extends ZodType | ZodMiniType>(\n target: keyof ValidationTargets,\n schema: S\n) {\n return validator(target, async (value) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return result.data as S extends ZodType ? outputV4<S> : outputMini<S>;\n\n const fieldViolations: BadRequest['fieldViolations'] = result.error.issues.map(\n ({ code, path, message }) => ({\n field: path.join('.'),\n description: message,\n reason: code?.toUpperCase() ?? 'INVALID_ARGUMENT',\n localizedMessage: { locale: 'en-US', message: message },\n })\n );\n const details = Details.new().badRequest({ fieldViolations });\n throw Status.invalidArgument().error(details);\n });\n}\n\nexport const bigintId = pipe(\n string(),\n transform((input, ctx) => {\n if (!/^(0|[1-9]\\d{0,19})$/.test(input)) {\n const message = `Invalid bigint id: ${input}`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n try {\n return BigInt(input);\n } catch {\n const message = `Parse bigint id: ${input} failed`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n })\n);\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAA0B,eAAe;AACzC,SAAS,cAAc;AAIhB,SAAS,WACd,QACA,QACA;AACA,SAAO,UAAU,QAAQ,OAAO,UAAU;AACxC,UAAM,SAAS,MAAM,OAAO,eAAe,KAAK;AAChD,QAAI,OAAO,QAAS,QAAO,OAAO;AAElC,UAAM,kBAAiD,OAAO,MAAM,OAAO;AAAA,MACzE,CAAC,EAAE,MAAM,MAAM,QAAQ,OAAO;AAAA,QAC5B,OAAO,KAAK,KAAK,GAAG;AAAA,QACpB,aAAa;AAAA,QACb,QAAQ,MAAM,YAAY,KAAK;AAAA,QAC/B,kBAAkB,EAAE,QAAQ,SAAS,QAAiB;AAAA,MACxD;AAAA,IACF;AACA,UAAM,UAAU,QAAQ,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC;AAC5D,UAAM,OAAO,gBAAgB,EAAE,MAAM,OAAO;AAAA,EAC9C,CAAC;AACH;AAEO,IAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,UAAU,CAAC,OAAO,QAAQ;AACxB,QAAI,CAAC,sBAAsB,KAAK,KAAK,GAAG;AACtC,YAAM,UAAU,sBAAsB,KAAK;AAC3C,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AACA,QAAI;AACF,aAAO,OAAO,KAAK;AAAA,IACrB,QAAQ;AACN,YAAM,UAAU,oBAAoB,KAAK;AACzC,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import type { ValidationTargets } from 'hono';\nimport type { ZodType, output as outputV4 } from 'zod';\nimport { validator } from 'hono/validator';\nimport {\n NEVER,\n type ZodMiniType,\n type output as outputMini,\n pipe,\n string,\n transform,\n} from 'zod/mini';\nimport { type BadRequest, Details } from '../error/detail';\nimport { Status } from '../error/status';\n\nexport function zValidator<S extends ZodType | ZodMiniType>(\n target: keyof ValidationTargets,\n schema: S\n) {\n return validator(target, async (value) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return result.data as S extends ZodType ? outputV4<S> : outputMini<S>;\n\n const fieldViolations: BadRequest['fieldViolations'] = result.error.issues.map(\n ({ code, path, message }) => ({\n field: path.join('.'),\n description: message,\n reason: code?.toUpperCase() ?? 'INVALID_ARGUMENT',\n localizedMessage: { locale: 'en-US', message: message },\n })\n );\n const details = Details.new().badRequest({ fieldViolations });\n throw Status.invalidArgument().error(details);\n });\n}\n\nexport const bigintId = pipe(\n string(),\n transform((input, ctx) => {\n if (!/^(0|[1-9]\\d{0,19})$/.test(input)) {\n const message = `Invalid bigint id: ${input}`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n try {\n return BigInt(input);\n } catch {\n const message = `Parse bigint id: ${input} failed`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n })\n);\n"],"mappings":";AAEA,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAA0B,eAAe;AACzC,SAAS,cAAc;AAEhB,SAAS,WACd,QACA,QACA;AACA,SAAO,UAAU,QAAQ,OAAO,UAAU;AACxC,UAAM,SAAS,MAAM,OAAO,eAAe,KAAK;AAChD,QAAI,OAAO,QAAS,QAAO,OAAO;AAElC,UAAM,kBAAiD,OAAO,MAAM,OAAO;AAAA,MACzE,CAAC,EAAE,MAAM,MAAM,QAAQ,OAAO;AAAA,QAC5B,OAAO,KAAK,KAAK,GAAG;AAAA,QACpB,aAAa;AAAA,QACb,QAAQ,MAAM,YAAY,KAAK;AAAA,QAC/B,kBAAkB,EAAE,QAAQ,SAAS,QAAiB;AAAA,MACxD;AAAA,IACF;AACA,UAAM,UAAU,QAAQ,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC;AAC5D,UAAM,OAAO,gBAAgB,EAAE,MAAM,OAAO;AAAA,EAC9C,CAAC;AACH;AAEO,IAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,UAAU,CAAC,OAAO,QAAQ;AACxB,QAAI,CAAC,sBAAsB,KAAK,KAAK,GAAG;AACtC,YAAM,UAAU,sBAAsB,KAAK;AAC3C,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AACA,QAAI;AACF,aAAO,OAAO,KAAK;AAAA,IACrB,QAAQ;AACN,YAAM,UAAU,oBAAoB,KAAK;AACzC,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shware/http",
3
- "version": "2.2.4",
3
+ "version": "2.3.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -38,13 +38,13 @@
38
38
  }
39
39
  },
40
40
  "dependencies": {
41
- "vitest": "^4.0.16",
41
+ "vitest": "^4.0.17",
42
42
  "zod": "^4.3.5",
43
43
  "@shware/utils": "^1.1.4"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^24",
47
- "@types/react": "^19.2.7",
47
+ "@types/react": "^19.2.8",
48
48
  "typescript": "^5.9.3",
49
49
  "@repo/typescript-config": "0.0.0"
50
50
  },