@shware/http 2.11.4 → 2.12.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.
- package/dist/_virtual/_rolldown/runtime.cjs +13 -0
- package/dist/_virtual/_rolldown/runtime.mjs +13 -0
- package/dist/cache/index.cjs +5 -30
- package/dist/cache/index.cjs.map +1 -1
- package/dist/cache/index.d.cts +7 -5
- package/dist/cache/index.d.cts.map +1 -0
- package/dist/cache/index.d.mts +11 -0
- package/dist/cache/index.d.mts.map +1 -0
- package/dist/cache/index.mjs +5 -6
- package/dist/cache/index.mjs.map +1 -1
- package/dist/error/detail.cjs +100 -90
- package/dist/error/detail.cjs.map +1 -1
- package/dist/error/detail.d.cts +77 -78
- package/dist/error/detail.d.cts.map +1 -0
- package/dist/error/detail.d.mts +108 -0
- package/dist/error/detail.d.mts.map +1 -0
- package/dist/error/detail.mjs +99 -65
- package/dist/error/detail.mjs.map +1 -1
- package/dist/error/i18n/en-us.cjs +5 -29
- package/dist/error/i18n/en-us.cjs.map +1 -1
- package/dist/error/i18n/en-us.d.cts +3 -1
- package/dist/error/i18n/en-us.d.cts.map +1 -0
- package/dist/error/i18n/en-us.d.mts +5 -0
- package/dist/error/i18n/en-us.d.mts.map +1 -0
- package/dist/error/i18n/en-us.mjs +5 -5
- package/dist/error/i18n/en-us.mjs.map +1 -1
- package/dist/error/index.cjs +29 -56
- package/dist/error/index.cjs.map +1 -1
- package/dist/error/index.d.cts +12 -10
- package/dist/error/index.d.cts.map +1 -0
- package/dist/error/index.d.mts +21 -0
- package/dist/error/index.d.mts.map +1 -0
- package/dist/error/index.mjs +25 -28
- package/dist/error/index.mjs.map +1 -1
- package/dist/error/parse.cjs +63 -61
- package/dist/error/parse.cjs.map +1 -1
- package/dist/error/parse.d.cts +8 -7
- package/dist/error/parse.d.cts.map +1 -0
- package/dist/error/{parse.d.ts → parse.d.mts} +8 -7
- package/dist/error/parse.d.mts.map +1 -0
- package/dist/error/parse.mjs +59 -33
- package/dist/error/parse.mjs.map +1 -1
- package/dist/error/reason.cjs +0 -19
- package/dist/error/reason.d.cts +5 -4
- package/dist/error/reason.d.cts.map +1 -0
- package/dist/error/reason.d.mts +6 -0
- package/dist/error/reason.d.mts.map +1 -0
- package/dist/error/reason.mjs +1 -1
- package/dist/error/status.cjs +103 -256
- package/dist/error/status.cjs.map +1 -1
- package/dist/error/status.d.cts +58 -58
- package/dist/error/status.d.cts.map +1 -0
- package/dist/error/status.d.mts +69 -0
- package/dist/error/status.d.mts.map +1 -0
- package/dist/error/status.mjs +98 -227
- package/dist/error/status.mjs.map +1 -1
- package/dist/google-one-tap/index.cjs +135 -138
- package/dist/google-one-tap/index.cjs.map +1 -1
- package/dist/google-one-tap/index.d.cts +49 -48
- package/dist/google-one-tap/index.d.cts.map +1 -0
- package/dist/google-one-tap/index.d.mts +82 -0
- package/dist/google-one-tap/index.d.mts.map +1 -0
- package/dist/google-one-tap/index.mjs +133 -112
- package/dist/google-one-tap/index.mjs.map +1 -1
- package/dist/google-one-tap/types.cjs +0 -19
- package/dist/google-one-tap/types.d.cts +124 -122
- package/dist/google-one-tap/types.d.cts.map +1 -0
- package/dist/google-one-tap/types.d.mts +157 -0
- package/dist/google-one-tap/types.d.mts.map +1 -0
- package/dist/google-one-tap/types.mjs +1 -1
- package/dist/hono/authorizer.cjs +28 -65
- package/dist/hono/authorizer.cjs.map +1 -1
- package/dist/hono/authorizer.d.cts +12 -11
- package/dist/hono/authorizer.d.cts.map +1 -0
- package/dist/hono/authorizer.d.mts +19 -0
- package/dist/hono/authorizer.d.mts.map +1 -0
- package/dist/hono/authorizer.mjs +23 -36
- package/dist/hono/authorizer.mjs.map +1 -1
- package/dist/hono/csrf.cjs +81 -92
- package/dist/hono/csrf.cjs.map +1 -1
- package/dist/hono/csrf.d.cts +46 -45
- package/dist/hono/csrf.d.cts.map +1 -0
- package/dist/hono/csrf.d.mts +76 -0
- package/dist/hono/csrf.d.mts.map +1 -0
- package/dist/hono/csrf.mjs +76 -63
- package/dist/hono/csrf.mjs.map +1 -1
- package/dist/hono/geolocation.cjs +10 -34
- package/dist/hono/geolocation.cjs.map +1 -1
- package/dist/hono/geolocation.d.cts +5 -4
- package/dist/hono/geolocation.d.cts.map +1 -0
- package/dist/hono/geolocation.d.mts +7 -0
- package/dist/hono/geolocation.d.mts.map +1 -0
- package/dist/hono/geolocation.mjs +8 -12
- package/dist/hono/geolocation.mjs.map +1 -1
- package/dist/hono/handler.cjs +37 -61
- package/dist/hono/handler.cjs.map +1 -1
- package/dist/hono/handler.d.cts +26 -25
- package/dist/hono/handler.d.cts.map +1 -0
- package/dist/hono/handler.d.mts +32 -0
- package/dist/hono/handler.d.mts.map +1 -0
- package/dist/hono/handler.mjs +34 -34
- package/dist/hono/handler.mjs.map +1 -1
- package/dist/hono/index.cjs +14 -48
- package/dist/hono/index.d.cts +7 -15
- package/dist/hono/index.d.mts +7 -0
- package/dist/hono/index.mjs +4 -14
- package/dist/hono/rate-limit.cjs +65 -110
- package/dist/hono/rate-limit.cjs.map +1 -1
- package/dist/hono/rate-limit.d.cts +27 -26
- package/dist/hono/rate-limit.d.cts.map +1 -0
- package/dist/hono/rate-limit.d.mts +36 -0
- package/dist/hono/rate-limit.d.mts.map +1 -0
- package/dist/hono/rate-limit.mjs +60 -81
- package/dist/hono/rate-limit.mjs.map +1 -1
- package/dist/hono/validator.cjs +47 -66
- package/dist/hono/validator.cjs.map +1 -1
- package/dist/hono/validator.d.cts +25 -30
- package/dist/hono/validator.d.cts.map +1 -0
- package/dist/hono/validator.d.mts +26 -0
- package/dist/hono/validator.d.mts.map +1 -0
- package/dist/hono/validator.mjs +43 -43
- package/dist/hono/validator.mjs.map +1 -1
- package/dist/index.cjs +39 -95
- package/dist/index.d.cts +12 -14
- package/dist/index.d.mts +12 -0
- package/dist/index.mjs +5 -48
- package/dist/iso/iso_3601_1.cjs +1512 -290
- package/dist/iso/iso_3601_1.cjs.map +1 -1
- package/dist/iso/iso_3601_1.d.cts +8 -6
- package/dist/iso/iso_3601_1.d.cts.map +1 -0
- package/dist/iso/iso_3601_1.d.mts +11 -0
- package/dist/iso/iso_3601_1.d.mts.map +1 -0
- package/dist/iso/iso_3601_1.mjs +1511 -265
- package/dist/iso/iso_3601_1.mjs.map +1 -1
- package/dist/max-length/index.cjs +158 -91
- package/dist/max-length/index.cjs.map +1 -1
- package/dist/max-length/index.d.cts +110 -1
- package/dist/max-length/index.d.cts.map +1 -0
- package/dist/{index-BhgdyigB.d.ts → max-length/index.d.mts} +9 -28
- package/dist/max-length/index.d.mts.map +1 -0
- package/dist/max-length/index.mjs +133 -47
- package/dist/max-length/index.mjs.map +1 -1
- package/dist/message.cjs +5 -30
- package/dist/message.cjs.map +1 -1
- package/dist/message.d.cts +3 -1
- package/dist/message.d.cts.map +1 -0
- package/dist/{message.d.ts → message.d.mts} +3 -1
- package/dist/message.d.mts.map +1 -0
- package/dist/message.mjs +5 -6
- package/dist/message.mjs.map +1 -1
- package/dist/polyfills/index.cjs +4 -4
- package/dist/polyfills/index.cjs.map +1 -1
- package/dist/polyfills/index.d.cts +1 -2
- package/dist/polyfills/index.d.mts +1 -0
- package/dist/polyfills/index.mjs +5 -2
- package/dist/polyfills/index.mjs.map +1 -1
- package/dist/response.cjs +191 -208
- package/dist/response.cjs.map +1 -1
- package/dist/response.d.cts +53 -54
- package/dist/response.d.cts.map +1 -0
- package/dist/response.d.mts +82 -0
- package/dist/response.d.mts.map +1 -0
- package/dist/response.mjs +182 -175
- package/dist/response.mjs.map +1 -1
- package/dist/snowflake.cjs +48 -70
- package/dist/snowflake.cjs.map +1 -1
- package/dist/snowflake.d.cts +16 -14
- package/dist/snowflake.d.cts.map +1 -0
- package/dist/snowflake.d.mts +31 -0
- package/dist/snowflake.d.mts.map +1 -0
- package/dist/snowflake.mjs +46 -44
- package/dist/snowflake.mjs.map +1 -1
- package/dist/utils/geolocation.cjs +51 -75
- package/dist/utils/geolocation.cjs.map +1 -1
- package/dist/utils/geolocation.d.cts +14 -12
- package/dist/utils/geolocation.d.cts.map +1 -0
- package/dist/utils/{geolocation.d.ts → geolocation.d.mts} +14 -12
- package/dist/utils/geolocation.d.mts.map +1 -0
- package/dist/utils/geolocation.mjs +47 -47
- package/dist/utils/geolocation.mjs.map +1 -1
- package/dist/utils/google-tag-gateway.cjs +35 -56
- package/dist/utils/google-tag-gateway.cjs.map +1 -1
- package/dist/utils/google-tag-gateway.d.cts +3 -1
- package/dist/utils/google-tag-gateway.d.cts.map +1 -0
- package/dist/utils/{google-tag-gateway.d.ts → google-tag-gateway.d.mts} +3 -1
- package/dist/utils/google-tag-gateway.d.mts.map +1 -0
- package/dist/utils/google-tag-gateway.mjs +33 -30
- package/dist/utils/google-tag-gateway.mjs.map +1 -1
- package/dist/utils/timing.cjs +50 -71
- package/dist/utils/timing.cjs.map +1 -1
- package/dist/utils/timing.d.cts +11 -9
- package/dist/utils/timing.d.cts.map +1 -0
- package/dist/utils/timing.d.mts +15 -0
- package/dist/utils/timing.d.mts.map +1 -0
- package/dist/utils/timing.mjs +49 -46
- package/dist/utils/timing.mjs.map +1 -1
- package/dist/webhook/index.cjs +43 -72
- package/dist/webhook/index.cjs.map +1 -1
- package/dist/webhook/index.d.cts +3 -1
- package/dist/webhook/index.d.cts.map +1 -0
- package/dist/webhook/{index.d.ts → index.d.mts} +3 -1
- package/dist/webhook/index.d.mts.map +1 -0
- package/dist/webhook/index.mjs +41 -46
- package/dist/webhook/index.mjs.map +1 -1
- package/package.json +49 -24
- package/dist/cache/index.d.ts +0 -9
- package/dist/error/detail.d.ts +0 -109
- package/dist/error/i18n/en-us.d.ts +0 -3
- package/dist/error/index.d.ts +0 -19
- package/dist/error/reason.cjs.map +0 -1
- package/dist/error/reason.d.ts +0 -5
- package/dist/error/reason.mjs.map +0 -1
- package/dist/error/status.d.ts +0 -69
- package/dist/google-one-tap/index.d.ts +0 -81
- package/dist/google-one-tap/types.cjs.map +0 -1
- package/dist/google-one-tap/types.d.ts +0 -155
- package/dist/google-one-tap/types.mjs.map +0 -1
- package/dist/hono/authorizer.d.ts +0 -18
- package/dist/hono/csrf.d.ts +0 -75
- package/dist/hono/geolocation.d.ts +0 -6
- package/dist/hono/handler.d.ts +0 -31
- package/dist/hono/index.cjs.map +0 -1
- package/dist/hono/index.d.ts +0 -15
- package/dist/hono/index.mjs.map +0 -1
- package/dist/hono/rate-limit.d.ts +0 -35
- package/dist/hono/validator.d.ts +0 -31
- package/dist/index-BhgdyigB.d.cts +0 -129
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -14
- package/dist/index.mjs.map +0 -1
- package/dist/iso/iso_3601_1.d.ts +0 -9
- package/dist/max-length/index.d.ts +0 -1
- package/dist/polyfills/index.d.ts +0 -2
- package/dist/response.d.ts +0 -83
- package/dist/snowflake.d.ts +0 -29
- package/dist/utils/timing.d.ts +0 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hono/rate-limit.ts"],"sourcesContent":["import type { Context, MiddlewareHandler } from 'hono';\nimport { Details } from '../error/detail';\nimport { Status } from '../error/status';\nimport { geolocation } from './geolocation';\n\nexport interface KV {\n setItem(key: string, value: string, expiresIn?: number): Promise<void>;\n getItem(key: string): Promise<string | null>;\n removeItem(key: string): Promise<void>;\n}\n\ninterface TokenBucketState {\n tokens: number;\n lastRefillTime: number;\n}\n\nexport interface RateLimitOptions {\n kv: KV;\n rate: number;\n capacity: number;\n requested?: number;\n keyPrefix?: string;\n expiresIn?: number;\n getIdentifier?: (c: Context) => string | undefined;\n onRateLimited?: (c: Context, retryAfter: number) => Response | Promise<Response>;\n skip?: (c: Context) => boolean | Promise<boolean>;\n}\n\nexport interface RateLimitResult {\n allowed: boolean;\n remaining: number;\n limit: number;\n reset: number;\n retryAfter?: number;\n}\n\nfunction calculateTokens(\n state: TokenBucketState | null,\n capacity: number,\n rate: number,\n now: number\n): { tokens: number; lastRefillTime: number } {\n if (!state) {\n return { tokens: capacity, lastRefillTime: now };\n }\n\n const elapsed = (now - state.lastRefillTime) / 1000;\n const tokensToAdd = elapsed * rate;\n const newTokens = Math.min(capacity, state.tokens + tokensToAdd);\n\n return {\n tokens: newTokens,\n lastRefillTime: now,\n };\n}\n\nfunction calculateResetTime(currentTokens: number, capacity: number, rate: number): number {\n if (currentTokens >= capacity) return 0;\n return Math.ceil((capacity - currentTokens) / rate);\n}\n\nfunction calculateRetryAfter(currentTokens: number, requested: number, rate: number): number {\n if (currentTokens >= requested) return 0;\n return Math.ceil((requested - currentTokens) / rate);\n}\n\nexport async function checkRateLimit(\n kv: KV,\n identifier: string,\n options: {\n rate: number;\n capacity: number;\n requested?: number;\n keyPrefix?: string;\n expiresIn?: number;\n }\n): Promise<RateLimitResult> {\n const {\n rate,\n capacity,\n requested = 1,\n keyPrefix = 'rate-limit:',\n expiresIn = Math.max(3600, Math.ceil((capacity / rate) * 2)),\n } = options;\n\n const key = `${keyPrefix}${identifier}`;\n const now = Date.now();\n\n const stateStr = await kv.getItem(key);\n const state: TokenBucketState | null = stateStr ? JSON.parse(stateStr) : null;\n\n const { tokens: currentTokens, lastRefillTime } = calculateTokens(state, capacity, rate, now);\n\n const allowed = currentTokens >= requested;\n const newTokens = allowed ? currentTokens - requested : currentTokens;\n\n const newState: TokenBucketState = { tokens: newTokens, lastRefillTime };\n await kv.setItem(key, JSON.stringify(newState), expiresIn);\n\n const result: RateLimitResult = {\n allowed,\n remaining: Math.floor(Math.max(0, newTokens)),\n limit: capacity,\n reset: calculateResetTime(newTokens, capacity, rate),\n };\n\n if (!allowed) {\n result.retryAfter = calculateRetryAfter(currentTokens, requested, rate);\n }\n\n return result;\n}\n\nexport function rateLimit(options: RateLimitOptions): MiddlewareHandler {\n const {\n kv,\n rate,\n capacity,\n requested = 1,\n keyPrefix = 'rate-limit:',\n expiresIn = Math.max(3600, Math.ceil((capacity / rate) * 2)),\n getIdentifier,\n onRateLimited,\n skip,\n } = options;\n\n return async (c, next) => {\n if (skip && (await skip(c))) {\n return next();\n }\n\n const identifier = getIdentifier ? getIdentifier(c) : geolocation(c).ip_address;\n if (!identifier) return next();\n\n const result = await checkRateLimit(kv, identifier, {\n rate,\n capacity,\n requested,\n keyPrefix,\n expiresIn,\n });\n\n c.header('X-RateLimit-Limit', String(result.limit));\n c.header('X-RateLimit-Remaining', String(result.remaining));\n c.header('X-RateLimit-Reset', String(result.reset));\n\n if (!result.allowed) {\n c.header('Retry-After', String(result.retryAfter ?? 1));\n if (onRateLimited) return onRateLimited(c, result.retryAfter ?? 1);\n\n const details = Details.new()\n .errorInfo({ reason: 'RATE_LIMIT_EXCEEDED' })\n .retryInfo({ retryDelay: result.retryAfter ?? 1 });\n\n const message = 'Rate limit exceeded. Please try again later.';\n return Status.resourceExhausted(message).response(details);\n }\n\n return next();\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"rate-limit.cjs","names":["geolocation","Details","Status"],"sources":["../../src/hono/rate-limit.ts"],"sourcesContent":["import type { Context, MiddlewareHandler } from 'hono';\nimport { Details } from '../error/detail';\nimport { Status } from '../error/status';\nimport { geolocation } from './geolocation';\n\nexport interface KV {\n setItem(key: string, value: string, expiresIn?: number): Promise<void>;\n getItem(key: string): Promise<string | null>;\n removeItem(key: string): Promise<void>;\n}\n\ninterface TokenBucketState {\n tokens: number;\n lastRefillTime: number;\n}\n\nexport interface RateLimitOptions {\n kv: KV;\n rate: number;\n capacity: number;\n requested?: number;\n keyPrefix?: string;\n expiresIn?: number;\n getIdentifier?: (c: Context) => string | undefined;\n onRateLimited?: (c: Context, retryAfter: number) => Response | Promise<Response>;\n skip?: (c: Context) => boolean | Promise<boolean>;\n}\n\nexport interface RateLimitResult {\n allowed: boolean;\n remaining: number;\n limit: number;\n reset: number;\n retryAfter?: number;\n}\n\nfunction calculateTokens(\n state: TokenBucketState | null,\n capacity: number,\n rate: number,\n now: number\n): { tokens: number; lastRefillTime: number } {\n if (!state) {\n return { tokens: capacity, lastRefillTime: now };\n }\n\n const elapsed = (now - state.lastRefillTime) / 1000;\n const tokensToAdd = elapsed * rate;\n const newTokens = Math.min(capacity, state.tokens + tokensToAdd);\n\n return {\n tokens: newTokens,\n lastRefillTime: now,\n };\n}\n\nfunction calculateResetTime(currentTokens: number, capacity: number, rate: number): number {\n if (currentTokens >= capacity) return 0;\n return Math.ceil((capacity - currentTokens) / rate);\n}\n\nfunction calculateRetryAfter(currentTokens: number, requested: number, rate: number): number {\n if (currentTokens >= requested) return 0;\n return Math.ceil((requested - currentTokens) / rate);\n}\n\nexport async function checkRateLimit(\n kv: KV,\n identifier: string,\n options: {\n rate: number;\n capacity: number;\n requested?: number;\n keyPrefix?: string;\n expiresIn?: number;\n }\n): Promise<RateLimitResult> {\n const {\n rate,\n capacity,\n requested = 1,\n keyPrefix = 'rate-limit:',\n expiresIn = Math.max(3600, Math.ceil((capacity / rate) * 2)),\n } = options;\n\n const key = `${keyPrefix}${identifier}`;\n const now = Date.now();\n\n const stateStr = await kv.getItem(key);\n const state: TokenBucketState | null = stateStr ? JSON.parse(stateStr) : null;\n\n const { tokens: currentTokens, lastRefillTime } = calculateTokens(state, capacity, rate, now);\n\n const allowed = currentTokens >= requested;\n const newTokens = allowed ? currentTokens - requested : currentTokens;\n\n const newState: TokenBucketState = { tokens: newTokens, lastRefillTime };\n await kv.setItem(key, JSON.stringify(newState), expiresIn);\n\n const result: RateLimitResult = {\n allowed,\n remaining: Math.floor(Math.max(0, newTokens)),\n limit: capacity,\n reset: calculateResetTime(newTokens, capacity, rate),\n };\n\n if (!allowed) {\n result.retryAfter = calculateRetryAfter(currentTokens, requested, rate);\n }\n\n return result;\n}\n\nexport function rateLimit(options: RateLimitOptions): MiddlewareHandler {\n const {\n kv,\n rate,\n capacity,\n requested = 1,\n keyPrefix = 'rate-limit:',\n expiresIn = Math.max(3600, Math.ceil((capacity / rate) * 2)),\n getIdentifier,\n onRateLimited,\n skip,\n } = options;\n\n return async (c, next) => {\n if (skip && (await skip(c))) {\n return next();\n }\n\n const identifier = getIdentifier ? getIdentifier(c) : geolocation(c).ip_address;\n if (!identifier) return next();\n\n const result = await checkRateLimit(kv, identifier, {\n rate,\n capacity,\n requested,\n keyPrefix,\n expiresIn,\n });\n\n c.header('X-RateLimit-Limit', String(result.limit));\n c.header('X-RateLimit-Remaining', String(result.remaining));\n c.header('X-RateLimit-Reset', String(result.reset));\n\n if (!result.allowed) {\n c.header('Retry-After', String(result.retryAfter ?? 1));\n if (onRateLimited) return onRateLimited(c, result.retryAfter ?? 1);\n\n const details = Details.new()\n .errorInfo({ reason: 'RATE_LIMIT_EXCEEDED' })\n .retryInfo({ retryDelay: result.retryAfter ?? 1 });\n\n const message = 'Rate limit exceeded. Please try again later.';\n return Status.resourceExhausted(message).response(details);\n }\n\n return next();\n };\n}\n"],"mappings":";;;;;AAoCA,SAAS,gBACP,OACA,UACA,MACA,KAC4C;CAC5C,IAAI,CAAC,OACH,OAAO;EAAE,QAAQ;EAAU,gBAAgB;CAAI;CAIjD,MAAM,eADW,MAAM,MAAM,kBAAkB,MACjB;CAG9B,OAAO;EACL,QAHgB,KAAK,IAAI,UAAU,MAAM,SAAS,WAGlC;EAChB,gBAAgB;CAClB;AACF;AAEA,SAAS,mBAAmB,eAAuB,UAAkB,MAAsB;CACzF,IAAI,iBAAiB,UAAU,OAAO;CACtC,OAAO,KAAK,MAAM,WAAW,iBAAiB,IAAI;AACpD;AAEA,SAAS,oBAAoB,eAAuB,WAAmB,MAAsB;CAC3F,IAAI,iBAAiB,WAAW,OAAO;CACvC,OAAO,KAAK,MAAM,YAAY,iBAAiB,IAAI;AACrD;AAEA,eAAsB,eACpB,IACA,YACA,SAO0B;CAC1B,MAAM,EACJ,MACA,UACA,YAAY,GACZ,YAAY,eACZ,YAAY,KAAK,IAAI,MAAM,KAAK,KAAM,WAAW,OAAQ,CAAC,CAAC,MACzD;CAEJ,MAAM,MAAM,GAAG,YAAY;CAC3B,MAAM,MAAM,KAAK,IAAI;CAErB,MAAM,WAAW,MAAM,GAAG,QAAQ,GAAG;CAGrC,MAAM,EAAE,QAAQ,eAAe,mBAAmB,gBAFX,WAAW,KAAK,MAAM,QAAQ,IAAI,MAEA,UAAU,MAAM,GAAG;CAE5F,MAAM,UAAU,iBAAiB;CACjC,MAAM,YAAY,UAAU,gBAAgB,YAAY;CAExD,MAAM,WAA6B;EAAE,QAAQ;EAAW;CAAe;CACvE,MAAM,GAAG,QAAQ,KAAK,KAAK,UAAU,QAAQ,GAAG,SAAS;CAEzD,MAAM,SAA0B;EAC9B;EACA,WAAW,KAAK,MAAM,KAAK,IAAI,GAAG,SAAS,CAAC;EAC5C,OAAO;EACP,OAAO,mBAAmB,WAAW,UAAU,IAAI;CACrD;CAEA,IAAI,CAAC,SACH,OAAO,aAAa,oBAAoB,eAAe,WAAW,IAAI;CAGxE,OAAO;AACT;AAEA,SAAgB,UAAU,SAA8C;CACtE,MAAM,EACJ,IACA,MACA,UACA,YAAY,GACZ,YAAY,eACZ,YAAY,KAAK,IAAI,MAAM,KAAK,KAAM,WAAW,OAAQ,CAAC,CAAC,GAC3D,eACA,eACA,SACE;CAEJ,OAAO,OAAO,GAAG,SAAS;EACxB,IAAI,QAAS,MAAM,KAAK,CAAC,GACvB,OAAO,KAAK;EAGd,MAAM,aAAa,gBAAgB,cAAc,CAAC,IAAIA,yBAAAA,YAAY,CAAC,CAAC,CAAC;EACrE,IAAI,CAAC,YAAY,OAAO,KAAK;EAE7B,MAAM,SAAS,MAAM,eAAe,IAAI,YAAY;GAClD;GACA;GACA;GACA;GACA;EACF,CAAC;EAED,EAAE,OAAO,qBAAqB,OAAO,OAAO,KAAK,CAAC;EAClD,EAAE,OAAO,yBAAyB,OAAO,OAAO,SAAS,CAAC;EAC1D,EAAE,OAAO,qBAAqB,OAAO,OAAO,KAAK,CAAC;EAElD,IAAI,CAAC,OAAO,SAAS;GACnB,EAAE,OAAO,eAAe,OAAO,OAAO,cAAc,CAAC,CAAC;GACtD,IAAI,eAAe,OAAO,cAAc,GAAG,OAAO,cAAc,CAAC;GAEjE,MAAM,UAAUC,qBAAAA,QAAQ,IAAI,CAAC,CAC1B,UAAU,EAAE,QAAQ,sBAAsB,CAAC,CAAC,CAC5C,UAAU,EAAE,YAAY,OAAO,cAAc,EAAE,CAAC;GAGnD,OAAOC,qBAAAA,OAAO,kBAAkB,8CAAO,CAAC,CAAC,SAAS,OAAO;EAC3D;EAEA,OAAO,KAAK;CACd;AACF"}
|
|
@@ -1,35 +1,36 @@
|
|
|
1
|
-
import { Context, MiddlewareHandler } from
|
|
2
|
-
|
|
1
|
+
import { Context, MiddlewareHandler } from "hono";
|
|
2
|
+
//#region src/hono/rate-limit.d.ts
|
|
3
3
|
interface KV {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
setItem(key: string, value: string, expiresIn?: number): Promise<void>;
|
|
5
|
+
getItem(key: string): Promise<string | null>;
|
|
6
|
+
removeItem(key: string): Promise<void>;
|
|
7
7
|
}
|
|
8
8
|
interface RateLimitOptions {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
kv: KV;
|
|
10
|
+
rate: number;
|
|
11
|
+
capacity: number;
|
|
12
|
+
requested?: number;
|
|
13
|
+
keyPrefix?: string;
|
|
14
|
+
expiresIn?: number;
|
|
15
|
+
getIdentifier?: (c: Context) => string | undefined;
|
|
16
|
+
onRateLimited?: (c: Context, retryAfter: number) => Response | Promise<Response>;
|
|
17
|
+
skip?: (c: Context) => boolean | Promise<boolean>;
|
|
18
18
|
}
|
|
19
19
|
interface RateLimitResult {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
allowed: boolean;
|
|
21
|
+
remaining: number;
|
|
22
|
+
limit: number;
|
|
23
|
+
reset: number;
|
|
24
|
+
retryAfter?: number;
|
|
25
25
|
}
|
|
26
26
|
declare function checkRateLimit(kv: KV, identifier: string, options: {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
rate: number;
|
|
28
|
+
capacity: number;
|
|
29
|
+
requested?: number;
|
|
30
|
+
keyPrefix?: string;
|
|
31
|
+
expiresIn?: number;
|
|
32
32
|
}): Promise<RateLimitResult>;
|
|
33
33
|
declare function rateLimit(options: RateLimitOptions): MiddlewareHandler;
|
|
34
|
-
|
|
35
|
-
export {
|
|
34
|
+
//#endregion
|
|
35
|
+
export { KV, RateLimitOptions, RateLimitResult, checkRateLimit, rateLimit };
|
|
36
|
+
//# sourceMappingURL=rate-limit.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.cts","names":[],"sources":["../../src/hono/rate-limit.ts"],"mappings":";;UAKiB;EACf,QAAQ,aAAa,eAAe,qBAAqB;EACzD,QAAQ,cAAc;EACtB,WAAW,cAAc;;UAQV;EACf,IAAI;EACJ;EACA;EACA;EACA;EACA;EACA,iBAAiB,GAAG;EACpB,iBAAiB,GAAG,SAAS,uBAAuB,WAAW,QAAQ;EACvE,QAAQ,GAAG,sBAAsB;;UAGlB;EACf;EACA;EACA;EACA;EACA;;iBAiCoB,eACpB,IAAI,IACJ,oBACA;EACE;EACA;EACA;EACA;EACA;IAED,QAAQ;iBAqCK,UAAU,SAAS,mBAAmB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Context, MiddlewareHandler } from "hono";
|
|
2
|
+
//#region src/hono/rate-limit.d.ts
|
|
3
|
+
interface KV {
|
|
4
|
+
setItem(key: string, value: string, expiresIn?: number): Promise<void>;
|
|
5
|
+
getItem(key: string): Promise<string | null>;
|
|
6
|
+
removeItem(key: string): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
interface RateLimitOptions {
|
|
9
|
+
kv: KV;
|
|
10
|
+
rate: number;
|
|
11
|
+
capacity: number;
|
|
12
|
+
requested?: number;
|
|
13
|
+
keyPrefix?: string;
|
|
14
|
+
expiresIn?: number;
|
|
15
|
+
getIdentifier?: (c: Context) => string | undefined;
|
|
16
|
+
onRateLimited?: (c: Context, retryAfter: number) => Response | Promise<Response>;
|
|
17
|
+
skip?: (c: Context) => boolean | Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
interface RateLimitResult {
|
|
20
|
+
allowed: boolean;
|
|
21
|
+
remaining: number;
|
|
22
|
+
limit: number;
|
|
23
|
+
reset: number;
|
|
24
|
+
retryAfter?: number;
|
|
25
|
+
}
|
|
26
|
+
declare function checkRateLimit(kv: KV, identifier: string, options: {
|
|
27
|
+
rate: number;
|
|
28
|
+
capacity: number;
|
|
29
|
+
requested?: number;
|
|
30
|
+
keyPrefix?: string;
|
|
31
|
+
expiresIn?: number;
|
|
32
|
+
}): Promise<RateLimitResult>;
|
|
33
|
+
declare function rateLimit(options: RateLimitOptions): MiddlewareHandler;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { KV, RateLimitOptions, RateLimitResult, checkRateLimit, rateLimit };
|
|
36
|
+
//# sourceMappingURL=rate-limit.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.mts","names":[],"sources":["../../src/hono/rate-limit.ts"],"mappings":";;UAKiB;EACf,QAAQ,aAAa,eAAe,qBAAqB;EACzD,QAAQ,cAAc;EACtB,WAAW,cAAc;;UAQV;EACf,IAAI;EACJ;EACA;EACA;EACA;EACA;EACA,iBAAiB,GAAG;EACpB,iBAAiB,GAAG,SAAS,uBAAuB,WAAW,QAAQ;EACvE,QAAQ,GAAG,sBAAsB;;UAGlB;EACf;EACA;EACA;EACA;EACA;;iBAiCoB,eACpB,IAAI,IACJ,oBACA;EACE;EACA;EACA;EACA;EACA;IAED,QAAQ;iBAqCK,UAAU,SAAS,mBAAmB"}
|
package/dist/hono/rate-limit.mjs
CHANGED
|
@@ -1,95 +1,74 @@
|
|
|
1
|
-
// src/hono/rate-limit.ts
|
|
2
1
|
import { Details } from "../error/detail.mjs";
|
|
3
2
|
import { Status } from "../error/status.mjs";
|
|
4
3
|
import { geolocation } from "./geolocation.mjs";
|
|
4
|
+
//#region src/hono/rate-limit.ts
|
|
5
5
|
function calculateTokens(state, capacity, rate, now) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
6
|
+
if (!state) return {
|
|
7
|
+
tokens: capacity,
|
|
8
|
+
lastRefillTime: now
|
|
9
|
+
};
|
|
10
|
+
const tokensToAdd = (now - state.lastRefillTime) / 1e3 * rate;
|
|
11
|
+
return {
|
|
12
|
+
tokens: Math.min(capacity, state.tokens + tokensToAdd),
|
|
13
|
+
lastRefillTime: now
|
|
14
|
+
};
|
|
16
15
|
}
|
|
17
16
|
function calculateResetTime(currentTokens, capacity, rate) {
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
if (currentTokens >= capacity) return 0;
|
|
18
|
+
return Math.ceil((capacity - currentTokens) / rate);
|
|
20
19
|
}
|
|
21
20
|
function calculateRetryAfter(currentTokens, requested, rate) {
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
if (currentTokens >= requested) return 0;
|
|
22
|
+
return Math.ceil((requested - currentTokens) / rate);
|
|
24
23
|
}
|
|
25
24
|
async function checkRateLimit(kv, identifier, options) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
reset: calculateResetTime(newTokens, capacity, rate)
|
|
47
|
-
};
|
|
48
|
-
if (!allowed) {
|
|
49
|
-
result.retryAfter = calculateRetryAfter(currentTokens, requested, rate);
|
|
50
|
-
}
|
|
51
|
-
return result;
|
|
25
|
+
const { rate, capacity, requested = 1, keyPrefix = "rate-limit:", expiresIn = Math.max(3600, Math.ceil(capacity / rate * 2)) } = options;
|
|
26
|
+
const key = `${keyPrefix}${identifier}`;
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
const stateStr = await kv.getItem(key);
|
|
29
|
+
const { tokens: currentTokens, lastRefillTime } = calculateTokens(stateStr ? JSON.parse(stateStr) : null, capacity, rate, now);
|
|
30
|
+
const allowed = currentTokens >= requested;
|
|
31
|
+
const newTokens = allowed ? currentTokens - requested : currentTokens;
|
|
32
|
+
const newState = {
|
|
33
|
+
tokens: newTokens,
|
|
34
|
+
lastRefillTime
|
|
35
|
+
};
|
|
36
|
+
await kv.setItem(key, JSON.stringify(newState), expiresIn);
|
|
37
|
+
const result = {
|
|
38
|
+
allowed,
|
|
39
|
+
remaining: Math.floor(Math.max(0, newTokens)),
|
|
40
|
+
limit: capacity,
|
|
41
|
+
reset: calculateResetTime(newTokens, capacity, rate)
|
|
42
|
+
};
|
|
43
|
+
if (!allowed) result.retryAfter = calculateRetryAfter(currentTokens, requested, rate);
|
|
44
|
+
return result;
|
|
52
45
|
}
|
|
53
46
|
function rateLimit(options) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
});
|
|
78
|
-
c.header("X-RateLimit-Limit", String(result.limit));
|
|
79
|
-
c.header("X-RateLimit-Remaining", String(result.remaining));
|
|
80
|
-
c.header("X-RateLimit-Reset", String(result.reset));
|
|
81
|
-
if (!result.allowed) {
|
|
82
|
-
c.header("Retry-After", String(result.retryAfter ?? 1));
|
|
83
|
-
if (onRateLimited) return onRateLimited(c, result.retryAfter ?? 1);
|
|
84
|
-
const details = Details.new().errorInfo({ reason: "RATE_LIMIT_EXCEEDED" }).retryInfo({ retryDelay: result.retryAfter ?? 1 });
|
|
85
|
-
const message = "Rate limit exceeded. Please try again later.";
|
|
86
|
-
return Status.resourceExhausted(message).response(details);
|
|
87
|
-
}
|
|
88
|
-
return next();
|
|
89
|
-
};
|
|
47
|
+
const { kv, rate, capacity, requested = 1, keyPrefix = "rate-limit:", expiresIn = Math.max(3600, Math.ceil(capacity / rate * 2)), getIdentifier, onRateLimited, skip } = options;
|
|
48
|
+
return async (c, next) => {
|
|
49
|
+
if (skip && await skip(c)) return next();
|
|
50
|
+
const identifier = getIdentifier ? getIdentifier(c) : geolocation(c).ip_address;
|
|
51
|
+
if (!identifier) return next();
|
|
52
|
+
const result = await checkRateLimit(kv, identifier, {
|
|
53
|
+
rate,
|
|
54
|
+
capacity,
|
|
55
|
+
requested,
|
|
56
|
+
keyPrefix,
|
|
57
|
+
expiresIn
|
|
58
|
+
});
|
|
59
|
+
c.header("X-RateLimit-Limit", String(result.limit));
|
|
60
|
+
c.header("X-RateLimit-Remaining", String(result.remaining));
|
|
61
|
+
c.header("X-RateLimit-Reset", String(result.reset));
|
|
62
|
+
if (!result.allowed) {
|
|
63
|
+
c.header("Retry-After", String(result.retryAfter ?? 1));
|
|
64
|
+
if (onRateLimited) return onRateLimited(c, result.retryAfter ?? 1);
|
|
65
|
+
const details = Details.new().errorInfo({ reason: "RATE_LIMIT_EXCEEDED" }).retryInfo({ retryDelay: result.retryAfter ?? 1 });
|
|
66
|
+
return Status.resourceExhausted("Rate limit exceeded. Please try again later.").response(details);
|
|
67
|
+
}
|
|
68
|
+
return next();
|
|
69
|
+
};
|
|
90
70
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
};
|
|
71
|
+
//#endregion
|
|
72
|
+
export { checkRateLimit, rateLimit };
|
|
73
|
+
|
|
95
74
|
//# sourceMappingURL=rate-limit.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hono/rate-limit.ts"],"sourcesContent":["import type { Context, MiddlewareHandler } from 'hono';\nimport { Details } from '../error/detail';\nimport { Status } from '../error/status';\nimport { geolocation } from './geolocation';\n\nexport interface KV {\n setItem(key: string, value: string, expiresIn?: number): Promise<void>;\n getItem(key: string): Promise<string | null>;\n removeItem(key: string): Promise<void>;\n}\n\ninterface TokenBucketState {\n tokens: number;\n lastRefillTime: number;\n}\n\nexport interface RateLimitOptions {\n kv: KV;\n rate: number;\n capacity: number;\n requested?: number;\n keyPrefix?: string;\n expiresIn?: number;\n getIdentifier?: (c: Context) => string | undefined;\n onRateLimited?: (c: Context, retryAfter: number) => Response | Promise<Response>;\n skip?: (c: Context) => boolean | Promise<boolean>;\n}\n\nexport interface RateLimitResult {\n allowed: boolean;\n remaining: number;\n limit: number;\n reset: number;\n retryAfter?: number;\n}\n\nfunction calculateTokens(\n state: TokenBucketState | null,\n capacity: number,\n rate: number,\n now: number\n): { tokens: number; lastRefillTime: number } {\n if (!state) {\n return { tokens: capacity, lastRefillTime: now };\n }\n\n const elapsed = (now - state.lastRefillTime) / 1000;\n const tokensToAdd = elapsed * rate;\n const newTokens = Math.min(capacity, state.tokens + tokensToAdd);\n\n return {\n tokens: newTokens,\n lastRefillTime: now,\n };\n}\n\nfunction calculateResetTime(currentTokens: number, capacity: number, rate: number): number {\n if (currentTokens >= capacity) return 0;\n return Math.ceil((capacity - currentTokens) / rate);\n}\n\nfunction calculateRetryAfter(currentTokens: number, requested: number, rate: number): number {\n if (currentTokens >= requested) return 0;\n return Math.ceil((requested - currentTokens) / rate);\n}\n\nexport async function checkRateLimit(\n kv: KV,\n identifier: string,\n options: {\n rate: number;\n capacity: number;\n requested?: number;\n keyPrefix?: string;\n expiresIn?: number;\n }\n): Promise<RateLimitResult> {\n const {\n rate,\n capacity,\n requested = 1,\n keyPrefix = 'rate-limit:',\n expiresIn = Math.max(3600, Math.ceil((capacity / rate) * 2)),\n } = options;\n\n const key = `${keyPrefix}${identifier}`;\n const now = Date.now();\n\n const stateStr = await kv.getItem(key);\n const state: TokenBucketState | null = stateStr ? JSON.parse(stateStr) : null;\n\n const { tokens: currentTokens, lastRefillTime } = calculateTokens(state, capacity, rate, now);\n\n const allowed = currentTokens >= requested;\n const newTokens = allowed ? currentTokens - requested : currentTokens;\n\n const newState: TokenBucketState = { tokens: newTokens, lastRefillTime };\n await kv.setItem(key, JSON.stringify(newState), expiresIn);\n\n const result: RateLimitResult = {\n allowed,\n remaining: Math.floor(Math.max(0, newTokens)),\n limit: capacity,\n reset: calculateResetTime(newTokens, capacity, rate),\n };\n\n if (!allowed) {\n result.retryAfter = calculateRetryAfter(currentTokens, requested, rate);\n }\n\n return result;\n}\n\nexport function rateLimit(options: RateLimitOptions): MiddlewareHandler {\n const {\n kv,\n rate,\n capacity,\n requested = 1,\n keyPrefix = 'rate-limit:',\n expiresIn = Math.max(3600, Math.ceil((capacity / rate) * 2)),\n getIdentifier,\n onRateLimited,\n skip,\n } = options;\n\n return async (c, next) => {\n if (skip && (await skip(c))) {\n return next();\n }\n\n const identifier = getIdentifier ? getIdentifier(c) : geolocation(c).ip_address;\n if (!identifier) return next();\n\n const result = await checkRateLimit(kv, identifier, {\n rate,\n capacity,\n requested,\n keyPrefix,\n expiresIn,\n });\n\n c.header('X-RateLimit-Limit', String(result.limit));\n c.header('X-RateLimit-Remaining', String(result.remaining));\n c.header('X-RateLimit-Reset', String(result.reset));\n\n if (!result.allowed) {\n c.header('Retry-After', String(result.retryAfter ?? 1));\n if (onRateLimited) return onRateLimited(c, result.retryAfter ?? 1);\n\n const details = Details.new()\n .errorInfo({ reason: 'RATE_LIMIT_EXCEEDED' })\n .retryInfo({ retryDelay: result.retryAfter ?? 1 });\n\n const message = 'Rate limit exceeded. Please try again later.';\n return Status.resourceExhausted(message).response(details);\n }\n\n return next();\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"rate-limit.mjs","names":[],"sources":["../../src/hono/rate-limit.ts"],"sourcesContent":["import type { Context, MiddlewareHandler } from 'hono';\nimport { Details } from '../error/detail';\nimport { Status } from '../error/status';\nimport { geolocation } from './geolocation';\n\nexport interface KV {\n setItem(key: string, value: string, expiresIn?: number): Promise<void>;\n getItem(key: string): Promise<string | null>;\n removeItem(key: string): Promise<void>;\n}\n\ninterface TokenBucketState {\n tokens: number;\n lastRefillTime: number;\n}\n\nexport interface RateLimitOptions {\n kv: KV;\n rate: number;\n capacity: number;\n requested?: number;\n keyPrefix?: string;\n expiresIn?: number;\n getIdentifier?: (c: Context) => string | undefined;\n onRateLimited?: (c: Context, retryAfter: number) => Response | Promise<Response>;\n skip?: (c: Context) => boolean | Promise<boolean>;\n}\n\nexport interface RateLimitResult {\n allowed: boolean;\n remaining: number;\n limit: number;\n reset: number;\n retryAfter?: number;\n}\n\nfunction calculateTokens(\n state: TokenBucketState | null,\n capacity: number,\n rate: number,\n now: number\n): { tokens: number; lastRefillTime: number } {\n if (!state) {\n return { tokens: capacity, lastRefillTime: now };\n }\n\n const elapsed = (now - state.lastRefillTime) / 1000;\n const tokensToAdd = elapsed * rate;\n const newTokens = Math.min(capacity, state.tokens + tokensToAdd);\n\n return {\n tokens: newTokens,\n lastRefillTime: now,\n };\n}\n\nfunction calculateResetTime(currentTokens: number, capacity: number, rate: number): number {\n if (currentTokens >= capacity) return 0;\n return Math.ceil((capacity - currentTokens) / rate);\n}\n\nfunction calculateRetryAfter(currentTokens: number, requested: number, rate: number): number {\n if (currentTokens >= requested) return 0;\n return Math.ceil((requested - currentTokens) / rate);\n}\n\nexport async function checkRateLimit(\n kv: KV,\n identifier: string,\n options: {\n rate: number;\n capacity: number;\n requested?: number;\n keyPrefix?: string;\n expiresIn?: number;\n }\n): Promise<RateLimitResult> {\n const {\n rate,\n capacity,\n requested = 1,\n keyPrefix = 'rate-limit:',\n expiresIn = Math.max(3600, Math.ceil((capacity / rate) * 2)),\n } = options;\n\n const key = `${keyPrefix}${identifier}`;\n const now = Date.now();\n\n const stateStr = await kv.getItem(key);\n const state: TokenBucketState | null = stateStr ? JSON.parse(stateStr) : null;\n\n const { tokens: currentTokens, lastRefillTime } = calculateTokens(state, capacity, rate, now);\n\n const allowed = currentTokens >= requested;\n const newTokens = allowed ? currentTokens - requested : currentTokens;\n\n const newState: TokenBucketState = { tokens: newTokens, lastRefillTime };\n await kv.setItem(key, JSON.stringify(newState), expiresIn);\n\n const result: RateLimitResult = {\n allowed,\n remaining: Math.floor(Math.max(0, newTokens)),\n limit: capacity,\n reset: calculateResetTime(newTokens, capacity, rate),\n };\n\n if (!allowed) {\n result.retryAfter = calculateRetryAfter(currentTokens, requested, rate);\n }\n\n return result;\n}\n\nexport function rateLimit(options: RateLimitOptions): MiddlewareHandler {\n const {\n kv,\n rate,\n capacity,\n requested = 1,\n keyPrefix = 'rate-limit:',\n expiresIn = Math.max(3600, Math.ceil((capacity / rate) * 2)),\n getIdentifier,\n onRateLimited,\n skip,\n } = options;\n\n return async (c, next) => {\n if (skip && (await skip(c))) {\n return next();\n }\n\n const identifier = getIdentifier ? getIdentifier(c) : geolocation(c).ip_address;\n if (!identifier) return next();\n\n const result = await checkRateLimit(kv, identifier, {\n rate,\n capacity,\n requested,\n keyPrefix,\n expiresIn,\n });\n\n c.header('X-RateLimit-Limit', String(result.limit));\n c.header('X-RateLimit-Remaining', String(result.remaining));\n c.header('X-RateLimit-Reset', String(result.reset));\n\n if (!result.allowed) {\n c.header('Retry-After', String(result.retryAfter ?? 1));\n if (onRateLimited) return onRateLimited(c, result.retryAfter ?? 1);\n\n const details = Details.new()\n .errorInfo({ reason: 'RATE_LIMIT_EXCEEDED' })\n .retryInfo({ retryDelay: result.retryAfter ?? 1 });\n\n const message = 'Rate limit exceeded. Please try again later.';\n return Status.resourceExhausted(message).response(details);\n }\n\n return next();\n };\n}\n"],"mappings":";;;;AAoCA,SAAS,gBACP,OACA,UACA,MACA,KAC4C;CAC5C,IAAI,CAAC,OACH,OAAO;EAAE,QAAQ;EAAU,gBAAgB;CAAI;CAIjD,MAAM,eADW,MAAM,MAAM,kBAAkB,MACjB;CAG9B,OAAO;EACL,QAHgB,KAAK,IAAI,UAAU,MAAM,SAAS,WAGlC;EAChB,gBAAgB;CAClB;AACF;AAEA,SAAS,mBAAmB,eAAuB,UAAkB,MAAsB;CACzF,IAAI,iBAAiB,UAAU,OAAO;CACtC,OAAO,KAAK,MAAM,WAAW,iBAAiB,IAAI;AACpD;AAEA,SAAS,oBAAoB,eAAuB,WAAmB,MAAsB;CAC3F,IAAI,iBAAiB,WAAW,OAAO;CACvC,OAAO,KAAK,MAAM,YAAY,iBAAiB,IAAI;AACrD;AAEA,eAAsB,eACpB,IACA,YACA,SAO0B;CAC1B,MAAM,EACJ,MACA,UACA,YAAY,GACZ,YAAY,eACZ,YAAY,KAAK,IAAI,MAAM,KAAK,KAAM,WAAW,OAAQ,CAAC,CAAC,MACzD;CAEJ,MAAM,MAAM,GAAG,YAAY;CAC3B,MAAM,MAAM,KAAK,IAAI;CAErB,MAAM,WAAW,MAAM,GAAG,QAAQ,GAAG;CAGrC,MAAM,EAAE,QAAQ,eAAe,mBAAmB,gBAFX,WAAW,KAAK,MAAM,QAAQ,IAAI,MAEA,UAAU,MAAM,GAAG;CAE5F,MAAM,UAAU,iBAAiB;CACjC,MAAM,YAAY,UAAU,gBAAgB,YAAY;CAExD,MAAM,WAA6B;EAAE,QAAQ;EAAW;CAAe;CACvE,MAAM,GAAG,QAAQ,KAAK,KAAK,UAAU,QAAQ,GAAG,SAAS;CAEzD,MAAM,SAA0B;EAC9B;EACA,WAAW,KAAK,MAAM,KAAK,IAAI,GAAG,SAAS,CAAC;EAC5C,OAAO;EACP,OAAO,mBAAmB,WAAW,UAAU,IAAI;CACrD;CAEA,IAAI,CAAC,SACH,OAAO,aAAa,oBAAoB,eAAe,WAAW,IAAI;CAGxE,OAAO;AACT;AAEA,SAAgB,UAAU,SAA8C;CACtE,MAAM,EACJ,IACA,MACA,UACA,YAAY,GACZ,YAAY,eACZ,YAAY,KAAK,IAAI,MAAM,KAAK,KAAM,WAAW,OAAQ,CAAC,CAAC,GAC3D,eACA,eACA,SACE;CAEJ,OAAO,OAAO,GAAG,SAAS;EACxB,IAAI,QAAS,MAAM,KAAK,CAAC,GACvB,OAAO,KAAK;EAGd,MAAM,aAAa,gBAAgB,cAAc,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;EACrE,IAAI,CAAC,YAAY,OAAO,KAAK;EAE7B,MAAM,SAAS,MAAM,eAAe,IAAI,YAAY;GAClD;GACA;GACA;GACA;GACA;EACF,CAAC;EAED,EAAE,OAAO,qBAAqB,OAAO,OAAO,KAAK,CAAC;EAClD,EAAE,OAAO,yBAAyB,OAAO,OAAO,SAAS,CAAC;EAC1D,EAAE,OAAO,qBAAqB,OAAO,OAAO,KAAK,CAAC;EAElD,IAAI,CAAC,OAAO,SAAS;GACnB,EAAE,OAAO,eAAe,OAAO,OAAO,cAAc,CAAC,CAAC;GACtD,IAAI,eAAe,OAAO,cAAc,GAAG,OAAO,cAAc,CAAC;GAEjE,MAAM,UAAU,QAAQ,IAAI,CAAC,CAC1B,UAAU,EAAE,QAAQ,sBAAsB,CAAC,CAAC,CAC5C,UAAU,EAAE,YAAY,OAAO,cAAc,EAAE,CAAC;GAGnD,OAAO,OAAO,kBAAkB,8CAAO,CAAC,CAAC,SAAS,OAAO;EAC3D;EAEA,OAAO,KAAK;CACd;AACF"}
|
package/dist/hono/validator.cjs
CHANGED
|
@@ -1,69 +1,50 @@
|
|
|
1
|
-
"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/hono/validator.ts
|
|
21
|
-
var validator_exports = {};
|
|
22
|
-
__export(validator_exports, {
|
|
23
|
-
bigintId: () => bigintId,
|
|
24
|
-
zValidator: () => zValidator
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(validator_exports);
|
|
27
|
-
var import_validator = require("hono/validator");
|
|
28
|
-
var import_mini = require("zod/mini");
|
|
29
|
-
var import_detail = require("../error/detail.cjs");
|
|
30
|
-
var import_status = require("../error/status.cjs");
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_error_detail = require("../error/detail.cjs");
|
|
3
|
+
const require_error_status = require("../error/status.cjs");
|
|
4
|
+
let zod_mini = require("zod/mini");
|
|
5
|
+
let hono_validator = require("hono/validator");
|
|
6
|
+
//#region src/hono/validator.ts
|
|
31
7
|
function zValidator(target, schema) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
8
|
+
return (0, hono_validator.validator)(target, async (value) => {
|
|
9
|
+
const result = await schema.safeParseAsync(value);
|
|
10
|
+
if (result.success) return result.data;
|
|
11
|
+
const fieldViolations = result.error.issues.map(({ code, path, message }) => ({
|
|
12
|
+
field: path.join("."),
|
|
13
|
+
description: message,
|
|
14
|
+
reason: code?.toUpperCase() ?? "INVALID_ARGUMENT",
|
|
15
|
+
localizedMessage: {
|
|
16
|
+
locale: "en-US",
|
|
17
|
+
message
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
const details = require_error_detail.Details.new().badRequest({ fieldViolations });
|
|
21
|
+
throw require_error_status.Status.invalidArgument().error(details);
|
|
22
|
+
});
|
|
46
23
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
24
|
+
const bigintId = (0, zod_mini.pipe)((0, zod_mini.string)(), (0, zod_mini.transform)((input, ctx) => {
|
|
25
|
+
if (!/^(0|[1-9]\d{0,19})$/.test(input)) {
|
|
26
|
+
const message = `Invalid bigint id: ${input}`;
|
|
27
|
+
ctx.issues.push({
|
|
28
|
+
code: "custom",
|
|
29
|
+
input,
|
|
30
|
+
message
|
|
31
|
+
});
|
|
32
|
+
return zod_mini.NEVER;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
return BigInt(input);
|
|
36
|
+
} catch {
|
|
37
|
+
const message = `Parse bigint id: ${input} failed`;
|
|
38
|
+
ctx.issues.push({
|
|
39
|
+
code: "custom",
|
|
40
|
+
input,
|
|
41
|
+
message
|
|
42
|
+
});
|
|
43
|
+
return zod_mini.NEVER;
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
//#endregion
|
|
47
|
+
exports.bigintId = bigintId;
|
|
48
|
+
exports.zValidator = zValidator;
|
|
49
|
+
|
|
69
50
|
//# sourceMappingURL=validator.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import type { ValidationTargets } from 'hono';\nimport { validator } from 'hono/validator';\nimport type { ZodType, output as outputV4 } from 'zod';\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":"
|
|
1
|
+
{"version":3,"file":"validator.cjs","names":["Details","Status","NEVER"],"sources":["../../src/hono/validator.ts"],"sourcesContent":["import type { ValidationTargets } from 'hono';\nimport { validator } from 'hono/validator';\nimport type { ZodType, output as outputV4 } from 'zod';\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":";;;;;;AAcA,SAAgB,WACd,QACA,QACA;CACA,QAAA,GAAA,eAAA,UAAA,CAAiB,QAAQ,OAAO,UAAU;EACxC,MAAM,SAAS,MAAM,OAAO,eAAe,KAAK;EAChD,IAAI,OAAO,SAAS,OAAO,OAAO;EAElC,MAAM,kBAAiD,OAAO,MAAM,OAAO,KACxE,EAAE,MAAM,MAAM,eAAe;GAC5B,OAAO,KAAK,KAAK,GAAG;GACpB,aAAa;GACb,QAAQ,MAAM,YAAY,KAAK;GAC/B,kBAAkB;IAAE,QAAQ;IAAkB;GAAQ;EACxD,EACF;EACA,MAAM,UAAUA,qBAAAA,QAAQ,IAAI,CAAC,CAAC,WAAW,EAAE,gBAAgB,CAAC;EAC5D,MAAMC,qBAAAA,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO;CAC9C,CAAC;AACH;AAEA,MAAa,YAAA,GAAA,SAAA,KAAA,EAAA,GAAA,SAAA,OAAA,CACJ,IAAA,GAAA,SAAA,UAAA,EACI,OAAO,QAAQ;CACxB,IAAI,CAAC,sBAAsB,KAAK,KAAK,GAAG;EACtC,MAAM,UAAU,sBAAsB;EACtC,IAAI,OAAO,KAAK;GAAE,MAAM;GAAU;GAAO;EAAQ,CAAC;EAClD,OAAOC,SAAAA;CACT;CACA,IAAI;EACF,OAAO,OAAO,KAAK;CACrB,QAAQ;EACN,MAAM,UAAU,oBAAoB,MAAM;EAC1C,IAAI,OAAO,KAAK;GAAE,MAAM;GAAU;GAAO;EAAQ,CAAC;EAClD,OAAOA,SAAAA;CACT;AACF,CAAC,CACH"}
|
|
@@ -1,31 +1,26 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
header: (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends infer T_10 ? T_10 extends (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_10 extends Response | hono.TypedResponse<any, any, any> ? never : T_10 : never : never;
|
|
26
|
-
cookie: (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends infer T_11 ? T_11 extends (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_11 extends Response | hono.TypedResponse<any, any, any> ? never : T_11 : never : never;
|
|
27
|
-
};
|
|
28
|
-
}, (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends infer T_12 ? T_12 extends (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_12 extends hono.TypedResponse<infer T_13, infer S_1 extends hono_utils_http_status.StatusCode, infer F extends string> ? hono.TypedResponse<T_13, S_1, F> : T_12 extends Response ? T_12 : T_12 extends undefined ? never : never : never : never>;
|
|
29
|
-
declare const bigintId: zod_mini.ZodMiniPipe<zod_mini.ZodMiniString<string>, zod_mini.ZodMiniTransform<bigint, string>>;
|
|
30
|
-
|
|
1
|
+
import { ValidationTargets } from "hono";
|
|
2
|
+
import { ZodType, output } from "zod";
|
|
3
|
+
import { ZodMiniType } from "zod/mini";
|
|
4
|
+
//#region src/hono/validator.d.ts
|
|
5
|
+
declare function zValidator<S extends ZodType | ZodMiniType>(target: keyof ValidationTargets, schema: S): import("hono").MiddlewareHandler<any, string, {
|
|
6
|
+
in: {
|
|
7
|
+
cookie: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "cookie", import("hono/types").FormValue>;
|
|
8
|
+
form: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "form", import("hono/types").FormValue>;
|
|
9
|
+
header: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "header", import("hono/types").FormValue>;
|
|
10
|
+
json: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T_1) ? T_1 extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_1 extends Response | import("hono").TypedResponse<any, any, any> ? never : T_1 : never : never;
|
|
11
|
+
param: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "param", import("hono/types").FormValue>;
|
|
12
|
+
query: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "query", import("hono/types").FormValue>;
|
|
13
|
+
};
|
|
14
|
+
out: {
|
|
15
|
+
cookie: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
16
|
+
form: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
17
|
+
header: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
18
|
+
json: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
19
|
+
param: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
20
|
+
query: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
21
|
+
};
|
|
22
|
+
}, (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T_2) ? T_2 extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_2 extends import("hono").TypedResponse<infer T_3, infer S_1 extends import("hono/utils/http-status").StatusCode, infer F extends string> ? import("hono").TypedResponse<T_3, S_1, F> : T_2 extends Response ? T_2 : T_2 extends undefined ? never : never : never : never>;
|
|
23
|
+
declare const bigintId: import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniString<string>, import("zod/mini").ZodMiniTransform<bigint, string>>;
|
|
24
|
+
//#endregion
|
|
31
25
|
export { bigintId, zValidator };
|
|
26
|
+
//# sourceMappingURL=validator.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.cts","names":[],"sources":["../../src/hono/validator.ts"],"mappings":";;;;iBAcgB,WAAW,UAAU,UAAU,aAC7C,cAAc,mBACd,QAAQ,mBAAC;;;;;;;;;;;;;;;;;;cAmBE,6BAAQ,+BAAA,0CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ZodMiniType } from "zod/mini";
|
|
2
|
+
import { ValidationTargets } from "hono";
|
|
3
|
+
import { ZodType, output } from "zod";
|
|
4
|
+
//#region src/hono/validator.d.ts
|
|
5
|
+
declare function zValidator<S extends ZodType | ZodMiniType>(target: keyof ValidationTargets, schema: S): import("hono").MiddlewareHandler<any, string, {
|
|
6
|
+
in: {
|
|
7
|
+
cookie: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "cookie", import("hono/types").FormValue>;
|
|
8
|
+
form: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "form", import("hono/types").FormValue>;
|
|
9
|
+
header: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "header", import("hono/types").FormValue>;
|
|
10
|
+
json: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T_1) ? T_1 extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_1 extends Response | import("hono").TypedResponse<any, any, any> ? never : T_1 : never : never;
|
|
11
|
+
param: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "param", import("hono/types").FormValue>;
|
|
12
|
+
query: import("hono/validator").InferInput<(S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never, "query", import("hono/types").FormValue>;
|
|
13
|
+
};
|
|
14
|
+
out: {
|
|
15
|
+
cookie: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
16
|
+
form: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
17
|
+
header: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
18
|
+
json: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
19
|
+
param: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
20
|
+
query: (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T) ? T extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T extends Response | import("hono").TypedResponse<any, any, any> ? never : T : never : never;
|
|
21
|
+
};
|
|
22
|
+
}, (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends (infer T_2) ? T_2 extends (S extends ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_2 extends import("hono").TypedResponse<infer T_3, infer S_1 extends import("hono/utils/http-status").StatusCode, infer F extends string> ? import("hono").TypedResponse<T_3, S_1, F> : T_2 extends Response ? T_2 : T_2 extends undefined ? never : never : never : never>;
|
|
23
|
+
declare const bigintId: import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniString<string>, import("zod/mini").ZodMiniTransform<bigint, string>>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { bigintId, zValidator };
|
|
26
|
+
//# sourceMappingURL=validator.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.mts","names":[],"sources":["../../src/hono/validator.ts"],"mappings":";;;;iBAcgB,WAAW,UAAU,UAAU,aAC7C,cAAc,mBACd,QAAQ,mBAAC;;;;;;;;;;;;;;;;;;cAmBE,6BAAQ,+BAAA,0CAAA"}
|