| import { z } from "zod"; |
| import { Node } from "@xyflow/react"; |
| import { Domain, ServiceType, VolumeType } from "./types.js"; |
| |
| export const serviceAnalyzisSchema = z.object({ |
| name: z.string(), |
| location: z.string(), |
| configVars: z.array( |
| z.object({ |
| name: z.string(), |
| category: z.enum(["CommandLineFlag", "EnvironmentVariable"]), |
| type: z.optional(z.enum(["String", "Number", "Boolean"])), |
| semanticType: z.optional( |
| z.enum([ |
| "EXPANDED_ENV_VAR", |
| "PORT", |
| "FILESYSTEM_PATH", |
| "DATABASE_URL", |
| "SQLITE_PATH", |
| "POSTGRES_URL", |
| "POSTGRES_PASSWORD", |
| "POSTGRES_USER", |
| "POSTGRES_DB", |
| "POSTGRES_PORT", |
| "POSTGRES_HOST", |
| "POSTGRES_SSL", |
| "MONGO_URL", |
| "MONGO_PASSWORD", |
| "MONGO_USER", |
| "MONGO_DB", |
| "MONGO_PORT", |
| "MONGO_HOST", |
| "MONGO_SSL", |
| ]), |
| ), |
| }), |
| ), |
| }); |
| |
| export type BoundEnvVar = |
| | { |
| id: string; |
| source: string | null; |
| } |
| | { |
| id: string; |
| source: string | null; |
| name: string; |
| isEditting: boolean; |
| } |
| | { |
| id: string; |
| source: string | null; |
| name: string; |
| alias: string; |
| isEditting: boolean; |
| } |
| | { |
| id: string; |
| source: string | null; |
| portId: string; |
| name: string; |
| alias: string; |
| isEditting: boolean; |
| } |
| | { |
| id: string; |
| source: null; |
| name: string; |
| value: string; |
| isEditting?: boolean; |
| }; |
| |
| export type EnvVar = { |
| name: string; |
| value: string; |
| }; |
| |
| export type InitData = { |
| label: string; |
| envVars: BoundEnvVar[]; |
| ports: Port[]; |
| }; |
| |
| export type NodeData = InitData & { |
| activeField?: string | undefined; |
| state?: string | null; |
| }; |
| |
| export type PortConnectedTo = { |
| serviceId: string; |
| portId: string; |
| }; |
| |
| export type NetworkData = NodeData & { |
| domain: string; |
| }; |
| |
| export type NetworkNode = Node<NetworkData> & { |
| type: "network"; |
| }; |
| |
| export type GatewayHttpsData = NodeData & { |
| readonly?: boolean; |
| network?: string; |
| subdomain?: string; |
| https?: PortConnectedTo; |
| auth?: { |
| enabled: boolean; |
| groups: string[]; |
| noAuthPathPatterns: string[]; |
| }; |
| }; |
| |
| export type GatewayHttpsNode = Node<GatewayHttpsData> & { |
| type: "gateway-https"; |
| }; |
| |
| export type GatewayTCPData = NodeData & { |
| readonly?: boolean; |
| network?: string; |
| subdomain?: string; |
| exposed: PortConnectedTo[]; |
| selected?: { |
| serviceId?: string; |
| portId?: string; |
| }; |
| }; |
| |
| export type GatewayTCPNode = Node<GatewayTCPData> & { |
| type: "gateway-tcp"; |
| }; |
| |
| export type Port = { |
| id: string; |
| name: string; |
| value: number; |
| }; |
| |
| export type ServiceData = NodeData & { |
| type: ServiceType; |
| repository?: |
| | { |
| id: number; |
| repoNodeId: string; |
| } |
| | { |
| id: number; |
| repoNodeId: string; |
| branch: string; |
| } |
| | { |
| id: number; |
| repoNodeId: string; |
| branch: string; |
| rootDir: string; |
| }; |
| env: string[]; |
| volume: string[]; |
| preBuildCommands: string; |
| isChoosingPortToConnect: boolean; |
| dev?: |
| | { |
| enabled: false; |
| expose?: Domain; |
| } |
| | { |
| enabled: true; |
| expose?: Domain; |
| codeServerNodeId: string; |
| sshNodeId: string; |
| }; |
| model?: { |
| name: "gemini" | "claude"; |
| apiKey?: string; |
| }; |
| info?: z.infer<typeof serviceAnalyzisSchema>; |
| }; |
| |
| export type ServiceNode = Node<ServiceData> & { |
| type: "app"; |
| }; |
| |
| export type VolumeData = NodeData & { |
| type: VolumeType; |
| size: string; |
| attachedTo: string[]; |
| }; |
| |
| export type VolumeNode = Node<VolumeData> & { |
| type: "volume"; |
| }; |
| |
| export type PostgreSQLData = NodeData & { |
| volumeId: string; |
| }; |
| |
| export type PostgreSQLNode = Node<PostgreSQLData> & { |
| type: "postgresql"; |
| }; |
| |
| export type MongoDBData = NodeData & { |
| volumeId: string; |
| }; |
| |
| export type MongoDBNode = Node<MongoDBData> & { |
| type: "mongodb"; |
| }; |
| |
| export type GithubData = NodeData & { |
| repository?: { |
| id: number; |
| sshURL: string; |
| fullName: string; |
| }; |
| }; |
| |
| export type GithubNode = Node<GithubData> & { |
| type: "github"; |
| }; |
| |
| export type NANode = Node<NodeData> & { |
| type: undefined; |
| }; |
| |
| export type AppNode = |
| | NetworkNode |
| | GatewayHttpsNode |
| | GatewayTCPNode |
| | ServiceNode |
| | VolumeNode |
| | PostgreSQLNode |
| | MongoDBNode |
| | GithubNode |
| | NANode; |
| |
| export type NodeType = Exclude<Pick<AppNode, "type">["type"], undefined>; |
| |
| export const networkSchema = z.object({ |
| name: z.string().min(1), |
| domain: z.string().min(1), |
| hasAuth: z.boolean(), |
| }); |
| |
| export type Network = z.infer<typeof networkSchema>; |
| |
| export const accessSchema = z.discriminatedUnion("type", [ |
| z.object({ |
| type: z.literal("https"), |
| name: z.string(), |
| address: z.string(), |
| agentName: z.string().optional(), |
| }), |
| z.object({ |
| type: z.literal("ssh"), |
| name: z.string(), |
| host: z.string(), |
| port: z.number(), |
| }), |
| z.object({ |
| type: z.literal("tcp"), |
| name: z.string(), |
| host: z.string(), |
| port: z.number(), |
| }), |
| z.object({ |
| type: z.literal("udp"), |
| name: z.string(), |
| host: z.string(), |
| port: z.number(), |
| }), |
| z.object({ |
| type: z.literal("postgresql"), |
| name: z.string(), |
| host: z.string(), |
| port: z.number(), |
| database: z.string(), |
| username: z.string(), |
| password: z.string(), |
| }), |
| z.object({ |
| type: z.literal("mongodb"), |
| name: z.string(), |
| host: z.string(), |
| port: z.number(), |
| database: z.string(), |
| username: z.string(), |
| password: z.string(), |
| }), |
| ]); |
| |
| export const serviceInfoSchema = z.object({ |
| name: z.string(), |
| workers: z.array( |
| z.object({ |
| id: z.string(), |
| commit: z |
| .object({ |
| hash: z.string(), |
| message: z.string(), |
| }) |
| .nullable() |
| .optional(), |
| commands: z |
| .array( |
| z.object({ |
| command: z.string(), |
| state: z.string(), |
| }), |
| ) |
| .optional(), |
| }), |
| ), |
| }); |
| |
| export const envSchema = z.object({ |
| deployKeyPublic: z.string().optional(), |
| instanceId: z.string().optional(), |
| networks: z.array( |
| z.object({ |
| name: z.string(), |
| domain: z.string(), |
| hasAuth: z.boolean(), |
| }), |
| ), |
| integrations: z.object({ |
| github: z.boolean(), |
| gemini: z.boolean(), |
| anthropic: z.boolean(), |
| }), |
| services: z.array(serviceInfoSchema), |
| user: z.object({ |
| id: z.string(), |
| username: z.string(), |
| }), |
| access: z.array(accessSchema), |
| }); |
| |
| export type ServiceInfo = z.infer<typeof serviceInfoSchema>; |
| export type Env = z.infer<typeof envSchema>; |
| export type Access = z.infer<typeof accessSchema>; |
| export type AgentAccess = Required<Extract<Access, { type: "https" }>>; |