kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: move db schemas to separate package to share types
rodzic
d0539ecaff
commit
4ec31b176c
|
@ -5,7 +5,7 @@ import { defineConfig } from 'drizzle-kit'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
out: './drizzle',
|
out: './drizzle',
|
||||||
schema: './src/db/schema/index.ts',
|
schema: './src/db/schema.ts',
|
||||||
dialect: 'postgresql',
|
dialect: 'postgresql',
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
url: process.env.DATABASE_URL!
|
url: process.env.DATABASE_URL!
|
||||||
|
|
|
@ -10,7 +10,10 @@ export default [
|
||||||
drizzle
|
drizzle
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
...drizzle.configs.recommended.rules
|
...drizzle.configs.recommended.rules,
|
||||||
|
'no-console': 'error',
|
||||||
|
'unicorn/no-array-reduce': 'off',
|
||||||
|
'no-restricted-imports': ['error', '@agentic/platform-db']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -23,29 +23,23 @@
|
||||||
"clean": "del dist",
|
"clean": "del dist",
|
||||||
"test": "run-s test:*",
|
"test": "run-s test:*",
|
||||||
"test:lint": "eslint .",
|
"test:lint": "eslint .",
|
||||||
"test:typecheck": "tsc --noEmit",
|
"test:typecheck": "tsc --noEmit"
|
||||||
"test:unit": "vitest run"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@agentic/platform-core": "workspace:*",
|
"@agentic/platform-core": "workspace:*",
|
||||||
"@agentic/validators": "workspace:*",
|
"@agentic/platform-db": "workspace:*",
|
||||||
"@fisch0920/drizzle-orm": "^0.43.7",
|
"@agentic/platform-validators": "workspace:*",
|
||||||
"@fisch0920/drizzle-zod": "^0.7.9",
|
|
||||||
"@hono/node-server": "^1.14.1",
|
"@hono/node-server": "^1.14.1",
|
||||||
"@hono/sentry": "^1.2.1",
|
"@hono/sentry": "^1.2.1",
|
||||||
"@hono/zod-openapi": "^0.19.6",
|
"@hono/zod-openapi": "^0.19.6",
|
||||||
"@hono/zod-validator": "^0.5.0",
|
|
||||||
"@paralleldrive/cuid2": "^2.2.2",
|
|
||||||
"@redocly/openapi-core": "^1.34.3",
|
"@redocly/openapi-core": "^1.34.3",
|
||||||
"@sentry/node": "^9.19.0",
|
"@sentry/node": "^9.19.0",
|
||||||
"bcryptjs": "^3.0.2",
|
|
||||||
"eventid": "^2.0.1",
|
"eventid": "^2.0.1",
|
||||||
"exit-hook": "catalog:",
|
"exit-hook": "catalog:",
|
||||||
"hono": "^4.7.9",
|
"hono": "^4.7.9",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"p-all": "^5.0.0",
|
"p-all": "^5.0.0",
|
||||||
"parse-json": "^8.3.0",
|
"parse-json": "^8.3.0",
|
||||||
"postgres": "^3.4.5",
|
|
||||||
"restore-cursor": "catalog:",
|
"restore-cursor": "catalog:",
|
||||||
"semver": "^7.7.2",
|
"semver": "^7.7.2",
|
||||||
"stripe": "^18.1.0",
|
"stripe": "^18.1.0",
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
import { consumerIdSchema, paginationSchema } from '@/db'
|
import {
|
||||||
import { consumerRelationsSchema } from '@/db/schema'
|
consumerIdSchema,
|
||||||
|
consumerRelationsSchema,
|
||||||
|
paginationSchema
|
||||||
|
} from '@/db'
|
||||||
|
|
||||||
export const consumerIdParamsSchema = z.object({
|
export const consumerIdParamsSchema = z.object({
|
||||||
consumerId: consumerIdSchema.openapi({
|
consumerId: consumerIdSchema.openapi({
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { assert, parseZodSchema, pick, sha256 } from '@agentic/platform-core'
|
import { assert, parseZodSchema, pick, sha256 } from '@agentic/platform-core'
|
||||||
import { validators } from '@agentic/validators'
|
import { validators } from '@agentic/platform-validators'
|
||||||
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
|
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
|
||||||
|
|
||||||
import type { AuthenticatedEnv } from '@/lib/types'
|
import type { AuthenticatedEnv } from '@/lib/types'
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
import { deploymentIdSchema, paginationSchema, projectIdSchema } from '@/db'
|
import {
|
||||||
import { deploymentRelationsSchema } from '@/db/schema'
|
deploymentIdSchema,
|
||||||
|
deploymentRelationsSchema,
|
||||||
|
paginationSchema,
|
||||||
|
projectIdSchema
|
||||||
|
} from '@/db'
|
||||||
|
|
||||||
export const deploymentIdParamsSchema = z.object({
|
export const deploymentIdParamsSchema = z.object({
|
||||||
deploymentId: deploymentIdSchema.openapi({
|
deploymentId: deploymentIdSchema.openapi({
|
||||||
|
|
|
@ -110,35 +110,36 @@ apiV1.route('/', privateRouter)
|
||||||
|
|
||||||
// API route types to be used by Hono's RPC client.
|
// API route types to be used by Hono's RPC client.
|
||||||
// Should include all routes except for internal and admin routes.
|
// Should include all routes except for internal and admin routes.
|
||||||
export type ApiRoutes =
|
// NOTE: Removing for now because Hono's RPC client / types are clunky and slow.
|
||||||
| ReturnType<typeof registerHealthCheck>
|
// export type ApiRoutes =
|
||||||
// Users
|
// | ReturnType<typeof registerHealthCheck>
|
||||||
| ReturnType<typeof registerV1UsersGetUser>
|
// // Users
|
||||||
| ReturnType<typeof registerV1UsersUpdateUser>
|
// | ReturnType<typeof registerV1UsersGetUser>
|
||||||
// Teams
|
// | ReturnType<typeof registerV1UsersUpdateUser>
|
||||||
| ReturnType<typeof registerV1TeamsCreateTeam>
|
// // Teams
|
||||||
| ReturnType<typeof registerV1TeamsListTeams>
|
// | ReturnType<typeof registerV1TeamsCreateTeam>
|
||||||
| ReturnType<typeof registerV1TeamsGetTeam>
|
// | ReturnType<typeof registerV1TeamsListTeams>
|
||||||
| ReturnType<typeof registerV1TeamsDeleteTeam>
|
// | ReturnType<typeof registerV1TeamsGetTeam>
|
||||||
| ReturnType<typeof registerV1TeamsUpdateTeam>
|
// | ReturnType<typeof registerV1TeamsDeleteTeam>
|
||||||
// Team members
|
// | ReturnType<typeof registerV1TeamsUpdateTeam>
|
||||||
| ReturnType<typeof registerV1TeamsMembersCreateTeamMember>
|
// // Team members
|
||||||
| ReturnType<typeof registerV1TeamsMembersUpdateTeamMember>
|
// | ReturnType<typeof registerV1TeamsMembersCreateTeamMember>
|
||||||
| ReturnType<typeof registerV1TeamsMembersDeleteTeamMember>
|
// | ReturnType<typeof registerV1TeamsMembersUpdateTeamMember>
|
||||||
// Projects
|
// | ReturnType<typeof registerV1TeamsMembersDeleteTeamMember>
|
||||||
| ReturnType<typeof registerV1ProjectsCreateProject>
|
// // Projects
|
||||||
| ReturnType<typeof registerV1ProjectsListProjects>
|
// | ReturnType<typeof registerV1ProjectsCreateProject>
|
||||||
| ReturnType<typeof registerV1ProjectsGetProject>
|
// | ReturnType<typeof registerV1ProjectsListProjects>
|
||||||
| ReturnType<typeof registerV1ProjectsUpdateProject>
|
// | ReturnType<typeof registerV1ProjectsGetProject>
|
||||||
// Consumers
|
// | ReturnType<typeof registerV1ProjectsUpdateProject>
|
||||||
| ReturnType<typeof registerV1ConsumersGetConsumer>
|
// // Consumers
|
||||||
| ReturnType<typeof registerV1ConsumersCreateConsumer>
|
// | ReturnType<typeof registerV1ConsumersGetConsumer>
|
||||||
| ReturnType<typeof registerV1ConsumersUpdateConsumer>
|
// | ReturnType<typeof registerV1ConsumersCreateConsumer>
|
||||||
| ReturnType<typeof registerV1ConsumersRefreshConsumerToken>
|
// | ReturnType<typeof registerV1ConsumersUpdateConsumer>
|
||||||
| ReturnType<typeof registerV1ProjectsListConsumers>
|
// | ReturnType<typeof registerV1ConsumersRefreshConsumerToken>
|
||||||
// Deployments
|
// | ReturnType<typeof registerV1ProjectsListConsumers>
|
||||||
| ReturnType<typeof registerV1DeploymentsGetDeployment>
|
// // Deployments
|
||||||
| ReturnType<typeof registerV1DeploymentsCreateDeployment>
|
// | ReturnType<typeof registerV1DeploymentsGetDeployment>
|
||||||
| ReturnType<typeof registerV1DeploymentsUpdateDeployment>
|
// | ReturnType<typeof registerV1DeploymentsCreateDeployment>
|
||||||
| ReturnType<typeof registerV1DeploymentsListDeployments>
|
// | ReturnType<typeof registerV1DeploymentsUpdateDeployment>
|
||||||
| ReturnType<typeof registerV1DeploymentsPublishDeployment>
|
// | ReturnType<typeof registerV1DeploymentsListDeployments>
|
||||||
|
// | ReturnType<typeof registerV1DeploymentsPublishDeployment>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
import { paginationSchema, projectIdSchema } from '@/db'
|
import { paginationSchema, projectIdSchema, projectRelationsSchema } from '@/db'
|
||||||
import { projectRelationsSchema } from '@/db/schema'
|
|
||||||
|
|
||||||
export const projectIdParamsSchema = z.object({
|
export const projectIdParamsSchema = z.object({
|
||||||
projectId: projectIdSchema.openapi({
|
projectId: projectIdSchema.openapi({
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { OpenAPIHono } from '@hono/zod-openapi'
|
import type { OpenAPIHono } from '@hono/zod-openapi'
|
||||||
import type Stripe from 'stripe'
|
import type Stripe from 'stripe'
|
||||||
import { assert,HttpError } from '@agentic/platform-core'
|
import { assert, HttpError } from '@agentic/platform-core'
|
||||||
|
|
||||||
import { and, db, eq, schema } from '@/db'
|
import { and, db, eq, schema } from '@/db'
|
||||||
import { env, isStripeLive } from '@/lib/env'
|
import { env, isStripeLive } from '@/lib/env'
|
||||||
|
|
|
@ -1,44 +1,20 @@
|
||||||
import { drizzle } from '@fisch0920/drizzle-orm/postgres-js'
|
// The only place we allow `@agentic/platform-db` imports is in this directory.
|
||||||
import postgres from 'postgres'
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
drizzle,
|
||||||
|
postgres,
|
||||||
|
type PostgresClient,
|
||||||
|
schema
|
||||||
|
} from '@agentic/platform-db'
|
||||||
|
|
||||||
import { env } from '@/lib/env'
|
import { env } from '@/lib/env'
|
||||||
|
|
||||||
import * as schema from './schema'
|
let _postgresClient: PostgresClient | undefined
|
||||||
|
|
||||||
let _postgresClient: ReturnType<typeof postgres> | undefined
|
|
||||||
const postgresClient =
|
const postgresClient =
|
||||||
_postgresClient ?? (_postgresClient = postgres(env.DATABASE_URL))
|
_postgresClient ?? (_postgresClient = postgres(env.DATABASE_URL))
|
||||||
|
|
||||||
export const db = drizzle({ client: postgresClient, schema })
|
export const db = drizzle({ client: postgresClient, schema })
|
||||||
|
|
||||||
export * as schema from './schema'
|
|
||||||
export * from './schemas'
|
export * from '@agentic/platform-db'
|
||||||
export type * from './types'
|
|
||||||
export {
|
|
||||||
and,
|
|
||||||
arrayContained,
|
|
||||||
arrayContains,
|
|
||||||
arrayOverlaps,
|
|
||||||
asc,
|
|
||||||
between,
|
|
||||||
desc,
|
|
||||||
eq,
|
|
||||||
exists,
|
|
||||||
gt,
|
|
||||||
gte,
|
|
||||||
ilike,
|
|
||||||
inArray,
|
|
||||||
isNotNull,
|
|
||||||
isNull,
|
|
||||||
like,
|
|
||||||
lt,
|
|
||||||
lte,
|
|
||||||
ne,
|
|
||||||
not,
|
|
||||||
notBetween,
|
|
||||||
notExists,
|
|
||||||
notIlike,
|
|
||||||
notInArray,
|
|
||||||
notLike,
|
|
||||||
or
|
|
||||||
} from '@fisch0920/drizzle-orm'
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
// The only place we allow `@agentic/platform-db` imports is in this directory.
|
||||||
|
|
||||||
|
|
||||||
|
export * from '@agentic/platform-db'
|
|
@ -1,5 +1,5 @@
|
||||||
import { assert } from '@agentic/platform-core'
|
import { assert } from '@agentic/platform-core'
|
||||||
import { parseFaasIdentifier } from '@agentic/validators'
|
import { parseFaasIdentifier } from '@agentic/platform-validators'
|
||||||
|
|
||||||
import type { AuthenticatedContext } from '@/lib/types'
|
import type { AuthenticatedContext } from '@/lib/types'
|
||||||
import { and, db, eq, schema } from '@/db'
|
import { and, db, eq, schema } from '@/db'
|
||||||
|
|
|
@ -2,14 +2,18 @@ import type Stripe from 'stripe'
|
||||||
import { assert } from '@agentic/platform-core'
|
import { assert } from '@agentic/platform-core'
|
||||||
import pAll from 'p-all'
|
import pAll from 'p-all'
|
||||||
|
|
||||||
import { db, eq, type RawDeployment, type RawProject, schema } from '@/db'
|
|
||||||
import {
|
import {
|
||||||
|
db,
|
||||||
|
eq,
|
||||||
getLabelForPricingInterval,
|
getLabelForPricingInterval,
|
||||||
getPricingPlanLineItemHashForStripePrice,
|
getPricingPlanLineItemHashForStripePrice,
|
||||||
getPricingPlansByInterval,
|
getPricingPlansByInterval,
|
||||||
type PricingPlan,
|
type PricingPlan,
|
||||||
type PricingPlanLineItem
|
type PricingPlanLineItem,
|
||||||
} from '@/db/schema'
|
type RawDeployment,
|
||||||
|
type RawProject,
|
||||||
|
schema
|
||||||
|
} from '@/db'
|
||||||
import { stripe } from '@/lib/stripe'
|
import { stripe } from '@/lib/stripe'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,13 +6,13 @@ import {
|
||||||
type ConsumerUpdate,
|
type ConsumerUpdate,
|
||||||
db,
|
db,
|
||||||
eq,
|
eq,
|
||||||
|
getStripePriceIdForPricingPlanLineItem,
|
||||||
type RawConsumer,
|
type RawConsumer,
|
||||||
type RawDeployment,
|
type RawDeployment,
|
||||||
type RawProject,
|
type RawProject,
|
||||||
type RawUser,
|
type RawUser,
|
||||||
schema
|
schema
|
||||||
} from '@/db'
|
} from '@/db'
|
||||||
import { getStripePriceIdForPricingPlanLineItem } from '@/db/schema'
|
|
||||||
import { stripe } from '@/lib/stripe'
|
import { stripe } from '@/lib/stripe'
|
||||||
|
|
||||||
export async function upsertStripeSubscription(
|
export async function upsertStripeSubscription(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { assert } from '@agentic/platform-core'
|
import { assert } from '@agentic/platform-core'
|
||||||
import semver from 'semver'
|
import semver from 'semver'
|
||||||
|
|
||||||
import type { RawProject } from '@/db/types'
|
import type { RawProject } from '@/db'
|
||||||
|
|
||||||
export function normalizeDeploymentVersion({
|
export function normalizeDeploymentVersion({
|
||||||
deploymentId,
|
deploymentId,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { assert } from '@agentic/platform-core'
|
import { assert } from '@agentic/platform-core'
|
||||||
import { parseFaasIdentifier } from '@agentic/validators'
|
import { parseFaasIdentifier } from '@agentic/platform-validators'
|
||||||
|
|
||||||
import type { AuthenticatedContext } from '@/lib/types'
|
import type { AuthenticatedContext } from '@/lib/types'
|
||||||
import { db, eq, type RawDeployment, schema } from '@/db'
|
import { db, eq, type RawDeployment, schema } from '@/db'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { assert } from '@agentic/platform-core'
|
import { assert } from '@agentic/platform-core'
|
||||||
|
|
||||||
import type { DeploymentOriginAdapter } from '@/db/schema'
|
import type { DeploymentOriginAdapter } from '@/db'
|
||||||
import type { Logger } from '@/lib/logger'
|
import type { Logger } from '@/lib/logger'
|
||||||
import { validateOpenAPISpec } from '@/lib/validate-openapi-spec'
|
import { validateOpenAPISpec } from '@/lib/validate-openapi-spec'
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { assert } from '@agentic/platform-core'
|
import { assert } from '@agentic/platform-core'
|
||||||
import { and, eq } from '@fisch0920/drizzle-orm'
|
|
||||||
import { createMiddleware } from 'hono/factory'
|
import { createMiddleware } from 'hono/factory'
|
||||||
|
|
||||||
import type { AuthenticatedEnv } from '@/lib/types'
|
import type { AuthenticatedEnv } from '@/lib/types'
|
||||||
import { db, schema } from '@/db'
|
import { and, db, eq, schema } from '@/db'
|
||||||
import { aclTeamMember } from '@/lib/acl-team-member'
|
import { aclTeamMember } from '@/lib/acl-team-member'
|
||||||
|
|
||||||
export const team = createMiddleware<AuthenticatedEnv>(
|
export const team = createMiddleware<AuthenticatedEnv>(
|
||||||
|
|
|
@ -38,5 +38,3 @@ initExitHooks({ server })
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Server running on port ${env.PORT}`)
|
console.log(`Server running on port ${env.PORT}`)
|
||||||
|
|
||||||
export { type ApiRoutes } from '@/api-v1'
|
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "run-s test:*",
|
"test": "run-s test:*",
|
||||||
"test:lint": "eslint .",
|
"test:lint": "eslint .",
|
||||||
"test:typecheck": "tsc --noEmit",
|
"test:typecheck": "tsc --noEmit"
|
||||||
"test:unit": "vitest run"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@agentic/platform-core": "workspace:*",
|
"@agentic/platform-core": "workspace:*",
|
||||||
|
@ -35,6 +34,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@agentic/platform-api": "workspace:*",
|
"@agentic/platform-api": "workspace:*",
|
||||||
|
"@agentic/platform-db": "workspace:*",
|
||||||
"@commander-js/extra-typings": "^14.0.0"
|
"@commander-js/extra-typings": "^14.0.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|
|
@ -8,6 +8,8 @@ export const signin = new Command('login')
|
||||||
.option('-u, --username <username>', 'account username')
|
.option('-u, --username <username>', 'account username')
|
||||||
.option('-e, --email <email>', 'account email')
|
.option('-e, --email <email>', 'account email')
|
||||||
.option('-p, --password <password>', 'account password')
|
.option('-p, --password <password>', 'account password')
|
||||||
.action(async (opts) => {
|
.action(async (_opts) => {
|
||||||
|
// TODO
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
console.log('TODO: signin')
|
console.log('TODO: signin')
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import { Command } from 'commander'
|
import { Command } from 'commander'
|
||||||
import { getAuth, requireAuth } from '../store'
|
|
||||||
|
import { getAuth } from '../store'
|
||||||
|
|
||||||
export const whoami = new Command('whoami')
|
export const whoami = new Command('whoami')
|
||||||
.description('Displays info about the current user')
|
.description('Displays info about the current user')
|
||||||
.action(async (opts) => {
|
.action(async () => {
|
||||||
const auth = getAuth()
|
const auth = getAuth()
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
console.log(
|
console.log(
|
||||||
JSON.stringify({ user: auth.user, team: auth.teamSlug }, null, 2)
|
JSON.stringify({ user: auth.user, team: auth.teamSlug }, null, 2)
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { User } from '@agentic/platform-db'
|
||||||
import { assert } from '@agentic/platform-core'
|
import { assert } from '@agentic/platform-core'
|
||||||
import Conf from 'conf'
|
import Conf from 'conf'
|
||||||
|
|
||||||
|
@ -5,7 +6,7 @@ export const store = new Conf({ projectName: 'agentic' })
|
||||||
|
|
||||||
export type Auth = {
|
export type Auth = {
|
||||||
token: string
|
token: string
|
||||||
user: string
|
user: User
|
||||||
teamId?: string
|
teamId?: string
|
||||||
teamSlug?: string
|
teamSlug?: string
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
"name": "@agentic/platform-db",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "Postgres database schemas and types for the Agentic platform using Drizzle as the ORM.",
|
||||||
|
"author": "Travis Fischer <travis@transitivebullsh.it>",
|
||||||
|
"license": "UNLICENSED",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/transitive-bullshit/agentic-platform.git",
|
||||||
|
"directory": "packages/db"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
|
"main": "./src/index.ts",
|
||||||
|
"source": "./src/index.ts",
|
||||||
|
"types": "./src/index.ts",
|
||||||
|
"sideEffects": false,
|
||||||
|
"exports": {
|
||||||
|
".": "./src/index.ts"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "run-s test:*",
|
||||||
|
"test:lint": "eslint .",
|
||||||
|
"test:typecheck": "tsc --noEmit",
|
||||||
|
"test:unit": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@agentic/platform-core": "workspace:*",
|
||||||
|
"@agentic/platform-validators": "workspace:*",
|
||||||
|
"@fisch0920/drizzle-orm": "^0.43.7",
|
||||||
|
"@fisch0920/drizzle-zod": "^0.7.9",
|
||||||
|
"@hono/zod-openapi": "^0.19.6",
|
||||||
|
"@paralleldrive/cuid2": "^2.2.2",
|
||||||
|
"bcryptjs": "^3.0.2",
|
||||||
|
"hono": "^4.7.9",
|
||||||
|
"parse-json": "^8.3.0",
|
||||||
|
"postgres": "^3.4.5",
|
||||||
|
"type-fest": "catalog:",
|
||||||
|
"zod": "catalog:"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
import type postgres from 'postgres'
|
||||||
|
|
||||||
|
export { drizzle } from '@fisch0920/drizzle-orm/postgres-js'
|
||||||
|
|
||||||
|
export type PostgresClient = ReturnType<typeof postgres>
|
||||||
|
|
||||||
|
export * as schema from './schema'
|
||||||
|
export * from './schema/schemas'
|
||||||
|
export * from './schemas'
|
||||||
|
export type * from './types'
|
||||||
|
export * from './utils'
|
||||||
|
export {
|
||||||
|
and,
|
||||||
|
arrayContained,
|
||||||
|
arrayContains,
|
||||||
|
arrayOverlaps,
|
||||||
|
asc,
|
||||||
|
between,
|
||||||
|
desc,
|
||||||
|
eq,
|
||||||
|
exists,
|
||||||
|
gt,
|
||||||
|
gte,
|
||||||
|
ilike,
|
||||||
|
inArray,
|
||||||
|
isNotNull,
|
||||||
|
isNull,
|
||||||
|
like,
|
||||||
|
lt,
|
||||||
|
lte,
|
||||||
|
ne,
|
||||||
|
not,
|
||||||
|
notBetween,
|
||||||
|
notExists,
|
||||||
|
notIlike,
|
||||||
|
notInArray,
|
||||||
|
notLike,
|
||||||
|
or
|
||||||
|
} from '@fisch0920/drizzle-orm'
|
||||||
|
export { default as postgres } from 'postgres'
|
|
@ -1,4 +1,3 @@
|
||||||
import { hashObject } from '@agentic/platform-core'
|
|
||||||
import { type Equal, sql, type Writable } from '@fisch0920/drizzle-orm'
|
import { type Equal, sql, type Writable } from '@fisch0920/drizzle-orm'
|
||||||
import {
|
import {
|
||||||
pgEnum,
|
pgEnum,
|
||||||
|
@ -14,14 +13,6 @@ import { createSchemaFactory } from '@fisch0920/drizzle-zod'
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
import { createId } from '@paralleldrive/cuid2'
|
import { createId } from '@paralleldrive/cuid2'
|
||||||
|
|
||||||
import type { RawProject } from '../types'
|
|
||||||
import type {
|
|
||||||
PricingInterval,
|
|
||||||
PricingPlan,
|
|
||||||
PricingPlanLineItem,
|
|
||||||
PricingPlanList
|
|
||||||
} from './schemas'
|
|
||||||
|
|
||||||
const usernameAndTeamSlugLength = 64 as const
|
const usernameAndTeamSlugLength = 64 as const
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,85 +116,3 @@ export const { createInsertSchema, createSelectSchema, createUpdateSchema } =
|
||||||
date: true
|
date: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the hash used to uniquely map a PricingPlanLineItem to its
|
|
||||||
* corresponding Stripe Price in a stable way across deployments within a
|
|
||||||
* project.
|
|
||||||
*
|
|
||||||
* This hash is used as the key for the `Project._stripePriceIdMap`.
|
|
||||||
*/
|
|
||||||
export function getPricingPlanLineItemHashForStripePrice({
|
|
||||||
pricingPlan,
|
|
||||||
pricingPlanLineItem,
|
|
||||||
project
|
|
||||||
}: {
|
|
||||||
pricingPlan: PricingPlan
|
|
||||||
pricingPlanLineItem: PricingPlanLineItem
|
|
||||||
project: RawProject
|
|
||||||
}) {
|
|
||||||
// TODO: use pricingPlan.slug as well here?
|
|
||||||
// TODO: not sure if this is needed or not...
|
|
||||||
// With pricing plan slug:
|
|
||||||
// - 'price:free:base:<hash>'
|
|
||||||
// - 'price:basic-monthly:base:<hash>'
|
|
||||||
// - 'price:basic-monthly:requests:<hash>'
|
|
||||||
// Without pricing plan slug:
|
|
||||||
// - 'price:base:<hash>'
|
|
||||||
// - 'price:base:<hash>'
|
|
||||||
// - 'price:requests:<hash>'
|
|
||||||
|
|
||||||
const hash = hashObject({
|
|
||||||
...pricingPlanLineItem,
|
|
||||||
projectId: project.id,
|
|
||||||
stripeAccountId: project._stripeAccountId,
|
|
||||||
currency: project.pricingCurrency
|
|
||||||
})
|
|
||||||
|
|
||||||
return `price:${pricingPlan.slug}:${pricingPlanLineItem.slug}:${hash}`
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getStripePriceIdForPricingPlanLineItem({
|
|
||||||
pricingPlan,
|
|
||||||
pricingPlanLineItem,
|
|
||||||
project
|
|
||||||
}: {
|
|
||||||
pricingPlan: PricingPlan
|
|
||||||
pricingPlanLineItem: PricingPlanLineItem
|
|
||||||
project: RawProject
|
|
||||||
}): string | undefined {
|
|
||||||
const pricingPlanLineItemHash = getPricingPlanLineItemHashForStripePrice({
|
|
||||||
pricingPlan,
|
|
||||||
pricingPlanLineItem,
|
|
||||||
project
|
|
||||||
})
|
|
||||||
|
|
||||||
return project._stripePriceIdMap[pricingPlanLineItemHash]
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPricingPlansByInterval({
|
|
||||||
pricingInterval,
|
|
||||||
pricingPlans
|
|
||||||
}: {
|
|
||||||
pricingInterval: PricingInterval
|
|
||||||
pricingPlans: PricingPlanList
|
|
||||||
}): PricingPlan[] {
|
|
||||||
return pricingPlans.filter(
|
|
||||||
(pricingPlan) =>
|
|
||||||
pricingPlan.interval === undefined ||
|
|
||||||
pricingPlan.interval === pricingInterval
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const pricingIntervalToLabelMap: Record<PricingInterval, string> = {
|
|
||||||
day: 'daily',
|
|
||||||
week: 'weekly',
|
|
||||||
month: 'monthly',
|
|
||||||
year: 'yearly'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getLabelForPricingInterval(
|
|
||||||
pricingInterval: PricingInterval
|
|
||||||
): string {
|
|
||||||
return pricingIntervalToLabelMap[pricingInterval]
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { validators } from '@agentic/validators'
|
import { validators } from '@agentic/platform-validators'
|
||||||
import { relations } from '@fisch0920/drizzle-orm'
|
import { relations } from '@fisch0920/drizzle-orm'
|
||||||
import {
|
import {
|
||||||
boolean,
|
boolean,
|
||||||
|
@ -9,13 +9,6 @@ import {
|
||||||
} from '@fisch0920/drizzle-orm/pg-core'
|
} from '@fisch0920/drizzle-orm/pg-core'
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
import { deployments, deploymentSelectSchema } from './deployment'
|
|
||||||
import { projects, projectSelectSchema } from './project'
|
|
||||||
import {
|
|
||||||
type StripeSubscriptionItemIdMap,
|
|
||||||
stripeSubscriptionItemIdMapSchema
|
|
||||||
} from './schemas'
|
|
||||||
import { users, userSelectSchema } from './user'
|
|
||||||
import {
|
import {
|
||||||
createInsertSchema,
|
createInsertSchema,
|
||||||
createSelectSchema,
|
createSelectSchema,
|
||||||
|
@ -26,7 +19,14 @@ import {
|
||||||
projectId,
|
projectId,
|
||||||
stripeId,
|
stripeId,
|
||||||
timestamps
|
timestamps
|
||||||
} from './utils'
|
} from './common'
|
||||||
|
import { deployments, deploymentSelectSchema } from './deployment'
|
||||||
|
import { projects, projectSelectSchema } from './project'
|
||||||
|
import {
|
||||||
|
type StripeSubscriptionItemIdMap,
|
||||||
|
stripeSubscriptionItemIdMapSchema
|
||||||
|
} from './schemas'
|
||||||
|
import { users, userSelectSchema } from './user'
|
||||||
|
|
||||||
// TODO: Consumers should be valid for any enabled project like in RapidAPI and GCP.
|
// TODO: Consumers should be valid for any enabled project like in RapidAPI and GCP.
|
||||||
// This may require a separate model to aggregate User Applications.
|
// This may require a separate model to aggregate User Applications.
|
||||||
|
@ -128,13 +128,6 @@ export const consumersRelations = relations(consumers, ({ one }) => ({
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export type ConsumerRelationFields = keyof ReturnType<
|
|
||||||
(typeof consumersRelations)['config']
|
|
||||||
>
|
|
||||||
|
|
||||||
export const consumerRelationsSchema: z.ZodType<ConsumerRelationFields> =
|
|
||||||
z.enum(['user', 'project', 'deployment'])
|
|
||||||
|
|
||||||
export const consumerSelectSchema = createSelectSchema(consumers, {
|
export const consumerSelectSchema = createSelectSchema(consumers, {
|
||||||
_stripeSubscriptionItemIdMap: stripeSubscriptionItemIdMapSchema,
|
_stripeSubscriptionItemIdMap: stripeSubscriptionItemIdMapSchema,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { validators } from '@agentic/validators'
|
import { validators } from '@agentic/platform-validators'
|
||||||
import { relations } from '@fisch0920/drizzle-orm'
|
import { relations } from '@fisch0920/drizzle-orm'
|
||||||
import {
|
import {
|
||||||
boolean,
|
boolean,
|
||||||
|
@ -9,6 +9,15 @@ import {
|
||||||
} from '@fisch0920/drizzle-orm/pg-core'
|
} from '@fisch0920/drizzle-orm/pg-core'
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
|
import {
|
||||||
|
createInsertSchema,
|
||||||
|
createSelectSchema,
|
||||||
|
createUpdateSchema,
|
||||||
|
cuid,
|
||||||
|
deploymentId,
|
||||||
|
projectId,
|
||||||
|
timestamps
|
||||||
|
} from './common'
|
||||||
import { projects } from './project'
|
import { projects } from './project'
|
||||||
import {
|
import {
|
||||||
type DeploymentOriginAdapter,
|
type DeploymentOriginAdapter,
|
||||||
|
@ -18,15 +27,6 @@ import {
|
||||||
} from './schemas'
|
} from './schemas'
|
||||||
import { teams, teamSelectSchema } from './team'
|
import { teams, teamSelectSchema } from './team'
|
||||||
import { users, userSelectSchema } from './user'
|
import { users, userSelectSchema } from './user'
|
||||||
import {
|
|
||||||
createInsertSchema,
|
|
||||||
createSelectSchema,
|
|
||||||
createUpdateSchema,
|
|
||||||
cuid,
|
|
||||||
deploymentId,
|
|
||||||
projectId,
|
|
||||||
timestamps
|
|
||||||
} from './utils'
|
|
||||||
|
|
||||||
export const deployments = pgTable(
|
export const deployments = pgTable(
|
||||||
'deployments',
|
'deployments',
|
||||||
|
@ -105,13 +105,6 @@ export const deploymentsRelations = relations(deployments, ({ one }) => ({
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export type DeploymentRelationFields = keyof ReturnType<
|
|
||||||
(typeof deploymentsRelations)['config']
|
|
||||||
>
|
|
||||||
|
|
||||||
export const deploymentRelationsSchema: z.ZodType<DeploymentRelationFields> =
|
|
||||||
z.enum(['user', 'team', 'project'])
|
|
||||||
|
|
||||||
// TODO: virtual hasFreeTier
|
// TODO: virtual hasFreeTier
|
||||||
// TODO: virtual url
|
// TODO: virtual url
|
||||||
// TODO: virtual openApiUrl
|
// TODO: virtual openApiUrl
|
|
@ -1,9 +1,8 @@
|
||||||
|
export * from './common'
|
||||||
export * from './consumer'
|
export * from './consumer'
|
||||||
export * from './deployment'
|
export * from './deployment'
|
||||||
export * from './log-entry'
|
export * from './log-entry'
|
||||||
export * from './project'
|
export * from './project'
|
||||||
export * from './schemas'
|
|
||||||
export * from './team'
|
export * from './team'
|
||||||
export * from './team-member'
|
export * from './team-member'
|
||||||
export * from './user'
|
export * from './user'
|
||||||
export * from './utils'
|
|
|
@ -2,10 +2,6 @@ import { relations } from '@fisch0920/drizzle-orm'
|
||||||
import { index, jsonb, pgTable, text } from '@fisch0920/drizzle-orm/pg-core'
|
import { index, jsonb, pgTable, text } from '@fisch0920/drizzle-orm/pg-core'
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
import { consumers, consumerSelectSchema } from './consumer'
|
|
||||||
import { deployments, deploymentSelectSchema } from './deployment'
|
|
||||||
import { projects, projectSelectSchema } from './project'
|
|
||||||
import { users, userSelectSchema } from './user'
|
|
||||||
import {
|
import {
|
||||||
createInsertSchema,
|
createInsertSchema,
|
||||||
createSelectSchema,
|
createSelectSchema,
|
||||||
|
@ -16,7 +12,11 @@ import {
|
||||||
logEntryTypeEnum,
|
logEntryTypeEnum,
|
||||||
projectId,
|
projectId,
|
||||||
timestamps
|
timestamps
|
||||||
} from './utils'
|
} from './common'
|
||||||
|
import { consumers, consumerSelectSchema } from './consumer'
|
||||||
|
import { deployments, deploymentSelectSchema } from './deployment'
|
||||||
|
import { projects, projectSelectSchema } from './project'
|
||||||
|
import { users, userSelectSchema } from './user'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `LogEntry` is an internal audit log entry.
|
* A `LogEntry` is an internal audit log entry.
|
|
@ -1,4 +1,4 @@
|
||||||
import { validators } from '@agentic/validators'
|
import { validators } from '@agentic/platform-validators'
|
||||||
import { relations } from '@fisch0920/drizzle-orm'
|
import { relations } from '@fisch0920/drizzle-orm'
|
||||||
import {
|
import {
|
||||||
boolean,
|
boolean,
|
||||||
|
@ -10,6 +10,18 @@ import {
|
||||||
} from '@fisch0920/drizzle-orm/pg-core'
|
} from '@fisch0920/drizzle-orm/pg-core'
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
|
import {
|
||||||
|
createInsertSchema,
|
||||||
|
createSelectSchema,
|
||||||
|
createUpdateSchema,
|
||||||
|
cuid,
|
||||||
|
deploymentId,
|
||||||
|
pricingCurrencyEnum,
|
||||||
|
pricingIntervalEnum,
|
||||||
|
projectId,
|
||||||
|
stripeId,
|
||||||
|
timestamps
|
||||||
|
} from './common'
|
||||||
import { deployments, deploymentSelectSchema } from './deployment'
|
import { deployments, deploymentSelectSchema } from './deployment'
|
||||||
import {
|
import {
|
||||||
pricingIntervalSchema,
|
pricingIntervalSchema,
|
||||||
|
@ -22,18 +34,6 @@ import {
|
||||||
} from './schemas'
|
} from './schemas'
|
||||||
import { teams, teamSelectSchema } from './team'
|
import { teams, teamSelectSchema } from './team'
|
||||||
import { users, userSelectSchema } from './user'
|
import { users, userSelectSchema } from './user'
|
||||||
import {
|
|
||||||
createInsertSchema,
|
|
||||||
createSelectSchema,
|
|
||||||
createUpdateSchema,
|
|
||||||
cuid,
|
|
||||||
deploymentId,
|
|
||||||
pricingCurrencyEnum,
|
|
||||||
pricingIntervalEnum,
|
|
||||||
projectId,
|
|
||||||
stripeId,
|
|
||||||
timestamps
|
|
||||||
} from './utils'
|
|
||||||
|
|
||||||
export const projects = pgTable(
|
export const projects = pgTable(
|
||||||
'projects',
|
'projects',
|
||||||
|
@ -157,17 +157,6 @@ export const projectsRelations = relations(projects, ({ one }) => ({
|
||||||
// })
|
// })
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export type ProjectRelationFields = keyof ReturnType<
|
|
||||||
(typeof projectsRelations)['config']
|
|
||||||
>
|
|
||||||
|
|
||||||
export const projectRelationsSchema: z.ZodType<ProjectRelationFields> = z.enum([
|
|
||||||
'user',
|
|
||||||
'team',
|
|
||||||
'lastPublishedDeployment',
|
|
||||||
'lastDeployment'
|
|
||||||
])
|
|
||||||
|
|
||||||
export const projectSelectSchema = createSelectSchema(projects, {
|
export const projectSelectSchema = createSelectSchema(projects, {
|
||||||
applicationFeePercent: (schema) => schema.nonnegative(),
|
applicationFeePercent: (schema) => schema.nonnegative(),
|
||||||
|
|
|
@ -7,8 +7,6 @@ import {
|
||||||
} from '@fisch0920/drizzle-orm/pg-core'
|
} from '@fisch0920/drizzle-orm/pg-core'
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
import { teams, teamSelectSchema } from './team'
|
|
||||||
import { users, userSelectSchema } from './user'
|
|
||||||
import {
|
import {
|
||||||
createInsertSchema,
|
createInsertSchema,
|
||||||
createSelectSchema,
|
createSelectSchema,
|
||||||
|
@ -18,7 +16,9 @@ import {
|
||||||
teamSlug,
|
teamSlug,
|
||||||
timestamp,
|
timestamp,
|
||||||
timestamps
|
timestamps
|
||||||
} from './utils'
|
} from './common'
|
||||||
|
import { teams, teamSelectSchema } from './team'
|
||||||
|
import { users, userSelectSchema } from './user'
|
||||||
|
|
||||||
export const teamMembers = pgTable(
|
export const teamMembers = pgTable(
|
||||||
'team_members',
|
'team_members',
|
|
@ -1,4 +1,4 @@
|
||||||
import { validators } from '@agentic/validators'
|
import { validators } from '@agentic/platform-validators'
|
||||||
import { relations } from '@fisch0920/drizzle-orm'
|
import { relations } from '@fisch0920/drizzle-orm'
|
||||||
import {
|
import {
|
||||||
index,
|
index,
|
||||||
|
@ -8,8 +8,6 @@ import {
|
||||||
} from '@fisch0920/drizzle-orm/pg-core'
|
} from '@fisch0920/drizzle-orm/pg-core'
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
import { teamMembers } from './team-member'
|
|
||||||
import { users, userSelectSchema } from './user'
|
|
||||||
import {
|
import {
|
||||||
createInsertSchema,
|
createInsertSchema,
|
||||||
createSelectSchema,
|
createSelectSchema,
|
||||||
|
@ -18,7 +16,9 @@ import {
|
||||||
id,
|
id,
|
||||||
teamSlug,
|
teamSlug,
|
||||||
timestamps
|
timestamps
|
||||||
} from './utils'
|
} from './common'
|
||||||
|
import { teamMembers } from './team-member'
|
||||||
|
import { users, userSelectSchema } from './user'
|
||||||
|
|
||||||
export const teams = pgTable(
|
export const teams = pgTable(
|
||||||
'teams',
|
'teams',
|
|
@ -1,5 +1,5 @@
|
||||||
import { sha256 } from '@agentic/platform-core'
|
import { sha256 } from '@agentic/platform-core'
|
||||||
import { validators } from '@agentic/validators'
|
import { validators } from '@agentic/platform-validators'
|
||||||
import { relations } from '@fisch0920/drizzle-orm'
|
import { relations } from '@fisch0920/drizzle-orm'
|
||||||
import {
|
import {
|
||||||
boolean,
|
boolean,
|
||||||
|
@ -11,8 +11,6 @@ import {
|
||||||
} from '@fisch0920/drizzle-orm/pg-core'
|
} from '@fisch0920/drizzle-orm/pg-core'
|
||||||
import { hashSync } from 'bcryptjs'
|
import { hashSync } from 'bcryptjs'
|
||||||
|
|
||||||
import { type AuthProviders, publicAuthProvidersSchema } from './schemas'
|
|
||||||
import { teams } from './team'
|
|
||||||
import {
|
import {
|
||||||
createInsertSchema,
|
createInsertSchema,
|
||||||
createSelectSchema,
|
createSelectSchema,
|
||||||
|
@ -23,7 +21,9 @@ import {
|
||||||
timestamps,
|
timestamps,
|
||||||
username,
|
username,
|
||||||
userRoleEnum
|
userRoleEnum
|
||||||
} from './utils'
|
} from './common'
|
||||||
|
import { type AuthProviders, publicAuthProvidersSchema } from './schemas'
|
||||||
|
import { teams } from './team'
|
||||||
|
|
||||||
export const users = pgTable(
|
export const users = pgTable(
|
||||||
'users',
|
'users',
|
|
@ -1,6 +1,10 @@
|
||||||
import { validators } from '@agentic/validators'
|
import { validators } from '@agentic/platform-validators'
|
||||||
import { z } from '@hono/zod-openapi'
|
import { z } from '@hono/zod-openapi'
|
||||||
|
|
||||||
|
import type { consumersRelations } from './schema/consumer'
|
||||||
|
import type { deploymentsRelations } from './schema/deployment'
|
||||||
|
import type { projectsRelations } from './schema/project'
|
||||||
|
|
||||||
function getCuidSchema(idLabel: string) {
|
function getCuidSchema(idLabel: string) {
|
||||||
return z.string().refine((id) => validators.cuid(id), {
|
return z.string().refine((id) => validators.cuid(id), {
|
||||||
message: `Invalid ${idLabel}`
|
message: `Invalid ${idLabel}`
|
||||||
|
@ -57,3 +61,25 @@ export const paginationSchema = z.object({
|
||||||
// )
|
// )
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
export type ProjectRelationFields = keyof ReturnType<
|
||||||
|
(typeof projectsRelations)['config']
|
||||||
|
>
|
||||||
|
export const projectRelationsSchema: z.ZodType<ProjectRelationFields> = z.enum([
|
||||||
|
'user',
|
||||||
|
'team',
|
||||||
|
'lastPublishedDeployment',
|
||||||
|
'lastDeployment'
|
||||||
|
])
|
||||||
|
|
||||||
|
export type DeploymentRelationFields = keyof ReturnType<
|
||||||
|
(typeof deploymentsRelations)['config']
|
||||||
|
>
|
||||||
|
export const deploymentRelationsSchema: z.ZodType<DeploymentRelationFields> =
|
||||||
|
z.enum(['user', 'team', 'project'])
|
||||||
|
|
||||||
|
export type ConsumerRelationFields = keyof ReturnType<
|
||||||
|
(typeof consumersRelations)['config']
|
||||||
|
>
|
||||||
|
export const consumerRelationsSchema: z.ZodType<ConsumerRelationFields> =
|
||||||
|
z.enum(['user', 'project', 'deployment'])
|
|
@ -1,7 +1,5 @@
|
||||||
import { expectTypeOf, test } from 'vitest'
|
import { expectTypeOf, test } from 'vitest'
|
||||||
|
|
||||||
import type { LogLevel } from '@/lib/logger'
|
|
||||||
|
|
||||||
import type { LogEntry, RawLogEntry, RawUser, User } from './types'
|
import type { LogEntry, RawLogEntry, RawUser, User } from './types'
|
||||||
|
|
||||||
type UserKeys = Exclude<keyof User & keyof RawUser, 'authProviders'>
|
type UserKeys = Exclude<keyof User & keyof RawUser, 'authProviders'>
|
||||||
|
@ -19,6 +17,4 @@ test('LogEntry types are compatible', () => {
|
||||||
expectTypeOf<LogEntry[LogEntryKeys]>().toEqualTypeOf<
|
expectTypeOf<LogEntry[LogEntryKeys]>().toEqualTypeOf<
|
||||||
RawLogEntry[LogEntryKeys]
|
RawLogEntry[LogEntryKeys]
|
||||||
>()
|
>()
|
||||||
|
|
||||||
expectTypeOf<LogEntry['level']>().toEqualTypeOf<LogLevel>()
|
|
||||||
})
|
})
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { hashObject } from '@agentic/platform-core'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
PricingInterval,
|
||||||
|
PricingPlan,
|
||||||
|
PricingPlanLineItem,
|
||||||
|
PricingPlanList
|
||||||
|
} from './schema/schemas'
|
||||||
|
import type { RawProject } from './types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hash used to uniquely map a PricingPlanLineItem to its
|
||||||
|
* corresponding Stripe Price in a stable way across deployments within a
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This hash is used as the key for the `Project._stripePriceIdMap`.
|
||||||
|
*/
|
||||||
|
export function getPricingPlanLineItemHashForStripePrice({
|
||||||
|
pricingPlan,
|
||||||
|
pricingPlanLineItem,
|
||||||
|
project
|
||||||
|
}: {
|
||||||
|
pricingPlan: PricingPlan
|
||||||
|
pricingPlanLineItem: PricingPlanLineItem
|
||||||
|
project: RawProject
|
||||||
|
}) {
|
||||||
|
// TODO: use pricingPlan.slug as well here?
|
||||||
|
// TODO: not sure if this is needed or not...
|
||||||
|
// With pricing plan slug:
|
||||||
|
// - 'price:free:base:<hash>'
|
||||||
|
// - 'price:basic-monthly:base:<hash>'
|
||||||
|
// - 'price:basic-monthly:requests:<hash>'
|
||||||
|
// Without pricing plan slug:
|
||||||
|
// - 'price:base:<hash>'
|
||||||
|
// - 'price:base:<hash>'
|
||||||
|
// - 'price:requests:<hash>'
|
||||||
|
|
||||||
|
const hash = hashObject({
|
||||||
|
...pricingPlanLineItem,
|
||||||
|
projectId: project.id,
|
||||||
|
stripeAccountId: project._stripeAccountId,
|
||||||
|
currency: project.pricingCurrency
|
||||||
|
})
|
||||||
|
|
||||||
|
return `price:${pricingPlan.slug}:${pricingPlanLineItem.slug}:${hash}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getStripePriceIdForPricingPlanLineItem({
|
||||||
|
pricingPlan,
|
||||||
|
pricingPlanLineItem,
|
||||||
|
project
|
||||||
|
}: {
|
||||||
|
pricingPlan: PricingPlan
|
||||||
|
pricingPlanLineItem: PricingPlanLineItem
|
||||||
|
project: RawProject
|
||||||
|
}): string | undefined {
|
||||||
|
const pricingPlanLineItemHash = getPricingPlanLineItemHashForStripePrice({
|
||||||
|
pricingPlan,
|
||||||
|
pricingPlanLineItem,
|
||||||
|
project
|
||||||
|
})
|
||||||
|
|
||||||
|
return project._stripePriceIdMap[pricingPlanLineItemHash]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPricingPlansByInterval({
|
||||||
|
pricingInterval,
|
||||||
|
pricingPlans
|
||||||
|
}: {
|
||||||
|
pricingInterval: PricingInterval
|
||||||
|
pricingPlans: PricingPlanList
|
||||||
|
}): PricingPlan[] {
|
||||||
|
return pricingPlans.filter(
|
||||||
|
(pricingPlan) =>
|
||||||
|
pricingPlan.interval === undefined ||
|
||||||
|
pricingPlan.interval === pricingInterval
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const pricingIntervalToLabelMap: Record<PricingInterval, string> = {
|
||||||
|
day: 'daily',
|
||||||
|
week: 'weekly',
|
||||||
|
month: 'monthly',
|
||||||
|
year: 'yearly'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLabelForPricingInterval(
|
||||||
|
pricingInterval: PricingInterval
|
||||||
|
): string {
|
||||||
|
return pricingIntervalToLabelMap[pricingInterval]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"extends": "@fisch0920/config/tsconfig-node",
|
||||||
|
"include": ["src", "*.config.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "@agentic/validators",
|
"name": "@agentic/platform-validators",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "Validation utils for the Agentic platform.",
|
"description": "Validation utils for the Agentic platform.",
|
||||||
|
|
|
@ -128,15 +128,12 @@ importers:
|
||||||
'@agentic/platform-core':
|
'@agentic/platform-core':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/core
|
version: link:../../packages/core
|
||||||
'@agentic/validators':
|
'@agentic/platform-db':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../packages/db
|
||||||
|
'@agentic/platform-validators':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/validators
|
version: link:../../packages/validators
|
||||||
'@fisch0920/drizzle-orm':
|
|
||||||
specifier: ^0.43.7
|
|
||||||
version: 0.43.7(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(postgres@3.4.5)
|
|
||||||
'@fisch0920/drizzle-zod':
|
|
||||||
specifier: ^0.7.9
|
|
||||||
version: 0.7.9(@fisch0920/drizzle-orm@0.43.7(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(postgres@3.4.5))(zod@3.24.4)
|
|
||||||
'@hono/node-server':
|
'@hono/node-server':
|
||||||
specifier: ^1.14.1
|
specifier: ^1.14.1
|
||||||
version: 1.14.1(hono@4.7.9)
|
version: 1.14.1(hono@4.7.9)
|
||||||
|
@ -146,21 +143,12 @@ importers:
|
||||||
'@hono/zod-openapi':
|
'@hono/zod-openapi':
|
||||||
specifier: ^0.19.6
|
specifier: ^0.19.6
|
||||||
version: 0.19.6(hono@4.7.9)(zod@3.24.4)
|
version: 0.19.6(hono@4.7.9)(zod@3.24.4)
|
||||||
'@hono/zod-validator':
|
|
||||||
specifier: ^0.5.0
|
|
||||||
version: 0.5.0(hono@4.7.9)(zod@3.24.4)
|
|
||||||
'@paralleldrive/cuid2':
|
|
||||||
specifier: ^2.2.2
|
|
||||||
version: 2.2.2
|
|
||||||
'@redocly/openapi-core':
|
'@redocly/openapi-core':
|
||||||
specifier: ^1.34.3
|
specifier: ^1.34.3
|
||||||
version: 1.34.3(supports-color@10.0.0)
|
version: 1.34.3(supports-color@10.0.0)
|
||||||
'@sentry/node':
|
'@sentry/node':
|
||||||
specifier: ^9.19.0
|
specifier: ^9.19.0
|
||||||
version: 9.19.0
|
version: 9.19.0
|
||||||
bcryptjs:
|
|
||||||
specifier: ^3.0.2
|
|
||||||
version: 3.0.2
|
|
||||||
eventid:
|
eventid:
|
||||||
specifier: ^2.0.1
|
specifier: ^2.0.1
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
|
@ -179,9 +167,6 @@ importers:
|
||||||
parse-json:
|
parse-json:
|
||||||
specifier: ^8.3.0
|
specifier: ^8.3.0
|
||||||
version: 8.3.0
|
version: 8.3.0
|
||||||
postgres:
|
|
||||||
specifier: ^3.4.5
|
|
||||||
version: 3.4.5
|
|
||||||
restore-cursor:
|
restore-cursor:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 5.1.0
|
version: 5.1.0
|
||||||
|
@ -238,6 +223,9 @@ importers:
|
||||||
'@agentic/platform-api':
|
'@agentic/platform-api':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../apps/api
|
version: link:../../apps/api
|
||||||
|
'@agentic/platform-db':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../db
|
||||||
'@commander-js/extra-typings':
|
'@commander-js/extra-typings':
|
||||||
specifier: ^14.0.0
|
specifier: ^14.0.0
|
||||||
version: 14.0.0(commander@14.0.0)
|
version: 14.0.0(commander@14.0.0)
|
||||||
|
@ -258,6 +246,45 @@ importers:
|
||||||
specifier: ^4.7.9
|
specifier: ^4.7.9
|
||||||
version: 4.7.9
|
version: 4.7.9
|
||||||
|
|
||||||
|
packages/db:
|
||||||
|
dependencies:
|
||||||
|
'@agentic/platform-core':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../core
|
||||||
|
'@agentic/platform-validators':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../validators
|
||||||
|
'@fisch0920/drizzle-orm':
|
||||||
|
specifier: ^0.43.7
|
||||||
|
version: 0.43.7(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(postgres@3.4.5)
|
||||||
|
'@fisch0920/drizzle-zod':
|
||||||
|
specifier: ^0.7.9
|
||||||
|
version: 0.7.9(@fisch0920/drizzle-orm@0.43.7(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(postgres@3.4.5))(zod@3.24.4)
|
||||||
|
'@hono/zod-openapi':
|
||||||
|
specifier: ^0.19.6
|
||||||
|
version: 0.19.6(hono@4.7.9)(zod@3.24.4)
|
||||||
|
'@paralleldrive/cuid2':
|
||||||
|
specifier: ^2.2.2
|
||||||
|
version: 2.2.2
|
||||||
|
bcryptjs:
|
||||||
|
specifier: ^3.0.2
|
||||||
|
version: 3.0.2
|
||||||
|
hono:
|
||||||
|
specifier: ^4.7.9
|
||||||
|
version: 4.7.9
|
||||||
|
parse-json:
|
||||||
|
specifier: ^8.3.0
|
||||||
|
version: 8.3.0
|
||||||
|
postgres:
|
||||||
|
specifier: ^3.4.5
|
||||||
|
version: 3.4.5
|
||||||
|
type-fest:
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 4.41.0
|
||||||
|
zod:
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 3.24.4
|
||||||
|
|
||||||
packages/validators:
|
packages/validators:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@paralleldrive/cuid2':
|
'@paralleldrive/cuid2':
|
||||||
|
|
Ładowanie…
Reference in New Issue