kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
f2f33948ef
commit
bf6fbb0e65
|
@ -18,6 +18,7 @@ export {
|
||||||
and,
|
and,
|
||||||
arrayContained,
|
arrayContained,
|
||||||
arrayContains,
|
arrayContains,
|
||||||
|
arrayOverlaps,
|
||||||
between,
|
between,
|
||||||
eq,
|
eq,
|
||||||
exists,
|
exists,
|
||||||
|
|
|
@ -18,6 +18,8 @@ import {
|
||||||
createUpdateSchema,
|
createUpdateSchema,
|
||||||
cuid,
|
cuid,
|
||||||
deploymentId,
|
deploymentId,
|
||||||
|
optionalCuid,
|
||||||
|
optionalText,
|
||||||
projectId,
|
projectId,
|
||||||
timestamps
|
timestamps
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
@ -30,18 +32,18 @@ export const deployments = pgTable(
|
||||||
...timestamps,
|
...timestamps,
|
||||||
|
|
||||||
hash: text().notNull(),
|
hash: text().notNull(),
|
||||||
version: text(),
|
version: optionalText(),
|
||||||
|
|
||||||
enabled: boolean().notNull().default(true),
|
enabled: boolean().default(true).notNull(),
|
||||||
published: boolean().notNull().default(false),
|
published: boolean().default(false).notNull(),
|
||||||
|
|
||||||
description: text().notNull().default(''),
|
description: text().default('').notNull(),
|
||||||
readme: text().notNull().default(''),
|
readme: text().default('').notNull(),
|
||||||
|
|
||||||
userId: cuid()
|
userId: cuid()
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => users.id),
|
.references(() => users.id),
|
||||||
teamId: cuid().references(() => teams.id),
|
teamId: optionalCuid().references(() => teams.id),
|
||||||
projectId: projectId()
|
projectId: projectId()
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => projects.id, {
|
.references(() => projects.id, {
|
||||||
|
@ -51,9 +53,9 @@ export const deployments = pgTable(
|
||||||
// TODO: tools?
|
// TODO: tools?
|
||||||
// services: jsonb().$type<Service[]>().default([]),
|
// services: jsonb().$type<Service[]>().default([]),
|
||||||
|
|
||||||
// Environment variables & secrets
|
// TODO: Environment variables & secrets
|
||||||
build: jsonb().$type<object>(),
|
// build: jsonb().$type<object>(),
|
||||||
env: jsonb().$type<object>(),
|
// env: jsonb().$type<object>(),
|
||||||
|
|
||||||
// TODO: metadata config (logo, keywords, etc)
|
// TODO: metadata config (logo, keywords, etc)
|
||||||
// TODO: webhooks
|
// TODO: webhooks
|
||||||
|
@ -63,7 +65,7 @@ export const deployments = pgTable(
|
||||||
_url: text().notNull(),
|
_url: text().notNull(),
|
||||||
|
|
||||||
pricingPlans: jsonb().$type<PricingPlan[]>().notNull(),
|
pricingPlans: jsonb().$type<PricingPlan[]>().notNull(),
|
||||||
coupons: jsonb().$type<Coupon[]>().notNull().default([])
|
coupons: jsonb().$type<Coupon[]>().default([]).notNull()
|
||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
index('deployment_userId_idx').on(table.userId),
|
index('deployment_userId_idx').on(table.userId),
|
||||||
|
@ -113,15 +115,18 @@ export const deploymentInsertSchema = createInsertSchema(deployments, {
|
||||||
|
|
||||||
_url: (schema) => schema.url(),
|
_url: (schema) => schema.url(),
|
||||||
|
|
||||||
build: z.object({}),
|
// build: z.object({}),
|
||||||
env: z.object({}),
|
// env: z.object({}),
|
||||||
pricingPlans: z.array(pricingPlanSchema),
|
pricingPlans: z.array(pricingPlanSchema),
|
||||||
coupons: z.array(couponSchema).optional()
|
coupons: z.array(couponSchema).optional()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const deploymentSelectSchema = createSelectSchema(deployments, {
|
export const deploymentSelectSchema = createSelectSchema(deployments, {
|
||||||
build: z.object({}),
|
version: z.string().nonempty().optional(),
|
||||||
env: z.object({}),
|
teamId: z.string().cuid2().optional(),
|
||||||
|
|
||||||
|
// build: z.object({}),
|
||||||
|
// env: z.object({}),
|
||||||
pricingPlans: z.array(pricingPlanSchema),
|
pricingPlans: z.array(pricingPlanSchema),
|
||||||
coupons: z.array(couponSchema)
|
coupons: z.array(couponSchema)
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,9 +21,10 @@ import {
|
||||||
createSelectSchema,
|
createSelectSchema,
|
||||||
createUpdateSchema,
|
createUpdateSchema,
|
||||||
cuid,
|
cuid,
|
||||||
deploymentId,
|
optionalDeploymentId,
|
||||||
|
optionalStripeId,
|
||||||
|
optionalText,
|
||||||
projectId,
|
projectId,
|
||||||
stripeId,
|
|
||||||
timestamps
|
timestamps
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ export const projects = pgTable(
|
||||||
...timestamps,
|
...timestamps,
|
||||||
|
|
||||||
name: text().notNull(),
|
name: text().notNull(),
|
||||||
alias: text(),
|
alias: optionalText(),
|
||||||
|
|
||||||
userId: cuid()
|
userId: cuid()
|
||||||
.notNull()
|
.notNull()
|
||||||
|
@ -43,38 +44,44 @@ export const projects = pgTable(
|
||||||
teamId: cuid().notNull(),
|
teamId: cuid().notNull(),
|
||||||
|
|
||||||
// Most recently published Deployment if one exists
|
// Most recently published Deployment if one exists
|
||||||
lastPublishedDeploymentId: deploymentId(),
|
lastPublishedDeploymentId: optionalDeploymentId(),
|
||||||
|
|
||||||
// Most recent Deployment if one exists
|
// Most recent Deployment if one exists
|
||||||
lastDeploymentId: deploymentId(),
|
lastDeploymentId: optionalDeploymentId(),
|
||||||
|
|
||||||
applicationFeePercent: integer().notNull().default(20),
|
applicationFeePercent: integer().default(20).notNull(),
|
||||||
|
|
||||||
// TODO: This is going to need to vary from dev to prod
|
// TODO: This is going to need to vary from dev to prod
|
||||||
isStripeConnectEnabled: boolean().notNull().default(false),
|
isStripeConnectEnabled: boolean().default(false).notNull(),
|
||||||
|
|
||||||
// All deployments share the same underlying proxy secret
|
// All deployments share the same underlying proxy secret
|
||||||
_secret: text(),
|
_secret: optionalText(),
|
||||||
|
|
||||||
// Auth token used to access the saasify API on behalf of this project
|
// Auth token used to access the saasify API on behalf of this project
|
||||||
_providerToken: text().notNull(),
|
_providerToken: text().notNull(),
|
||||||
|
|
||||||
// TODO: Full-text search
|
// TODO: Full-text search
|
||||||
_text: text().default(''),
|
_text: text().default('').notNull(),
|
||||||
|
|
||||||
_webhooks: jsonb().$type<Webhook[]>().default([]),
|
_webhooks: jsonb().$type<Webhook[]>().default([]).notNull(),
|
||||||
|
|
||||||
// Stripe products corresponding to the stripe plans across deployments
|
// Stripe products corresponding to the stripe plans across deployments
|
||||||
stripeBaseProductId: stripeId(),
|
stripeBaseProductId: optionalStripeId(),
|
||||||
stripeRequestProductId: stripeId(),
|
stripeRequestProductId: optionalStripeId(),
|
||||||
|
|
||||||
// [metricSlug: string]: string
|
// [metricSlug: string]: string
|
||||||
stripeMetricProductIds: jsonb().$type<Record<string, string>>().default({}),
|
stripeMetricProductIds: jsonb()
|
||||||
|
.$type<Record<string, string>>()
|
||||||
|
.default({})
|
||||||
|
.notNull(),
|
||||||
|
|
||||||
// Stripe coupons associated with this project, mapping from unique coupon
|
// Stripe coupons associated with this project, mapping from unique coupon
|
||||||
// hash to stripe coupon id.
|
// hash to stripe coupon id.
|
||||||
// `[hash: string]: string`
|
// `[hash: string]: string`
|
||||||
_stripeCouponIds: jsonb().$type<Record<string, string>>().default({}),
|
_stripeCouponIds: jsonb()
|
||||||
|
.$type<Record<string, string>>()
|
||||||
|
.default({})
|
||||||
|
.notNull(),
|
||||||
|
|
||||||
// Stripe billing plans associated with this project (created lazily),
|
// Stripe billing plans associated with this project (created lazily),
|
||||||
// mapping from unique plan hash to stripe plan ids for base and request
|
// mapping from unique plan hash to stripe plan ids for base and request
|
||||||
|
@ -82,7 +89,8 @@ export const projects = pgTable(
|
||||||
// `[hash: string]: { basePlanId: string, requestPlanId: string }`
|
// `[hash: string]: { basePlanId: string, requestPlanId: string }`
|
||||||
_stripePlanIds: jsonb()
|
_stripePlanIds: jsonb()
|
||||||
.$type<Record<string, { basePlanId: string; requestPlanId: string }>>()
|
.$type<Record<string, { basePlanId: string; requestPlanId: string }>>()
|
||||||
.default({}),
|
.default({})
|
||||||
|
.notNull(),
|
||||||
|
|
||||||
// Connected Stripe account (standard or express).
|
// Connected Stripe account (standard or express).
|
||||||
// If not defined, then subscriptions for this project route through our
|
// If not defined, then subscriptions for this project route through our
|
||||||
|
@ -91,7 +99,7 @@ export const projects = pgTable(
|
||||||
// the stripeID utility.
|
// the stripeID utility.
|
||||||
// TODO: is it wise to share this between dev and prod?
|
// TODO: is it wise to share this between dev and prod?
|
||||||
// TODO: is it okay for this to be public?
|
// TODO: is it okay for this to be public?
|
||||||
_stripeAccountId: stripeId()
|
_stripeAccountId: optionalStripeId()
|
||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
index('project_userId_idx').on(table.userId),
|
index('project_userId_idx').on(table.userId),
|
||||||
|
@ -151,7 +159,17 @@ export const projectInsertSchema = createInsertSchema(projects, {
|
||||||
})
|
})
|
||||||
|
|
||||||
export const projectSelectSchema = createSelectSchema(projects, {
|
export const projectSelectSchema = createSelectSchema(projects, {
|
||||||
stripeMetricProductIds: z.record(z.string(), z.string()).optional()
|
alias: z.string().nonempty().optional(),
|
||||||
|
|
||||||
|
lastPublishedDeploymentId: z.string().nonempty().optional(),
|
||||||
|
lastDeploymentId: z.string().nonempty().optional(),
|
||||||
|
|
||||||
|
_secret: z.string().nonempty().optional(),
|
||||||
|
|
||||||
|
stripeBaseProductId: z.string().nonempty().optional(),
|
||||||
|
stripeRequestProductId: z.string().nonempty().optional(),
|
||||||
|
|
||||||
|
stripeMetricProductIds: z.record(z.string(), z.string()).optional(),
|
||||||
// _webhooks: z.array(webhookSchema),
|
// _webhooks: z.array(webhookSchema),
|
||||||
// _stripeCouponIds: z.record(z.string(), z.string()).optional(),
|
// _stripeCouponIds: z.record(z.string(), z.string()).optional(),
|
||||||
// _stripePlanIds: z
|
// _stripePlanIds: z
|
||||||
|
@ -163,6 +181,7 @@ export const projectSelectSchema = createSelectSchema(projects, {
|
||||||
// })
|
// })
|
||||||
// )
|
// )
|
||||||
// .optional()
|
// .optional()
|
||||||
|
_stripeAccountId: z.string().nonempty().optional()
|
||||||
})
|
})
|
||||||
.omit({
|
.omit({
|
||||||
_secret: true,
|
_secret: true,
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
|
import { z } from '@hono/zod-openapi'
|
||||||
import { relations } from 'drizzle-orm'
|
import { relations } from 'drizzle-orm'
|
||||||
import {
|
import { index, pgTable, primaryKey } from 'drizzle-orm/pg-core'
|
||||||
boolean,
|
|
||||||
index,
|
|
||||||
pgTable,
|
|
||||||
primaryKey,
|
|
||||||
timestamp
|
|
||||||
} from 'drizzle-orm/pg-core'
|
|
||||||
|
|
||||||
import { teams } from './team'
|
import { teams } from './team'
|
||||||
import { users } from './user'
|
import { users } from './user'
|
||||||
import {
|
import {
|
||||||
createSelectSchema,
|
createSelectSchema,
|
||||||
cuid,
|
cuid,
|
||||||
|
optionalBoolean,
|
||||||
|
optionalTimestamp,
|
||||||
teamMemberRoleEnum,
|
teamMemberRoleEnum,
|
||||||
timestamps
|
timestamps
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
@ -29,8 +26,8 @@ export const teamMembers = pgTable(
|
||||||
.references(() => teams.id, { onDelete: 'cascade' }),
|
.references(() => teams.id, { onDelete: 'cascade' }),
|
||||||
role: teamMemberRoleEnum().default('user').notNull(),
|
role: teamMemberRoleEnum().default('user').notNull(),
|
||||||
|
|
||||||
confirmed: boolean().default(false),
|
confirmed: optionalBoolean().default(false).notNull(),
|
||||||
confirmedAt: timestamp({ mode: 'string' })
|
confirmedAt: optionalTimestamp()
|
||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
primaryKey({ columns: [table.userId, table.teamId] }),
|
primaryKey({ columns: [table.userId, table.teamId] }),
|
||||||
|
@ -52,5 +49,7 @@ export const teamMembersRelations = relations(teamMembers, ({ one }) => ({
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export const teamMemberSelectSchema =
|
export const teamMemberSelectSchema = createSelectSchema(teamMembers, {
|
||||||
createSelectSchema(teamMembers).openapi('TeamMember')
|
confirmed: z.boolean(),
|
||||||
|
confirmedAt: z.string().datetime().optional()
|
||||||
|
}).openapi('TeamMember')
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { validators } from '@agentic/validators'
|
import { validators } from '@agentic/validators'
|
||||||
|
import { z } from '@hono/zod-openapi'
|
||||||
import { relations } from 'drizzle-orm'
|
import { relations } from 'drizzle-orm'
|
||||||
import {
|
import {
|
||||||
boolean,
|
boolean,
|
||||||
|
@ -6,7 +7,6 @@ import {
|
||||||
jsonb,
|
jsonb,
|
||||||
pgTable,
|
pgTable,
|
||||||
text,
|
text,
|
||||||
timestamp,
|
|
||||||
uniqueIndex
|
uniqueIndex
|
||||||
} from 'drizzle-orm/pg-core'
|
} from 'drizzle-orm/pg-core'
|
||||||
|
|
||||||
|
@ -19,7 +19,9 @@ import {
|
||||||
createSelectSchema,
|
createSelectSchema,
|
||||||
createUpdateSchema,
|
createUpdateSchema,
|
||||||
id,
|
id,
|
||||||
stripeId,
|
optionalStripeId,
|
||||||
|
optionalText,
|
||||||
|
optionalTimestamp,
|
||||||
timestamps,
|
timestamps,
|
||||||
userRoleEnum
|
userRoleEnum
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
@ -33,25 +35,25 @@ export const users = pgTable(
|
||||||
username: text().notNull().unique(),
|
username: text().notNull().unique(),
|
||||||
role: userRoleEnum().default('user').notNull(),
|
role: userRoleEnum().default('user').notNull(),
|
||||||
|
|
||||||
email: text().unique(),
|
email: optionalText().unique(),
|
||||||
password: text(),
|
password: optionalText(),
|
||||||
|
|
||||||
// metadata
|
// metadata
|
||||||
firstName: text(),
|
firstName: optionalText(),
|
||||||
lastName: text(),
|
lastName: optionalText(),
|
||||||
image: text(),
|
image: optionalText(),
|
||||||
|
|
||||||
emailConfirmed: boolean().default(false),
|
emailConfirmed: boolean().default(false).notNull(),
|
||||||
emailConfirmedAt: timestamp({ mode: 'string' }),
|
emailConfirmedAt: optionalTimestamp(),
|
||||||
emailConfirmToken: text().unique().default(sha256()),
|
emailConfirmToken: text().unique().default(sha256()).notNull(),
|
||||||
passwordResetToken: text().unique(),
|
passwordResetToken: optionalText().unique(),
|
||||||
|
|
||||||
isStripeConnectEnabledByDefault: boolean().default(true),
|
isStripeConnectEnabledByDefault: boolean().default(true).notNull(),
|
||||||
|
|
||||||
// third-party auth providers
|
// third-party auth providers
|
||||||
providers: jsonb().$type<AuthProviders>().default({}),
|
providers: jsonb().$type<AuthProviders>().default({}).notNull(),
|
||||||
|
|
||||||
stripeCustomerId: stripeId().unique()
|
stripeCustomerId: optionalStripeId().unique()
|
||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
uniqueIndex('user_email_idx').on(table.email),
|
uniqueIndex('user_email_idx').on(table.email),
|
||||||
|
@ -98,7 +100,19 @@ export const userInsertSchema = createInsertSchema(users, {
|
||||||
})
|
})
|
||||||
|
|
||||||
export const userSelectSchema = createSelectSchema(users, {
|
export const userSelectSchema = createSelectSchema(users, {
|
||||||
providers: authProvidersSchema
|
email: z.string().email().optional(),
|
||||||
|
password: z.string().nonempty().optional(),
|
||||||
|
|
||||||
|
firstName: z.string().optional(),
|
||||||
|
lastName: z.string().optional(),
|
||||||
|
image: z.string().nonempty().optional(),
|
||||||
|
|
||||||
|
emailConfirmedAt: z.string().datetime().optional(),
|
||||||
|
passwordResetToken: z.string().nonempty().optional(),
|
||||||
|
|
||||||
|
providers: authProvidersSchema,
|
||||||
|
|
||||||
|
stripeCustomerId: z.string().nonempty().optional()
|
||||||
}).openapi('User')
|
}).openapi('User')
|
||||||
|
|
||||||
export const userUpdateSchema = createUpdateSchema(users)
|
export const userUpdateSchema = createUpdateSchema(users)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { z } from '@hono/zod-openapi'
|
||||||
import { createId } from '@paralleldrive/cuid2'
|
import { createId } from '@paralleldrive/cuid2'
|
||||||
import { sql, type Writable } from 'drizzle-orm'
|
import { sql, type Writable } from 'drizzle-orm'
|
||||||
import {
|
import {
|
||||||
|
customType,
|
||||||
pgEnum,
|
pgEnum,
|
||||||
type PgVarcharBuilderInitial,
|
type PgVarcharBuilderInitial,
|
||||||
type PgVarcharConfig,
|
type PgVarcharConfig,
|
||||||
|
@ -84,3 +85,94 @@ export const { createInsertSchema, createSelectSchema, createUpdateSchema } =
|
||||||
date: true
|
date: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export type ColumnType =
|
||||||
|
// string
|
||||||
|
| 'text'
|
||||||
|
| 'varchar'
|
||||||
|
| 'timestamp'
|
||||||
|
| 'stripeId'
|
||||||
|
| 'projectId'
|
||||||
|
| 'deploymentId'
|
||||||
|
| 'cuid'
|
||||||
|
// boolean
|
||||||
|
| 'boolean'
|
||||||
|
// number
|
||||||
|
| 'integer'
|
||||||
|
| 'smallint'
|
||||||
|
| 'bigint'
|
||||||
|
// json
|
||||||
|
| 'json'
|
||||||
|
| 'jsonb'
|
||||||
|
|
||||||
|
export type ColumnTypeToTSType<T extends ColumnType> = T extends
|
||||||
|
| 'text'
|
||||||
|
| 'varchar'
|
||||||
|
| 'timestamp'
|
||||||
|
| 'cuid'
|
||||||
|
| 'stripeId'
|
||||||
|
| 'projectId'
|
||||||
|
| 'deploymentId'
|
||||||
|
? string
|
||||||
|
: T extends 'boolean'
|
||||||
|
? boolean
|
||||||
|
: T extends 'integer' | 'smallint' | 'bigint'
|
||||||
|
? number
|
||||||
|
: never
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://github.com/drizzle-team/drizzle-orm/issues/2745
|
||||||
|
*/
|
||||||
|
function optional<
|
||||||
|
T extends ColumnType,
|
||||||
|
InferredType extends
|
||||||
|
| string
|
||||||
|
| boolean
|
||||||
|
| number
|
||||||
|
| object = ColumnTypeToTSType<T>
|
||||||
|
>(dataType: T) {
|
||||||
|
return customType<{
|
||||||
|
data: InferredType | undefined
|
||||||
|
driverData: InferredType | null
|
||||||
|
config: T extends 'stripeId'
|
||||||
|
? {
|
||||||
|
length: number
|
||||||
|
}
|
||||||
|
: never
|
||||||
|
}>({
|
||||||
|
dataType() {
|
||||||
|
if (dataType === 'stripeId') {
|
||||||
|
return 'varchar({ length: 255 })'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataType === 'cuid') {
|
||||||
|
return 'varchar({ length: 24 })'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataType === 'projectId') {
|
||||||
|
return 'varchar({ length: 130 })'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataType === 'deploymentId') {
|
||||||
|
return 'varchar({ length: 160 })'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataType === 'timestamp') {
|
||||||
|
return 'timestamp({ mode: "string" })'
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataType
|
||||||
|
},
|
||||||
|
fromDriver: (v) => v ?? undefined,
|
||||||
|
toDriver: (v) => v ?? null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const optionalText = optional('text')
|
||||||
|
export const optionalTimestamp = optional('timestamp')
|
||||||
|
export const optionalBoolean = optional('boolean')
|
||||||
|
export const optionalVarchar = optional('varchar')
|
||||||
|
export const optionalCuid = optional('cuid')
|
||||||
|
export const optionalStripeId = optional('stripeId')
|
||||||
|
export const optionalProjectId = optional('projectId')
|
||||||
|
export const optionalDeploymentId = optional('deploymentId')
|
||||||
|
|
|
@ -7,30 +7,39 @@ export type Tables = ExtractTablesWithRelations<typeof schema>
|
||||||
|
|
||||||
export type User = z.infer<typeof schema.userSelectSchema>
|
export type User = z.infer<typeof schema.userSelectSchema>
|
||||||
|
|
||||||
|
// export type User2 = typeof schema.users.$inferSelect
|
||||||
|
// export type User3 = NullToUndefinedDeep<typeof schema.users.$inferSelect>
|
||||||
|
|
||||||
export type Team = z.infer<typeof schema.teamSelectSchema>
|
export type Team = z.infer<typeof schema.teamSelectSchema>
|
||||||
export type TeamWithMembers = BuildQueryResult<
|
export type TeamWithMembers = NullToUndefinedDeep<
|
||||||
Tables,
|
BuildQueryResult<Tables, Tables['teams'], { with: { members: true } }>
|
||||||
Tables['teams'],
|
|
||||||
{ with: { members: true } }
|
|
||||||
>
|
>
|
||||||
|
|
||||||
export type TeamMember = z.infer<typeof schema.teamMemberSelectSchema>
|
export type TeamMember = z.infer<typeof schema.teamMemberSelectSchema>
|
||||||
export type TeamMemberWithTeam = BuildQueryResult<
|
export type TeamMemberWithTeam = NullToUndefinedDeep<
|
||||||
Tables,
|
BuildQueryResult<Tables, Tables['teamMembers'], { with: { team: true } }>
|
||||||
Tables['teamMembers'],
|
|
||||||
{ with: { team: true } }
|
|
||||||
>
|
>
|
||||||
|
|
||||||
export type Project = typeof schema.projects.$inferSelect
|
export type Project = z.infer<typeof schema.projectSelectSchema>
|
||||||
export type ProjectWithLastPublishedDeployment = BuildQueryResult<
|
export type ProjectWithLastPublishedDeployment = NullToUndefinedDeep<
|
||||||
Tables,
|
BuildQueryResult<
|
||||||
Tables['projects'],
|
Tables,
|
||||||
{ with: { lastPublishedDeployment: true } }
|
Tables['projects'],
|
||||||
|
{ with: { lastPublishedDeployment: true } }
|
||||||
|
>
|
||||||
>
|
>
|
||||||
|
|
||||||
export type Deployment = typeof schema.deployments.$inferSelect
|
export type Deployment = z.infer<typeof schema.deploymentSelectSchema>
|
||||||
export type DeploymentWithProject = BuildQueryResult<
|
export type DeploymentWithProject = NullToUndefinedDeep<
|
||||||
Tables,
|
BuildQueryResult<Tables, Tables['deployments'], { with: { project: true } }>
|
||||||
Tables['deployments'],
|
|
||||||
{ with: { project: true } }
|
|
||||||
>
|
>
|
||||||
|
|
||||||
|
export type NullToUndefinedDeep<T> = T extends null
|
||||||
|
? undefined
|
||||||
|
: T extends Date
|
||||||
|
? T
|
||||||
|
: T extends readonly (infer U)[]
|
||||||
|
? NullToUndefinedDeep<U>[]
|
||||||
|
: T extends object
|
||||||
|
? { [K in keyof T]: NullToUndefinedDeep<T[K]> }
|
||||||
|
: T
|
||||||
|
|
Ładowanie…
Reference in New Issue