kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
4ec31b176c
commit
095c513b52
|
|
@ -3,6 +3,7 @@ import { fromError } from 'zod-validation-error'
|
|||
|
||||
import type { AuthenticatedEnv } from '@/lib/types'
|
||||
import * as middleware from '@/lib/middleware'
|
||||
import { registerOpenAPIErrorResponses } from '@/lib/openapi-utils'
|
||||
|
||||
import { registerV1AdminConsumersGetConsumerByToken } from './consumers/admin-get-consumer-by-token'
|
||||
import { registerV1ConsumersCreateConsumer } from './consumers/create-consumer'
|
||||
|
|
@ -51,6 +52,8 @@ apiV1.openAPIRegistry.registerComponent('securitySchemes', 'Bearer', {
|
|||
bearerFormat: 'JWT'
|
||||
})
|
||||
|
||||
registerOpenAPIErrorResponses(apiV1)
|
||||
|
||||
// Public routes
|
||||
const publicRouter = new OpenAPIHono()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import 'dotenv/config'
|
|||
import { parseZodSchema } from '@agentic/platform-core'
|
||||
import { z } from 'zod'
|
||||
|
||||
import { logLevelsSchema } from './logger'
|
||||
|
||||
export const envSchema = z.object({
|
||||
NODE_ENV: z
|
||||
.enum(['development', 'test', 'production'])
|
||||
|
|
@ -10,13 +12,14 @@ export const envSchema = z.object({
|
|||
|
||||
DATABASE_URL: z.string().url(),
|
||||
|
||||
JWT_SECRET: z.string(),
|
||||
PORT: z.number().default(3000),
|
||||
JWT_SECRET: z.string().nonempty(),
|
||||
SENTRY_DSN: z.string().url(),
|
||||
PORT: z.number().default(3000),
|
||||
LOG_LEVEL: logLevelsSchema.default('info'),
|
||||
|
||||
STRIPE_SECRET_KEY: z.string(),
|
||||
STRIPE_PUBLISHABLE_KEY: z.string(),
|
||||
STRIPE_WEBHOOK_SECRET: z.string()
|
||||
STRIPE_SECRET_KEY: z.string().nonempty(),
|
||||
STRIPE_PUBLISHABLE_KEY: z.string().nonempty(),
|
||||
STRIPE_WEBHOOK_SECRET: z.string().nonempty()
|
||||
})
|
||||
export type Env = z.infer<typeof envSchema>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { assert } from '@agentic/platform-core'
|
||||
import * as Sentry from '@sentry/node'
|
||||
import { z } from 'zod'
|
||||
|
||||
import type { Environment, Service } from '@/lib/types'
|
||||
import { env } from '@/lib/env'
|
||||
|
|
@ -13,7 +15,17 @@ export interface Logger {
|
|||
error(message?: any, ...detail: any[]): void
|
||||
}
|
||||
|
||||
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error'
|
||||
const rawLogLevels = ['trace', 'debug', 'info', 'warn', 'error'] as const
|
||||
export const logLevelsSchema = z.enum(rawLogLevels)
|
||||
export type LogLevel = z.infer<typeof logLevelsSchema>
|
||||
|
||||
export const logLevelsMap = rawLogLevels.reduce(
|
||||
(acc, level, index) => {
|
||||
acc[level] = index
|
||||
return acc
|
||||
},
|
||||
{} as Record<LogLevel, number>
|
||||
)
|
||||
|
||||
export class ConsoleLogger implements Logger {
|
||||
protected readonly environment: Environment
|
||||
|
|
@ -21,44 +33,70 @@ export class ConsoleLogger implements Logger {
|
|||
protected readonly requestId: string
|
||||
protected readonly metadata: Record<string, unknown>
|
||||
protected readonly console: Console
|
||||
protected readonly logLevel: LogLevel
|
||||
|
||||
constructor({
|
||||
requestId,
|
||||
service,
|
||||
environment = env.NODE_ENV,
|
||||
metadata = {},
|
||||
console = globalThis.console
|
||||
console = globalThis.console,
|
||||
logLevel = env.LOG_LEVEL
|
||||
}: {
|
||||
requestId: string
|
||||
service: Service
|
||||
environment?: Environment
|
||||
metadata?: Record<string, unknown>
|
||||
console?: Console
|
||||
logLevel?: LogLevel
|
||||
}) {
|
||||
assert(console, 500, '`console` is required for Logger')
|
||||
|
||||
this.requestId = requestId
|
||||
this.service = service
|
||||
this.environment = environment
|
||||
this.metadata = metadata
|
||||
this.console = console
|
||||
this.logLevel = logLevel
|
||||
}
|
||||
|
||||
trace(message?: any, ...detail: any[]) {
|
||||
if (logLevelsMap[this.logLevel] > logLevelsMap.trace) {
|
||||
return
|
||||
}
|
||||
|
||||
this.console.trace(this._marshal('trace', message, ...detail))
|
||||
}
|
||||
|
||||
debug(message?: any, ...detail: any[]) {
|
||||
if (logLevelsMap[this.logLevel] > logLevelsMap.debug) {
|
||||
return
|
||||
}
|
||||
|
||||
this.console.debug(this._marshal('debug', message, ...detail))
|
||||
}
|
||||
|
||||
info(message?: any, ...detail: any[]) {
|
||||
if (logLevelsMap[this.logLevel] > logLevelsMap.info) {
|
||||
return
|
||||
}
|
||||
|
||||
this.console.info(this._marshal('info', message, ...detail))
|
||||
}
|
||||
|
||||
warn(message?: any, ...detail: any[]) {
|
||||
if (logLevelsMap[this.logLevel] > logLevelsMap.warn) {
|
||||
return
|
||||
}
|
||||
|
||||
this.console.warn(this._marshal('warn', message, ...detail))
|
||||
}
|
||||
|
||||
error(message?: any, ...detail: any[]) {
|
||||
if (logLevelsMap[this.logLevel] > logLevelsMap.error) {
|
||||
return
|
||||
}
|
||||
|
||||
this.console.error(this._marshal('error', message, ...detail))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { unless } from './unless'
|
|||
export const accessLogger = unless(
|
||||
createMiddleware<DefaultEnv>(async (ctx, next) => {
|
||||
const logger = ctx.get('logger')
|
||||
await honoLogger(logger.trace)(ctx, next)
|
||||
await honoLogger(logger.trace.bind(logger))(ctx, next)
|
||||
}),
|
||||
'/v1/health'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,46 +1,32 @@
|
|||
import { z } from '@hono/zod-openapi'
|
||||
|
||||
const openapiErrorContent = {
|
||||
'application/json': {
|
||||
schema: z.object({
|
||||
error: z.string()
|
||||
})
|
||||
}
|
||||
} as const
|
||||
import type { OpenAPIHono } from '@hono/zod-openapi'
|
||||
|
||||
export const openapiErrorResponses = {
|
||||
400: {
|
||||
description: 'Bad Request',
|
||||
content: openapiErrorContent
|
||||
$ref: '#/components/responses/400'
|
||||
},
|
||||
401: {
|
||||
description: 'Unauthorized',
|
||||
content: openapiErrorContent
|
||||
$ref: '#/components/responses/401'
|
||||
},
|
||||
403: {
|
||||
description: 'Forbidden',
|
||||
content: openapiErrorContent
|
||||
$ref: '#/components/responses/403'
|
||||
}
|
||||
} as const
|
||||
|
||||
export const openapiErrorResponse404 = {
|
||||
404: {
|
||||
description: 'Not Found',
|
||||
content: openapiErrorContent
|
||||
$ref: '#/components/responses/404'
|
||||
}
|
||||
} as const
|
||||
|
||||
export const openapiErrorResponse409 = {
|
||||
409: {
|
||||
description: 'Conflict',
|
||||
content: openapiErrorContent
|
||||
$ref: '#/components/responses/409'
|
||||
}
|
||||
} as const
|
||||
|
||||
export const openapiErrorResponse410 = {
|
||||
410: {
|
||||
description: 'Gone',
|
||||
content: openapiErrorContent
|
||||
$ref: '#/components/responses/410'
|
||||
}
|
||||
} as const
|
||||
|
||||
|
|
@ -50,3 +36,49 @@ export const openapiAuthenticatedSecuritySchemas = [
|
|||
Bearer: []
|
||||
}
|
||||
]
|
||||
|
||||
const openapiErrorContent = {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object' as const,
|
||||
properties: {
|
||||
error: {
|
||||
type: 'string' as const
|
||||
}
|
||||
},
|
||||
required: ['error' as const]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function registerOpenAPIErrorResponses(app: OpenAPIHono) {
|
||||
app.openAPIRegistry.registerComponent('responses', '400', {
|
||||
description: 'Bad Request',
|
||||
content: openapiErrorContent
|
||||
})
|
||||
|
||||
app.openAPIRegistry.registerComponent('responses', '401', {
|
||||
description: 'Unauthorized',
|
||||
content: openapiErrorContent
|
||||
})
|
||||
|
||||
app.openAPIRegistry.registerComponent('responses', '403', {
|
||||
description: 'Forbidden',
|
||||
content: openapiErrorContent
|
||||
})
|
||||
|
||||
app.openAPIRegistry.registerComponent('responses', '404', {
|
||||
description: 'Not Found',
|
||||
content: openapiErrorContent
|
||||
})
|
||||
|
||||
app.openAPIRegistry.registerComponent('responses', '409', {
|
||||
description: 'Conflict',
|
||||
content: openapiErrorContent
|
||||
})
|
||||
|
||||
app.openAPIRegistry.registerComponent('responses', '410', {
|
||||
description: 'Gone',
|
||||
content: openapiErrorContent
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
"zod": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@agentic/platform-api": "workspace:*",
|
||||
"@agentic/platform-db": "workspace:*",
|
||||
"@commander-js/extra-typings": "^14.0.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ import {
|
|||
stripeId,
|
||||
timestamps
|
||||
} from './common'
|
||||
import { deployments, deploymentSelectSchema } from './deployment'
|
||||
import { projects, projectSelectSchema } from './project'
|
||||
import { deployments } from './deployment'
|
||||
import { projects } from './project'
|
||||
import {
|
||||
type StripeSubscriptionItemIdMap,
|
||||
stripeSubscriptionItemIdMapSchema
|
||||
} from './schemas'
|
||||
import { users, userSelectSchema } from './user'
|
||||
import { users } from './user'
|
||||
|
||||
// TODO: Consumers should be valid for any enabled project like in RapidAPI and GCP.
|
||||
// This may require a separate model to aggregate User Applications.
|
||||
|
|
@ -146,22 +146,22 @@ export const consumerSelectSchema = createSelectSchema(consumers, {
|
|||
_stripeSubscriptionItemIdMap: true,
|
||||
_stripeCustomerId: true
|
||||
})
|
||||
.extend({
|
||||
user: z
|
||||
.lazy(() => userSelectSchema)
|
||||
.optional()
|
||||
.openapi('User', { type: 'object' }),
|
||||
// .extend({
|
||||
// user: z
|
||||
// .lazy(() => userSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('User', { type: 'object' }),
|
||||
|
||||
project: z
|
||||
.lazy(() => projectSelectSchema)
|
||||
.optional()
|
||||
.openapi('Project', { type: 'object' }),
|
||||
// project: z
|
||||
// .lazy(() => projectSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Project', { type: 'object' }),
|
||||
|
||||
deployment: z
|
||||
.lazy(() => deploymentSelectSchema)
|
||||
.optional()
|
||||
.openapi('Deployment', { type: 'object' })
|
||||
})
|
||||
// deployment: z
|
||||
// .lazy(() => deploymentSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Deployment', { type: 'object' })
|
||||
// })
|
||||
.strip()
|
||||
.openapi('Consumer')
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ import {
|
|||
type PricingPlanList,
|
||||
pricingPlanListSchema
|
||||
} from './schemas'
|
||||
import { teams, teamSelectSchema } from './team'
|
||||
import { users, userSelectSchema } from './user'
|
||||
import { teams } from './team'
|
||||
import { users } from './user'
|
||||
|
||||
export const deployments = pgTable(
|
||||
'deployments',
|
||||
|
|
@ -131,20 +131,20 @@ export const deploymentSelectSchema = createSelectSchema(deployments, {
|
|||
.omit({
|
||||
originUrl: true
|
||||
})
|
||||
.extend({
|
||||
user: z
|
||||
.lazy(() => userSelectSchema)
|
||||
.optional()
|
||||
.openapi('User', { type: 'object' }),
|
||||
// .extend({
|
||||
// user: z
|
||||
// .lazy(() => userSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('User', { type: 'object' }),
|
||||
|
||||
team: z
|
||||
.lazy(() => teamSelectSchema)
|
||||
.optional()
|
||||
.openapi('Team', { type: 'object' }),
|
||||
// team: z
|
||||
// .lazy(() => teamSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Team', { type: 'object' }),
|
||||
|
||||
// TODO: Circular references make this schema less than ideal
|
||||
project: z.object({}).optional().openapi('Project', { type: 'object' })
|
||||
})
|
||||
// // TODO: Circular references make this schema less than ideal
|
||||
// project: z.object({}).optional().openapi('Project', { type: 'object' })
|
||||
// })
|
||||
.strip()
|
||||
.openapi('Deployment')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { relations } from '@fisch0920/drizzle-orm'
|
||||
import { index, jsonb, pgTable, text } from '@fisch0920/drizzle-orm/pg-core'
|
||||
import { z } from '@hono/zod-openapi'
|
||||
|
||||
import {
|
||||
createInsertSchema,
|
||||
|
|
@ -13,10 +12,10 @@ import {
|
|||
projectId,
|
||||
timestamps
|
||||
} from './common'
|
||||
import { consumers, consumerSelectSchema } from './consumer'
|
||||
import { deployments, deploymentSelectSchema } from './deployment'
|
||||
import { projects, projectSelectSchema } from './project'
|
||||
import { users, userSelectSchema } from './user'
|
||||
import { consumers } from './consumer'
|
||||
import { deployments } from './deployment'
|
||||
import { projects } from './project'
|
||||
import { users } from './user'
|
||||
|
||||
/**
|
||||
* A `LogEntry` is an internal audit log entry.
|
||||
|
|
@ -83,27 +82,27 @@ export const logEntriesRelations = relations(logEntries, ({ one }) => ({
|
|||
}))
|
||||
|
||||
export const logEntrySelectSchema = createSelectSchema(logEntries)
|
||||
.extend({
|
||||
user: z
|
||||
.lazy(() => userSelectSchema)
|
||||
.optional()
|
||||
.openapi('User', { type: 'object' }),
|
||||
// .extend({
|
||||
// user: z
|
||||
// .lazy(() => userSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('User', { type: 'object' }),
|
||||
|
||||
project: z
|
||||
.lazy(() => projectSelectSchema)
|
||||
.optional()
|
||||
.openapi('Project', { type: 'object' }),
|
||||
// project: z
|
||||
// .lazy(() => projectSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Project', { type: 'object' }),
|
||||
|
||||
deployment: z
|
||||
.lazy(() => deploymentSelectSchema)
|
||||
.optional()
|
||||
.openapi('Deployment', { type: 'object' }),
|
||||
// deployment: z
|
||||
// .lazy(() => deploymentSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Deployment', { type: 'object' }),
|
||||
|
||||
consumer: z
|
||||
.lazy(() => consumerSelectSchema)
|
||||
.optional()
|
||||
.openapi('Consumer', { type: 'object' })
|
||||
})
|
||||
// consumer: z
|
||||
// .lazy(() => consumerSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Consumer', { type: 'object' })
|
||||
// })
|
||||
.strip()
|
||||
.openapi('LogEntry')
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import {
|
|||
stripeId,
|
||||
timestamps
|
||||
} from './common'
|
||||
import { deployments, deploymentSelectSchema } from './deployment'
|
||||
import { deployments } from './deployment'
|
||||
import {
|
||||
pricingIntervalSchema,
|
||||
type StripeMeterIdMap,
|
||||
|
|
@ -32,8 +32,8 @@ import {
|
|||
type StripeProductIdMap,
|
||||
stripeProductIdMapSchema
|
||||
} from './schemas'
|
||||
import { teams, teamSelectSchema } from './team'
|
||||
import { users, userSelectSchema } from './user'
|
||||
import { teams } from './team'
|
||||
import { users } from './user'
|
||||
|
||||
export const projects = pgTable(
|
||||
'projects',
|
||||
|
|
@ -176,27 +176,27 @@ export const projectSelectSchema = createSelectSchema(projects, {
|
|||
_stripeMeterIdMap: true,
|
||||
_stripeAccountId: true
|
||||
})
|
||||
.extend({
|
||||
user: z
|
||||
.lazy(() => userSelectSchema)
|
||||
.optional()
|
||||
.openapi('User', { type: 'object' }),
|
||||
// .extend({
|
||||
// user: z
|
||||
// .lazy(() => userSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('User', { type: 'object' }),
|
||||
|
||||
team: z
|
||||
.lazy(() => teamSelectSchema)
|
||||
.optional()
|
||||
.openapi('Team', { type: 'object' }),
|
||||
// team: z
|
||||
// .lazy(() => teamSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Team', { type: 'object' }),
|
||||
|
||||
lastPublishedDeployment: z
|
||||
.lazy(() => deploymentSelectSchema)
|
||||
.optional()
|
||||
.openapi('Deployment', { type: 'object' }),
|
||||
// lastPublishedDeployment: z
|
||||
// .lazy(() => deploymentSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Deployment', { type: 'object' }),
|
||||
|
||||
lastDeployment: z
|
||||
.lazy(() => deploymentSelectSchema)
|
||||
.optional()
|
||||
.openapi('Deployment', { type: 'object' })
|
||||
})
|
||||
// lastDeployment: z
|
||||
// .lazy(() => deploymentSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Deployment', { type: 'object' })
|
||||
// })
|
||||
.strip()
|
||||
.openapi('Project')
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,14 @@ import { z } from '@hono/zod-openapi'
|
|||
import parseJson from 'parse-json'
|
||||
|
||||
export const authProviderTypeSchema = z
|
||||
.enum(['github', 'google', 'spotify', 'twitter', 'linkedin', 'stripe'])
|
||||
.union([
|
||||
z.literal('github'),
|
||||
z.literal('google'),
|
||||
z.literal('spotify'),
|
||||
z.literal('twitter'),
|
||||
z.literal('linkedin'),
|
||||
z.literal('stripe')
|
||||
])
|
||||
.openapi('AuthProviderType')
|
||||
export type AuthProviderType = z.infer<typeof authProviderTypeSchema>
|
||||
|
||||
|
|
@ -83,7 +90,12 @@ export const pricingPlanTierSchema = z
|
|||
export type PricingPlanTier = z.infer<typeof pricingPlanTierSchema>
|
||||
|
||||
export const pricingIntervalSchema = z
|
||||
.enum(['day', 'week', 'month', 'year'])
|
||||
.union([
|
||||
z.literal('day'),
|
||||
z.literal('week'),
|
||||
z.literal('month'),
|
||||
z.literal('year')
|
||||
])
|
||||
.describe('The frequency at which a subscription is billed.')
|
||||
.openapi('PricingInterval')
|
||||
export type PricingInterval = z.infer<typeof pricingIntervalSchema>
|
||||
|
|
@ -178,13 +190,15 @@ export const pricingPlanLineItemSchema = z
|
|||
* tiering strategy as defined using the `tiers` and `tiersMode`
|
||||
* attributes.
|
||||
*/
|
||||
billingScheme: z.enum(['per_unit', 'tiered']),
|
||||
billingScheme: z.union([z.literal('per_unit'), z.literal('tiered')]),
|
||||
|
||||
// Only applicable for `per_unit` billing schemes
|
||||
unitAmount: z.number().nonnegative().optional(),
|
||||
|
||||
// Only applicable for `tiered` billing schemes
|
||||
tiersMode: z.enum(['graduated', 'volume']).optional(),
|
||||
tiersMode: z
|
||||
.union([z.literal('graduated'), z.literal('volume')])
|
||||
.optional(),
|
||||
tiers: z.array(pricingPlanTierSchema).optional(),
|
||||
|
||||
// TODO: add support for tiered rate limits?
|
||||
|
|
@ -204,7 +218,9 @@ export const pricingPlanLineItemSchema = z
|
|||
*
|
||||
* Defaults to `sum`.
|
||||
*/
|
||||
formula: z.enum(['sum', 'count', 'last']).default('sum')
|
||||
formula: z
|
||||
.union([z.literal('sum'), z.literal('count'), z.literal('last')])
|
||||
.default('sum')
|
||||
})
|
||||
.optional(),
|
||||
|
||||
|
|
@ -223,7 +239,7 @@ export const pricingPlanLineItemSchema = z
|
|||
/**
|
||||
* After division, either round the result `up` or `down`.
|
||||
*/
|
||||
round: z.enum(['down', 'up'])
|
||||
round: z.union([z.literal('down'), z.literal('up')])
|
||||
})
|
||||
.optional()
|
||||
})
|
||||
|
|
@ -428,18 +444,19 @@ export type StripeSubscriptionItemIdMap = z.infer<
|
|||
// .openapi('Coupon')
|
||||
// export type Coupon = z.infer<typeof couponSchema>
|
||||
|
||||
export const deploymentOriginAdapterLocationSchema = z.enum([
|
||||
'external'
|
||||
// 'internal'
|
||||
])
|
||||
export const deploymentOriginAdapterLocationSchema = z.literal('external')
|
||||
// z.union([
|
||||
// z.literal('external'),
|
||||
// z.literal('internal')
|
||||
// ])
|
||||
export type DeploymentOriginAdapterLocation = z.infer<
|
||||
typeof deploymentOriginAdapterLocationSchema
|
||||
>
|
||||
|
||||
// export const deploymentOriginAdapterInternalTypeSchema = z.enum([
|
||||
// // 'docker',
|
||||
// // 'mcp'
|
||||
// // 'python-fastapi'
|
||||
// export const deploymentOriginAdapterInternalTypeSchema = z.union([
|
||||
// z.literal('docker'),
|
||||
// z.literal('mcp'),
|
||||
// z.literal('python-fastapi'),
|
||||
// // etc
|
||||
// ])
|
||||
// export type DeploymentOriginAdapterInternalType = z.infer<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import {
|
|||
pgTable,
|
||||
primaryKey
|
||||
} from '@fisch0920/drizzle-orm/pg-core'
|
||||
import { z } from '@hono/zod-openapi'
|
||||
|
||||
import {
|
||||
createInsertSchema,
|
||||
|
|
@ -17,8 +16,8 @@ import {
|
|||
timestamp,
|
||||
timestamps
|
||||
} from './common'
|
||||
import { teams, teamSelectSchema } from './team'
|
||||
import { users, userSelectSchema } from './user'
|
||||
import { teams } from './team'
|
||||
import { users } from './user'
|
||||
|
||||
export const teamMembers = pgTable(
|
||||
'team_members',
|
||||
|
|
@ -61,17 +60,17 @@ export const teamMembersRelations = relations(teamMembers, ({ one }) => ({
|
|||
}))
|
||||
|
||||
export const teamMemberSelectSchema = createSelectSchema(teamMembers)
|
||||
.extend({
|
||||
user: z
|
||||
.lazy(() => userSelectSchema)
|
||||
.optional()
|
||||
.openapi('User', { type: 'object' }),
|
||||
// .extend({
|
||||
// user: z
|
||||
// .lazy(() => userSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('User', { type: 'object' }),
|
||||
|
||||
team: z
|
||||
.lazy(() => teamSelectSchema)
|
||||
.optional()
|
||||
.openapi('Team', { type: 'object' })
|
||||
})
|
||||
// team: z
|
||||
// .lazy(() => teamSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('Team', { type: 'object' })
|
||||
// })
|
||||
.strip()
|
||||
.openapi('TeamMember')
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import {
|
|||
text,
|
||||
uniqueIndex
|
||||
} from '@fisch0920/drizzle-orm/pg-core'
|
||||
import { z } from '@hono/zod-openapi'
|
||||
|
||||
import {
|
||||
createInsertSchema,
|
||||
|
|
@ -18,7 +17,7 @@ import {
|
|||
timestamps
|
||||
} from './common'
|
||||
import { teamMembers } from './team-member'
|
||||
import { users, userSelectSchema } from './user'
|
||||
import { users } from './user'
|
||||
|
||||
export const teams = pgTable(
|
||||
'teams',
|
||||
|
|
@ -47,12 +46,12 @@ export const teamsRelations = relations(teams, ({ one, many }) => ({
|
|||
}))
|
||||
|
||||
export const teamSelectSchema = createSelectSchema(teams)
|
||||
.extend({
|
||||
owner: z
|
||||
.lazy(() => userSelectSchema)
|
||||
.optional()
|
||||
.openapi('User', { type: 'object' })
|
||||
})
|
||||
// .extend({
|
||||
// owner: z
|
||||
// .lazy(() => userSelectSchema)
|
||||
// .optional()
|
||||
// .openapi('User', { type: 'object' })
|
||||
// })
|
||||
.strip()
|
||||
.openapi('Team')
|
||||
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue