feat: Clerk Middleware (#151)
* initial commit * wip * Update README.md * tests(clerk-auth): Setup testing and added first test * docs(clerk-auth): Update README.md * tests(clerk-auth): Added some more tests * chore(clerk-auth): Added refernece in tests * ci(clerk-atuh): Add Clerk Auth workflow * use `env` helper to get enviroment variables --------- Co-authored-by: Yusuke Wada <yusuke@kamawada.com>pull/213/head
parent
90d3e84831
commit
a18da2a545
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/clerk-auth': major
|
||||
---
|
||||
|
||||
Added Clerk Middleware
|
|
@ -0,0 +1,25 @@
|
|||
name: ci-clerk-auth
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'packages/clerk-auth/**'
|
||||
pull_request:
|
||||
branches: ['*']
|
||||
paths:
|
||||
- 'packages/clerk-auth/**'
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./packages/clerk-auth
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.x
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn build
|
||||
- run: yarn test
|
|
@ -15,6 +15,7 @@
|
|||
"build:sentry": "yarn workspace @hono/sentry build",
|
||||
"build:firebase-auth": "yarn workspace @hono/firebase-auth build",
|
||||
"build:trpc-server": "yarn workspace @hono/trpc-server build",
|
||||
"build:clerk-auth": "yarn workspace @hono/clerk-auth build",
|
||||
"build:typebox-validator": "yarn workspace @hono/typebox-validator build",
|
||||
"build:medley-router": "yarn workspace @hono/medley-router build",
|
||||
"build:valibot-validator": "yarn workspace @hono/valibot-validator build",
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
# Clerk middleware for Hono
|
||||
|
||||
This is a [Clerk](https://clerk.com) third-party middleware for [Hono](https://github.com/honojs/hono).
|
||||
|
||||
This middleware can be used to inject the active Clerk session into the request context.
|
||||
|
||||
## Installation
|
||||
|
||||
```plain
|
||||
npm i hono @hono/clerk-auth @clerk/backend
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Before starting using the middleware you must set the following environment variables:
|
||||
|
||||
```plain
|
||||
CLERK_SECRET_KEY=<You-secret-key>
|
||||
CLERK_PUBLISHABLE_KEY=<Your-publishable-key>
|
||||
```
|
||||
|
||||
## How to Use
|
||||
|
||||
```ts
|
||||
import { clerkMiddleware, getAuth } from '@hono/clerk-auth'
|
||||
import { Hono } from 'hono'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use('*', clerkMiddleware())
|
||||
app.get('/', (c) => {
|
||||
const auth = getAuth(c)
|
||||
|
||||
if (!auth?.userId) {
|
||||
return c.json({
|
||||
message: 'You are not logged in.'
|
||||
})
|
||||
}
|
||||
|
||||
return c.json({
|
||||
message: 'You are logged in!',
|
||||
userId: auth.userId
|
||||
})
|
||||
})
|
||||
|
||||
export default app
|
||||
```
|
||||
|
||||
## Accessing instance of Backend API client
|
||||
|
||||
```ts
|
||||
import { clerkMiddleware, getAuth } from '@hono/clerk-auth'
|
||||
import { Hono } from 'hono'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use('*', clerkMiddleware())
|
||||
app.get('/', async (c) => {
|
||||
const clerk = c.get('clerk')
|
||||
|
||||
try {
|
||||
const user = await clerkClient.users.getUser('user_id_....')
|
||||
|
||||
return c.json({
|
||||
user,
|
||||
})
|
||||
} catch (e) {
|
||||
return c.json({
|
||||
message: 'User not found.'
|
||||
}, 404)
|
||||
}
|
||||
})
|
||||
|
||||
export default app
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
Vaggelis Yfantis <https://github.com/octoper>
|
|
@ -0,0 +1,12 @@
|
|||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||
module.exports = {
|
||||
displayName: 'hono',
|
||||
injectGlobals: true,
|
||||
testMatch: ['**/test/**/*.+(ts|tsx|js)', '**/src/**/(*.)+(spec|test).+(ts|tsx|js)'],
|
||||
transform: { '^.+\\.m?tsx?$': 'ts-jest' },
|
||||
testPathIgnorePatterns: ['/node_modules/', '/jest/'],
|
||||
moduleNameMapper: {
|
||||
'#crypto': '@clerk/backend/dist/runtime/node/crypto.js',
|
||||
'#fetch': '@clerk/backend/dist/runtime/node/fetch.js',
|
||||
},
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "@hono/clerk-auth",
|
||||
"version": "0.0.0",
|
||||
"description": "A third-party Clerk auth middleware for Hono",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "rimraf dist && tsc",
|
||||
"prerelease": "yarn build && yarn test",
|
||||
"release": "yarn publish"
|
||||
},
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org",
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/honojs/middleware.git"
|
||||
},
|
||||
"homepage": "https://github.com/honojs/middleware",
|
||||
"peerDependencies": {
|
||||
"@clerk/backend": "0.30.*",
|
||||
"hono": "3.*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clerk/backend": "^0.30.1",
|
||||
"hono": "^3.7.3",
|
||||
"node-fetch-native": "^1.4.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
import type { ClerkOptions } from '@clerk/backend'
|
||||
import { Clerk, createIsomorphicRequest, constants } from '@clerk/backend'
|
||||
import type { Context, MiddlewareHandler } from 'hono'
|
||||
import { env } from 'hono/adapter'
|
||||
|
||||
type ClerkAuth = Awaited<ReturnType<ReturnType<typeof Clerk>['authenticateRequest']>>['toAuth']
|
||||
|
||||
declare module 'hono' {
|
||||
interface ContextVariableMap {
|
||||
clerk: ReturnType<typeof Clerk>
|
||||
clerkAuth: ReturnType<ClerkAuth>
|
||||
}
|
||||
}
|
||||
|
||||
export const getAuth = (c: Context) => {
|
||||
return c.get('clerkAuth')
|
||||
}
|
||||
|
||||
type ClerkEnv = {
|
||||
CLERK_SECRET_KEY: string
|
||||
CLERK_PUBLISHABLE_KEY: string
|
||||
CLERK_API_URL: string
|
||||
CLERK_API_VERSION: string
|
||||
CLERK_FRONTEND_API: string
|
||||
}
|
||||
|
||||
export const clerkMiddleware = (options?: ClerkOptions): MiddlewareHandler => {
|
||||
return async (c, next) => {
|
||||
const clerkEnv = env<ClerkEnv>(c)
|
||||
const { secretKey, publishableKey, apiUrl, apiVersion, ...rest } = options || {
|
||||
secretKey: clerkEnv.CLERK_SECRET_KEY || '',
|
||||
publishableKey: clerkEnv.CLERK_PUBLISHABLE_KEY || '',
|
||||
apiUrl: clerkEnv.CLERK_API_URL || 'https://api.clerk.dev',
|
||||
apiVersion: clerkEnv.CLERK_API_VERSION || 'v1',
|
||||
}
|
||||
const frontendApi = clerkEnv.CLERK_FRONTEND_API || ''
|
||||
if (!secretKey) {
|
||||
throw new Error('Missing Clerk Secret key')
|
||||
}
|
||||
|
||||
if (!publishableKey) {
|
||||
throw new Error('Missing Clerk Publishable key')
|
||||
}
|
||||
|
||||
const clerkClient = Clerk({
|
||||
...rest,
|
||||
apiUrl,
|
||||
apiVersion,
|
||||
secretKey,
|
||||
publishableKey,
|
||||
})
|
||||
|
||||
const requestState = await clerkClient.authenticateRequest({
|
||||
...rest,
|
||||
secretKey,
|
||||
publishableKey,
|
||||
request: createIsomorphicRequest((Request) => {
|
||||
return new Request(c.req.url, {
|
||||
method: c.req.method,
|
||||
headers: c.req.raw.headers,
|
||||
})
|
||||
}),
|
||||
})
|
||||
|
||||
// Interstitial cases
|
||||
if (requestState.isUnknown) {
|
||||
c.header(constants.Headers.AuthReason, requestState.reason)
|
||||
c.header(constants.Headers.AuthMessage, requestState.message)
|
||||
return c.body(null, 401)
|
||||
}
|
||||
|
||||
if (requestState.isInterstitial) {
|
||||
const interstitialHtmlPage = clerkClient.localInterstitial({
|
||||
publishableKey,
|
||||
frontendApi,
|
||||
})
|
||||
|
||||
c.header(constants.Headers.AuthReason, requestState.reason)
|
||||
c.header(constants.Headers.AuthMessage, requestState.message)
|
||||
|
||||
return c.html(interstitialHtmlPage, 401)
|
||||
}
|
||||
|
||||
c.set('clerkAuth', requestState.toAuth())
|
||||
c.set('clerk', clerkClient)
|
||||
|
||||
await next()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { Hono } from 'hono'
|
||||
import { clerkMiddleware, getAuth } from '../src'
|
||||
|
||||
const EnvVariables = {
|
||||
CLERK_SECRET_KEY: 'TEST_API_KEY',
|
||||
CLERK_PUBLISHABLE_KEY: 'TEST_API_KEY',
|
||||
}
|
||||
|
||||
const authenticateRequestMock = jest.fn()
|
||||
const localInterstitialMock = jest.fn()
|
||||
|
||||
jest.mock('@clerk/backend', () => {
|
||||
return {
|
||||
...jest.requireActual('@clerk/backend'),
|
||||
Clerk: () => {
|
||||
return {
|
||||
authenticateRequest: (...args: any) => authenticateRequestMock(...args),
|
||||
localInterstitial: (...args: any) => localInterstitialMock(...args),
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
// Test are based on Clerk's test suite for Fastify plugin - https://github.com/clerkinc/javascript/blob/main/packages/fastify/src/withClerkMiddleware.test.ts
|
||||
describe('clerkMiddleware()', () => {
|
||||
beforeEach(() => {
|
||||
process.env.CLERK_SECRET_KEY = EnvVariables.CLERK_SECRET_KEY
|
||||
process.env.CLERK_PUBLISHABLE_KEY = EnvVariables.CLERK_PUBLISHABLE_KEY
|
||||
jest.clearAllMocks()
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
test('handles signin with Authorization Bearer', async () => {
|
||||
authenticateRequestMock.mockResolvedValue({
|
||||
isUnknown: false,
|
||||
isInterstitial: false,
|
||||
isSignedIn: true,
|
||||
toAuth: () => 'mockedAuth',
|
||||
})
|
||||
const app = new Hono()
|
||||
app.use('*', clerkMiddleware())
|
||||
|
||||
app.get('/', (ctx) => {
|
||||
const auth = getAuth(ctx)
|
||||
return ctx.json({ auth })
|
||||
})
|
||||
|
||||
const req = new Request('http://localhost/', {
|
||||
headers: {
|
||||
Authorization: 'Bearer deadbeef',
|
||||
Origin: 'http://origin.com',
|
||||
Host: 'host.com',
|
||||
'X-Forwarded-Port': '1234',
|
||||
'X-Forwarded-Host': 'forwarded-host.com',
|
||||
Referer: 'referer.com',
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
|
||||
},
|
||||
})
|
||||
|
||||
const response = await app.request(req)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(await response.json()).toEqual({ auth: 'mockedAuth' })
|
||||
expect(authenticateRequestMock).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
secretKey: EnvVariables.CLERK_SECRET_KEY,
|
||||
publishableKey: EnvVariables.CLERK_PUBLISHABLE_KEY,
|
||||
request: expect.any(Request),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
test('handles signin with cookie', async () => {
|
||||
authenticateRequestMock.mockResolvedValue({
|
||||
isUnknown: false,
|
||||
isInterstitial: false,
|
||||
isSignedIn: true,
|
||||
toAuth: () => 'mockedAuth',
|
||||
})
|
||||
const app = new Hono()
|
||||
app.use('*', clerkMiddleware())
|
||||
|
||||
app.get('/', (ctx) => {
|
||||
const auth = getAuth(ctx)
|
||||
return ctx.json({ auth })
|
||||
})
|
||||
|
||||
const req = new Request('http://localhost/', {
|
||||
headers: {
|
||||
cookie: '_gcl_au=value1; ko_id=value2; __session=deadbeef; __client_uat=1675692233',
|
||||
Origin: 'http://origin.com',
|
||||
Host: 'host.com',
|
||||
'X-Forwarded-Port': '1234',
|
||||
'X-Forwarded-Host': 'forwarded-host.com',
|
||||
Referer: 'referer.com',
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
|
||||
},
|
||||
})
|
||||
|
||||
const response = await app.request(req)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(await response.json()).toEqual({ auth: 'mockedAuth' })
|
||||
expect(authenticateRequestMock).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
secretKey: EnvVariables.CLERK_SECRET_KEY,
|
||||
publishableKey: EnvVariables.CLERK_PUBLISHABLE_KEY,
|
||||
request: expect.any(Request),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
test('handles unknown case by terminating the request with empty response and 401 http code', async () => {
|
||||
authenticateRequestMock.mockResolvedValue({
|
||||
isUnknown: true,
|
||||
isInterstitial: false,
|
||||
isSignedIn: false,
|
||||
reason: 'auth-reason',
|
||||
message: 'auth-message',
|
||||
toAuth: () => 'mockedAuth',
|
||||
})
|
||||
const app = new Hono()
|
||||
app.use('*', clerkMiddleware())
|
||||
|
||||
app.get('/', (ctx) => {
|
||||
const auth = getAuth(ctx)
|
||||
return ctx.json({ auth })
|
||||
})
|
||||
|
||||
const req = new Request('http://localhost/', {
|
||||
headers: {
|
||||
cookie: '_gcl_au=value1; ko_id=value2; __session=deadbeef; __client_uat=1675692233',
|
||||
},
|
||||
})
|
||||
|
||||
const response = await app.request(req)
|
||||
|
||||
expect(response.status).toEqual(401)
|
||||
expect(response.headers.get('x-clerk-auth-reason')).toEqual('auth-reason')
|
||||
expect(response.headers.get('x-clerk-auth-message')).toEqual('auth-message')
|
||||
expect(await response.text()).toEqual('')
|
||||
})
|
||||
|
||||
test('handles interstitial case by terminating the request with interstitial html page and 401 http code', async () => {
|
||||
authenticateRequestMock.mockResolvedValue({
|
||||
isUnknown: false,
|
||||
isInterstitial: true,
|
||||
isSignedIn: false,
|
||||
reason: 'auth-reason',
|
||||
message: 'auth-message',
|
||||
toAuth: () => 'mockedAuth',
|
||||
})
|
||||
localInterstitialMock.mockReturnValue('<html><body>Interstitial</body></html>')
|
||||
const app = new Hono()
|
||||
app.use('*', clerkMiddleware())
|
||||
|
||||
app.get('/', (ctx) => {
|
||||
const auth = getAuth(ctx)
|
||||
return ctx.json({ auth })
|
||||
})
|
||||
|
||||
const req = new Request('http://localhost/', {
|
||||
headers: {
|
||||
cookie: '_gcl_au=value1; ko_id=value2; __session=deadbeef; __client_uat=1675692233',
|
||||
},
|
||||
})
|
||||
|
||||
const response = await app.request(req)
|
||||
|
||||
expect(response.status).toEqual(401)
|
||||
expect(response.headers.get('content-type')).toMatch('text/html')
|
||||
expect(response.headers.get('x-clerk-auth-reason')).toEqual('auth-reason')
|
||||
expect(response.headers.get('x-clerk-auth-message')).toEqual('auth-message')
|
||||
expect(await response.text()).toEqual('<html><body>Interstitial</body></html>')
|
||||
})
|
||||
|
||||
test('handles signout case by populating the req.auth', async () => {
|
||||
authenticateRequestMock.mockResolvedValue({
|
||||
isUnknown: false,
|
||||
isInterstitial: false,
|
||||
isSignedIn: false,
|
||||
toAuth: () => 'mockedAuth',
|
||||
})
|
||||
const app = new Hono()
|
||||
app.use('*', clerkMiddleware())
|
||||
|
||||
app.get('/', (ctx) => {
|
||||
const auth = getAuth(ctx)
|
||||
return ctx.json({ auth })
|
||||
})
|
||||
|
||||
const req = new Request('http://localhost/', {
|
||||
headers: {
|
||||
Authorization: 'Bearer deadbeef',
|
||||
},
|
||||
})
|
||||
|
||||
const response = await app.request(req)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(await response.json()).toEqual({ auth: 'mockedAuth' })
|
||||
expect(authenticateRequestMock).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
secretKey: EnvVariables.CLERK_SECRET_KEY,
|
||||
publishableKey: EnvVariables.CLERK_PUBLISHABLE_KEY,
|
||||
request: expect.any(Request),
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
}
|
172
yarn.lock
172
yarn.lock
|
@ -560,6 +560,27 @@
|
|||
human-id "^1.0.2"
|
||||
prettier "^2.7.1"
|
||||
|
||||
"@clerk/backend@^0.30.1":
|
||||
version "0.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@clerk/backend/-/backend-0.30.1.tgz#23179c68f0ce8a94d99bc2e8c5000cf896c8e577"
|
||||
integrity sha512-+769bWE89Ejdy4ddu4wF/yBZypGVA5G/vAerJsXv/sdos3rSFtSghLx5OMdatn/2XqZUnrZoQGLtUz5ZxzDJXg==
|
||||
dependencies:
|
||||
"@clerk/types" "^3.53.0"
|
||||
"@peculiar/webcrypto" "1.4.1"
|
||||
"@types/node" "16.18.6"
|
||||
cookie "0.5.0"
|
||||
deepmerge "4.2.2"
|
||||
node-fetch-native "1.0.1"
|
||||
snakecase-keys "5.4.4"
|
||||
tslib "2.4.1"
|
||||
|
||||
"@clerk/types@^3.53.0":
|
||||
version "3.53.0"
|
||||
resolved "https://registry.yarnpkg.com/@clerk/types/-/types-3.53.0.tgz#5a7436e0ff89134401edafef7d50557e626a928f"
|
||||
integrity sha512-V+9BvKAo9f2ShgP+RpQ/MgJTbx4ayk3sYiFbMtLYlmtLCsn0xwglfP7i++7640d6+MAtCnMTAcrTp61IvUxSFw==
|
||||
dependencies:
|
||||
csstype "3.1.1"
|
||||
|
||||
"@cloudflare/workers-types@^3.14.0", "@cloudflare/workers-types@^3.14.1":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-3.19.0.tgz#f3791b80b23f7cf0072f2e67e98aa37801204b6c"
|
||||
|
@ -1621,6 +1642,33 @@
|
|||
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.3.1.tgz#ba07b864a3c955f061aa30ea3ef7f4ae4449794a"
|
||||
integrity sha512-wU5J8rUoo32oSef/rFpOT1HIjLjAv3qIDHkw1QIhODV3OpAVHi5oVzlouozg9obUmZKtbZ0qUe/m7FP0y0yBzA==
|
||||
|
||||
"@peculiar/asn1-schema@^2.3.0", "@peculiar/asn1-schema@^2.3.6":
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz#3dd3c2ade7f702a9a94dfb395c192f5fa5d6b922"
|
||||
integrity sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==
|
||||
dependencies:
|
||||
asn1js "^3.0.5"
|
||||
pvtsutils "^1.3.2"
|
||||
tslib "^2.4.0"
|
||||
|
||||
"@peculiar/json-schema@^1.1.12":
|
||||
version "1.1.12"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/json-schema/-/json-schema-1.1.12.tgz#fe61e85259e3b5ba5ad566cb62ca75b3d3cd5339"
|
||||
integrity sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==
|
||||
dependencies:
|
||||
tslib "^2.0.0"
|
||||
|
||||
"@peculiar/webcrypto@1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/webcrypto/-/webcrypto-1.4.1.tgz#821493bd5ad0f05939bd5f53b28536f68158360a"
|
||||
integrity sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.3.0"
|
||||
"@peculiar/json-schema" "^1.1.12"
|
||||
pvtsutils "^1.3.2"
|
||||
tslib "^2.4.1"
|
||||
webcrypto-core "^1.7.4"
|
||||
|
||||
"@pkgjs/parseargs@^0.11.0":
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
|
||||
|
@ -2093,6 +2141,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe"
|
||||
integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==
|
||||
|
||||
"@types/node@16.18.6":
|
||||
version "16.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.6.tgz#87846192fd51b693368fad3e99123169225621d4"
|
||||
integrity sha512-vmYJF0REqDyyU0gviezF/KHq/fYaUbFhkcNbQCuPGFQj6VTbXuHZoxs/Y7mutWe73C8AC6l9fFu8mSYiBAqkGA==
|
||||
|
||||
"@types/node@^12.7.1":
|
||||
version "12.20.55"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
|
||||
|
@ -2636,6 +2689,15 @@ asn1@~0.2.3:
|
|||
dependencies:
|
||||
safer-buffer "~2.1.0"
|
||||
|
||||
asn1js@^3.0.1, asn1js@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.5.tgz#5ea36820443dbefb51cc7f88a2ebb5b462114f38"
|
||||
integrity sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==
|
||||
dependencies:
|
||||
pvtsutils "^1.3.2"
|
||||
pvutils "^1.1.3"
|
||||
tslib "^2.4.0"
|
||||
|
||||
assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
|
@ -3755,6 +3817,11 @@ csso@^5.0.5:
|
|||
dependencies:
|
||||
css-tree "~2.2.0"
|
||||
|
||||
csstype@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
|
||||
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
|
||||
|
||||
csstype@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
|
||||
|
@ -3908,6 +3975,11 @@ deep-is@^0.1.3, deep-is@~0.1.3:
|
|||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
||||
deepmerge@4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
||||
|
||||
deepmerge@^4.2.2:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
|
||||
|
@ -4117,6 +4189,14 @@ domutils@^3.0.1:
|
|||
domelementtype "^2.3.0"
|
||||
domhandler "^5.0.3"
|
||||
|
||||
dot-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
|
||||
integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==
|
||||
dependencies:
|
||||
no-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
dot-prop@^5.2.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
|
||||
|
@ -5869,6 +5949,11 @@ hono@^3.5.8:
|
|||
resolved "https://registry.yarnpkg.com/hono/-/hono-3.5.8.tgz#9bbc412f5a54183cf2a81a36a9b9ea56da10f785"
|
||||
integrity sha512-ZipTmGfHm43q5QOEBGog2wyejyNUcicjPt0BLDQ8yz9xij/y9RYXRpR1YPxMpQqeyNM7isvpsIAe9Ems51Wq0Q==
|
||||
|
||||
hono@^3.7.3:
|
||||
version "3.7.3"
|
||||
resolved "https://registry.yarnpkg.com/hono/-/hono-3.7.3.tgz#01fd88360e9a431235110197fbb5a998131e104e"
|
||||
integrity sha512-BQHdLPXb30hQ9k+04byeSi4QMHk20U1GUq0nT5kGUCGZtxeYhAS7mUJ1wgjn4SCvgiw1rcc6oBOAlwJQ7jQymA==
|
||||
|
||||
hono@^3.7.2:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.yarnpkg.com/hono/-/hono-3.7.2.tgz#c3839d7ffbb5120850b2b926363d065020f4d18c"
|
||||
|
@ -8003,6 +8088,13 @@ loupe@^2.3.1, loupe@^2.3.6:
|
|||
dependencies:
|
||||
get-func-name "^2.0.0"
|
||||
|
||||
lower-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
|
||||
integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
|
||||
|
@ -8104,7 +8196,7 @@ map-obj@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
|
||||
integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==
|
||||
|
||||
map-obj@^4.0.0:
|
||||
map-obj@^4.0.0, map-obj@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a"
|
||||
integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==
|
||||
|
@ -8945,6 +9037,14 @@ nice-try@^1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
no-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
|
||||
integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
|
||||
dependencies:
|
||||
lower-case "^2.0.2"
|
||||
tslib "^2.0.3"
|
||||
|
||||
node-abi@^3.3.0:
|
||||
version "3.47.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.47.0.tgz#6cbfa2916805ae25c2b7156ca640131632eb05e8"
|
||||
|
@ -8964,6 +9064,16 @@ node-emoji@^1.11.0:
|
|||
dependencies:
|
||||
lodash "^4.17.21"
|
||||
|
||||
node-fetch-native@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.0.1.tgz#1dfe78f57545d07e07016b7df4c0cb9d2ff416c7"
|
||||
integrity sha512-VzW+TAk2wE4X9maiKMlT+GsPU4OMmR1U9CrHSmd3DFLn2IcZ9VJ6M6BBugGfYUnPCLSYxXdZy17M0BEJyhUTwg==
|
||||
|
||||
node-fetch-native@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.4.0.tgz#fbe8ac033cb6aa44bd106b5e4fd2b6277ba70fa1"
|
||||
integrity sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==
|
||||
|
||||
node-fetch@^2.5.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.6.9:
|
||||
version "2.6.11"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25"
|
||||
|
@ -10006,6 +10116,18 @@ pure-rand@^6.0.0:
|
|||
resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306"
|
||||
integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==
|
||||
|
||||
pvtsutils@^1.3.2:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.5.tgz#b8705b437b7b134cd7fd858f025a23456f1ce910"
|
||||
integrity sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==
|
||||
dependencies:
|
||||
tslib "^2.6.1"
|
||||
|
||||
pvutils@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3"
|
||||
integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==
|
||||
|
||||
qs@6.11.0:
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
|
||||
|
@ -10728,6 +10850,23 @@ smartwrap@^2.0.2:
|
|||
wcwidth "^1.0.1"
|
||||
yargs "^15.1.0"
|
||||
|
||||
snake-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c"
|
||||
integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==
|
||||
dependencies:
|
||||
dot-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
snakecase-keys@5.4.4:
|
||||
version "5.4.4"
|
||||
resolved "https://registry.yarnpkg.com/snakecase-keys/-/snakecase-keys-5.4.4.tgz#28745b0175863ffc292ad97d96fe4e8e288a87a2"
|
||||
integrity sha512-YTywJG93yxwHLgrYLZjlC75moVEX04LZM4FHfihjHe1FCXm+QaLOFfSf535aXOAd0ArVQMWUAe8ZPm4VtWyXaA==
|
||||
dependencies:
|
||||
map-obj "^4.1.0"
|
||||
snake-case "^3.0.4"
|
||||
type-fest "^2.5.2"
|
||||
|
||||
socks-proxy-agent@5, socks-proxy-agent@^5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e"
|
||||
|
@ -11522,21 +11661,26 @@ tsconfig-paths@^3.14.1:
|
|||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
|
||||
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
|
||||
|
||||
tslib@^1.8.1, tslib@^1.9.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.0.3, tslib@^2.4.0, tslib@^2.4.1, "tslib@^2.4.1 || ^1.9.3", tslib@^2.6.1:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
|
||||
tslib@^2.0.1, tslib@^2.1.0, tslib@^2.5.0:
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913"
|
||||
integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==
|
||||
|
||||
"tslib@^2.4.1 || ^1.9.3":
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
|
||||
tsup@^7.2.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/tsup/-/tsup-7.2.0.tgz#bb24c0d5e436477900c712e42adc67200607303c"
|
||||
|
@ -11648,6 +11792,11 @@ type-fest@^0.8.1:
|
|||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
type-fest@^2.5.2:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
|
||||
integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
|
||||
|
||||
type-fest@^3.0.0:
|
||||
version "3.12.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.12.0.tgz#4ce26edc1ccc59fc171e495887ef391fe1f5280e"
|
||||
|
@ -12148,6 +12297,17 @@ wcwidth@^1.0.1:
|
|||
dependencies:
|
||||
defaults "^1.0.3"
|
||||
|
||||
webcrypto-core@^1.7.4:
|
||||
version "1.7.7"
|
||||
resolved "https://registry.yarnpkg.com/webcrypto-core/-/webcrypto-core-1.7.7.tgz#06f24b3498463e570fed64d7cab149e5437b162c"
|
||||
integrity sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.3.6"
|
||||
"@peculiar/json-schema" "^1.1.12"
|
||||
asn1js "^3.0.1"
|
||||
pvtsutils "^1.3.2"
|
||||
tslib "^2.4.0"
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
|
|
Loading…
Reference in New Issue