Compare commits
27 Commits
@hono/stan
...
main
Author | SHA1 | Date |
---|---|---|
|
0dc6a1f5e6 | |
|
d89fed7eec | |
|
b24925168a | |
|
2a46bfbba0 | |
|
28601b311b | |
|
5a3cbc4cc6 | |
|
e835cf6183 | |
|
2339eefa1c | |
|
7d82875634 | |
|
c6a16ab7aa | |
|
1a564d5fb6 | |
|
9216d2a666 | |
|
845e336ff4 | |
|
2a589b0728 | |
|
47cb4c8569 | |
|
3705fe6560 | |
|
9f6278f51c | |
|
55e4b19a50 | |
|
68cbb31af4 | |
|
b5186da328 | |
|
037fd94b7b | |
|
2498ccab03 | |
|
6e53f6e8f3 | |
|
18dec85b78 | |
|
4e5f592359 | |
|
0f472345c7 | |
|
0a82c1faed |
|
@ -54,7 +54,7 @@ jobs:
|
|||
- uses: denoland/setup-deno@v2
|
||||
with:
|
||||
cache: true
|
||||
deno-version: v2.x
|
||||
deno-version: v2.3.7
|
||||
- run: deno install --no-lock
|
||||
- run: deno publish --dry-run
|
||||
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# @hono/auth-js
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1324](https://github.com/honojs/middleware/pull/1324) [`d89fed7eecfa151c18b0a8cf95dae1dfe83dfec2`](https://github.com/honojs/middleware/commit/d89fed7eecfa151c18b0a8cf95dae1dfe83dfec2) Thanks [@jamestalmage](https://github.com/jamestalmage)! - Allow async authjs Config
|
||||
|
||||
## 1.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/auth-js",
|
||||
"version": "1.0.17",
|
||||
"version": "1.1.0",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/auth-js",
|
||||
"version": "1.0.17",
|
||||
"version": "1.1.0",
|
||||
"description": "A third-party Auth js middleware for Hono",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
|
|
|
@ -47,6 +47,27 @@ describe('Config', () => {
|
|||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
it('Should allow async ConfigHandler', async () => {
|
||||
globalThis.process.env = { AUTH_SECRET: 'secret' }
|
||||
const app = new Hono()
|
||||
|
||||
app.use(
|
||||
'/*',
|
||||
initAuthConfig(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1))
|
||||
return {
|
||||
basePath: '/api/auth',
|
||||
providers: [],
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
app.use('/api/auth/*', authHandler())
|
||||
const req = new Request('http://localhost/api/auth/signin')
|
||||
const res = await app.request(req)
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
it('Should return 401 is if auth cookie is invalid or missing', async () => {
|
||||
const app = new Hono()
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ export type AuthUser = {
|
|||
|
||||
export interface AuthConfig extends Omit<AuthConfigCore, 'raw'> {}
|
||||
|
||||
export type ConfigHandler = (c: Context) => AuthConfig
|
||||
export type ConfigHandler = (c: Context) => AuthConfig | Promise<AuthConfig>
|
||||
|
||||
export function setEnvDefaults(env: AuthEnv, config: AuthConfig): void {
|
||||
config.secret ??= env.AUTH_SECRET
|
||||
|
@ -118,7 +118,7 @@ export function verifyAuth(): MiddlewareHandler {
|
|||
|
||||
export function initAuthConfig(cb: ConfigHandler): MiddlewareHandler {
|
||||
return async (c, next) => {
|
||||
const config = cb(c)
|
||||
const config = await cb(c)
|
||||
c.set('authConfig', config)
|
||||
await next()
|
||||
}
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
// See https://github.com/vitest-dev/vitest/issues/5277
|
||||
pool: 'forks',
|
||||
setupFiles: ['./vitest.setup.ts'],
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
typecheck: {
|
||||
tsconfig: './tsconfig.json',
|
||||
enabled: true,
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# @hono/clerk-auth
|
||||
|
||||
## 3.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1295](https://github.com/honojs/middleware/pull/1295) [`0f472345c737ed054bf26c2e0ab13d71dc0fcbcd`](https://github.com/honojs/middleware/commit/0f472345c737ed054bf26c2e0ab13d71dc0fcbcd) Thanks [@brkalow](https://github.com/brkalow)! - Upgrade clerk dependencies.
|
||||
|
||||
## 3.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/clerk-auth",
|
||||
"version": "3.0.1",
|
||||
"version": "3.0.2",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/clerk-auth",
|
||||
"version": "3.0.1",
|
||||
"version": "3.0.2",
|
||||
"description": "A third-party Clerk auth middleware for Hono",
|
||||
"type": "module",
|
||||
"main": "dist/index.cjs",
|
||||
|
@ -41,8 +41,8 @@
|
|||
},
|
||||
"homepage": "https://github.com/honojs/middleware",
|
||||
"dependencies": {
|
||||
"@clerk/backend": "^2.2.0",
|
||||
"@clerk/types": "^4.61.0"
|
||||
"@clerk/backend": "^2.4.1",
|
||||
"@clerk/types": "^4.64.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hono": ">=3.0.0"
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
restoreMocks: true,
|
||||
unstubEnvs: true,
|
||||
},
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { defineProject } from 'vitest/config'
|
||||
|
||||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
|
@ -29,8 +29,5 @@
|
|||
"eslint-plugin-import-x": "^4.1.1",
|
||||
"eslint-plugin-n": "^17.10.2",
|
||||
"typescript-eslint": "^8.27.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"hono": "^4.8.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -23,6 +23,7 @@ const firebasePlugin = {
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
|
||||
plugins: [firebasePlugin],
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { defaultExclude, defineProject } from 'vitest/config'
|
||||
import { defineProject } from 'vitest/config'
|
||||
|
||||
export default defineProject({
|
||||
test: {
|
||||
exclude: [...defaultExclude, 'bun_test'],
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
restoreMocks: true,
|
||||
unstubEnvs: true,
|
||||
},
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
restoreMocks: true,
|
||||
unstubEnvs: true,
|
||||
},
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineWorkersProject } from '@cloudflare/vitest-pool-workers/config'
|
|||
export default defineWorkersProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts?(x)'],
|
||||
poolOptions: {
|
||||
workers: {
|
||||
miniflare: {
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
restoreMocks: true,
|
||||
unstubEnvs: true,
|
||||
},
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
# @hono/session
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1272](https://github.com/honojs/middleware/pull/1272) [`68cbb31af43fd5916173f9f6b07c8cedb3dbe706`](https://github.com/honojs/middleware/commit/68cbb31af43fd5916173f9f6b07c8cedb3dbe706) Thanks [@yusukebe](https://github.com/yusukebe)! - feat: enable accessing sid via `c.var.session.id`
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1301](https://github.com/honojs/middleware/pull/1301) [`037fd94b7b0e17a049c979fa8750bd6673fdae19`](https://github.com/honojs/middleware/commit/037fd94b7b0e17a049c979fa8750bd6673fdae19) Thanks [@BarryThePenguin](https://github.com/BarryThePenguin)! - Fix types for `SessionOptions` cookie methods
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "@hono/session",
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./cookies": "./src/cookies.ts",
|
||||
"./testing": "./src/helper/testing/index.ts"
|
||||
},
|
||||
"imports": {
|
||||
"hono": "jsr:@hono/hono@^4.8.3",
|
||||
"jose": "jsr:@panva/jose@^6.0.11"
|
||||
},
|
||||
"publish": {
|
||||
"include": ["deno.json", "README.md", "src/**/*.ts"],
|
||||
"exclude": ["src/**/*.test.ts"]
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/session",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"description": "Session middleware for Hono",
|
||||
"type": "module",
|
||||
"module": "dist/index.js",
|
||||
|
|
|
@ -939,3 +939,85 @@ describe('session events', () => {
|
|||
expect(onUpdate).toHaveBeenCalledWith({ sub })
|
||||
})
|
||||
})
|
||||
|
||||
describe('session.id', () => {
|
||||
const app = new Hono()
|
||||
.get('/session-id', useSession<TestData>({ secret }), async (c) => {
|
||||
await c.var.session.get()
|
||||
return c.json({ id: c.var.session.id })
|
||||
})
|
||||
.put('/session-id/:sub', useSession<TestData>({ secret }), async (c) => {
|
||||
const sub = c.req.param('sub')
|
||||
await c.var.session.update({ sub })
|
||||
return c.json({ id: c.var.session.id })
|
||||
})
|
||||
|
||||
it('throws an error when session is not initialised', async () => {
|
||||
const app = new Hono().get('/session-id', useSession<TestData>({ secret }), (c) => {
|
||||
return c.json({ id: c.var.session.id })
|
||||
})
|
||||
|
||||
const res = await app.request('/session-id')
|
||||
expect(res.status).toBe(500)
|
||||
})
|
||||
|
||||
it('returns session id after get()', async () => {
|
||||
const res = await app.request('/session-id')
|
||||
const data = await res.json()
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
expect(data.id).toBeTypeOf('string')
|
||||
expect(data.id.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('returns session id after update()', async () => {
|
||||
const res = await app.request('/session-id/test-user', { method: 'PUT' })
|
||||
const data = await res.json()
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
expect(data.id).toBeTypeOf('string')
|
||||
expect(data.id.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('returns same session id for existing session', async () => {
|
||||
const cookie = await encrypt(session.payload)
|
||||
const res = await app.request('/session-id', {
|
||||
headers: { cookie: `sid=${cookie}` },
|
||||
})
|
||||
const data = await res.json()
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
expect(data.id).toBe(sid) // 'some-session-id'
|
||||
})
|
||||
|
||||
it('generates different session ids for new sessions', async () => {
|
||||
const res1 = await app.request('/session-id')
|
||||
const res2 = await app.request('/session-id')
|
||||
const data1 = await res1.json()
|
||||
const data2 = await res2.json()
|
||||
|
||||
expect(res1.status).toBe(200)
|
||||
expect(res2.status).toBe(200)
|
||||
expect(data1.id).not.toBe(data2.id)
|
||||
expect(data1.id).toBeTypeOf('string')
|
||||
expect(data2.id).toBeTypeOf('string')
|
||||
})
|
||||
|
||||
it('preserves session id across requests with same cookie', async () => {
|
||||
// First request - create session
|
||||
const firstRes = await app.request('/session-id/user1', { method: 'PUT' })
|
||||
const sessionCookie = await getSetCookie(firstRes, 'sid', decrypt)
|
||||
const firstData = await firstRes.json()
|
||||
|
||||
// Second request - use same cookie
|
||||
const secondRes = await app.request('/session-id', {
|
||||
headers: { cookie: `sid=${sessionCookie?.value}` },
|
||||
})
|
||||
const secondData = await secondRes.json()
|
||||
|
||||
expect(firstRes.status).toBe(200)
|
||||
expect(secondRes.status).toBe(200)
|
||||
expect(firstData.id).toBe(secondData.id)
|
||||
expect(firstData.id).toBe(sessionCookie?.payload.sid)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -37,9 +37,9 @@ export interface SessionOptions<Data> extends SessionEvents<Data> {
|
|||
*/
|
||||
secret?: string | EncryptionKey
|
||||
|
||||
deleteCookie?: typeof cookie.deleteCookie
|
||||
getCookie?: typeof cookie.getCookie
|
||||
setCookie?: typeof cookie.setCookie
|
||||
deleteCookie?: (c: Context, name: string, opt?: CookieOptions) => void
|
||||
getCookie?: (c: Context, name: string) => string | undefined
|
||||
setCookie?: (c: Context, name: string, value: string, opt?: CookieOptions) => void
|
||||
}
|
||||
|
||||
export type SessionEnv<Data = SessionData> = Env & {
|
||||
|
@ -104,6 +104,9 @@ export const useSession = <Data extends SessionData>(
|
|||
get data() {
|
||||
return session.data
|
||||
},
|
||||
get id() {
|
||||
return session.id
|
||||
},
|
||||
delete() {
|
||||
session.delete()
|
||||
},
|
||||
|
|
|
@ -26,6 +26,11 @@ export interface Session<Data> {
|
|||
*/
|
||||
readonly data: Data | null
|
||||
|
||||
/**
|
||||
* Current session ID.
|
||||
*/
|
||||
readonly id: string | null
|
||||
|
||||
/**
|
||||
* Delete the current session, removing the session cookie and data from storage.
|
||||
*/
|
||||
|
@ -122,6 +127,17 @@ export function getSession<Data extends SessionData>({
|
|||
|
||||
return session.data ?? null
|
||||
},
|
||||
get id() {
|
||||
if (!session) {
|
||||
throw new Error('Session not initialised. Call get() or update() first.')
|
||||
}
|
||||
|
||||
if (session.action === 'destroy') {
|
||||
throw new Error('Session has been destroyed.')
|
||||
}
|
||||
|
||||
return session.payload?.sid ?? null
|
||||
},
|
||||
delete() {
|
||||
if (session) {
|
||||
onDelete?.(session.data)
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineWorkersProject } from '@cloudflare/vitest-pool-workers/config'
|
|||
export default defineWorkersProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['examples/**/*.test.ts', 'src/**/*.test.ts'],
|
||||
restoreMocks: true,
|
||||
poolOptions: {
|
||||
workers: {
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# @hono/standard-validator
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1282](https://github.com/honojs/middleware/pull/1282) [`2a46bfbba0695ae713b58211fd5e83a08b829ad6`](https://github.com/honojs/middleware/commit/2a46bfbba0695ae713b58211fd5e83a08b829ad6) Thanks [@MonsterDeveloper](https://github.com/MonsterDeveloper)! - Fix cookies output for arktype in standard schema validator
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -26,7 +26,12 @@ const querySortSchema = type({
|
|||
order: "'asc'|'desc'",
|
||||
})
|
||||
|
||||
const headerSchema = type({
|
||||
'user-agent': 'string',
|
||||
})
|
||||
|
||||
export {
|
||||
headerSchema,
|
||||
idJSONSchema,
|
||||
personJSONSchema,
|
||||
postJSONSchema,
|
||||
|
|
|
@ -28,7 +28,12 @@ const querySortSchema = object({
|
|||
order: picklist(['asc', 'desc']),
|
||||
})
|
||||
|
||||
const headerSchema = object({
|
||||
'user-agent': string(),
|
||||
})
|
||||
|
||||
export {
|
||||
headerSchema,
|
||||
idJSONSchema,
|
||||
personJSONSchema,
|
||||
postJSONSchema,
|
||||
|
|
|
@ -28,7 +28,12 @@ const querySortSchema = z.object({
|
|||
order: z.enum(['asc', 'desc']),
|
||||
})
|
||||
|
||||
const headerSchema = z.object({
|
||||
'user-agent': z.string(),
|
||||
})
|
||||
|
||||
export {
|
||||
headerSchema,
|
||||
idJSONSchema,
|
||||
personJSONSchema,
|
||||
postJSONSchema,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/standard-validator",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/standard-validator",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"description": "Validator middleware using Standard Schema",
|
||||
"type": "module",
|
||||
"main": "dist/index.cjs",
|
||||
|
|
|
@ -352,6 +352,47 @@ describe('Standard Schema Validation', () => {
|
|||
>
|
||||
})
|
||||
})
|
||||
|
||||
describe('Sensitive Data Removal', () => {
|
||||
it("doesn't return cookies after headers validation", async () => {
|
||||
const app = new Hono()
|
||||
|
||||
const schema = schemas.headerSchema
|
||||
|
||||
app.get('/headers', sValidator('header', schema), (c) =>
|
||||
c.json({ success: true, userAgent: c.req.header('User-Agent') })
|
||||
)
|
||||
|
||||
const req = new Request('http://localhost/headers', {
|
||||
headers: {
|
||||
// Not passing the User-Agent header to trigger the validation error
|
||||
Cookie: 'SECRET=123',
|
||||
},
|
||||
})
|
||||
|
||||
const res = await app.request(req)
|
||||
expect(res.status).toBe(400)
|
||||
const data = (await res.json()) as { success: false; error: unknown[] }
|
||||
expect(data.success).toBe(false)
|
||||
expect(data.error).toBeDefined()
|
||||
|
||||
if (lib === 'arktype') {
|
||||
expect(
|
||||
(data.error as { data: Record<string, unknown> }[]).some(
|
||||
(error) => error.data && error.data.cookie
|
||||
)
|
||||
).toBe(false)
|
||||
}
|
||||
|
||||
if (lib === 'valibot') {
|
||||
expect(
|
||||
(data.error as { path: { input: Record<string, unknown> }[] }[]).some((error) =>
|
||||
error.path.some((path) => path.input.cookie)
|
||||
)
|
||||
).toBe(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
||||
import type { Context, Env, Input, MiddlewareHandler, TypedResponse, ValidationTargets } from 'hono'
|
||||
import { validator } from 'hono/validator'
|
||||
import { sanitizeIssues } from './sanitize-issues'
|
||||
|
||||
type HasUndefined<T> = undefined extends T ? true : false
|
||||
type TOrPromiseOfT<T> = T | Promise<T>
|
||||
|
@ -21,6 +22,67 @@ type Hook<
|
|||
c: Context<E, P>
|
||||
) => TOrPromiseOfT<Response | void | TypedResponse<O>>
|
||||
|
||||
/**
|
||||
* Validation middleware for libraries that support [Standard Schema](https://standardschema.dev/) specification.
|
||||
*
|
||||
* This middleware validates incoming request data against a provided schema
|
||||
* that conforms to the Standard Schema specification. It supports validation
|
||||
* of JSON bodies, headers, queries, forms, and other request targets.
|
||||
*
|
||||
* @param target - The request target to validate ('json', 'header', 'query', 'form', etc.)
|
||||
* @param schema - A schema object conforming to Standard Schema specification
|
||||
* @param hook - Optional hook function called with validation results for custom error handling
|
||||
* @returns A Hono middleware handler that validates requests and makes validated data available via `c.req.valid()`
|
||||
*
|
||||
* @example Basic JSON validation
|
||||
* ```ts
|
||||
* import { z } from 'zod'
|
||||
* import { sValidator } from '@hono/standard-validator'
|
||||
*
|
||||
* const schema = z.object({
|
||||
* name: z.string(),
|
||||
* age: z.number(),
|
||||
* })
|
||||
*
|
||||
* app.post('/author', sValidator('json', schema), (c) => {
|
||||
* const data = c.req.valid('json')
|
||||
* return c.json({
|
||||
* success: true,
|
||||
* message: `${data.name} is ${data.age}`,
|
||||
* })
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @example With custom error handling hook
|
||||
* ```ts
|
||||
* app.post(
|
||||
* '/post',
|
||||
* sValidator('json', schema, (result, c) => {
|
||||
* if (!result.success) {
|
||||
* return c.text('Invalid!', 400)
|
||||
* }
|
||||
* }),
|
||||
* (c) => {
|
||||
* // Handler code
|
||||
* }
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @example Header validation
|
||||
* ```ts
|
||||
* import { object, string } from 'valibot'
|
||||
*
|
||||
* const schema = object({
|
||||
* 'content-type': string(),
|
||||
* 'user-agent': string(),
|
||||
* })
|
||||
*
|
||||
* app.post('/author', sValidator('header', schema), (c) => {
|
||||
* const headers = c.req.valid('header')
|
||||
* // do something with headers
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
const sValidator = <
|
||||
Schema extends StandardSchemaV1,
|
||||
Target extends keyof ValidationTargets,
|
||||
|
@ -71,7 +133,9 @@ const sValidator = <
|
|||
}
|
||||
|
||||
if (result.issues) {
|
||||
return c.json({ data: value, error: result.issues, success: false }, 400)
|
||||
const processedIssues = sanitizeIssues(result.issues, schema['~standard'].vendor, target)
|
||||
|
||||
return c.json({ data: value, error: processedIssues, success: false }, 400)
|
||||
}
|
||||
|
||||
return result.value as StandardSchemaV1.InferOutput<Schema>
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
||||
import type { ValidationTargets } from 'hono'
|
||||
|
||||
const RESTRICTED_DATA_FIELDS = {
|
||||
header: ['cookie'],
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes validation issues by removing sensitive data fields from error messages.
|
||||
*
|
||||
* This function removes potentially sensitive information (like cookies) from validation
|
||||
* error messages before they are returned to the client. It handles different validation
|
||||
* library formats based on the vendor string.
|
||||
*
|
||||
* @param issues - Array of validation issues from Standard Schema validation
|
||||
* @param vendor - The validation library vendor identifier (e.g., 'arktype', 'valibot')
|
||||
* @param target - The validation target being processed ('header', 'json', etc.)
|
||||
* @returns Sanitized array of validation issues with sensitive data removed
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const issues = [{ message: 'Invalid header', data: { cookie: 'secret' } }]
|
||||
* const sanitized = sanitizeIssues(issues, 'arktype', 'header')
|
||||
* // Returns issues with cookie field removed from data
|
||||
* ```
|
||||
*/
|
||||
export function sanitizeIssues(
|
||||
issues: readonly StandardSchemaV1.Issue[],
|
||||
vendor: string,
|
||||
target: keyof ValidationTargets
|
||||
): readonly StandardSchemaV1.Issue[] {
|
||||
if (!(target in RESTRICTED_DATA_FIELDS)) {
|
||||
return issues
|
||||
}
|
||||
|
||||
const restrictedFields =
|
||||
RESTRICTED_DATA_FIELDS[target as keyof typeof RESTRICTED_DATA_FIELDS] || []
|
||||
|
||||
if (vendor === 'arktype') {
|
||||
return sanitizeArktypeIssues(issues, restrictedFields)
|
||||
}
|
||||
|
||||
if (vendor === 'valibot') {
|
||||
return sanitizeValibotIssues(issues, restrictedFields)
|
||||
}
|
||||
|
||||
return issues
|
||||
}
|
||||
|
||||
function sanitizeArktypeIssues(
|
||||
issues: readonly StandardSchemaV1.Issue[],
|
||||
restrictedFields: string[]
|
||||
): readonly StandardSchemaV1.Issue[] {
|
||||
return issues.map((issue) => {
|
||||
if (
|
||||
issue &&
|
||||
typeof issue === 'object' &&
|
||||
'data' in issue &&
|
||||
typeof issue.data === 'object' &&
|
||||
issue.data !== null &&
|
||||
!Array.isArray(issue.data)
|
||||
) {
|
||||
const dataCopy = { ...(issue.data as Record<string, unknown>) }
|
||||
for (const field of restrictedFields) {
|
||||
delete dataCopy[field]
|
||||
}
|
||||
return { ...issue, data: dataCopy }
|
||||
}
|
||||
return issue
|
||||
}) as readonly StandardSchemaV1.Issue[]
|
||||
}
|
||||
|
||||
function sanitizeValibotIssues(
|
||||
issues: readonly StandardSchemaV1.Issue[],
|
||||
restrictedFields: string[]
|
||||
): readonly StandardSchemaV1.Issue[] {
|
||||
return issues.map((issue) => {
|
||||
if (issue && typeof issue === 'object' && 'path' in issue && Array.isArray(issue.path)) {
|
||||
for (const path of issue.path) {
|
||||
if (
|
||||
typeof path === 'object' &&
|
||||
'input' in path &&
|
||||
typeof path.input === 'object' &&
|
||||
path.input !== null &&
|
||||
!Array.isArray(path.input)
|
||||
) {
|
||||
for (const field of restrictedFields) {
|
||||
delete path.input[field]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return issue
|
||||
}) as readonly StandardSchemaV1.Issue[]
|
||||
}
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
restoreMocks: true,
|
||||
unstubEnvs: true,
|
||||
},
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -4,10 +4,11 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
plugins: [
|
||||
UnpluginTypia({
|
||||
tsconfig: './tsconfig.json',
|
||||
tsconfig: './tsconfig.build.json',
|
||||
}),
|
||||
],
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
# @hono/ua-blocker
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1309](https://github.com/honojs/middleware/pull/1309) [`47cb4c85693ebe77d3b8b55f6e1e59778f671a15`](https://github.com/honojs/middleware/commit/47cb4c85693ebe77d3b8b55f6e1e59778f671a15) Thanks [@github-actions](https://github.com/apps/github-actions)! - chore(ua-blocker): sync `robots.json` with upstream
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1298](https://github.com/honojs/middleware/pull/1298) [`18dec85b7833d1b3e80b5e1443f636f8c34adbc4`](https://github.com/honojs/middleware/commit/18dec85b7833d1b3e80b5e1443f636f8c34adbc4) Thanks [@github-actions](https://github.com/apps/github-actions)! - chore(ua-blocker): sync `robots.json` with upstream
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/ua-blocker",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.6",
|
||||
"description": "User agent-based blocker for Hono",
|
||||
"type": "module",
|
||||
"module": "dist/index.js",
|
||||
|
|
|
@ -251,6 +251,13 @@
|
|||
"frequency": "No information.",
|
||||
"description": "Used to train Gemini and Vertex AI generative APIs. Does not impact a site's inclusion or ranking in Google Search."
|
||||
},
|
||||
"GoogleAgent-Mariner": {
|
||||
"operator": "Unclear at this time.",
|
||||
"respect": "Unclear at this time.",
|
||||
"function": "AI Agents",
|
||||
"frequency": "Unclear at this time.",
|
||||
"description": "GoogleAgent-Mariner is an AI agent created by Google that can use a web browser. It can intelligently navigate and interact with websites to complete multi-step tasks on behalf of a human user. More info can be found at https://darkvisitors.com/agents/agents/googleagent-mariner"
|
||||
},
|
||||
"GoogleOther": {
|
||||
"description": "\"Used by various product teams for fetching publicly accessible content from sites. For example, it may be used for one-off crawls for internal research and development.\"",
|
||||
"frequency": "No information.",
|
||||
|
@ -524,6 +531,20 @@
|
|||
"operator": "[Sidetrade](https://www.sidetrade.com)",
|
||||
"respect": "Unclear at this time."
|
||||
},
|
||||
"SummalyBot": {
|
||||
"description": "AI input summarization.",
|
||||
"frequency": "No information.",
|
||||
"function": "Extracts data to provide summaries for user; additional usages unclear.",
|
||||
"operator": "Unclear at this time.",
|
||||
"respect": "Unclear at this time."
|
||||
},
|
||||
"Thinkbot": {
|
||||
"operator": "[Thinkbot](https://www.thinkbot.agency)",
|
||||
"respect": "No",
|
||||
"function": "Insights on AI integration and automation.",
|
||||
"frequency": "Unclear at this time.",
|
||||
"description": "Collects data for analysis on AI usage and automation."
|
||||
},
|
||||
"TikTokSpider": {
|
||||
"operator": "ByteDance",
|
||||
"respect": "Unclear at this time.",
|
||||
|
|
|
@ -35,6 +35,7 @@ User-agent: FriendlyCrawler
|
|||
User-agent: Gemini-Deep-Research
|
||||
User-agent: Google-CloudVertexBot
|
||||
User-agent: Google-Extended
|
||||
User-agent: GoogleAgent-Mariner
|
||||
User-agent: GoogleOther
|
||||
User-agent: GoogleOther-Image
|
||||
User-agent: GoogleOther-Video
|
||||
|
@ -74,6 +75,8 @@ User-agent: Scrapy
|
|||
User-agent: SemrushBot-OCOB
|
||||
User-agent: SemrushBot-SWA
|
||||
User-agent: Sidetrade indexer bot
|
||||
User-agent: SummalyBot
|
||||
User-agent: Thinkbot
|
||||
User-agent: TikTokSpider
|
||||
User-agent: Timpibot
|
||||
User-agent: VelenPublicWebCrawler
|
||||
|
@ -85,7 +88,7 @@ User-agent: YandexAdditionalBot
|
|||
User-agent: YouBot
|
||||
Disallow: /
|
||||
`;
|
||||
export const ALL_BOTS = ["AI2Bot", "Ai2Bot-Dolma", "aiHitBot", "Amazonbot", "Andibot", "anthropic-ai", "Applebot", "Applebot-Extended", "Awario", "bedrockbot", "Brightbot 1.0", "Bytespider", "CCBot", "ChatGPT-User", "Claude-SearchBot", "Claude-User", "Claude-Web", "ClaudeBot", "cohere-ai", "cohere-training-data-crawler", "Cotoyogi", "Crawlspace", "Datenbank Crawler", "Devin", "Diffbot", "DuckAssistBot", "Echobot Bot", "EchoboxBot", "FacebookBot", "facebookexternalhit", "Factset_spyderbot", "FirecrawlAgent", "FriendlyCrawler", "Gemini-Deep-Research", "Google-CloudVertexBot", "Google-Extended", "GoogleOther", "GoogleOther-Image", "GoogleOther-Video", "GPTBot", "iaskspider/2.0", "ICC-Crawler", "ImagesiftBot", "img2dataset", "ISSCyberRiskCrawler", "Kangaroo Bot", "meta-externalagent", "Meta-ExternalAgent", "meta-externalfetcher", "Meta-ExternalFetcher", "MistralAI-User", "MistralAI-User/1.0", "MyCentralAIScraperBot", "netEstate Imprint Crawler", "NovaAct", "OAI-SearchBot", "omgili", "omgilibot", "Operator", "PanguBot", "Panscient", "panscient.com", "Perplexity-User", "PerplexityBot", "PetalBot", "PhindBot", "Poseidon Research Crawler", "QualifiedBot", "QuillBot", "quillbot.com", "SBIntuitionsBot", "Scrapy", "SemrushBot-OCOB", "SemrushBot-SWA", "Sidetrade indexer bot", "TikTokSpider", "Timpibot", "VelenPublicWebCrawler", "WARDBot", "Webzio-Extended", "wpbot", "YandexAdditional", "YandexAdditionalBot", "YouBot"];
|
||||
export const NON_RESPECTING_BOTS = ["Andibot", "anthropic-ai", "Applebot", "Awario", "Brightbot 1.0", "Bytespider", "Claude-Web", "cohere-ai", "cohere-training-data-crawler", "Datenbank Crawler", "Devin", "Diffbot", "DuckAssistBot", "Echobot Bot", "EchoboxBot", "facebookexternalhit", "Factset_spyderbot", "Gemini-Deep-Research", "iaskspider/2.0", "img2dataset", "ISSCyberRiskCrawler", "Kangaroo Bot", "Meta-ExternalAgent", "meta-externalfetcher", "Meta-ExternalFetcher", "MistralAI-User", "MyCentralAIScraperBot", "netEstate Imprint Crawler", "NovaAct", "Operator", "PanguBot", "Perplexity-User", "PhindBot", "Poseidon Research Crawler", "QualifiedBot", "QuillBot", "quillbot.com", "Scrapy", "Sidetrade indexer bot", "TikTokSpider", "Timpibot", "WARDBot", "Webzio-Extended", "wpbot"];
|
||||
export const ALL_BOTS_REGEX = /(AI2BOT|AI2BOT-DOLMA|AIHITBOT|AMAZONBOT|ANDIBOT|ANTHROPIC-AI|APPLEBOT|APPLEBOT-EXTENDED|AWARIO|BEDROCKBOT|BRIGHTBOT 1.0|BYTESPIDER|CCBOT|CHATGPT-USER|CLAUDE-SEARCHBOT|CLAUDE-USER|CLAUDE-WEB|CLAUDEBOT|COHERE-AI|COHERE-TRAINING-DATA-CRAWLER|COTOYOGI|CRAWLSPACE|DATENBANK CRAWLER|DEVIN|DIFFBOT|DUCKASSISTBOT|ECHOBOT BOT|ECHOBOXBOT|FACEBOOKBOT|FACEBOOKEXTERNALHIT|FACTSET_SPYDERBOT|FIRECRAWLAGENT|FRIENDLYCRAWLER|GEMINI-DEEP-RESEARCH|GOOGLE-CLOUDVERTEXBOT|GOOGLE-EXTENDED|GOOGLEOTHER|GOOGLEOTHER-IMAGE|GOOGLEOTHER-VIDEO|GPTBOT|IASKSPIDER\/2.0|ICC-CRAWLER|IMAGESIFTBOT|IMG2DATASET|ISSCYBERRISKCRAWLER|KANGAROO BOT|META-EXTERNALAGENT|META-EXTERNALAGENT|META-EXTERNALFETCHER|META-EXTERNALFETCHER|MISTRALAI-USER|MISTRALAI-USER\/1.0|MYCENTRALAISCRAPERBOT|NETESTATE IMPRINT CRAWLER|NOVAACT|OAI-SEARCHBOT|OMGILI|OMGILIBOT|OPERATOR|PANGUBOT|PANSCIENT|PANSCIENT.COM|PERPLEXITY-USER|PERPLEXITYBOT|PETALBOT|PHINDBOT|POSEIDON RESEARCH CRAWLER|QUALIFIEDBOT|QUILLBOT|QUILLBOT.COM|SBINTUITIONSBOT|SCRAPY|SEMRUSHBOT-OCOB|SEMRUSHBOT-SWA|SIDETRADE INDEXER BOT|TIKTOKSPIDER|TIMPIBOT|VELENPUBLICWEBCRAWLER|WARDBOT|WEBZIO-EXTENDED|WPBOT|YANDEXADDITIONAL|YANDEXADDITIONALBOT|YOUBOT)/;
|
||||
export const NON_RESPECTING_BOTS_REGEX = /(ANDIBOT|ANTHROPIC-AI|APPLEBOT|AWARIO|BRIGHTBOT 1.0|BYTESPIDER|CLAUDE-WEB|COHERE-AI|COHERE-TRAINING-DATA-CRAWLER|DATENBANK CRAWLER|DEVIN|DIFFBOT|DUCKASSISTBOT|ECHOBOT BOT|ECHOBOXBOT|FACEBOOKEXTERNALHIT|FACTSET_SPYDERBOT|GEMINI-DEEP-RESEARCH|IASKSPIDER\/2.0|IMG2DATASET|ISSCYBERRISKCRAWLER|KANGAROO BOT|META-EXTERNALAGENT|META-EXTERNALFETCHER|META-EXTERNALFETCHER|MISTRALAI-USER|MYCENTRALAISCRAPERBOT|NETESTATE IMPRINT CRAWLER|NOVAACT|OPERATOR|PANGUBOT|PERPLEXITY-USER|PHINDBOT|POSEIDON RESEARCH CRAWLER|QUALIFIEDBOT|QUILLBOT|QUILLBOT.COM|SCRAPY|SIDETRADE INDEXER BOT|TIKTOKSPIDER|TIMPIBOT|WARDBOT|WEBZIO-EXTENDED|WPBOT)/;
|
||||
export const ALL_BOTS = ["AI2Bot", "Ai2Bot-Dolma", "aiHitBot", "Amazonbot", "Andibot", "anthropic-ai", "Applebot", "Applebot-Extended", "Awario", "bedrockbot", "Brightbot 1.0", "Bytespider", "CCBot", "ChatGPT-User", "Claude-SearchBot", "Claude-User", "Claude-Web", "ClaudeBot", "cohere-ai", "cohere-training-data-crawler", "Cotoyogi", "Crawlspace", "Datenbank Crawler", "Devin", "Diffbot", "DuckAssistBot", "Echobot Bot", "EchoboxBot", "FacebookBot", "facebookexternalhit", "Factset_spyderbot", "FirecrawlAgent", "FriendlyCrawler", "Gemini-Deep-Research", "Google-CloudVertexBot", "Google-Extended", "GoogleAgent-Mariner", "GoogleOther", "GoogleOther-Image", "GoogleOther-Video", "GPTBot", "iaskspider/2.0", "ICC-Crawler", "ImagesiftBot", "img2dataset", "ISSCyberRiskCrawler", "Kangaroo Bot", "meta-externalagent", "Meta-ExternalAgent", "meta-externalfetcher", "Meta-ExternalFetcher", "MistralAI-User", "MistralAI-User/1.0", "MyCentralAIScraperBot", "netEstate Imprint Crawler", "NovaAct", "OAI-SearchBot", "omgili", "omgilibot", "Operator", "PanguBot", "Panscient", "panscient.com", "Perplexity-User", "PerplexityBot", "PetalBot", "PhindBot", "Poseidon Research Crawler", "QualifiedBot", "QuillBot", "quillbot.com", "SBIntuitionsBot", "Scrapy", "SemrushBot-OCOB", "SemrushBot-SWA", "Sidetrade indexer bot", "SummalyBot", "Thinkbot", "TikTokSpider", "Timpibot", "VelenPublicWebCrawler", "WARDBot", "Webzio-Extended", "wpbot", "YandexAdditional", "YandexAdditionalBot", "YouBot"];
|
||||
export const NON_RESPECTING_BOTS = ["Andibot", "anthropic-ai", "Applebot", "Awario", "Brightbot 1.0", "Bytespider", "Claude-Web", "cohere-ai", "cohere-training-data-crawler", "Datenbank Crawler", "Devin", "Diffbot", "DuckAssistBot", "Echobot Bot", "EchoboxBot", "facebookexternalhit", "Factset_spyderbot", "Gemini-Deep-Research", "GoogleAgent-Mariner", "iaskspider/2.0", "img2dataset", "ISSCyberRiskCrawler", "Kangaroo Bot", "Meta-ExternalAgent", "meta-externalfetcher", "Meta-ExternalFetcher", "MistralAI-User", "MyCentralAIScraperBot", "netEstate Imprint Crawler", "NovaAct", "Operator", "PanguBot", "Perplexity-User", "PhindBot", "Poseidon Research Crawler", "QualifiedBot", "QuillBot", "quillbot.com", "Scrapy", "Sidetrade indexer bot", "SummalyBot", "Thinkbot", "TikTokSpider", "Timpibot", "WARDBot", "Webzio-Extended", "wpbot"];
|
||||
export const ALL_BOTS_REGEX = /(AI2BOT|AI2BOT-DOLMA|AIHITBOT|AMAZONBOT|ANDIBOT|ANTHROPIC-AI|APPLEBOT|APPLEBOT-EXTENDED|AWARIO|BEDROCKBOT|BRIGHTBOT 1.0|BYTESPIDER|CCBOT|CHATGPT-USER|CLAUDE-SEARCHBOT|CLAUDE-USER|CLAUDE-WEB|CLAUDEBOT|COHERE-AI|COHERE-TRAINING-DATA-CRAWLER|COTOYOGI|CRAWLSPACE|DATENBANK CRAWLER|DEVIN|DIFFBOT|DUCKASSISTBOT|ECHOBOT BOT|ECHOBOXBOT|FACEBOOKBOT|FACEBOOKEXTERNALHIT|FACTSET_SPYDERBOT|FIRECRAWLAGENT|FRIENDLYCRAWLER|GEMINI-DEEP-RESEARCH|GOOGLE-CLOUDVERTEXBOT|GOOGLE-EXTENDED|GOOGLEAGENT-MARINER|GOOGLEOTHER|GOOGLEOTHER-IMAGE|GOOGLEOTHER-VIDEO|GPTBOT|IASKSPIDER\/2.0|ICC-CRAWLER|IMAGESIFTBOT|IMG2DATASET|ISSCYBERRISKCRAWLER|KANGAROO BOT|META-EXTERNALAGENT|META-EXTERNALAGENT|META-EXTERNALFETCHER|META-EXTERNALFETCHER|MISTRALAI-USER|MISTRALAI-USER\/1.0|MYCENTRALAISCRAPERBOT|NETESTATE IMPRINT CRAWLER|NOVAACT|OAI-SEARCHBOT|OMGILI|OMGILIBOT|OPERATOR|PANGUBOT|PANSCIENT|PANSCIENT.COM|PERPLEXITY-USER|PERPLEXITYBOT|PETALBOT|PHINDBOT|POSEIDON RESEARCH CRAWLER|QUALIFIEDBOT|QUILLBOT|QUILLBOT.COM|SBINTUITIONSBOT|SCRAPY|SEMRUSHBOT-OCOB|SEMRUSHBOT-SWA|SIDETRADE INDEXER BOT|SUMMALYBOT|THINKBOT|TIKTOKSPIDER|TIMPIBOT|VELENPUBLICWEBCRAWLER|WARDBOT|WEBZIO-EXTENDED|WPBOT|YANDEXADDITIONAL|YANDEXADDITIONALBOT|YOUBOT)/;
|
||||
export const NON_RESPECTING_BOTS_REGEX = /(ANDIBOT|ANTHROPIC-AI|APPLEBOT|AWARIO|BRIGHTBOT 1.0|BYTESPIDER|CLAUDE-WEB|COHERE-AI|COHERE-TRAINING-DATA-CRAWLER|DATENBANK CRAWLER|DEVIN|DIFFBOT|DUCKASSISTBOT|ECHOBOT BOT|ECHOBOXBOT|FACEBOOKEXTERNALHIT|FACTSET_SPYDERBOT|GEMINI-DEEP-RESEARCH|GOOGLEAGENT-MARINER|IASKSPIDER\/2.0|IMG2DATASET|ISSCYBERRISKCRAWLER|KANGAROO BOT|META-EXTERNALAGENT|META-EXTERNALFETCHER|META-EXTERNALFETCHER|MISTRALAI-USER|MYCENTRALAISCRAPERBOT|NETESTATE IMPRINT CRAWLER|NOVAACT|OPERATOR|PANGUBOT|PERPLEXITY-USER|PHINDBOT|POSEIDON RESEARCH CRAWLER|QUALIFIEDBOT|QUILLBOT|QUILLBOT.COM|SCRAPY|SIDETRADE INDEXER BOT|SUMMALYBOT|THINKBOT|TIKTOKSPIDER|TIMPIBOT|WARDBOT|WEBZIO-EXTENDED|WPBOT)/;
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
# @hono/zod-openapi
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1320](https://github.com/honojs/middleware/pull/1320) [`e835cf6183fb4717cfdbe156d9b3d423625a0e15`](https://github.com/honojs/middleware/commit/e835cf6183fb4717cfdbe156d9b3d423625a0e15) Thanks [@yusukebe](https://github.com/yusukebe)! - fix: correct importing `zod`
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c6a16ab7aa8fba2403d4294e7673f96796020c65`](https://github.com/honojs/middleware/commit/c6a16ab7aa8fba2403d4294e7673f96796020c65)]:
|
||||
- @hono/zod-validator@0.7.2
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#1223](https://github.com/honojs/middleware/pull/1223) [`845e336ff41d29fa74ec3cf84afc16f5ac0c2c77`](https://github.com/honojs/middleware/commit/845e336ff41d29fa74ec3cf84afc16f5ac0c2c77) Thanks [@yusukebe](https://github.com/yusukebe)! - feat: support Zod v4
|
||||
|
||||
Zod OpenAPI has been migrated the Zod version from v3 to v4. As a result, the `zod` in `peerDependencies` has been updated to 4.0.0 or higher.
|
||||
|
||||
Although this is not a breaking change, it is a major change, so it is considered a major version upgrade.
|
||||
|
||||
## 0.19.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9f6278f51c846a171a9baa6335fb8fbd9b42cb1c`](https://github.com/honojs/middleware/commit/9f6278f51c846a171a9baa6335fb8fbd9b42cb1c), [`9f6278f51c846a171a9baa6335fb8fbd9b42cb1c`](https://github.com/honojs/middleware/commit/9f6278f51c846a171a9baa6335fb8fbd9b42cb1c)]:
|
||||
- @hono/zod-validator@0.7.1
|
||||
|
||||
## 0.19.9
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/zod-openapi",
|
||||
"version": "0.19.9",
|
||||
"version": "1.0.2",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/zod-openapi",
|
||||
"version": "0.19.9",
|
||||
"version": "1.0.2",
|
||||
"description": "A wrapper class of Hono which supports OpenAPI.",
|
||||
"type": "module",
|
||||
"module": "dist/index.js",
|
||||
|
@ -41,7 +41,7 @@
|
|||
"homepage": "https://github.com/honojs/middleware",
|
||||
"peerDependencies": {
|
||||
"hono": ">=4.3.6",
|
||||
"zod": ">=3.0.0"
|
||||
"zod": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.17.4",
|
||||
|
@ -51,10 +51,10 @@
|
|||
"typescript": "^5.8.2",
|
||||
"vitest": "^3.2.4",
|
||||
"yaml": "^2.4.3",
|
||||
"zod": "^3.22.1"
|
||||
"zod": "^4.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@asteasolutions/zod-to-openapi": "^7.3.0",
|
||||
"@asteasolutions/zod-to-openapi": "^8.0.0",
|
||||
"@hono/zod-validator": "workspace:^",
|
||||
"openapi3-ts": "^4.5.0"
|
||||
},
|
||||
|
|
|
@ -240,7 +240,7 @@ describe('coerce', () => {
|
|||
type Actual = ExtractSchema<typeof routes>['/api/users/:id']['$get']['input']
|
||||
type Expected = {
|
||||
param: {
|
||||
id: number
|
||||
id: unknown
|
||||
}
|
||||
}
|
||||
type verify = Expect<Equal<Expected, Actual>>
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
OpenApiGeneratorV3,
|
||||
OpenApiGeneratorV31,
|
||||
extendZodWithOpenApi,
|
||||
getOpenApiMetadata,
|
||||
} from '@asteasolutions/zod-to-openapi'
|
||||
import { zValidator } from '@hono/zod-validator'
|
||||
import { Hono } from 'hono'
|
||||
|
@ -38,8 +39,8 @@ import type { JSONParsed, JSONValue, RemoveBlankRecord, SimplifyDeepArray } from
|
|||
import { mergePath } from 'hono/utils/url'
|
||||
import type { OpenAPIObject } from 'openapi3-ts/oas30'
|
||||
import type { OpenAPIObject as OpenAPIV31bject } from 'openapi3-ts/oas31'
|
||||
import type { ZodError, ZodSchema } from 'zod'
|
||||
import { ZodType, z } from 'zod'
|
||||
import type { ZodError } from 'zod'
|
||||
|
||||
type MaybePromise<T> = Promise<T> | T
|
||||
|
||||
|
@ -128,7 +129,7 @@ type InputTypeJson<R extends RouteConfig> = R['request'] extends RequestTypes
|
|||
? {}
|
||||
: R['request']['body']['content'][keyof R['request']['body']['content']] extends Record<
|
||||
'schema',
|
||||
ZodSchema<any>
|
||||
ZodType<any>
|
||||
>
|
||||
? {
|
||||
in: {
|
||||
|
@ -154,7 +155,7 @@ type InputTypeForm<R extends RouteConfig> = R['request'] extends RequestTypes
|
|||
? {}
|
||||
: R['request']['body']['content'][keyof R['request']['body']['content']] extends Record<
|
||||
'schema',
|
||||
ZodSchema<any>
|
||||
ZodType<any>
|
||||
>
|
||||
? {
|
||||
in: {
|
||||
|
@ -181,7 +182,7 @@ type InputTypeCookie<R extends RouteConfig> = InputTypeBase<R, 'cookies', 'cooki
|
|||
type ExtractContent<T> = T extends {
|
||||
[K in keyof T]: infer A
|
||||
}
|
||||
? A extends Record<'schema', ZodSchema>
|
||||
? A extends Record<'schema', ZodType>
|
||||
? z.infer<A['schema']>
|
||||
: never
|
||||
: never
|
||||
|
@ -659,11 +660,14 @@ export class OpenAPIHono<
|
|||
}
|
||||
|
||||
case 'schema':
|
||||
return this.openAPIRegistry.register(def.schema._def.openapi._internal.refId, def.schema)
|
||||
return this.openAPIRegistry.register(
|
||||
getOpenApiMetadata(def.schema)._internal?.refId,
|
||||
def.schema
|
||||
)
|
||||
|
||||
case 'parameter':
|
||||
return this.openAPIRegistry.registerParameter(
|
||||
def.schema._def.openapi._internal.refId,
|
||||
getOpenApiMetadata(def.schema)._internal?.refId,
|
||||
def.schema
|
||||
)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
typecheck: {
|
||||
tsconfig: './tsconfig.json',
|
||||
enabled: true,
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
# @hono/zod-validator
|
||||
|
||||
## 0.7.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1315](https://github.com/honojs/middleware/pull/1315) [`c6a16ab7aa8fba2403d4294e7673f96796020c65`](https://github.com/honojs/middleware/commit/c6a16ab7aa8fba2403d4294e7673f96796020c65) Thanks [@yusukebe](https://github.com/yusukebe)! - fix: support transform
|
||||
|
||||
## 0.7.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1302](https://github.com/honojs/middleware/pull/1302) [`9f6278f51c846a171a9baa6335fb8fbd9b42cb1c`](https://github.com/honojs/middleware/commit/9f6278f51c846a171a9baa6335fb8fbd9b42cb1c) Thanks [@kiki-kanri](https://github.com/kiki-kanri)! - correctly set the zod version to follow the official website doc
|
||||
|
||||
- [#1302](https://github.com/honojs/middleware/pull/1302) [`9f6278f51c846a171a9baa6335fb8fbd9b42cb1c`](https://github.com/honojs/middleware/commit/9f6278f51c846a171a9baa6335fb8fbd9b42cb1c) Thanks [@kiki-kanri](https://github.com/kiki-kanri)! - upgrade zod to v4 and import style to be more tree-shakeable in README.md
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
|
|
@ -7,7 +7,7 @@ The validator middleware using [Zod](https://zod.dev) for [Hono](https://honojs.
|
|||
## Usage
|
||||
|
||||
```ts
|
||||
import { z } from 'zod'
|
||||
import * as z from 'zod'
|
||||
import { zValidator } from '@hono/zod-validator'
|
||||
|
||||
const schema = z.object({
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/zod-validator",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.2",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/zod-validator",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.2",
|
||||
"description": "Validator middleware using Zod",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
@ -42,7 +42,7 @@
|
|||
"homepage": "https://github.com/honojs/middleware",
|
||||
"peerDependencies": {
|
||||
"hono": ">=3.9.0",
|
||||
"zod": "^3.25.0"
|
||||
"zod": "^3.25.0 || ^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.17.4",
|
||||
|
@ -51,6 +51,6 @@
|
|||
"tsup": "^8.4.0",
|
||||
"typescript": "^5.8.2",
|
||||
"vitest": "^3.2.4",
|
||||
"zod": "~3.25.6"
|
||||
"zod": "^4.0.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import type { Context, Env, Input, MiddlewareHandler, TypedResponse, ValidationTargets } from 'hono'
|
||||
import { validator } from 'hono/validator'
|
||||
import type * as v3 from 'zod'
|
||||
import type * as v3 from 'zod/v3'
|
||||
import type { ZodSafeParseResult as v4ZodSafeParseResult } from 'zod/v4'
|
||||
import type * as v4 from 'zod/v4/core'
|
||||
|
||||
|
@ -73,7 +73,7 @@ export const zValidator = <
|
|||
if ((target === 'header' && '_def' in schema) || (target === 'header' && '_zod' in schema)) {
|
||||
// create an object that maps lowercase schema keys to lowercase
|
||||
// @ts-expect-error the schema is a Zod Schema
|
||||
const schemaKeys = Object.keys(schema.shape)
|
||||
const schemaKeys = Object.keys('in' in schema ? schema.in.shape : schema.shape)
|
||||
const caseInsensitiveKeymap = Object.fromEntries(
|
||||
schemaKeys.map((key) => [key.toLowerCase(), key])
|
||||
)
|
||||
|
|
|
@ -464,3 +464,39 @@ describe('With options + validationFunction', () => {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Transform', () => {
|
||||
const schema = z
|
||||
.object({
|
||||
'user-agent': z.string(),
|
||||
})
|
||||
.transform((data) => ({
|
||||
userAgent: data['user-agent'],
|
||||
}))
|
||||
|
||||
const zValidatorHeader = zValidator('header', schema)
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.post('/test', zValidatorHeader, async (c) => {
|
||||
const header = c.req.valid('header')
|
||||
return c.json(header)
|
||||
})
|
||||
|
||||
it('Should return 400 response', async () => {
|
||||
const res = await app.request('/test', {
|
||||
method: 'POST',
|
||||
})
|
||||
expect(res.status).toBe(400)
|
||||
})
|
||||
|
||||
it('Should return 200 response', async () => {
|
||||
const res = await app.request('/test', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'user-agent': 'my-agent',
|
||||
},
|
||||
})
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -3,5 +3,6 @@ import { defineProject } from 'vitest/config'
|
|||
export default defineProject({
|
||||
test: {
|
||||
globals: true,
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import { defineConfig, coverageConfigDefaults } from 'vitest/config'
|
||||
import { defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
coverage: {
|
||||
exclude: ['**/dist/**', ...coverageConfigDefaults.exclude],
|
||||
// TODO: use v8 - https://github.com/vitest-dev/vitest/issues/5783
|
||||
provider: 'istanbul',
|
||||
thresholds: {
|
||||
autoUpdate: true,
|
||||
},
|
||||
},
|
||||
projects: ['packages/*', '!packages/bun-transpiler'],
|
||||
projects: ['packages/*/vitest.config.ts'],
|
||||
},
|
||||
})
|
||||
|
|
90
yarn.lock
90
yarn.lock
|
@ -99,14 +99,14 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@asteasolutions/zod-to-openapi@npm:^7.3.0":
|
||||
version: 7.3.0
|
||||
resolution: "@asteasolutions/zod-to-openapi@npm:7.3.0"
|
||||
"@asteasolutions/zod-to-openapi@npm:^8.0.0":
|
||||
version: 8.0.0
|
||||
resolution: "@asteasolutions/zod-to-openapi@npm:8.0.0"
|
||||
dependencies:
|
||||
openapi3-ts: "npm:^4.1.2"
|
||||
peerDependencies:
|
||||
zod: ^3.20.2
|
||||
checksum: 10c0/f0a68a89929cdeaa3e21d2027489689f982824d676a9332c680e119f60881dd39b571324b24ad4837fda49bf6fe7c3e2af2199268b281bf1aec923d7a7cbfc40
|
||||
zod: ^4.0.0
|
||||
checksum: 10c0/b522d074832fb137dca724c8bd4bb134c7b4d4cad12c247ed3c864f993923b3475fc06580e6e1cbc4fd8641cd361679bbe1dd87c9bb42e142bc056d96d59fbc8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -694,24 +694,25 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@clerk/backend@npm:^2.2.0":
|
||||
version: 2.2.0
|
||||
resolution: "@clerk/backend@npm:2.2.0"
|
||||
"@clerk/backend@npm:^2.4.1":
|
||||
version: 2.4.1
|
||||
resolution: "@clerk/backend@npm:2.4.1"
|
||||
dependencies:
|
||||
"@clerk/shared": "npm:^3.9.8"
|
||||
"@clerk/types": "npm:^4.61.0"
|
||||
"@clerk/shared": "npm:^3.11.0"
|
||||
"@clerk/types": "npm:^4.64.0"
|
||||
cookie: "npm:1.0.2"
|
||||
snakecase-keys: "npm:8.0.1"
|
||||
standardwebhooks: "npm:^1.0.0"
|
||||
tslib: "npm:2.8.1"
|
||||
checksum: 10c0/deaf688e085ec2a28b8e98453b3ce2c293f19adf440acd8b295c71c7d765ad1c98841e8a5e9ee5d254e91d18884533cc11f6880c34ec99f4d3b57b330b47fe70
|
||||
checksum: 10c0/1b6324a44c908c3623e60a2b25f814074e0beab78bf2dfc3ff2401215b5c8e5d8757a1df33af537f6a0a4540ac933d0583dab5aaba5664c0a719ce5d70b4cea0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@clerk/shared@npm:^3.9.8":
|
||||
version: 3.9.8
|
||||
resolution: "@clerk/shared@npm:3.9.8"
|
||||
"@clerk/shared@npm:^3.11.0":
|
||||
version: 3.11.0
|
||||
resolution: "@clerk/shared@npm:3.11.0"
|
||||
dependencies:
|
||||
"@clerk/types": "npm:^4.61.0"
|
||||
"@clerk/types": "npm:^4.64.0"
|
||||
dequal: "npm:2.0.3"
|
||||
glob-to-regexp: "npm:0.4.1"
|
||||
js-cookie: "npm:3.0.5"
|
||||
|
@ -725,16 +726,16 @@ __metadata:
|
|||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
checksum: 10c0/64f21c38900dd41229c94920ce7fa52dba67b1bb3fdca4468d99a7bca450b1f1d1cfebecd1867657554bf915b26c24cb46d0962746ec9b92dad6d435571f05d2
|
||||
checksum: 10c0/f5b6099f506bfdbf8a03fb615597500adddab7350d2d1e39ee0ff0f5775d10b712e6fcbf8a551ea6c17d96d242a59fccaed4e536122b8306137a942582ecf2b7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@clerk/types@npm:^4.61.0":
|
||||
version: 4.61.0
|
||||
resolution: "@clerk/types@npm:4.61.0"
|
||||
"@clerk/types@npm:^4.64.0":
|
||||
version: 4.64.0
|
||||
resolution: "@clerk/types@npm:4.64.0"
|
||||
dependencies:
|
||||
csstype: "npm:3.1.3"
|
||||
checksum: 10c0/4f05bbdc6562c3e8f114ccfe378bfb7c622ce49338336ec962c7bf7f69bdd7eab98484c69e43dd69ffc8f7d2fea43609c1f8a37a650b475361cf8dea541b9ee3
|
||||
checksum: 10c0/83ad0a436deedfe2148f99af905dd54f945acb04a2eb5a822d119e071abc3d4123b72d2132276dac5f0c0c4dba5bd6b2e56d4b3789721919b1badde760288ee0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -2171,8 +2172,8 @@ __metadata:
|
|||
resolution: "@hono/clerk-auth@workspace:packages/clerk-auth"
|
||||
dependencies:
|
||||
"@arethetypeswrong/cli": "npm:^0.17.4"
|
||||
"@clerk/backend": "npm:^2.2.0"
|
||||
"@clerk/types": "npm:^4.61.0"
|
||||
"@clerk/backend": "npm:^2.4.1"
|
||||
"@clerk/types": "npm:^4.64.0"
|
||||
"@types/react": "npm:^18"
|
||||
hono: "npm:^4.8.4"
|
||||
publint: "npm:^0.3.9"
|
||||
|
@ -2266,7 +2267,6 @@ __metadata:
|
|||
eslint-import-resolver-typescript: "npm:^4.2.2"
|
||||
eslint-plugin-import-x: "npm:^4.1.1"
|
||||
eslint-plugin-n: "npm:^17.10.2"
|
||||
hono: "npm:^4.8.4"
|
||||
typescript-eslint: "npm:^8.27.0"
|
||||
peerDependencies:
|
||||
eslint: ^9.0.0
|
||||
|
@ -2734,7 +2734,7 @@ __metadata:
|
|||
resolution: "@hono/zod-openapi@workspace:packages/zod-openapi"
|
||||
dependencies:
|
||||
"@arethetypeswrong/cli": "npm:^0.17.4"
|
||||
"@asteasolutions/zod-to-openapi": "npm:^7.3.0"
|
||||
"@asteasolutions/zod-to-openapi": "npm:^8.0.0"
|
||||
"@hono/zod-validator": "workspace:^"
|
||||
hono: "npm:^4.8.4"
|
||||
openapi3-ts: "npm:^4.5.0"
|
||||
|
@ -2743,10 +2743,10 @@ __metadata:
|
|||
typescript: "npm:^5.8.2"
|
||||
vitest: "npm:^3.2.4"
|
||||
yaml: "npm:^2.4.3"
|
||||
zod: "npm:^3.22.1"
|
||||
zod: "npm:^4.0.5"
|
||||
peerDependencies:
|
||||
hono: ">=4.3.6"
|
||||
zod: ">=3.0.0"
|
||||
zod: ^4.0.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
|
@ -2760,10 +2760,10 @@ __metadata:
|
|||
tsup: "npm:^8.4.0"
|
||||
typescript: "npm:^5.8.2"
|
||||
vitest: "npm:^3.2.4"
|
||||
zod: "npm:~3.25.6"
|
||||
zod: "npm:^4.0.5"
|
||||
peerDependencies:
|
||||
hono: ">=3.9.0"
|
||||
zod: ^3.25.0
|
||||
zod: ^3.25.0 || ^4.0.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
|
@ -4410,6 +4410,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@stablelib/base64@npm:^1.0.0":
|
||||
version: 1.0.1
|
||||
resolution: "@stablelib/base64@npm:1.0.1"
|
||||
checksum: 10c0/6330720f021819d19cecfe274111b79a256caa81df478d6b0ae7effc8842b96915b6aeed85926ff05b4d48ec1fc78ad043d928b730ee4e6cc6e8cba6aa097bed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standard-schema/spec@npm:1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@standard-schema/spec@npm:1.0.0"
|
||||
|
@ -8380,6 +8387,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-sha256@npm:^1.3.0":
|
||||
version: 1.3.0
|
||||
resolution: "fast-sha256@npm:1.3.0"
|
||||
checksum: 10c0/87f9e4baa7639576cf60a2b6235c9f436e1a1c52323abbd8a705b5bea8355500acf176f2aed0c14f2ecd6d6007e26151461bab2f27b8953bcca8d9d6b76a86e4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-uri@npm:^3.0.1":
|
||||
version: 3.0.6
|
||||
resolution: "fast-uri@npm:3.0.6"
|
||||
|
@ -14505,6 +14519,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"standardwebhooks@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "standardwebhooks@npm:1.0.0"
|
||||
dependencies:
|
||||
"@stablelib/base64": "npm:^1.0.0"
|
||||
fast-sha256: "npm:^1.3.0"
|
||||
checksum: 10c0/aee097d0f3c05172c19b80df1ed9596a2ce92f8956957650d0bbe47c2ca6d36515796b51d523333cb4a48c889b2ab130d789e7879e14975c4381bc7a61274327
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"statuses@npm:2.0.1, statuses@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "statuses@npm:2.0.1"
|
||||
|
@ -16806,7 +16830,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zod@npm:^3.20.2, zod@npm:^3.22.1, zod@npm:^3.22.3":
|
||||
"zod@npm:^3.20.2, zod@npm:^3.22.3":
|
||||
version: 3.24.2
|
||||
resolution: "zod@npm:3.24.2"
|
||||
checksum: 10c0/c638c7220150847f13ad90635b3e7d0321b36cce36f3fc6050ed960689594c949c326dfe2c6fa87c14b126ee5d370ccdebd6efb304f41ef5557a4aaca2824565
|
||||
|
@ -16841,10 +16865,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zod@npm:~3.25.6":
|
||||
version: 3.25.36
|
||||
resolution: "zod@npm:3.25.36"
|
||||
checksum: 10c0/9ad8ca759d1a5d19c86d6e49a1bda817b3c0566ea0a8726d45994b9fcaac8d569db45a65218a7b4067ca18b07c5fc636a587a94cd05f76793174ace8b81742e3
|
||||
"zod@npm:^4.0.5":
|
||||
version: 4.0.5
|
||||
resolution: "zod@npm:4.0.5"
|
||||
checksum: 10c0/59449d731ca63849b6bcb14300aa6e2f042d440b3ed294b45c248519aec78780f85a5d1939a62c2ce82e9dc60afca77c8005e0a98d7517b0c2586d6c76940424
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Loading…
Reference in New Issue