kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
5fa7c5ae2d
commit
1e90451b0c
|
@ -46,7 +46,8 @@
|
|||
"postgres": "^3.4.5",
|
||||
"restore-cursor": "catalog:",
|
||||
"type-fest": "catalog:",
|
||||
"zod": "catalog:"
|
||||
"zod": "catalog:",
|
||||
"zod-validation-error": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsonwebtoken": "^9.0.9",
|
||||
|
|
|
@ -2,6 +2,8 @@ import 'dotenv/config'
|
|||
|
||||
import { z } from 'zod'
|
||||
|
||||
import { parseZodSchema } from './utils'
|
||||
|
||||
export const envSchema = z.object({
|
||||
NODE_ENV: z
|
||||
.enum(['development', 'test', 'production'])
|
||||
|
@ -10,8 +12,11 @@ export const envSchema = z.object({
|
|||
JWT_SECRET: z.string(),
|
||||
PORT: z.number().default(3000)
|
||||
})
|
||||
export type Env = z.infer<typeof envSchema>
|
||||
|
||||
// eslint-disable-next-line no-process-env
|
||||
export const env = envSchema.parse(process.env)
|
||||
export const env = parseZodSchema(envSchema, process.env, {
|
||||
error: 'Invalid environment variables'
|
||||
})
|
||||
|
||||
export const isProd = env.NODE_ENV === 'production'
|
||||
|
|
|
@ -1,17 +1,41 @@
|
|||
import type { ContentfulStatusCode } from 'hono/utils/http-status'
|
||||
import { fromError } from 'zod-validation-error'
|
||||
|
||||
export class HttpError extends Error {
|
||||
export class BaseError extends Error {
|
||||
constructor({ message, cause }: { message: string; cause?: unknown }) {
|
||||
super(message, { cause })
|
||||
|
||||
// Ensure the name of this error is the same as the class name
|
||||
this.name = this.constructor.name
|
||||
|
||||
// Set stack trace to caller
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class HttpError extends BaseError {
|
||||
readonly statusCode: ContentfulStatusCode
|
||||
|
||||
constructor({
|
||||
statusCode = 500,
|
||||
message
|
||||
message,
|
||||
cause
|
||||
}: {
|
||||
statusCode?: ContentfulStatusCode
|
||||
message: string
|
||||
cause?: unknown
|
||||
}) {
|
||||
super(message)
|
||||
super({ message, cause })
|
||||
|
||||
this.statusCode = statusCode
|
||||
}
|
||||
}
|
||||
|
||||
export class ZodValidationError extends BaseError {
|
||||
constructor({ prefix, cause }: { prefix?: string; cause: unknown }) {
|
||||
const error = fromError(cause, { prefix })
|
||||
super({ message: error.message, cause })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,4 +37,6 @@ export function initExitHooks({
|
|||
wait: timeoutMs
|
||||
}
|
||||
)
|
||||
|
||||
// TODO: On Node.js, log unhandledRejection, uncaughtException, and warning events
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { createHash, randomUUID } from 'node:crypto'
|
||||
|
||||
import { HttpError } from './errors'
|
||||
import type { ContentfulStatusCode } from 'hono/utils/http-status'
|
||||
import type { ZodSchema } from 'zod'
|
||||
|
||||
import { HttpError, ZodValidationError } from './errors'
|
||||
|
||||
export function sha256(input: string = randomUUID()) {
|
||||
return createHash('sha256').update(input).digest('hex')
|
||||
|
@ -9,12 +12,12 @@ export function sha256(input: string = randomUUID()) {
|
|||
export function assert(expr: unknown, message?: string): asserts expr
|
||||
export function assert(
|
||||
expr: unknown,
|
||||
statusCode?: number,
|
||||
statusCode?: ContentfulStatusCode,
|
||||
message?: string
|
||||
): asserts expr
|
||||
export function assert(
|
||||
expr: unknown,
|
||||
statusCodeOrMessage?: number | string,
|
||||
statusCodeOrMessage?: ContentfulStatusCode | string,
|
||||
message = 'Internal assertion failed'
|
||||
): asserts expr {
|
||||
if (expr) {
|
||||
|
@ -27,3 +30,22 @@ export function assert(
|
|||
throw new Error(statusCodeOrMessage ?? message)
|
||||
}
|
||||
}
|
||||
|
||||
export function parseZodSchema<T>(
|
||||
schema: ZodSchema<T>,
|
||||
input: unknown,
|
||||
{
|
||||
error
|
||||
}: {
|
||||
error?: string
|
||||
} = {}
|
||||
): T {
|
||||
try {
|
||||
return schema.parse(input)
|
||||
} catch (err) {
|
||||
throw new ZodValidationError({
|
||||
prefix: error,
|
||||
cause: err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
147
pnpm-lock.yaml
147
pnpm-lock.yaml
|
@ -6,15 +6,60 @@ settings:
|
|||
|
||||
catalogs:
|
||||
default:
|
||||
'@fisch0920/config':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4
|
||||
'@types/node':
|
||||
specifier: ^22.14.1
|
||||
version: 22.14.1
|
||||
del-cli:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
dotenv:
|
||||
specifier: ^16.5.0
|
||||
version: 16.5.0
|
||||
eslint:
|
||||
specifier: ^9.25.1
|
||||
version: 9.25.1
|
||||
exit-hook:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
lint-staged:
|
||||
specifier: ^15.5.1
|
||||
version: 15.5.1
|
||||
npm-run-all2:
|
||||
specifier: ^7.0.2
|
||||
version: 7.0.2
|
||||
only-allow:
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1
|
||||
prettier:
|
||||
specifier: ^3.5.3
|
||||
version: 3.5.3
|
||||
restore-cursor:
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0
|
||||
simple-git-hooks:
|
||||
specifier: ^2.12.1
|
||||
version: 2.12.1
|
||||
tsup:
|
||||
specifier: ^8.4.0
|
||||
version: 8.4.0
|
||||
tsx:
|
||||
specifier: ^4.19.3
|
||||
version: 4.19.3
|
||||
turbo:
|
||||
specifier: ^2.5.0
|
||||
version: 2.5.0
|
||||
type-fest:
|
||||
specifier: ^4.40.0
|
||||
version: 4.40.0
|
||||
typescript:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
vitest:
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2
|
||||
zod:
|
||||
specifier: ^3.24.3
|
||||
version: 3.24.3
|
||||
|
@ -116,6 +161,9 @@ importers:
|
|||
zod:
|
||||
specifier: 'catalog:'
|
||||
version: 3.24.3
|
||||
zod-validation-error:
|
||||
specifier: ^3.4.0
|
||||
version: 3.4.0(zod@3.24.3)
|
||||
devDependencies:
|
||||
'@types/jsonwebtoken':
|
||||
specifier: ^9.0.9
|
||||
|
@ -771,10 +819,6 @@ packages:
|
|||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/scope-manager@8.29.0':
|
||||
resolution: {integrity: sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/scope-manager@8.31.0':
|
||||
resolution: {integrity: sha512-knO8UyF78Nt8O/B64i7TlGXod69ko7z6vJD9uhSlm0qkAbGeRUSudcm0+K/4CrRjrpiHfBCjMWlc08Vav1xwcw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
@ -786,33 +830,16 @@ packages:
|
|||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/types@8.29.0':
|
||||
resolution: {integrity: sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/types@8.31.0':
|
||||
resolution: {integrity: sha512-Ch8oSjVyYyJxPQk8pMiP2FFGYatqXQfQIaMp+TpuuLlDachRWpUAeEu1u9B/v/8LToehUIWyiKcA/w5hUFRKuQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.29.0':
|
||||
resolution: {integrity: sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.31.0':
|
||||
resolution: {integrity: sha512-xLmgn4Yl46xi6aDSZ9KkyfhhtnYI15/CvHbpOy/eR5NWhK/BK8wc709KKwhAR0m4ZKRP7h07bm4BWUYOCuRpQQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/utils@8.29.0':
|
||||
resolution: {integrity: sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/utils@8.31.0':
|
||||
resolution: {integrity: sha512-qi6uPLt9cjTFxAb1zGNgTob4x9ur7xC6mHQJ8GwEzGMGE9tYniublmJaowOJ9V2jUzxrltTPfdG2nKlWsq0+Ww==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
@ -820,10 +847,6 @@ packages:
|
|||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.29.0':
|
||||
resolution: {integrity: sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.31.0':
|
||||
resolution: {integrity: sha512-QcGHmlRHWOl93o64ZUMNewCdwKGU6WItOU52H0djgNmn1EOrhVudrDzXz4OycCRSCPwFCDrE2iIt5vmuUdHxuQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
@ -1532,14 +1555,6 @@ packages:
|
|||
fastq@1.19.1:
|
||||
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
|
||||
|
||||
fdir@6.4.3:
|
||||
resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==}
|
||||
peerDependencies:
|
||||
picomatch: ^3 || ^4
|
||||
peerDependenciesMeta:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
fdir@6.4.4:
|
||||
resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==}
|
||||
peerDependencies:
|
||||
|
@ -2666,10 +2681,6 @@ packages:
|
|||
tinyexec@0.3.2:
|
||||
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
||||
|
||||
tinyglobby@0.2.12:
|
||||
resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
tinyglobby@0.2.13:
|
||||
resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
@ -2979,6 +2990,12 @@ packages:
|
|||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
zod-validation-error@3.4.0:
|
||||
resolution: {integrity: sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
peerDependencies:
|
||||
zod: ^3.18.0
|
||||
|
||||
zod@3.24.3:
|
||||
resolution: {integrity: sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==}
|
||||
|
||||
|
@ -3508,11 +3525,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/scope-manager@8.29.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.29.0
|
||||
'@typescript-eslint/visitor-keys': 8.29.0
|
||||
|
||||
'@typescript-eslint/scope-manager@8.31.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.31.0
|
||||
|
@ -3529,24 +3541,8 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/types@8.29.0': {}
|
||||
|
||||
'@typescript-eslint/types@8.31.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.29.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.29.0
|
||||
'@typescript-eslint/visitor-keys': 8.29.0
|
||||
debug: 4.4.0
|
||||
fast-glob: 3.3.3
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.5
|
||||
semver: 7.7.1
|
||||
ts-api-utils: 2.1.0(typescript@5.8.3)
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.31.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.31.0
|
||||
|
@ -3561,17 +3557,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.29.0(eslint@9.25.1)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.5.1(eslint@9.25.1)
|
||||
'@typescript-eslint/scope-manager': 8.29.0
|
||||
'@typescript-eslint/types': 8.29.0
|
||||
'@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.3)
|
||||
eslint: 9.25.1
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.31.0(eslint@9.25.1)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.5.1(eslint@9.25.1)
|
||||
|
@ -3583,11 +3568,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.29.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.29.0
|
||||
eslint-visitor-keys: 4.2.0
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.31.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.31.0
|
||||
|
@ -4285,8 +4265,8 @@ snapshots:
|
|||
|
||||
eslint-plugin-testing-library@7.1.1(eslint@9.25.1)(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.29.0
|
||||
'@typescript-eslint/utils': 8.29.0(eslint@9.25.1)(typescript@5.8.3)
|
||||
'@typescript-eslint/scope-manager': 8.31.0
|
||||
'@typescript-eslint/utils': 8.31.0(eslint@9.25.1)(typescript@5.8.3)
|
||||
eslint: 9.25.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -4420,10 +4400,6 @@ snapshots:
|
|||
dependencies:
|
||||
reusify: 1.1.0
|
||||
|
||||
fdir@6.4.3(picomatch@4.0.2):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.2
|
||||
|
||||
fdir@6.4.4(picomatch@4.0.2):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.2
|
||||
|
@ -5588,11 +5564,6 @@ snapshots:
|
|||
|
||||
tinyexec@0.3.2: {}
|
||||
|
||||
tinyglobby@0.2.12:
|
||||
dependencies:
|
||||
fdir: 6.4.3(picomatch@4.0.2)
|
||||
picomatch: 4.0.2
|
||||
|
||||
tinyglobby@0.2.13:
|
||||
dependencies:
|
||||
fdir: 6.4.4(picomatch@4.0.2)
|
||||
|
@ -5645,7 +5616,7 @@ snapshots:
|
|||
source-map: 0.8.0-beta.0
|
||||
sucrase: 3.35.0
|
||||
tinyexec: 0.3.2
|
||||
tinyglobby: 0.2.12
|
||||
tinyglobby: 0.2.13
|
||||
tree-kill: 1.2.2
|
||||
optionalDependencies:
|
||||
postcss: 8.5.3
|
||||
|
@ -5939,4 +5910,8 @@ snapshots:
|
|||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
zod-validation-error@3.4.0(zod@3.24.3):
|
||||
dependencies:
|
||||
zod: 3.24.3
|
||||
|
||||
zod@3.24.3: {}
|
||||
|
|
Ładowanie…
Reference in New Issue