From 7a401b0850d60e3fc59c80cfe69034fd72d257c1 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Wed, 25 Dec 2024 18:08:43 +0900 Subject: [PATCH] chore: use the latest eslint and `@hono/eslint-config` (#904) * chore: use the latest eslint and `@hono/eslint-config` * update codes --- .eslintignore | 1 - .eslintrc.js | 3 - eslint.config.mjs | 8 + package.json | 4 +- packages/ajv-validator/src/index.ts | 35 ++-- packages/ajv-validator/test/index.test.ts | 140 ++++++------- packages/arktype-validator/src/index.ts | 3 +- packages/auth-js/src/client.ts | 5 +- packages/auth-js/src/index.ts | 18 +- packages/auth-js/src/react.tsx | 42 ++-- packages/auth-js/test/index.test.ts | 2 +- packages/casbin/src/helper/jwt.ts | 10 +- packages/casbin/src/index.ts | 2 +- packages/casbin/test/index.test.ts | 8 +- packages/class-validator/src/index.ts | 8 +- packages/class-validator/test/index.test.ts | 9 +- packages/clerk-auth/src/index.ts | 3 +- packages/cloudflare-access/src/index.test.ts | 194 +++++++++-------- packages/cloudflare-access/src/index.ts | 51 +++-- packages/conform-validator/src/index.ts | 2 +- .../conform-validator/test/common.test.ts | 2 +- packages/conform-validator/test/hook.test.ts | 6 +- .../conform-validator/test/valibot.test.ts | 8 +- packages/conform-validator/test/yup.test.ts | 8 +- packages/conform-validator/test/zod.test.ts | 8 +- packages/event-emitter/src/index.test.ts | 8 +- packages/node-ws/src/events.ts | 27 ++- packages/node-ws/src/index.test.ts | 3 +- packages/node-ws/src/index.ts | 4 +- .../src/providers/discord/discordAuth.ts | 2 +- .../src/providers/facebook/facebookAuth.ts | 2 +- .../src/providers/github/githubAuth.ts | 2 +- .../src/providers/linkedin/linkedinAuth.ts | 2 +- .../oauth-providers/src/providers/x/xAuth.ts | 2 +- packages/oidc-auth/package.json | 1 + packages/oidc-auth/test/index.test.ts | 6 +- packages/prometheus/src/index.ts | 7 +- packages/prometheus/src/standardMetrics.ts | 4 +- packages/qwik-city/src/index.ts | 1 - packages/react-renderer/src/react-renderer.ts | 3 +- packages/swagger-ui/src/index.ts | 2 +- packages/tsyringe/src/index.test.ts | 2 +- packages/tsyringe/src/index.ts | 3 +- packages/typebox-validator/src/index.ts | 30 ++- packages/typebox-validator/test/index.test.ts | 141 ++++++------- packages/typia-validator/src/http.ts | 14 +- packages/typia-validator/test/http.test.ts | 3 +- packages/valibot-validator/src/index.ts | 8 +- packages/valibot-validator/test/index.test.ts | 2 +- packages/valibot-validator/tsup.config.ts | 10 +- packages/zod-openapi/src/index.ts | 3 +- packages/zod-openapi/test/index.test-d.ts | 13 +- packages/zod-openapi/test/index.test.ts | 8 +- packages/zod-validator/src/index.ts | 3 +- packages/zod-validator/test/index.test.ts | 2 +- yarn.lock | 197 +++++++++++++++++- 56 files changed, 671 insertions(+), 424 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.js create mode 100644 eslint.config.mjs diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 1521c8b76..000000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 76158072a..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['./packages/eslint-config/index.js'], -} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..b3364b0eb --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,8 @@ +import baseConfig from './packages/eslint-config/index.js' + +export default [ + ...baseConfig, + { + ignores: ['**/dist/*'], + }, +] diff --git a/package.json b/package.json index a3e75b17b..18965c52a 100644 --- a/package.json +++ b/package.json @@ -61,9 +61,7 @@ "@types/node": "^20.10.4", "@typescript-eslint/eslint-plugin": "^8.7.0", "@typescript-eslint/parser": "^8.7.0", - "eslint": "^8.57.0", - "eslint-plugin-import-x": "^4.1.1", - "eslint-plugin-n": "^17.10.2", + "eslint": "^9.17.0", "jest": "^29.5.0", "jest-environment-miniflare": "^2.14.1", "npm-run-all2": "^6.2.2", diff --git a/packages/ajv-validator/src/index.ts b/packages/ajv-validator/src/index.ts index 0e8cc8e97..768f0d05d 100644 --- a/packages/ajv-validator/src/index.ts +++ b/packages/ajv-validator/src/index.ts @@ -1,11 +1,12 @@ -import type { Context, Env, MiddlewareHandler, ValidationTargets } from 'hono'; -import { validator } from 'hono/validator'; -import { Ajv, type JSONSchemaType, type ErrorObject } from 'ajv'; +import { Ajv } from 'ajv' +import type { JSONSchemaType, ErrorObject } from 'ajv' +import type { Context, Env, MiddlewareHandler, ValidationTargets } from 'hono' +import { validator } from 'hono/validator' type Hook = ( result: { success: true; data: T } | { success: false; errors: ErrorObject[] }, c: Context -) => Response | Promise | void; +) => Response | Promise | void /** * Hono middleware that validates incoming data via an Ajv JSON schema. @@ -75,32 +76,32 @@ export function ajvValidator< E, P, { - in: { [K in Target]: T }; - out: { [K in Target]: T }; + in: { [K in Target]: T } + out: { [K in Target]: T } } > { - const ajv = new Ajv(); - const validate = ajv.compile(schema); + const ajv = new Ajv() + const validate = ajv.compile(schema) return validator(target, (data, c) => { - const valid = validate(data); + const valid = validate(data) if (valid) { if (hook) { - const hookResult = hook({ success: true, data: data as T }, c); + const hookResult = hook({ success: true, data: data as T }, c) if (hookResult instanceof Response || hookResult instanceof Promise) { - return hookResult; + return hookResult } } - return data as T; + return data as T } - const errors = validate.errors || []; + const errors = validate.errors || [] if (hook) { - const hookResult = hook({ success: false, errors }, c); + const hookResult = hook({ success: false, errors }, c) if (hookResult instanceof Response || hookResult instanceof Promise) { - return hookResult; + return hookResult } } - return c.json({ success: false, errors }, 400); - }); + return c.json({ success: false, errors }, 400) + }) } diff --git a/packages/ajv-validator/test/index.test.ts b/packages/ajv-validator/test/index.test.ts index 2cc71ffc2..8497c796f 100644 --- a/packages/ajv-validator/test/index.test.ts +++ b/packages/ajv-validator/test/index.test.ts @@ -1,12 +1,12 @@ -import { Hono } from 'hono'; -import type { Equal, Expect } from 'hono/utils/types'; -import { ajvValidator } from '../src'; -import { JSONSchemaType, type ErrorObject } from 'ajv'; +import type { JSONSchemaType, type ErrorObject } from 'ajv' +import { Hono } from 'hono' +import type { Equal, Expect } from 'hono/utils/types' +import { ajvValidator } from '../src' -type ExtractSchema = T extends Hono ? S : never; +type ExtractSchema = T extends Hono ? S : never describe('Basic', () => { - const app = new Hono(); + const app = new Hono() const schema: JSONSchemaType<{ name: string; age: number }> = { type: 'object', @@ -16,35 +16,35 @@ describe('Basic', () => { }, required: ['name', 'age'], additionalProperties: false, - }; + } const route = app.post('/author', ajvValidator('json', schema), (c) => { - const data = c.req.valid('json'); + const data = c.req.valid('json') return c.json({ success: true, message: `${data.name} is ${data.age}`, - }); - }); + }) + }) - type Actual = ExtractSchema; + type Actual = ExtractSchema type Expected = { '/author': { $post: { input: { json: { - name: string; - age: number; - }; - }; + name: string + age: number + } + } output: { - success: boolean; - message: string; - }; - }; - }; - }; + success: boolean + message: string + } + } + } + } - type verify = Expect>; + type verify = Expect> it('Should return 200 response', async () => { const req = new Request('http://localhost/author', { @@ -56,15 +56,15 @@ describe('Basic', () => { headers: { 'Content-Type': 'application/json', }, - }); - const res = await app.request(req); - expect(res).not.toBeNull(); - expect(res.status).toBe(200); + }) + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(200) expect(await res.json()).toEqual({ success: true, message: 'Superman is 20', - }); - }); + }) + }) it('Should return 400 response', async () => { const req = new Request('http://localhost/author', { @@ -76,17 +76,17 @@ describe('Basic', () => { headers: { 'Content-Type': 'application/json', }, - }); - const res = await app.request(req); - expect(res).not.toBeNull(); - expect(res.status).toBe(400); - const data = (await res.json()) as { success: boolean }; - expect(data.success).toBe(false); - }); -}); + }) + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(400) + const data = (await res.json()) as { success: boolean } + expect(data.success).toBe(false) + }) +}) describe('With Hook', () => { - const app = new Hono(); + const app = new Hono() const schema: JSONSchemaType<{ id: number; title: string }> = { type: 'object', @@ -96,39 +96,39 @@ describe('With Hook', () => { }, required: ['id', 'title'], additionalProperties: false, - }; + } app .post( '/post', ajvValidator('json', schema, (result, c) => { if (!result.success) { - return c.text('Invalid!', 400); + return c.text('Invalid!', 400) } - const data = result.data; - return c.text(`${data.id} is valid!`); + const data = result.data + return c.text(`${data.id} is valid!`) }), (c) => { - const data = c.req.valid('json'); + const data = c.req.valid('json') return c.json({ success: true, message: `${data.id} is ${data.title}`, - }); + }) } ) .post( '/errorTest', ajvValidator('json', schema, (result, c) => { - return c.json(result, 400); + return c.json(result, 400) }), (c) => { - const data = c.req.valid('json'); + const data = c.req.valid('json') return c.json({ success: true, message: `${data.id} is ${data.title}`, - }); + }) } - ); + ) it('Should return 200 response', async () => { const req = new Request('http://localhost/post', { @@ -140,12 +140,12 @@ describe('With Hook', () => { headers: { 'Content-Type': 'application/json', }, - }); - const res = await app.request(req); - expect(res).not.toBeNull(); - expect(res.status).toBe(200); - expect(await res.text()).toBe('123 is valid!'); - }); + }) + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(200) + expect(await res.text()).toBe('123 is valid!') + }) it('Should return 400 response', async () => { const req = new Request('http://localhost/post', { @@ -157,11 +157,11 @@ describe('With Hook', () => { headers: { 'Content-Type': 'application/json', }, - }); - const res = await app.request(req); - expect(res).not.toBeNull(); - expect(res.status).toBe(400); - }); + }) + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(400) + }) it('Should return 400 response and error array', async () => { const req = new Request('http://localhost/errorTest', { @@ -172,17 +172,17 @@ describe('With Hook', () => { headers: { 'Content-Type': 'application/json', }, - }); - const res = await app.request(req); - expect(res).not.toBeNull(); - expect(res.status).toBe(400); + }) + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(400) const { errors, success } = (await res.json()) as { - success: boolean; - errors: ErrorObject[]; - }; - expect(success).toBe(false); - expect(Array.isArray(errors)).toBe(true); + success: boolean + errors: ErrorObject[] + } + expect(success).toBe(false) + expect(Array.isArray(errors)).toBe(true) expect( errors.map((e: ErrorObject) => ({ keyword: e.keyword, @@ -195,6 +195,6 @@ describe('With Hook', () => { instancePath: '', message: "must have required property 'title'", }, - ]); - }); -}); + ]) + }) +}) diff --git a/packages/arktype-validator/src/index.ts b/packages/arktype-validator/src/index.ts index 3e15feab3..63a45d307 100644 --- a/packages/arktype-validator/src/index.ts +++ b/packages/arktype-validator/src/index.ts @@ -1,4 +1,5 @@ -import { type, type Type, type ArkErrors } from 'arktype' +import { type } from 'arktype' +import type { Type, ArkErrors } from 'arktype' import type { Context, MiddlewareHandler, Env, ValidationTargets, TypedResponse } from 'hono' import { validator } from 'hono/validator' diff --git a/packages/auth-js/src/client.ts b/packages/auth-js/src/client.ts index 95ebf09ef..6ece911d7 100644 --- a/packages/auth-js/src/client.ts +++ b/packages/auth-js/src/client.ts @@ -93,7 +93,7 @@ export type WindowProps = { } export type AuthState = { - status: 'loading' | 'success' | 'errored' + status: 'loading' | 'success' | 'errored' error?: string } @@ -163,8 +163,7 @@ export function now() { export function parseUrl(url?: string) { const defaultUrl = 'http://localhost:3000/api/auth' - const parsedUrl = new URL(url?.startsWith('http') ? url : `https://${url}` || defaultUrl) - + const parsedUrl = new URL(url ? (url.startsWith('http') ? url : `https://${url}`) : defaultUrl) const path = parsedUrl.pathname === '/' ? '/api/auth' : parsedUrl.pathname.replace(/\/$/, '') const base = `${parsedUrl.origin}${path}` diff --git a/packages/auth-js/src/index.ts b/packages/auth-js/src/index.ts index cfda40c05..ca0875a92 100644 --- a/packages/auth-js/src/index.ts +++ b/packages/auth-js/src/index.ts @@ -1,12 +1,11 @@ import type { AuthConfig as AuthConfigCore } from '@auth/core' -import { Auth } from '@auth/core' +import { Auth, setEnvDefaults as coreSetEnvDefaults } from '@auth/core' import type { AdapterUser } from '@auth/core/adapters' import type { JWT } from '@auth/core/jwt' import type { Session } from '@auth/core/types' import type { Context, MiddlewareHandler } from 'hono' import { env } from 'hono/adapter' import { HTTPException } from 'hono/http-exception' -import { setEnvDefaults as coreSetEnvDefaults } from '@auth/core' declare module 'hono' { interface ContextVariableMap { @@ -43,7 +42,9 @@ export function reqWithEnvUrl(req: Request, authUrl?: string) { const authUrlObj = new URL(authUrl) const props = ['hostname', 'protocol', 'port', 'password', 'username'] as const for (const prop of props) { - if (authUrlObj[prop]) reqUrlObj[prop] = authUrlObj[prop] + if (authUrlObj[prop]) { + reqUrlObj[prop] = authUrlObj[prop] + } } return new Request(reqUrlObj.href, req) } @@ -51,12 +52,17 @@ export function reqWithEnvUrl(req: Request, authUrl?: string) { const newReq = new Request(url.href, req) const proto = newReq.headers.get('x-forwarded-proto') const host = newReq.headers.get('x-forwarded-host') ?? newReq.headers.get('host') - if (proto != null) url.protocol = proto.endsWith(':') ? proto : `${proto}:` + if (proto != null) { + url.protocol = proto.endsWith(':') ? proto : `${proto}:` + } if (host != null) { url.host = host const portMatch = host.match(/:(\d+)$/) - if (portMatch) url.port = portMatch[1] - else url.port = '' + if (portMatch) { + url.port = portMatch[1] + } else { + url.port = '' + } newReq.headers.delete('x-forwarded-host') newReq.headers.delete('Host') newReq.headers.set('Host', host) diff --git a/packages/auth-js/src/react.tsx b/packages/auth-js/src/react.tsx index 731fd7d0e..1cdbbcd4f 100644 --- a/packages/auth-js/src/react.tsx +++ b/packages/auth-js/src/react.tsx @@ -1,28 +1,24 @@ +import type { BuiltInProviderType, RedirectableProviderType } from '@auth/core/providers' +import type { LoggerInstance, Session } from '@auth/core/types' import * as React from 'react' -import { - type AuthClientConfig, - ClientSessionError, - fetchData, - now, - parseUrl, - useOnline, - type SessionContextValue, - type SessionProviderProps, - type GetSessionParams, - type UseSessionOptions, - type LiteralUnion, - type SignInOptions, - type SignInAuthorizationParams, - type SignInResponse, - type ClientSafeProvider, - type SignOutParams, - type SignOutResponse, +import { useCallback, useContext, useEffect, useMemo, useState } from 'react' +import { ClientSessionError, fetchData, now, parseUrl, useOnline } from './client' +import type { WindowProps, AuthState, + AuthClientConfig, + SessionContextValue, + SessionProviderProps, + GetSessionParams, + UseSessionOptions, + LiteralUnion, + SignInOptions, + SignInAuthorizationParams, + SignInResponse, + ClientSafeProvider, + SignOutParams, + SignOutResponse, } from './client' -import type { LoggerInstance, Session } from '@auth/core/types' -import { useCallback, useContext, useEffect, useMemo, useState } from 'react' -import type { BuiltInProviderType, RedirectableProviderType } from '@auth/core/providers' const logger: LoggerInstance = { debug: console.debug, @@ -431,7 +427,9 @@ export const useOauthPopupLogin = ( useEffect(() => { const handleMessage = (event: MessageEvent) => { - if (event.origin !== window.location.origin) return + if (event.origin !== window.location.origin) { + return + } if (event.data.status) { setState(event.data) if (event.data.status === 'success') { diff --git a/packages/auth-js/test/index.test.ts b/packages/auth-js/test/index.test.ts index 15b89576f..ec0aad259 100644 --- a/packages/auth-js/test/index.test.ts +++ b/packages/auth-js/test/index.test.ts @@ -1,9 +1,9 @@ -import { webcrypto } from 'node:crypto' import { skipCSRFCheck } from '@auth/core' import type { Adapter } from '@auth/core/adapters' import Credentials from '@auth/core/providers/credentials' import { Hono } from 'hono' import { describe, expect, it, vi } from 'vitest' +import { webcrypto } from 'node:crypto' import type { AuthConfig } from '../src' import { authHandler, verifyAuth, initAuthConfig, reqWithEnvUrl } from '../src' diff --git a/packages/casbin/src/helper/jwt.ts b/packages/casbin/src/helper/jwt.ts index ee0bbc42b..7620e885e 100644 --- a/packages/casbin/src/helper/jwt.ts +++ b/packages/casbin/src/helper/jwt.ts @@ -1,6 +1,6 @@ -import { decode } from 'hono/jwt' import type { Enforcer } from 'casbin' import type { Context } from 'hono' +import { decode } from 'hono/jwt' import type { JWTPayload } from 'hono/utils/jwt/types' export const jwtAuthorizer = async ( @@ -14,10 +14,14 @@ export const jwtAuthorizer = async ( if (!payload) { const credentials = c.req.header('Authorization') - if (!credentials) return false + if (!credentials) { + return false + } const parts = credentials.split(/\s+/) - if (parts.length !== 2 || parts[0] !== 'Bearer') return false + if (parts.length !== 2 || parts[0] !== 'Bearer') { + return false + } const token = parts[1] diff --git a/packages/casbin/src/index.ts b/packages/casbin/src/index.ts index 77a9f3eeb..9b4a56575 100644 --- a/packages/casbin/src/index.ts +++ b/packages/casbin/src/index.ts @@ -1,5 +1,5 @@ import { Enforcer } from 'casbin' -import { type Context, MiddlewareHandler } from 'hono' +import type { MiddlewareHandler, type Context } from 'hono' interface CasbinOptions { newEnforcer: Promise diff --git a/packages/casbin/test/index.test.ts b/packages/casbin/test/index.test.ts index 7b680bf1a..b38411927 100644 --- a/packages/casbin/test/index.test.ts +++ b/packages/casbin/test/index.test.ts @@ -1,10 +1,10 @@ -import { describe, it, expect } from 'vitest' -import { Hono } from 'hono' import { newEnforcer } from 'casbin' +import { Hono } from 'hono' +import { basicAuth } from 'hono/basic-auth' +import { jwt, sign } from 'hono/jwt' +import { describe, it, expect } from 'vitest' import { casbin } from '../src' import { basicAuthorizer, jwtAuthorizer } from '../src/helper' -import { jwt, sign } from 'hono/jwt' -import { basicAuth } from 'hono/basic-auth' describe('Casbin Middleware Tests', () => { describe('BasicAuthorizer', () => { diff --git a/packages/class-validator/src/index.ts b/packages/class-validator/src/index.ts index 513f96468..68994381a 100644 --- a/packages/class-validator/src/index.ts +++ b/packages/class-validator/src/index.ts @@ -1,8 +1,10 @@ import 'reflect-metadata' +import type { ClassConstructor, ClassTransformOptions } from 'class-transformer' +import { plainToClass } from 'class-transformer' +import type { ValidationError } from 'class-validator' +import { validate } from 'class-validator' +import type { Context, Env, Input, MiddlewareHandler, TypedResponse, ValidationTargets } from 'hono' import { validator } from 'hono/validator' -import { ClassConstructor, ClassTransformOptions, plainToClass } from 'class-transformer' -import { Context, Env, Input, MiddlewareHandler, TypedResponse, ValidationTargets } from 'hono' -import { ValidationError, validate } from 'class-validator' /** * Hono middleware that validates incoming data using class-validator(https://github.com/typestack/class-validator). diff --git a/packages/class-validator/test/index.test.ts b/packages/class-validator/test/index.test.ts index da524350d..4fce5b1cb 100644 --- a/packages/class-validator/test/index.test.ts +++ b/packages/class-validator/test/index.test.ts @@ -1,9 +1,10 @@ +import { Type } from 'class-transformer' +import type { ValidationError } from 'class-validator' +import { IsInt, IsString, ValidateNested } from 'class-validator' import { Hono } from 'hono' -import { classValidator } from '../src' +import type { ExtractSchema } from 'hono/types' import type { Equal, Expect } from 'hono/utils/types' -import { IsInt, IsString, ValidateNested, ValidationError } from 'class-validator' -import { ExtractSchema } from 'hono/types' -import { Type } from 'class-transformer' +import { classValidator } from '../src' describe('Basic', () => { const app = new Hono() diff --git a/packages/clerk-auth/src/index.ts b/packages/clerk-auth/src/index.ts index 47c1f2a78..f86c59e87 100644 --- a/packages/clerk-auth/src/index.ts +++ b/packages/clerk-auth/src/index.ts @@ -1,4 +1,5 @@ -import { type ClerkClient, type ClerkOptions, createClerkClient } from '@clerk/backend' +import { createClerkClient } from '@clerk/backend' +import type { ClerkClient, ClerkOptions } from '@clerk/backend' import type { Context, MiddlewareHandler } from 'hono' import { env } from 'hono/adapter' diff --git a/packages/cloudflare-access/src/index.test.ts b/packages/cloudflare-access/src/index.test.ts index 542f801de..157821a13 100644 --- a/packages/cloudflare-access/src/index.test.ts +++ b/packages/cloudflare-access/src/index.test.ts @@ -1,24 +1,24 @@ import { Hono } from 'hono' -import { cloudflareAccess } from '../src' import { describe, expect, it, vi } from 'vitest' -import crypto from 'crypto'; -import { promisify } from 'util'; +import crypto from 'crypto' +import { promisify } from 'util' +import { cloudflareAccess } from '../src' -const generateKeyPair = promisify(crypto.generateKeyPair); +const generateKeyPair = promisify(crypto.generateKeyPair) interface KeyPairResult { - publicKey: string; - privateKey: string; + publicKey: string + privateKey: string } interface JWK { - kid: string; - kty: string; - alg: string; - use: string; - e: string; - n: string; + kid: string + kty: string + alg: string + use: string + e: string + n: string } async function generateJWTKeyPair(): Promise { @@ -27,38 +27,38 @@ async function generateJWTKeyPair(): Promise { modulusLength: 2048, publicKeyEncoding: { type: 'spki', - format: 'pem' + format: 'pem', }, privateKeyEncoding: { type: 'pkcs8', - format: 'pem' - } - }); + format: 'pem', + }, + }) return { publicKey, - privateKey - }; + privateKey, + } } catch (error) { - throw new Error(`Failed to generate key pair: ${(error as Error).message}`); + throw new Error(`Failed to generate key pair: ${(error as Error).message}`) } } function generateKeyThumbprint(modulusBase64: string): string { - const hash = crypto.createHash('sha256'); - hash.update(Buffer.from(modulusBase64, 'base64')); - return hash.digest('hex'); + const hash = crypto.createHash('sha256') + hash.update(Buffer.from(modulusBase64, 'base64')) + return hash.digest('hex') } function publicKeyToJWK(publicKey: string): JWK { // Convert PEM to key object - const keyObject = crypto.createPublicKey(publicKey); + const keyObject = crypto.createPublicKey(publicKey) // Export the key in JWK format - const jwk = keyObject.export({ format: 'jwk' }); + const jwk = keyObject.export({ format: 'jwk' }) // Generate key ID using the modulus - const kid = generateKeyThumbprint(jwk.n as string); + const kid = generateKeyThumbprint(jwk.n as string) return { kid, @@ -67,66 +67,65 @@ function publicKeyToJWK(publicKey: string): JWK { use: 'sig', e: jwk.e as string, n: jwk.n as string, - }; + } } - function base64URLEncode(str: string): string { return Buffer.from(str) .toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_') - .replace(/=/g, ''); + .replace(/=/g, '') } -function generateJWT(privateKey: string, payload: Record, expiresIn: number = 3600): string { +function generateJWT( + privateKey: string, + payload: Record, + expiresIn: number = 3600 +): string { // Create header const header = { alg: 'RS256', - typ: 'JWT' - }; + typ: 'JWT', + } // Add expiration to payload - const now = Math.floor(Date.now() / 1000); + const now = Math.floor(Date.now() / 1000) const fullPayload = { ...payload, iat: now, - exp: now + expiresIn - }; + exp: now + expiresIn, + } // Encode header and payload - const encodedHeader = base64URLEncode(JSON.stringify(header)); - const encodedPayload = base64URLEncode(JSON.stringify(fullPayload)); + const encodedHeader = base64URLEncode(JSON.stringify(header)) + const encodedPayload = base64URLEncode(JSON.stringify(fullPayload)) // Create signature - const signatureInput = `${encodedHeader}.${encodedPayload}`; - const signer = crypto.createSign('RSA-SHA256'); - signer.update(signatureInput); - const signature = signer.sign(privateKey); - // @ts-ignore - const encodedSignature = base64URLEncode(signature); + const signatureInput = `${encodedHeader}.${encodedPayload}` + const signer = crypto.createSign('RSA-SHA256') + signer.update(signatureInput) + const signature = signer.sign(privateKey) + // @ts-expect-error signature is not typed correctly + const encodedSignature = base64URLEncode(signature) // Combine all parts - return `${encodedHeader}.${encodedPayload}.${encodedSignature}`; + return `${encodedHeader}.${encodedPayload}.${encodedSignature}` } - describe('Cloudflare Access middleware', async () => { - const keyPair1 = await generateJWTKeyPair(); - const keyPair2 = await generateJWTKeyPair(); - const keyPair3 = await generateJWTKeyPair(); + const keyPair1 = await generateJWTKeyPair() + const keyPair2 = await generateJWTKeyPair() + const keyPair3 = await generateJWTKeyPair() beforeEach(() => { - vi.clearAllMocks(); + vi.clearAllMocks() vi.stubGlobal('fetch', async () => { return Response.json({ - keys: [ - publicKeyToJWK(keyPair1.publicKey), - publicKeyToJWK(keyPair2.publicKey), - ], + keys: [publicKeyToJWK(keyPair1.publicKey), publicKeyToJWK(keyPair2.publicKey)], }) }) - }); + }) const app = new Hono() @@ -135,9 +134,12 @@ describe('Cloudflare Access middleware', async () => { app.get('/access-payload', (c) => c.json(c.get('accessPayload'))) app.onError((err, c) => { - return c.json({ - err: err.toString(), - }, 500) + return c.json( + { + err: err.toString(), + }, + 500 + ) }) it('Should be throw Missing bearer token when nothing is sent', async () => { @@ -150,8 +152,8 @@ describe('Cloudflare Access middleware', async () => { it('Should be throw Unable to decode Bearer token when sending garbage', async () => { const res = await app.request('http://localhost/hello-behind-access', { headers: { - 'cf-access-jwt-assertion': 'asdasdasda' - } + 'cf-access-jwt-assertion': 'asdasdasda', + }, }) expect(res).not.toBeNull() expect(res.status).toBe(401) @@ -159,14 +161,18 @@ describe('Cloudflare Access middleware', async () => { }) it('Should be throw Token is expired when sending expired token', async () => { - const token = generateJWT(keyPair1.privateKey, { - sub: '1234567890', - }, -3600); + const token = generateJWT( + keyPair1.privateKey, + { + sub: '1234567890', + }, + -3600 + ) const res = await app.request('http://localhost/hello-behind-access', { headers: { - 'cf-access-jwt-assertion': token - } + 'cf-access-jwt-assertion': token, + }, }) expect(res).not.toBeNull() expect(res.status).toBe(401) @@ -177,28 +183,30 @@ describe('Cloudflare Access middleware', async () => { const token = generateJWT(keyPair1.privateKey, { sub: '1234567890', iss: 'https://different-team.cloudflareaccess.com', - }); + }) const res = await app.request('http://localhost/hello-behind-access', { headers: { - 'cf-access-jwt-assertion': token - } + 'cf-access-jwt-assertion': token, + }, }) expect(res).not.toBeNull() expect(res.status).toBe(401) - expect(await res.text()).toBe('Authentication error: Expected team name https://my-cool-team-name.cloudflareaccess.com, but received https://different-team.cloudflareaccess.com') + expect(await res.text()).toBe( + 'Authentication error: Expected team name https://my-cool-team-name.cloudflareaccess.com, but received https://different-team.cloudflareaccess.com' + ) }) it('Should be throw Invalid token when sending token signed with private key not in the allowed list', async () => { const token = generateJWT(keyPair3.privateKey, { sub: '1234567890', iss: 'https://my-cool-team-name.cloudflareaccess.com', - }); + }) const res = await app.request('http://localhost/hello-behind-access', { headers: { - 'cf-access-jwt-assertion': token - } + 'cf-access-jwt-assertion': token, + }, }) expect(res).not.toBeNull() expect(res.status).toBe(401) @@ -209,12 +217,12 @@ describe('Cloudflare Access middleware', async () => { const token = generateJWT(keyPair1.privateKey, { sub: '1234567890', iss: 'https://my-cool-team-name.cloudflareaccess.com', - }); + }) const res = await app.request('http://localhost/hello-behind-access', { headers: { - 'cf-access-jwt-assertion': token - } + 'cf-access-jwt-assertion': token, + }, }) expect(res).not.toBeNull() expect(res.status).toBe(200) @@ -225,12 +233,12 @@ describe('Cloudflare Access middleware', async () => { const token = generateJWT(keyPair2.privateKey, { sub: '1234567890', iss: 'https://my-cool-team-name.cloudflareaccess.com', - }); + }) const res = await app.request('http://localhost/hello-behind-access', { headers: { - 'cf-access-jwt-assertion': token - } + 'cf-access-jwt-assertion': token, + }, }) expect(res).not.toBeNull() expect(res.status).toBe(200) @@ -241,50 +249,54 @@ describe('Cloudflare Access middleware', async () => { const token = generateJWT(keyPair1.privateKey, { sub: '1234567890', iss: 'https://my-cool-team-name.cloudflareaccess.com', - }); + }) const res = await app.request('http://localhost/access-payload', { headers: { - 'cf-access-jwt-assertion': token - } + 'cf-access-jwt-assertion': token, + }, }) expect(res).not.toBeNull() expect(res.status).toBe(200) expect(await res.json()).toEqual({ - "sub":"1234567890", - "iss":"https://my-cool-team-name.cloudflareaccess.com", - "iat":expect.any(Number), - "exp":expect.any(Number) + sub: '1234567890', + iss: 'https://my-cool-team-name.cloudflareaccess.com', + iat: expect.any(Number), + exp: expect.any(Number), }) }) it('Should throw an error, if the access organization does not exist', async () => { vi.stubGlobal('fetch', async () => { - return Response.json({success: false}, {status: 404}) + return Response.json({ success: false }, { status: 404 }) }) const res = await app.request('http://localhost/hello-behind-access', { headers: { - 'cf-access-jwt-assertion': 'asdads' - } + 'cf-access-jwt-assertion': 'asdads', + }, }) expect(res).not.toBeNull() expect(res.status).toBe(500) - expect(await res.json()).toEqual({"err":"Error: Authentication error: The Access Organization 'my-cool-team-name' does not exist"}) + expect(await res.json()).toEqual({ + err: "Error: Authentication error: The Access Organization 'my-cool-team-name' does not exist", + }) }) it('Should throw an error, if the access certs url is unavailable', async () => { vi.stubGlobal('fetch', async () => { - return Response.json({success: false}, {status: 500}) + return Response.json({ success: false }, { status: 500 }) }) const res = await app.request('http://localhost/hello-behind-access', { headers: { - 'cf-access-jwt-assertion': 'asdads' - } + 'cf-access-jwt-assertion': 'asdads', + }, }) expect(res).not.toBeNull() expect(res.status).toBe(500) - expect(await res.json()).toEqual({"err":"Error: Authentication error: Received unexpected HTTP code 500 from Cloudflare Access"}) + expect(await res.json()).toEqual({ + err: 'Error: Authentication error: Received unexpected HTTP code 500 from Cloudflare Access', + }) }) }) diff --git a/packages/cloudflare-access/src/index.ts b/packages/cloudflare-access/src/index.ts index f7718d00d..67cc578b9 100644 --- a/packages/cloudflare-access/src/index.ts +++ b/packages/cloudflare-access/src/index.ts @@ -1,18 +1,18 @@ +import type { Context } from 'hono' import { createMiddleware } from 'hono/factory' -import { Context } from 'hono' import { HTTPException } from 'hono/http-exception' export type CloudflareAccessPayload = { - aud: string[], - email: string, - exp: number, - iat: number, - nbf: number, - iss: string, - type: string, - identity_nonce: string, - sub: string, - country: string, + aud: string[] + email: string + exp: number + iat: number + nbf: number + iss: string + type: string + identity_nonce: string + sub: string + country: string } export type CloudflareAccessVariables = { @@ -39,7 +39,9 @@ export const cloudflareAccess = (accessTeamName: string) => { return createMiddleware(async (c, next) => { const encodedToken = getJwt(c) - if (encodedToken === null) return c.text('Authentication error: Missing bearer token', 401) + if (encodedToken === null) { + return c.text('Authentication error: Missing bearer token', 401) + } // Load jwt keys if they are not in memory or already expired if (Object.keys(cacheKeys).length === 0 || Math.floor(Date.now() / 1000) < cacheExpiration) { @@ -59,19 +61,23 @@ export const cloudflareAccess = (accessTeamName: string) => { // Is the token expired? const expiryDate = new Date(token.payload.exp * 1000) const currentDate = new Date(Date.now()) - if (expiryDate <= currentDate) return c.text('Authentication error: Token is expired', 401) + if (expiryDate <= currentDate) { + return c.text('Authentication error: Token is expired', 401) + } // Check is token is valid against at least one public key? - if (!(await isValidJwtSignature(token, cacheKeys))) + if (!(await isValidJwtSignature(token, cacheKeys))) { return c.text('Authentication error: Invalid Token', 401) + } // Is signed from the correct team? const expectedIss = `https://${accessTeamName}.cloudflareaccess.com` - if (token.payload?.iss !== expectedIss) + if (token.payload?.iss !== expectedIss) { return c.text( `Authentication error: Expected team name ${expectedIss}, but received ${token.payload?.iss}`, 401 ) + } c.set('accessPayload', token.payload) await next() @@ -83,7 +89,6 @@ async function getPublicKeys(accessTeamName: string) { const result = await fetch(jwtUrl, { method: 'GET', - // @ts-ignore cf: { // Dont cache error responses cacheTtlByStatus: { '200-299': 30, '300-599': 0 }, @@ -92,16 +97,20 @@ async function getPublicKeys(accessTeamName: string) { if (!result.ok) { if (result.status === 404) { - throw new HTTPException(500, { message: `Authentication error: The Access Organization '${accessTeamName}' does not exist` }) + throw new HTTPException(500, { + message: `Authentication error: The Access Organization '${accessTeamName}' does not exist`, + }) } - throw new HTTPException(500, { message: `Authentication error: Received unexpected HTTP code ${result.status} from Cloudflare Access` }) + throw new HTTPException(500, { + message: `Authentication error: Received unexpected HTTP code ${result.status} from Cloudflare Access`, + }) } const data: any = await result.json() // Because we keep CryptoKey's in memory between requests, we need to make sure they are refreshed once in a while - let cacheExpiration = Math.floor(Date.now() / 1000) + 3600 // 1h + const cacheExpiration = Math.floor(Date.now() / 1000) + 3600 // 1h const importedKeys: Record = {} for (const key of data.keys) { @@ -158,7 +167,9 @@ async function isValidJwtSignature(token: DecodedToken, keys: Record { diff --git a/packages/conform-validator/test/hook.test.ts b/packages/conform-validator/test/hook.test.ts index a4b07dee4..4dfcc9157 100644 --- a/packages/conform-validator/test/hook.test.ts +++ b/packages/conform-validator/test/hook.test.ts @@ -1,9 +1,9 @@ -import * as z from 'zod' +import { parseWithZod } from '@conform-to/zod' import { Hono } from 'hono' import { hc } from 'hono/client' -import { parseWithZod } from '@conform-to/zod' -import { conformValidator } from '../src' import { vi } from 'vitest' +import * as z from 'zod' +import { conformValidator } from '../src' describe('Validate the hook option processing', () => { const app = new Hono() diff --git a/packages/conform-validator/test/valibot.test.ts b/packages/conform-validator/test/valibot.test.ts index 363c2d407..324cb15e2 100644 --- a/packages/conform-validator/test/valibot.test.ts +++ b/packages/conform-validator/test/valibot.test.ts @@ -1,10 +1,10 @@ +import { parseWithValibot } from 'conform-to-valibot' +import { Hono } from 'hono' +import { hc } from 'hono/client' import type { ExtractSchema, ParsedFormValue } from 'hono/types' -import type { Equal, Expect } from 'hono/utils/types' import type { StatusCode } from 'hono/utils/http-status' +import type { Equal, Expect } from 'hono/utils/types' import * as v from 'valibot' -import { Hono } from 'hono' -import { hc } from 'hono/client' -import { parseWithValibot } from 'conform-to-valibot' import { conformValidator } from '../src' describe('Validate requests using a Valibot schema', () => { diff --git a/packages/conform-validator/test/yup.test.ts b/packages/conform-validator/test/yup.test.ts index f8c81d0f2..e83f9c8a4 100644 --- a/packages/conform-validator/test/yup.test.ts +++ b/packages/conform-validator/test/yup.test.ts @@ -1,10 +1,10 @@ +import { parseWithYup } from '@conform-to/yup' +import { Hono } from 'hono' +import { hc } from 'hono/client' import type { ExtractSchema, ParsedFormValue } from 'hono/types' -import type { Equal, Expect } from 'hono/utils/types' import type { StatusCode } from 'hono/utils/http-status' +import type { Equal, Expect } from 'hono/utils/types' import * as y from 'yup' -import { Hono } from 'hono' -import { hc } from 'hono/client' -import { parseWithYup } from '@conform-to/yup' import { conformValidator } from '../src' describe('Validate requests using a Yup schema', () => { diff --git a/packages/conform-validator/test/zod.test.ts b/packages/conform-validator/test/zod.test.ts index 7cb091319..f46d536d0 100644 --- a/packages/conform-validator/test/zod.test.ts +++ b/packages/conform-validator/test/zod.test.ts @@ -1,10 +1,10 @@ +import { parseWithZod } from '@conform-to/zod' +import { Hono } from 'hono' +import { hc } from 'hono/client' import type { ExtractSchema, ParsedFormValue } from 'hono/types' -import type { Equal, Expect } from 'hono/utils/types' import type { StatusCode } from 'hono/utils/http-status' +import type { Equal, Expect } from 'hono/utils/types' import * as z from 'zod' -import { Hono } from 'hono' -import { hc } from 'hono/client' -import { parseWithZod } from '@conform-to/zod' import { conformValidator } from '../src' describe('Validate requests using a Zod schema', () => { diff --git a/packages/event-emitter/src/index.test.ts b/packages/event-emitter/src/index.test.ts index b7c24ff63..b0fe094a3 100644 --- a/packages/event-emitter/src/index.test.ts +++ b/packages/event-emitter/src/index.test.ts @@ -1,8 +1,8 @@ -import { Hono } from 'hono' -import type {Context} from 'hono' +import { Hono } from 'hono' +import type { Context } from 'hono' import { describe, expect, it, vi } from 'vitest' -import { createEmitter, defineHandler, defineHandlers, emitter } from './index' -import type {Emitter} from './index' // Adjust the import path as needed +import { createEmitter, defineHandler, defineHandlers, emitter } from './index' +import type { Emitter } from './index' // Adjust the import path as needed describe('Event Emitter Middleware', () => { describe('createEmitter', () => { diff --git a/packages/node-ws/src/events.ts b/packages/node-ws/src/events.ts index 539762b23..3cb34cbcb 100644 --- a/packages/node-ws/src/events.ts +++ b/packages/node-ws/src/events.ts @@ -1,32 +1,31 @@ interface CloseEventInit extends EventInit { - code?: number; - reason?: string; - wasClean?: boolean; + code?: number + reason?: string + wasClean?: boolean } /** * @link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent */ -export const CloseEvent = globalThis.CloseEvent ?? class extends Event { +export const CloseEvent = + globalThis.CloseEvent ?? + class extends Event { #eventInitDict - constructor( - type: string, - eventInitDict: CloseEventInit = {} - ) { - super(type, eventInitDict) - this.#eventInitDict = eventInitDict + constructor(type: string, eventInitDict: CloseEventInit = {}) { + super(type, eventInitDict) + this.#eventInitDict = eventInitDict } get wasClean(): boolean { - return this.#eventInitDict.wasClean ?? false + return this.#eventInitDict.wasClean ?? false } get code(): number { - return this.#eventInitDict.code ?? 0 + return this.#eventInitDict.code ?? 0 } get reason(): string { - return this.#eventInitDict.reason ?? '' + return this.#eventInitDict.reason ?? '' } -} + } diff --git a/packages/node-ws/src/index.test.ts b/packages/node-ws/src/index.test.ts index 9cb12cb03..06b4e3b53 100644 --- a/packages/node-ws/src/index.test.ts +++ b/packages/node-ws/src/index.test.ts @@ -1,9 +1,9 @@ import { serve } from '@hono/node-server' import type { ServerType } from '@hono/node-server/dist/types' import { Hono } from 'hono' +import type { WSMessageReceive } from 'hono/ws' import { WebSocket } from 'ws' import { createNodeWebSocket } from '.' -import type { WSMessageReceive } from 'hono/ws' describe('WebSocket helper', () => { let app: Hono @@ -13,7 +13,6 @@ describe('WebSocket helper', () => { beforeEach(async () => { app = new Hono() - ;({ injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })) server = await new Promise((resolve) => { diff --git a/packages/node-ws/src/index.ts b/packages/node-ws/src/index.ts index 4ef690224..b7d6f5c83 100644 --- a/packages/node-ws/src/index.ts +++ b/packages/node-ws/src/index.ts @@ -1,10 +1,10 @@ -import type { Server } from 'node:http' -import type { Http2SecureServer, Http2Server } from 'node:http2' import type { Hono } from 'hono' import type { UpgradeWebSocket, WSContext } from 'hono/ws' import type { WebSocket } from 'ws' import { WebSocketServer } from 'ws' import type { IncomingMessage } from 'http' +import type { Server } from 'node:http' +import type { Http2SecureServer, Http2Server } from 'node:http2' import { CloseEvent } from './events' export interface NodeWebSocket { diff --git a/packages/oauth-providers/src/providers/discord/discordAuth.ts b/packages/oauth-providers/src/providers/discord/discordAuth.ts index 729bff389..4d4972a65 100644 --- a/packages/oauth-providers/src/providers/discord/discordAuth.ts +++ b/packages/oauth-providers/src/providers/discord/discordAuth.ts @@ -1,6 +1,6 @@ import type { MiddlewareHandler } from 'hono' -import { getCookie, setCookie } from 'hono/cookie' import { env } from 'hono/adapter' +import { getCookie, setCookie } from 'hono/cookie' import { HTTPException } from 'hono/http-exception' import { getRandomState } from '../../utils/getRandomState' diff --git a/packages/oauth-providers/src/providers/facebook/facebookAuth.ts b/packages/oauth-providers/src/providers/facebook/facebookAuth.ts index cdf75403b..75865d7a3 100644 --- a/packages/oauth-providers/src/providers/facebook/facebookAuth.ts +++ b/packages/oauth-providers/src/providers/facebook/facebookAuth.ts @@ -1,6 +1,6 @@ import type { MiddlewareHandler } from 'hono' -import { getCookie, setCookie } from 'hono/cookie' import { env } from 'hono/adapter' +import { getCookie, setCookie } from 'hono/cookie' import { HTTPException } from 'hono/http-exception' import { getRandomState } from '../../utils/getRandomState' diff --git a/packages/oauth-providers/src/providers/github/githubAuth.ts b/packages/oauth-providers/src/providers/github/githubAuth.ts index 9729337d8..3e0875abe 100644 --- a/packages/oauth-providers/src/providers/github/githubAuth.ts +++ b/packages/oauth-providers/src/providers/github/githubAuth.ts @@ -1,6 +1,6 @@ import type { MiddlewareHandler } from 'hono' -import { getCookie, setCookie } from 'hono/cookie' import { env } from 'hono/adapter' +import { getCookie, setCookie } from 'hono/cookie' import { HTTPException } from 'hono/http-exception' import { getRandomState } from '../../utils/getRandomState' diff --git a/packages/oauth-providers/src/providers/linkedin/linkedinAuth.ts b/packages/oauth-providers/src/providers/linkedin/linkedinAuth.ts index 297460dce..e0ac131f9 100644 --- a/packages/oauth-providers/src/providers/linkedin/linkedinAuth.ts +++ b/packages/oauth-providers/src/providers/linkedin/linkedinAuth.ts @@ -1,6 +1,6 @@ import type { MiddlewareHandler } from 'hono' -import { getCookie, setCookie } from 'hono/cookie' import { env } from 'hono/adapter' +import { getCookie, setCookie } from 'hono/cookie' import { HTTPException } from 'hono/http-exception' import { getRandomState } from '../../utils/getRandomState' diff --git a/packages/oauth-providers/src/providers/x/xAuth.ts b/packages/oauth-providers/src/providers/x/xAuth.ts index 00f9ff95b..18381a35d 100644 --- a/packages/oauth-providers/src/providers/x/xAuth.ts +++ b/packages/oauth-providers/src/providers/x/xAuth.ts @@ -1,6 +1,6 @@ import type { MiddlewareHandler } from 'hono' -import { getCookie, setCookie } from 'hono/cookie' import { env } from 'hono/adapter' +import { getCookie, setCookie } from 'hono/cookie' import { HTTPException } from 'hono/http-exception' import { getCodeChallenge } from '../../utils/getCodeChallenge' diff --git a/packages/oidc-auth/package.json b/packages/oidc-auth/package.json index c8cbb23a0..803222c2a 100644 --- a/packages/oidc-auth/package.json +++ b/packages/oidc-auth/package.json @@ -36,6 +36,7 @@ "hono": ">=3.*" }, "devDependencies": { + "@jest/globals": "^29.7.0", "@types/jest": "^29.5.11", "@types/jsonwebtoken": "^9.0.5", "hono": "^4.0.1", diff --git a/packages/oidc-auth/test/index.test.ts b/packages/oidc-auth/test/index.test.ts index cd71457f5..7c1e7fa4d 100644 --- a/packages/oidc-auth/test/index.test.ts +++ b/packages/oidc-auth/test/index.test.ts @@ -1,8 +1,8 @@ -import crypto from 'node:crypto' import { jest } from '@jest/globals' import { Hono } from 'hono' import jwt from 'jsonwebtoken' import * as oauth2 from 'oauth4webapi' +import crypto from 'node:crypto' const MOCK_ISSUER = 'https://accounts.google.com' const MOCK_CLIENT_ID = 'CLIENT_ID_001' @@ -387,7 +387,9 @@ describe('processOAuthCallback()', () => { expect(res).not.toBeNull() expect(res.status).toBe(302) expect(res.headers.get('set-cookie')).toMatch( - new RegExp(`${MOCK_COOKIE_NAME}=[^;]+; Path=${process.env.OIDC_COOKIE_PATH}; HttpOnly; Secure`) + new RegExp( + `${MOCK_COOKIE_NAME}=[^;]+; Path=${process.env.OIDC_COOKIE_PATH}; HttpOnly; Secure` + ) ) }) test('Should return an error if the state parameter does not match', async () => { diff --git a/packages/prometheus/src/index.ts b/packages/prometheus/src/index.ts index a797242dd..578431b9e 100644 --- a/packages/prometheus/src/index.ts +++ b/packages/prometheus/src/index.ts @@ -2,11 +2,8 @@ import type { Context } from 'hono' import { createMiddleware } from 'hono/factory' import type { DefaultMetricsCollectorConfiguration, RegistryContentType } from 'prom-client' import { Registry, collectDefaultMetrics as promCollectDefaultMetrics } from 'prom-client' -import { - type MetricOptions, - type CustomMetricsOptions, - createStandardMetrics, -} from './standardMetrics' +import { createStandardMetrics } from './standardMetrics' +import type { MetricOptions, CustomMetricsOptions } from './standardMetrics' interface PrometheusOptions { registry?: Registry diff --git a/packages/prometheus/src/standardMetrics.ts b/packages/prometheus/src/standardMetrics.ts index 4335ef736..811df79ba 100644 --- a/packages/prometheus/src/standardMetrics.ts +++ b/packages/prometheus/src/standardMetrics.ts @@ -1,6 +1,6 @@ import type { Context } from 'hono' -import type { CounterConfiguration, HistogramConfiguration, Metric } from 'prom-client' -import { Counter, Histogram, type Registry } from 'prom-client' +import { Counter, Histogram } from 'prom-client' +import type { CounterConfiguration, HistogramConfiguration, Metric, Registry } from 'prom-client' export type MetricOptions = { disabled?: boolean diff --git a/packages/qwik-city/src/index.ts b/packages/qwik-city/src/index.ts index 20c382e75..ff506ed50 100644 --- a/packages/qwik-city/src/index.ts +++ b/packages/qwik-city/src/index.ts @@ -13,7 +13,6 @@ import { import type { MiddlewareHandler } from 'hono' export const qwikMiddleware = (opts: ServerRenderOptions): MiddlewareHandler => { - // eslint-disable-next-line @typescript-eslint/no-extra-semi ;(globalThis as any).TextEncoderStream = TextEncoderStream const qwikSerializer = { _deserializeData, diff --git a/packages/react-renderer/src/react-renderer.ts b/packages/react-renderer/src/react-renderer.ts index fa58e5d53..a36d7c7b2 100644 --- a/packages/react-renderer/src/react-renderer.ts +++ b/packages/react-renderer/src/react-renderer.ts @@ -1,7 +1,8 @@ import type { Context } from 'hono' import type { Env, MiddlewareHandler } from 'hono/types' import React from 'react' -import { renderToString, type RenderToReadableStreamOptions } from 'react-dom/server' +import { renderToString } from 'react-dom/server' +import type { RenderToReadableStreamOptions } from 'react-dom/server' import type { Props } from '.' type RendererOptions = { diff --git a/packages/swagger-ui/src/index.ts b/packages/swagger-ui/src/index.ts index 5e20f1763..a5dc37a37 100644 --- a/packages/swagger-ui/src/index.ts +++ b/packages/swagger-ui/src/index.ts @@ -69,7 +69,7 @@ const SwaggerUI = (options: SwaggerUIOptions) => { const middleware = (options: SwaggerUIOptions): MiddlewareHandler => async (c) => { - const title = options?.title ?? "SwaggerUI" + const title = options?.title ?? 'SwaggerUI' return c.html(/* html */ ` diff --git a/packages/tsyringe/src/index.test.ts b/packages/tsyringe/src/index.test.ts index 43f7e828e..0bea2687a 100644 --- a/packages/tsyringe/src/index.test.ts +++ b/packages/tsyringe/src/index.test.ts @@ -1,6 +1,6 @@ import 'reflect-metadata' -import { injectable, inject } from 'tsyringe' import { Hono } from 'hono' +import { injectable, inject } from 'tsyringe' import { tsyringe } from '../src' class Config { diff --git a/packages/tsyringe/src/index.ts b/packages/tsyringe/src/index.ts index 1a0c25ec7..1c4e83d9d 100644 --- a/packages/tsyringe/src/index.ts +++ b/packages/tsyringe/src/index.ts @@ -1,6 +1,7 @@ -import { container, DependencyContainer, InjectionToken } from 'tsyringe' import type { Context, MiddlewareHandler } from 'hono' import { createMiddleware } from 'hono/factory' +import type { DependencyContainer, InjectionToken } from 'tsyringe' +import { container } from 'tsyringe' declare module 'hono' { interface ContextVariableMap { diff --git a/packages/typebox-validator/src/index.ts b/packages/typebox-validator/src/index.ts index 7b5aa8c05..aad082bed 100644 --- a/packages/typebox-validator/src/index.ts +++ b/packages/typebox-validator/src/index.ts @@ -1,5 +1,7 @@ -import { TSchema, Static, TypeGuard, ValueGuard } from '@sinclair/typebox' -import { Value, type ValueError } from '@sinclair/typebox/value' +import type { TSchema, Static } from '@sinclair/typebox' +import { TypeGuard, ValueGuard } from '@sinclair/typebox' +import { Value } from '@sinclair/typebox/value' +import type { ValueError } from '@sinclair/typebox/value' import type { Context, Env, MiddlewareHandler, ValidationTargets } from 'hono' import { validator } from 'hono/validator' import IsObject = ValueGuard.IsObject @@ -7,7 +9,7 @@ import IsArray = ValueGuard.IsArray export type Hook = ( result: { success: true; data: T } | { success: false; errors: ValueError[] }, - c: Context, + c: Context ) => Response | Promise | void /** @@ -61,11 +63,18 @@ export function tbValidator< E extends Env, P extends string, V extends { in: { [K in Target]: Static }; out: { [K in Target]: Static } } ->(target: Target, schema: T, hook?: Hook, E, P>, stripNonSchemaItems?: boolean): MiddlewareHandler { +>( + target: Target, + schema: T, + hook?: Hook, E, P>, + stripNonSchemaItems?: boolean +): MiddlewareHandler { // Compile the provided schema once rather than per validation. This could be optimized further using a shared schema // compilation pool similar to the Fastify implementation. return validator(target, (unprocessedData, c) => { - const data = stripNonSchemaItems ? removeNonSchemaItems(schema, unprocessedData) : unprocessedData + const data = stripNonSchemaItems + ? removeNonSchemaItems(schema, unprocessedData) + : unprocessedData if (Value.Check(schema, data)) { if (hook) { @@ -90,7 +99,9 @@ export function tbValidator< } function removeNonSchemaItems(schema: T, obj: any): Static { - if (typeof obj !== 'object' || obj === null) return obj + if (typeof obj !== 'object' || obj === null) { + return obj + } if (Array.isArray(obj)) { return obj.map((item) => removeNonSchemaItems(schema.items, item)) @@ -98,12 +109,9 @@ function removeNonSchemaItems(schema: T, obj: any): Static const result: any = {} for (const key in schema.properties) { - if (obj.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { const propertySchema = schema.properties[key] - if ( - IsObject(propertySchema) && - !IsArray(propertySchema) - ) { + if (IsObject(propertySchema) && !IsArray(propertySchema)) { result[key] = removeNonSchemaItems(propertySchema as unknown as TSchema, obj[key]) } else { result[key] = obj[key] diff --git a/packages/typebox-validator/test/index.test.ts b/packages/typebox-validator/test/index.test.ts index 4197e0cd2..7557f09af 100644 --- a/packages/typebox-validator/test/index.test.ts +++ b/packages/typebox-validator/test/index.test.ts @@ -1,8 +1,8 @@ import { Type as T } from '@sinclair/typebox' +import type { ValueError } from '@sinclair/typebox/value' import { Hono } from 'hono' import type { Equal, Expect } from 'hono/utils/types' import { tbValidator } from '../src' -import { ValueError } from '@sinclair/typebox/value' // eslint-disable-next-line @typescript-eslint/no-unused-vars type ExtractSchema = T extends Hono ? S : never @@ -91,35 +91,37 @@ describe('With Hook', () => { title: T.String(), }) - app.post( - '/post', - tbValidator('json', schema, (result, c) => { - if (!result.success) { - return c.text('Invalid!', 400) + app + .post( + '/post', + tbValidator('json', schema, (result, c) => { + if (!result.success) { + return c.text('Invalid!', 400) + } + const data = result.data + return c.text(`${data.id} is valid!`) + }), + (c) => { + const data = c.req.valid('json') + return c.json({ + success: true, + message: `${data.id} is ${data.title}`, + }) } - const data = result.data - return c.text(`${data.id} is valid!`) - }), - (c) => { - const data = c.req.valid('json') - return c.json({ - success: true, - message: `${data.id} is ${data.title}`, - }) - }, - ).post( - '/errorTest', - tbValidator('json', schema, (result, c) => { - return c.json(result, 400) - }), - (c) => { - const data = c.req.valid('json') - return c.json({ - success: true, - message: `${data.id} is ${data.title}`, - }) - }, - ) + ) + .post( + '/errorTest', + tbValidator('json', schema, (result, c) => { + return c.json(result, 400) + }), + (c) => { + const data = c.req.valid('json') + return c.json({ + success: true, + message: `${data.id} is ${data.title}`, + }) + } + ) it('Should return 200 response', async () => { const req = new Request('http://localhost/post', { @@ -171,20 +173,22 @@ describe('With Hook', () => { const { errors, success } = (await res.json()) as { success: boolean; errors: any[] } expect(success).toBe(false) expect(Array.isArray(errors)).toBe(true) - expect(errors.map((e: ValueError) => ({ - 'type': e?.schema?.type, - path: e?.path, - message: e?.message, - }))).toEqual([ + expect( + errors.map((e: ValueError) => ({ + type: e?.schema?.type, + path: e?.path, + message: e?.message, + })) + ).toEqual([ { - 'type': 'string', - 'path': '/title', - 'message': 'Required property', + type: 'string', + path: '/title', + message: 'Required property', }, { - 'type': 'string', - 'path': '/title', - 'message': 'Expected string', + type: 'string', + path: '/title', + message: 'Expected string', }, ]) }) @@ -207,25 +211,19 @@ describe('Remove non schema items', () => { }), }) - app.post( - '/stripValuesNested', - tbValidator('json', nestedSchema, undefined, true), - (c) => { + app + .post('/stripValuesNested', tbValidator('json', nestedSchema, undefined, true), (c) => { return c.json({ success: true, message: c.req.valid('json'), }) - }, - ).post( - '/stripValuesArray', - tbValidator('json', T.Array(schema), undefined, true), - (c) => { + }) + .post('/stripValuesArray', tbValidator('json', T.Array(schema), undefined, true), (c) => { return c.json({ success: true, message: c.req.valid('json'), }) - }, - ) + }) it('Should remove all the values in the nested object and return a 200 response', async () => { const req = new Request('http://localhost/stripValuesNested', { @@ -274,20 +272,21 @@ describe('Remove non schema items', () => { const { message, success } = (await res.json()) as { success: boolean; message: any } expect(success).toBe(true) - expect(message).toEqual( - { - 'id': 123, - 'itemArray': [{ 'id': 123, 'title': 'Hello' }, { - 'id': 123, - 'title': 'Hello', - }], - 'item': { 'id': 123, 'title': 'Hello' }, - 'itemObject': { - 'item1': { 'id': 123, 'title': 'Hello' }, - 'item2': { 'id': 123, 'title': 'Hello' }, + expect(message).toEqual({ + id: 123, + itemArray: [ + { id: 123, title: 'Hello' }, + { + id: 123, + title: 'Hello', }, + ], + item: { id: 123, title: 'Hello' }, + itemObject: { + item1: { id: 123, title: 'Hello' }, + item2: { id: 123, title: 'Hello' }, }, - ) + }) }) it('Should remove all the values in the array and return a 200 response', async () => { @@ -303,7 +302,8 @@ describe('Remove non schema items', () => { title: 'Hello 2', nonExistentKey: 'error', }, - ]), method: 'POST', + ]), + method: 'POST', headers: { 'Content-Type': 'application/json', }, @@ -313,11 +313,12 @@ describe('Remove non schema items', () => { const { message, success } = (await res.json()) as { success: boolean; message: Array } expect(res.status).toBe(200) expect(success).toBe(true) - expect(message).toEqual([{ 'id': 123, 'title': 'Hello' }, { - 'id': 123, - 'title': 'Hello 2', - }], - ) + expect(message).toEqual([ + { id: 123, title: 'Hello' }, + { + id: 123, + title: 'Hello 2', + }, + ]) }) }) - diff --git a/packages/typia-validator/src/http.ts b/packages/typia-validator/src/http.ts index 3eb930763..938b1f9e1 100644 --- a/packages/typia-validator/src/http.ts +++ b/packages/typia-validator/src/http.ts @@ -129,7 +129,7 @@ export const typiaValidator: TypiaValidator = ( validate: (input: any) => IValidation, hook?: Hook ): MiddlewareHandler => { - if (target === 'query' || target === 'header') + if (target === 'query' || target === 'header') { return async (c, next) => { let value: any if (target === 'query') { @@ -140,15 +140,20 @@ export const typiaValidator: TypiaValidator = ( } satisfies IReadableURLSearchParams } else { value = Object.create(null) - for (const [key, headerValue] of c.req.raw.headers) value[key.toLowerCase()] = headerValue - if (c.req.raw.headers.has('Set-Cookie')) + for (const [key, headerValue] of c.req.raw.headers) { + value[key.toLowerCase()] = headerValue + } + if (c.req.raw.headers.has('Set-Cookie')) { value['Set-Cookie'] = c.req.raw.headers.getSetCookie() + } } const result = validate(value) if (hook) { const res = await hook(result as never, c) - if (res instanceof Response) return res + if (res instanceof Response) { + return res + } } if (!result.success) { return c.json({ success: false, error: result.errors }, 400) @@ -157,6 +162,7 @@ export const typiaValidator: TypiaValidator = ( await next() } + } return validator(target, async (value, c) => { const result = validate(value) diff --git a/packages/typia-validator/test/http.test.ts b/packages/typia-validator/test/http.test.ts index 61ff106d4..426599ae0 100644 --- a/packages/typia-validator/test/http.test.ts +++ b/packages/typia-validator/test/http.test.ts @@ -1,6 +1,7 @@ import { Hono } from 'hono' import type { Equal, Expect } from 'hono/utils/types' -import typia, { tags } from 'typia' +import type { tags } from 'typia' +import typia from 'typia' import { typiaValidator } from '../src/http' // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/packages/valibot-validator/src/index.ts b/packages/valibot-validator/src/index.ts index e430583f6..75fb4a7c2 100644 --- a/packages/valibot-validator/src/index.ts +++ b/packages/valibot-validator/src/index.ts @@ -1,6 +1,12 @@ import type { Context, Env, Input as HonoInput, MiddlewareHandler, ValidationTargets } from 'hono' import { validator } from 'hono/validator' -import type { GenericSchema, GenericSchemaAsync, InferInput, InferOutput, SafeParseResult } from 'valibot' +import type { + GenericSchema, + GenericSchemaAsync, + InferInput, + InferOutput, + SafeParseResult, +} from 'valibot' import { safeParseAsync } from 'valibot' export type Hook = ( diff --git a/packages/valibot-validator/test/index.test.ts b/packages/valibot-validator/test/index.test.ts index 40bb3bf24..d50fd78e9 100644 --- a/packages/valibot-validator/test/index.test.ts +++ b/packages/valibot-validator/test/index.test.ts @@ -1,8 +1,8 @@ import { Hono } from 'hono' +import type { StatusCode } from 'hono/utils/http-status' import type { Equal, Expect } from 'hono/utils/types' import { number, object, objectAsync, optional, optionalAsync, string } from 'valibot' import { vValidator } from '../src' -import { StatusCode } from 'hono/utils/http-status' // eslint-disable-next-line @typescript-eslint/no-unused-vars type ExtractSchema = T extends Hono ? S : never diff --git a/packages/valibot-validator/tsup.config.ts b/packages/valibot-validator/tsup.config.ts index b3b7e42d5..33194da7c 100644 --- a/packages/valibot-validator/tsup.config.ts +++ b/packages/valibot-validator/tsup.config.ts @@ -1,9 +1,9 @@ -import { defineConfig } from "tsup"; +import { defineConfig } from 'tsup' export default defineConfig({ - entryPoints: ["src/index.ts"], - format: ["cjs", "esm"], + entryPoints: ['src/index.ts'], + format: ['cjs', 'esm'], dts: true, - outDir: "dist", + outDir: 'dist', clean: true, -}); \ No newline at end of file +}) diff --git a/packages/zod-openapi/src/index.ts b/packages/zod-openapi/src/index.ts index 58ee6e558..af4922014 100644 --- a/packages/zod-openapi/src/index.ts +++ b/packages/zod-openapi/src/index.ts @@ -26,7 +26,6 @@ import type { ValidationTargets, } from 'hono' import type { MergePath, MergeSchemaPath } from 'hono/types' -import type { JSONParsed, JSONValue, RemoveBlankRecord, SimplifyDeepArray } from 'hono/utils/types' import type { ClientErrorStatusCode, InfoStatusCode, @@ -35,6 +34,7 @@ import type { StatusCode, SuccessStatusCode, } from 'hono/utils/http-status' +import type { JSONParsed, JSONValue, RemoveBlankRecord, SimplifyDeepArray } from 'hono/utils/types' import { mergePath } from 'hono/utils/url' import type { ZodError, ZodSchema } from 'zod' import { ZodType, z } from 'zod' @@ -657,7 +657,6 @@ export class OpenAPIHono< } }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any return this as any } diff --git a/packages/zod-openapi/test/index.test-d.ts b/packages/zod-openapi/test/index.test-d.ts index e23ab9de9..ec9354ef2 100644 --- a/packages/zod-openapi/test/index.test-d.ts +++ b/packages/zod-openapi/test/index.test-d.ts @@ -1,8 +1,9 @@ -import { assertType, describe, it } from 'vitest' -import { MiddlewareToHandlerType, OfHandlerType, OpenAPIHono, createRoute, z } from '../src/index' import { createMiddleware } from 'hono/factory' import type { ExtractSchema } from 'hono/types' import type { Equal, Expect } from 'hono/utils/types' +import { assertType, describe, it } from 'vitest' +import { OpenAPIHono, createRoute, z } from '../src/index' +import type { MiddlewareToHandlerType, OfHandlerType } from '../src/index' describe('Types', () => { const RequestSchema = z.object({ @@ -276,7 +277,7 @@ describe('Middleware', () => { }) it('Should infer Env from router middleware', async () => { - const app = new OpenAPIHono<{ Variables: { too: Symbol } }>() + const app = new OpenAPIHono<{ Variables: { too: symbol } }>() app.openapi( createRoute({ method: 'get', @@ -308,7 +309,7 @@ describe('Middleware', () => { type verifyFoo = Expect> type verifyBar = Expect> - type verifyToo = Expect> + type verifyToo = Expect> return c.json({}) } @@ -316,7 +317,7 @@ describe('Middleware', () => { }) it('Should infer Env root when no middleware provided', async () => { - const app = new OpenAPIHono<{ Variables: { too: Symbol } }>() + const app = new OpenAPIHono<{ Variables: { too: symbol } }>() app.openapi( createRoute({ method: 'get', @@ -331,7 +332,7 @@ describe('Middleware', () => { (c) => { c.var.too - type verify = Expect> + type verify = Expect> return c.json({}) } diff --git a/packages/zod-openapi/test/index.test.ts b/packages/zod-openapi/test/index.test.ts index 375c325e4..8f08f3c84 100644 --- a/packages/zod-openapi/test/index.test.ts +++ b/packages/zod-openapi/test/index.test.ts @@ -1,14 +1,14 @@ import type { RouteConfig } from '@asteasolutions/zod-to-openapi' import type { Context, TypedResponse } from 'hono' +import { accepts } from 'hono/accepts' import { bearerAuth } from 'hono/bearer-auth' import { hc } from 'hono/client' +import type { ServerErrorStatusCode } from 'hono/utils/http-status' +import type { Equal, Expect } from 'hono/utils/types' import { describe, expect, expectTypeOf, it, vi } from 'vitest' +import { stringify } from 'yaml' import type { RouteConfigToTypedResponse } from '../src/index' import { OpenAPIHono, createRoute, z } from '../src/index' -import type { Equal, Expect } from 'hono/utils/types' -import type { ServerErrorStatusCode } from 'hono/utils/http-status' -import { stringify } from 'yaml' -import { accepts } from 'hono/accepts' describe('Constructor', () => { it('Should not require init object', () => { diff --git a/packages/zod-validator/src/index.ts b/packages/zod-validator/src/index.ts index bdccd3a81..8a96e9d3c 100644 --- a/packages/zod-validator/src/index.ts +++ b/packages/zod-validator/src/index.ts @@ -1,6 +1,7 @@ import type { Context, Env, Input, MiddlewareHandler, TypedResponse, ValidationTargets } from 'hono' import { validator } from 'hono/validator' -import { ZodObject, type ZodError, type ZodSchema, type z } from 'zod' +import { ZodObject } from 'zod' +import type { ZodError, ZodSchema, z } from 'zod' export type Hook< T, diff --git a/packages/zod-validator/test/index.test.ts b/packages/zod-validator/test/index.test.ts index b0e863797..390862ddf 100644 --- a/packages/zod-validator/test/index.test.ts +++ b/packages/zod-validator/test/index.test.ts @@ -1,8 +1,8 @@ import { Hono } from 'hono' import type { Equal, Expect } from 'hono/utils/types' +import { vi } from 'vitest' import { z } from 'zod' import { zValidator } from '../src' -import { vi } from 'vitest' // eslint-disable-next-line @typescript-eslint/no-unused-vars type ExtractSchema = T extends Hono ? S : never diff --git a/yarn.lock b/yarn.lock index dd3c4665c..1ddd55f98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2221,6 +2221,13 @@ __metadata: languageName: node linkType: hard +"@eslint-community/regexpp@npm:^4.12.1": + version: 4.12.1 + resolution: "@eslint-community/regexpp@npm:4.12.1" + checksum: a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 + languageName: node + linkType: hard + "@eslint-community/regexpp@npm:^4.4.0": version: 4.11.1 resolution: "@eslint-community/regexpp@npm:4.11.1" @@ -2246,6 +2253,26 @@ __metadata: languageName: node linkType: hard +"@eslint/config-array@npm:^0.19.0": + version: 0.19.1 + resolution: "@eslint/config-array@npm:0.19.1" + dependencies: + "@eslint/object-schema": "npm:^2.1.5" + debug: "npm:^4.3.1" + minimatch: "npm:^3.1.2" + checksum: 43b01f596ddad404473beae5cf95c013d29301c72778d0f5bf8a6699939c8a9a5663dbd723b53c5f476b88b0c694f76ea145d1aa9652230d140fe1161e4a4b49 + languageName: node + linkType: hard + +"@eslint/core@npm:^0.9.0": + version: 0.9.1 + resolution: "@eslint/core@npm:0.9.1" + dependencies: + "@types/json-schema": "npm:^7.0.15" + checksum: 638104b1b5833a9bbf2329f0c0ddf322e4d6c0410b149477e02cd2b78c04722be90c14b91b8ccdef0d63a2404dff72a17b6b412ce489ea429ae6a8fcb8abff28 + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^2.1.4": version: 2.1.4 resolution: "@eslint/eslintrc@npm:2.1.4" @@ -2280,6 +2307,23 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^3.2.0": + version: 3.2.0 + resolution: "@eslint/eslintrc@npm:3.2.0" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.3.2" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" + strip-json-comments: "npm:^3.1.1" + checksum: 43867a07ff9884d895d9855edba41acf325ef7664a8df41d957135a81a477ff4df4196f5f74dc3382627e5cc8b7ad6b815c2cea1b58f04a75aced7c43414ab8b + languageName: node + linkType: hard + "@eslint/js@npm:8.57.0": version: 8.57.0 resolution: "@eslint/js@npm:8.57.0" @@ -2294,6 +2338,13 @@ __metadata: languageName: node linkType: hard +"@eslint/js@npm:9.17.0": + version: 9.17.0 + resolution: "@eslint/js@npm:9.17.0" + checksum: a0fda8657a01c60aa540f95397754267ba640ffb126e011b97fd65c322a94969d161beeaef57c1441c495da2f31167c34bd38209f7c146c7225072378c3a933d + languageName: node + linkType: hard + "@eslint/object-schema@npm:^2.1.4": version: 2.1.4 resolution: "@eslint/object-schema@npm:2.1.4" @@ -2301,6 +2352,13 @@ __metadata: languageName: node linkType: hard +"@eslint/object-schema@npm:^2.1.5": + version: 2.1.5 + resolution: "@eslint/object-schema@npm:2.1.5" + checksum: 5320691ed41ecd09a55aff40ce8e56596b4eb81f3d4d6fe530c50fdd6552d88102d1c1a29d970ae798ce30849752a708772de38ded07a6f25b3da32ebea081d8 + languageName: node + linkType: hard + "@eslint/plugin-kit@npm:^0.1.0": version: 0.1.0 resolution: "@eslint/plugin-kit@npm:0.1.0" @@ -2310,6 +2368,15 @@ __metadata: languageName: node linkType: hard +"@eslint/plugin-kit@npm:^0.2.3": + version: 0.2.4 + resolution: "@eslint/plugin-kit@npm:0.2.4" + dependencies: + levn: "npm:^0.4.1" + checksum: 1bcfc0a30b1df891047c1d8b3707833bded12a057ba01757a2a8591fdc8d8fe0dbb8d51d4b0b61b2af4ca1d363057abd7d2fb4799f1706b105734f4d3fa0dbf1 + languageName: node + linkType: hard + "@fastify/busboy@npm:^2.0.0": version: 2.1.0 resolution: "@fastify/busboy@npm:2.1.0" @@ -2719,6 +2786,7 @@ __metadata: version: 0.0.0-use.local resolution: "@hono/oidc-auth@workspace:packages/oidc-auth" dependencies: + "@jest/globals": "npm:^29.7.0" "@types/jest": "npm:^29.5.11" "@types/jsonwebtoken": "npm:^9.0.5" hono: "npm:^4.0.1" @@ -2958,6 +3026,23 @@ __metadata: languageName: unknown linkType: soft +"@humanfs/core@npm:^0.19.1": + version: 0.19.1 + resolution: "@humanfs/core@npm:0.19.1" + checksum: aa4e0152171c07879b458d0e8a704b8c3a89a8c0541726c6b65b81e84fd8b7564b5d6c633feadc6598307d34564bd53294b533491424e8e313d7ab6c7bc5dc67 + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.6 + resolution: "@humanfs/node@npm:0.16.6" + dependencies: + "@humanfs/core": "npm:^0.19.1" + "@humanwhocodes/retry": "npm:^0.3.0" + checksum: 8356359c9f60108ec204cbd249ecd0356667359b2524886b357617c4a7c3b6aace0fd5a369f63747b926a762a88f8a25bc066fa1778508d110195ce7686243e1 + languageName: node + linkType: hard + "@humanwhocodes/config-array@npm:^0.11.14": version: 0.11.14 resolution: "@humanwhocodes/config-array@npm:0.11.14" @@ -2990,6 +3075,13 @@ __metadata: languageName: node linkType: hard +"@humanwhocodes/retry@npm:^0.4.1": + version: 0.4.1 + resolution: "@humanwhocodes/retry@npm:0.4.1" + checksum: be7bb6841c4c01d0b767d9bb1ec1c9359ee61421ce8ba66c249d035c5acdfd080f32d55a5c9e859cdd7868788b8935774f65b2caf24ec0b7bd7bf333791f063b + languageName: node + linkType: hard + "@iarna/toml@npm:^2.2.5": version: 2.2.5 resolution: "@iarna/toml@npm:2.2.5" @@ -4908,7 +5000,7 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:1.0.6": +"@types/estree@npm:1.0.6, @types/estree@npm:^1.0.6": version: 1.0.6 resolution: "@types/estree@npm:1.0.6" checksum: cdfd751f6f9065442cd40957c07fd80361c962869aa853c1c2fd03e101af8b9389d8ff4955a43a6fcfa223dd387a089937f95be0f3eec21ca527039fd2d9859a @@ -5002,7 +5094,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db @@ -6105,6 +6197,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.14.0": + version: 8.14.0 + resolution: "acorn@npm:8.14.0" + bin: + acorn: bin/acorn + checksum: 6d4ee461a7734b2f48836ee0fbb752903606e576cc100eb49340295129ca0b452f3ba91ddd4424a1d4406a98adfb2ebb6bd0ff4c49d7a0930c10e462719bbfd7 + languageName: node + linkType: hard + "agent-base@npm:6": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -8011,6 +8112,17 @@ __metadata: languageName: node linkType: hard +"cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 053ea8b2135caff68a9e81470e845613e374e7309a47731e81639de3eaeb90c3d01af0e0b44d2ab9d50b43467223b88567dfeb3262db942dc063b9976718ffc1 + languageName: node + linkType: hard + "crypto-random-string@npm:^2.0.0": version: 2.0.0 resolution: "crypto-random-string@npm:2.0.0" @@ -9695,6 +9807,16 @@ __metadata: languageName: node linkType: hard +"eslint-scope@npm:^8.2.0": + version: 8.2.0 + resolution: "eslint-scope@npm:8.2.0" + dependencies: + esrecurse: "npm:^4.3.0" + estraverse: "npm:^5.2.0" + checksum: 8d2d58e2136d548ac7e0099b1a90d9fab56f990d86eb518de1247a7066d38c908be2f3df477a79cf60d70b30ba18735d6c6e70e9914dca2ee515a729975d70d6 + languageName: node + linkType: hard + "eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" @@ -9709,6 +9831,13 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^4.2.0": + version: 4.2.0 + resolution: "eslint-visitor-keys@npm:4.2.0" + checksum: 2ed81c663b147ca6f578312919483eb040295bbab759e5a371953456c636c5b49a559883e2677112453728d66293c0a4c90ab11cab3428cf02a0236d2e738269 + languageName: node + linkType: hard + "eslint@npm:^8.57.0": version: 8.57.0 resolution: "eslint@npm:8.57.0" @@ -9806,6 +9935,55 @@ __metadata: languageName: node linkType: hard +"eslint@npm:^9.17.0": + version: 9.17.0 + resolution: "eslint@npm:9.17.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.2.0" + "@eslint-community/regexpp": "npm:^4.12.1" + "@eslint/config-array": "npm:^0.19.0" + "@eslint/core": "npm:^0.9.0" + "@eslint/eslintrc": "npm:^3.2.0" + "@eslint/js": "npm:9.17.0" + "@eslint/plugin-kit": "npm:^0.2.3" + "@humanfs/node": "npm:^0.16.6" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@humanwhocodes/retry": "npm:^0.4.1" + "@types/estree": "npm:^1.0.6" + "@types/json-schema": "npm:^7.0.15" + ajv: "npm:^6.12.4" + chalk: "npm:^4.0.0" + cross-spawn: "npm:^7.0.6" + debug: "npm:^4.3.2" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^8.2.0" + eslint-visitor-keys: "npm:^4.2.0" + espree: "npm:^10.3.0" + esquery: "npm:^1.5.0" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:^8.0.0" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + ignore: "npm:^5.2.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + lodash.merge: "npm:^4.6.2" + minimatch: "npm:^3.1.2" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.3" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + bin: + eslint: bin/eslint.js + checksum: 9edd8dd782b4ae2eb00a158ed4708194835d4494d75545fa63a51f020ed17f865c49b4ae1914a2ecbc7fdb262bd8059e811aeef9f0bae63dced9d3293be1bbdd + languageName: node + linkType: hard + "espree@npm:^10.0.1, espree@npm:^10.1.0": version: 10.1.0 resolution: "espree@npm:10.1.0" @@ -9817,6 +9995,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^10.3.0": + version: 10.3.0 + resolution: "espree@npm:10.3.0" + dependencies: + acorn: "npm:^8.14.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^4.2.0" + checksum: 272beeaca70d0a1a047d61baff64db04664a33d7cfb5d144f84bc8a5c6194c6c8ebe9cc594093ca53add88baa23e59b01e69e8a0160ab32eac570482e165c462 + languageName: node + linkType: hard + "espree@npm:^9.0.0, espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" @@ -11398,9 +11587,7 @@ __metadata: "@types/node": "npm:^20.10.4" "@typescript-eslint/eslint-plugin": "npm:^8.7.0" "@typescript-eslint/parser": "npm:^8.7.0" - eslint: "npm:^8.57.0" - eslint-plugin-import-x: "npm:^4.1.1" - eslint-plugin-n: "npm:^17.10.2" + eslint: "npm:^9.17.0" jest: "npm:^29.5.0" jest-environment-miniflare: "npm:^2.14.1" npm-run-all2: "npm:^6.2.2"