import { PostgrestClient } from '@supabase/postgrest-js'; import { MergeDeep } from 'type-fest'; export { uuidv7 as uuid } from 'uuidv7'; type Json = string | number | boolean | null | { [key: string]: Json | undefined; } | Json[]; type Database = { public: { Tables: { _prisma_migrations: { Row: { applied_steps_count: number; checksum: string; finished_at: string | null; id: string; logs: string | null; migration_name: string; rolled_back_at: string | null; started_at: string; }; Insert: { applied_steps_count?: number; checksum: string; finished_at?: string | null; id: string; logs?: string | null; migration_name: string; rolled_back_at?: string | null; started_at?: string; }; Update: { applied_steps_count?: number; checksum?: string; finished_at?: string | null; id?: string; logs?: string | null; migration_name?: string; rolled_back_at?: string | null; started_at?: string; }; Relationships: []; }; ApiKey: { Row: { applicationId: string; createdAt: string; hashedSecret: string; id: string; identifier: string; lastUsedAt: string | null; name: string | null; updatedAt: string; }; Insert: { applicationId: string; createdAt?: string; hashedSecret: string; id: string; identifier: string; lastUsedAt?: string | null; name?: string | null; updatedAt: string; }; Update: { applicationId?: string; createdAt?: string; hashedSecret?: string; id?: string; identifier?: string; lastUsedAt?: string | null; name?: string | null; updatedAt?: string; }; Relationships: [ { foreignKeyName: "ApiKey_applicationId_fkey"; columns: ["applicationId"]; isOneToOne: false; referencedRelation: "Application"; referencedColumns: ["id"]; } ]; }; Application: { Row: { createdAt: string; domain: string; id: string; name: string; repo: string; status: string; teamId: string; updatedAt: string; }; Insert: { createdAt?: string; domain: string; id: string; name: string; repo: string; status: string; teamId: string; updatedAt: string; }; Update: { createdAt?: string; domain?: string; id?: string; name?: string; repo?: string; status?: string; teamId?: string; updatedAt?: string; }; Relationships: [ { foreignKeyName: "Application_teamId_fkey"; columns: ["teamId"]; isOneToOne: false; referencedRelation: "Team"; referencedColumns: ["id"]; } ]; }; Deployment: { Row: { applicationId: string; archive: string | null; createdAt: string; deployment: Json; gitSha: string; id: string; originEnv: string | null; status: string; statusInfo: string | null; updatedAt: string; }; Insert: { applicationId: string; archive?: string | null; createdAt?: string; deployment: Json; gitSha: string; id: string; originEnv?: string | null; status: string; statusInfo?: string | null; updatedAt: string; }; Update: { applicationId?: string; archive?: string | null; createdAt?: string; deployment?: Json; gitSha?: string; id?: string; originEnv?: string | null; status?: string; statusInfo?: string | null; updatedAt?: string; }; Relationships: [ { foreignKeyName: "Deployment_applicationId_fkey"; columns: ["applicationId"]; isOneToOne: false; referencedRelation: "Application"; referencedColumns: ["id"]; } ]; }; EnvVar: { Row: { applicationId: string; createdAt: string; id: string; name: string; updatedAt: string; value: string; }; Insert: { applicationId: string; createdAt?: string; id: string; name: string; updatedAt: string; value: string; }; Update: { applicationId?: string; createdAt?: string; id?: string; name?: string; updatedAt?: string; value?: string; }; Relationships: [ { foreignKeyName: "EnvVar_applicationId_fkey"; columns: ["applicationId"]; isOneToOne: false; referencedRelation: "Application"; referencedColumns: ["id"]; } ]; }; ReconcilerLogs: { Row: { action: string; createdAt: string; errorMessage: string | null; id: string; metadata: Json | null; orgId: string | null; resourceId: string; resourceType: string; status: string; }; Insert: { action: string; createdAt?: string; errorMessage?: string | null; id: string; metadata?: Json | null; orgId?: string | null; resourceId: string; resourceType: string; status: string; }; Update: { action?: string; createdAt?: string; errorMessage?: string | null; id?: string; metadata?: Json | null; orgId?: string | null; resourceId?: string; resourceType?: string; status?: string; }; Relationships: []; }; Secret: { Row: { applicationId: string; createdAt: string; id: string; name: string; updatedAt: string; valueEnc: string; }; Insert: { applicationId: string; createdAt?: string; id: string; name: string; updatedAt: string; valueEnc: string; }; Update: { applicationId?: string; createdAt?: string; id?: string; name?: string; updatedAt?: string; valueEnc?: string; }; Relationships: [ { foreignKeyName: "Secret_applicationId_fkey"; columns: ["applicationId"]; isOneToOne: false; referencedRelation: "Application"; referencedColumns: ["id"]; } ]; }; SystemConfig: { Row: { createdAt: string; id: string; name: string; updatedAt: string; value: string; }; Insert: { createdAt?: string; id: string; name: string; updatedAt: string; value: string; }; Update: { createdAt?: string; id?: string; name?: string; updatedAt?: string; value?: string; }; Relationships: []; }; Team: { Row: { createdAt: string; emailDomain: string | null; id: string; name: string; status: string; updatedAt: string; }; Insert: { createdAt?: string; emailDomain?: string | null; id: string; name: string; status: string; updatedAt: string; }; Update: { createdAt?: string; emailDomain?: string | null; id?: string; name?: string; status?: string; updatedAt?: string; }; Relationships: []; }; TeamSecret: { Row: { createdAt: string; createdById: string; id: string; name: string; teamId: string; updatedAt: string; valueEnc: string; }; Insert: { createdAt?: string; createdById: string; id: string; name: string; teamId: string; updatedAt: string; valueEnc: string; }; Update: { createdAt?: string; createdById?: string; id?: string; name?: string; teamId?: string; updatedAt?: string; valueEnc?: string; }; Relationships: [ { foreignKeyName: "TeamSecret_createdById_fkey"; columns: ["createdById"]; isOneToOne: false; referencedRelation: "User"; referencedColumns: ["id"]; }, { foreignKeyName: "TeamSecret_teamId_fkey"; columns: ["teamId"]; isOneToOne: false; referencedRelation: "Team"; referencedColumns: ["id"]; } ]; }; User: { Row: { createdAt: string; email: string; githubId: string; githubUsername: string; id: string; isSuperUser: boolean; name: string; updatedAt: string; }; Insert: { createdAt?: string; email: string; githubId: string; githubUsername: string; id: string; isSuperUser?: boolean; name: string; updatedAt: string; }; Update: { createdAt?: string; email?: string; githubId?: string; githubUsername?: string; id?: string; isSuperUser?: boolean; name?: string; updatedAt?: string; }; Relationships: []; }; UserRequest: { Row: { createdAt: string; id: string; requestId: string; response: string | null; updatedAt: string; userId: string; }; Insert: { createdAt?: string; id: string; requestId: string; response?: string | null; updatedAt: string; userId: string; }; Update: { createdAt?: string; id?: string; requestId?: string; response?: string | null; updatedAt?: string; userId?: string; }; Relationships: [ { foreignKeyName: "UserRequest_userId_fkey"; columns: ["userId"]; isOneToOne: false; referencedRelation: "User"; referencedColumns: ["id"]; } ]; }; UserTeam: { Row: { role: Database["public"]["Enums"]["UserRole"]; teamId: string; userId: string; }; Insert: { role?: Database["public"]["Enums"]["UserRole"]; teamId: string; userId: string; }; Update: { role?: Database["public"]["Enums"]["UserRole"]; teamId?: string; userId?: string; }; Relationships: [ { foreignKeyName: "UserTeam_teamId_fkey"; columns: ["teamId"]; isOneToOne: false; referencedRelation: "Team"; referencedColumns: ["id"]; }, { foreignKeyName: "UserTeam_userId_fkey"; columns: ["userId"]; isOneToOne: false; referencedRelation: "User"; referencedColumns: ["id"]; } ]; }; }; Views: { [_ in never]: never; }; Functions: { [_ in never]: never; }; Enums: { UserRole: "ADMIN" | "MEMBER"; }; CompositeTypes: { [_ in never]: never; }; }; }; /** * Modify the Postgrest types to account for default values and other differences with Prisma/Postgres. */ type DatabaseModified = MergeDeep & { createdAt?: string; }; }; Application: { Insert: Omit & { createdAt?: string; }; }; Deployment: { Insert: Omit & { createdAt?: string; }; }; ReconcilerLogs: { Insert: Omit & { createdAt?: string; }; }; EnvVar: { Insert: Omit & { createdAt?: string; }; }; Secret: { Insert: Omit & { createdAt?: string; }; }; SystemConfig: { Insert: Omit & { createdAt?: string; }; }; Team: { Insert: Omit & { createdAt?: string; }; }; TeamSecret: { Insert: Omit & { createdAt?: string; }; }; User: { Insert: Omit & { createdAt?: string; isSuperUser?: boolean; }; }; UserTeam: { Insert: Omit & { role?: Database["public"]["Enums"]["UserRole"]; }; }; }; }; }>; type ReadOnlyTable = Omit & { Insert: never; Update: never; }; type TenantDBTableNames = "Team" | "User" | "UserTeam" | "SystemConfig" | "ReconcilerLogs"; type TenantDB = { public: { Tables: { [K in TenantDBTableNames]: DatabaseModified["public"]["Tables"][K]; }; Views: DatabaseModified["public"]["Views"]; Functions: DatabaseModified["public"]["Functions"]; Enums: DatabaseModified["public"]["Enums"]; CompositeTypes: DatabaseModified["public"]["CompositeTypes"]; }; }; type OrgDBTableNames = Exclude; type OrgDB = { public: { Tables: { [K in OrgDBTableNames]: DatabaseModified["public"]["Tables"][K]; }; Views: { [K in TenantDBTableNames]: ReadOnlyTable; }; Functions: DatabaseModified["public"]["Functions"]; Enums: DatabaseModified["public"]["Enums"]; CompositeTypes: DatabaseModified["public"]["CompositeTypes"]; }; }; type TenantTables = TenantDB["public"]["Tables"][T]["Row"]; type OrgTables = OrgDB["public"]["Tables"][T]["Row"]; type OrgViews = Pick["Row"]; type TenantTablesInsert = TenantDB["public"]["Tables"][T]["Insert"]; type OrgTablesInsert = OrgDB["public"]["Tables"][T]["Insert"]; type TenantTablesUpdate = TenantDB["public"]["Tables"][T]["Update"]; type OrgTablesUpdate = OrgDB["public"]["Tables"][T]["Update"]; type TenantEnums = TenantDB["public"]["Enums"][T]; type OrgEnums = OrgDB["public"]["Enums"][T]; type PostgrestClientOptions = { url?: string; token?: string; useProvidedUrlAsIs?: boolean; }; /** * Create a pre-configured, typed postgrest client for the tenant-db or org-db. * For the Postgrest options, either pass a `url` and `token` to use, or rely * on the `POSTGREST_URL and `JWT_TOKEN` env vars. */ declare function createPostgrestClient(): PostgrestClient; declare function createPostgrestClient(options: PostgrestClientOptions | undefined): PostgrestClient; declare function createPostgrestClient(teamName: string, options?: PostgrestClientOptions): PostgrestClient; type ApiKey = OrgTables<"ApiKey">; type Application = OrgTables<"Application">; type Deployment = OrgTables<"Deployment">; type EnvVar = OrgTables<"EnvVar">; type Secret = OrgTables<"Secret">; type TeamSecret = OrgTables<"TeamSecret">; declare class OrgDatabase { postgrest: PostgrestClient; constructor(teamName: string, options?: PostgrestClientOptions); /** * Application */ getApplications(): Promise<{ createdAt: string; domain: string; id: string; name: string; repo: string; status: string; teamId: string; updatedAt: string; }[]>; getApplicationById(id: string): Promise<{ createdAt: string; domain: string; id: string; name: string; repo: string; status: string; teamId: string; updatedAt: string; }>; getLatestApplicationDeployments(appIds: string[]): Promise<{ id: string; createdAt: string; applicationId: string; status: string; }[]>; /** * Deployment */ getDeploymentJson(deploymentId: string): Promise; /** * Env Vars */ listEnvVars(applicationId?: string | undefined): Promise<{ id: string; name: string; value: string; applicationId: string; createdAt: string; updatedAt: string; Application: { id: string; name: string; }; }[]>; setEnvVar({ applicationId, name, value, }: { applicationId?: string; name: string; value: string; }): Promise<{ applicationId: string; createdAt: string; id: string; name: string; updatedAt: string; value: string; }>; unsetEnvVar({ applicationId, name, }: { applicationId?: string; name: string; }): Promise; /** * Secrets */ listSecrets(applicationId?: string | undefined): Promise<{ id: string; name: string; valueEnc: string; applicationId: string; createdAt: string; updatedAt: string; Application: { id: string; name: string; }; }[]>; setSecret({ applicationId, name, value, alreadyEncrypted, }: { applicationId?: string; name: string; value: string; alreadyEncrypted?: boolean; }): Promise<{ applicationId: string; createdAt: string; id: string; name: string; updatedAt: string; valueEnc: string; }>; encryptDataWithPublicKey(value: string): Promise; unsetSecret({ applicationId, name, }: { applicationId?: string; name: string; }): Promise; setTeamSecret({ teamId, name, value, createdById, alreadyEncrypted, }: { teamId: string; name: string; value: string; createdById: string; alreadyEncrypted?: boolean; }): Promise<{ createdAt: string; createdById: string; id: string; name: string; teamId: string; updatedAt: string; valueEnc: string; }>; updateTeamSecretValue({ teamId, name, value, alreadyEncrypted, }: { teamId: string; name: string; value: string; alreadyEncrypted?: boolean; }): Promise<{ createdAt: string; createdById: string; id: string; name: string; teamId: string; updatedAt: string; valueEnc: string; }>; unsetTeamSecret({ teamId, name }: { teamId: string; name: string; }): Promise; /** * API Keys */ /** * Creates an API Key for the given application, optionally with a `name`, stores * in the database, then returns it. If the `name` already exists, we rotate the key. * @param name an optional name to associate with the API Key * @param applicationId either an applicationId provided, or the default in the env * @returns */ createApiKey(name?: string, applicationId?: string | undefined): Promise; /** * Verifies an API Key to make sure that it exists for the given application. * @param apiKey an API key to verify * @param applicationId either an applicationId provided, or the default in the env */ verifyApiKey(apiKey: string, applicationId?: string | undefined): Promise; /** * Revoke the given API Key by its name or identifier * @param identifierOrName - the API Key's identifier or name * @param applicationId either an applicationId provided, or the default in the env */ revokeApiKey(identifierOrName: string, applicationId?: string | undefined): Promise<{ identifier: string; name: string | null; applicationId: string; }>; /** * Rotates the secret portion of an existing API Key using its identifier or name * @returns */ rotateApiKey(identifierOrName: string, applicationId?: string | undefined): Promise<{ apiKey: string; identifier: string; name: string | null; applicationId: string; }>; /** * Get a list of all API Keys for a given application. * @param applicationId either an applicationId provided, or the default in the env */ listApiKeys(applicationId?: string | undefined): Promise<{ id: string; identifier: string; name: string | null; createdAt: string; updatedAt: string; lastUsedAt: string | null; }[]>; /** * Default DS API Key - we sync the Default DS API Key between API Keys and Secrets */ createDefaultApiKey(applicationId?: string | undefined): Promise; revokeDefaultApiKey(applicationId?: string | undefined): Promise<{ identifier: string; name: string | null; applicationId: string; }>; rotateDefaultApiKey(applicationId?: string | undefined): Promise<{ apiKey: string; identifier: string; name: string | null; applicationId: string; }>; createUserRequest({ userId, requestId, payload, }: { userId: string; requestId: string; payload: string; }): Promise; } type Team = TenantTables<"Team">; type User = TenantTables<"User">; type UserTeam = TenantTables<"UserTeam">; type SystemConfig = TenantTables<"SystemConfig">; type ReconcilerLogEntry = Omit & { action: "DEPLOY" | "DESTROY" | "RESET" | "DELETE" | "DEPLOY_NO_DB" | "DEPLOY_WEB_CONSOLE_ONLY"; status: "failed" | "success" | "pending" | "skipped" | "error" | "in_progress" | "cancelled"; }, "id" | "createdAt">; declare class TenantDatabase { postgrest: PostgrestClient; constructor(options?: PostgrestClientOptions); getTeam(teamId: string): Promise<{ createdAt: string; emailDomain: string | null; id: string; name: string; status: string; updatedAt: string; } | null>; getTeamByName(teamName: string): Promise<{ createdAt: string; emailDomain: string | null; id: string; name: string; status: string; updatedAt: string; } | null>; getUser(email: string): Promise<{ createdAt: string; email: string; githubId: string; githubUsername: string; id: string; isSuperUser: boolean; name: string; updatedAt: string; } | null>; insertReconcilerLog(log: ReconcilerLogEntry): Promise<{ id: string; }>; getReconcilerLog(logId: string): Promise<{ action: string; createdAt: string; errorMessage: string | null; id: string; metadata: string | number | boolean | Json[] | { [x: string]: string | number | boolean | Json[] | any | null | undefined; } | null; orgId: string | null; resourceId: string; resourceType: string; status: string; }>; getReconcilerLogs(orgId?: string, limit?: number): Promise<{ action: string; createdAt: string; errorMessage: string | null; id: string; metadata: string | number | boolean | Json[] | { [x: string]: string | number | boolean | Json[] | any | null | undefined; } | null; orgId: string | null; resourceId: string; resourceType: string; status: string; }[]>; getReconcilerLogsByResource(orgId: string, resourceId: string, limit?: number): Promise<{ action: string; createdAt: string; errorMessage: string | null; id: string; metadata: string | number | boolean | Json[] | { [x: string]: string | number | boolean | Json[] | any | null | undefined; } | null; orgId: string | null; resourceId: string; resourceType: string; status: string; }[]>; /** * Watch a deployment-reconciler resource via the reconciler logs, yielding logs whenever the * status changes, and throwing or exiting when reaching a terminal state. * @param orgId The organization/team ID * @param resourceId The specific resource ID to watch * @param resourceType The type of resource being watched * @param action The action being performed on the resource * @param options Polling options * @yields Event objects containing the status and full log entry * @throws Error if timeout reached or invalid status encountered * @returns Completes when a terminal status is reached (success/error/failed/skipped/cancelled) */ watchReconcilerLogsByResource(orgId: string, resourceId: string, resourceType: ReconcilerLogEntry["resourceType"], action: ReconcilerLogEntry["action"], options?: { timeoutMS?: number; intervalMS?: number; maxLogsPerPoll?: number; }): AsyncGenerator<{ status: ReconcilerLogEntry["status"]; log: TenantTables<"ReconcilerLogs">; logLines?: string[]; }, void, undefined>; } /** * Generate an API Key, possibly using an existing identifier * @param identifier an optional identifier to use, otherwise one will be generated */ declare function generateApiKey(identifier?: string): string; type ParsedApiKey = { identifier: string; secret: string; }; declare function parseApiKey(apiKey: string): ParsedApiKey; /** * Masks the secret part of an API key for display or logging purposes. * @param apiKey The full API key string. * @returns The API key with the secret part masked. */ declare function maskApiKey(apiKey: string): string; declare const generateRandomIdNice: (size: number) => string; type UserRequestObject = { type: "org" | "app" | "local"; id: string; requestId: string; activeTeamId: string; }; /** * (this is used as an utility when we store data in UserRequest table) * User request IDs are in the format of: -:: * * @param id - the id to parse * @returns an object with the following properties: * - type: the type of the request (org, app, local) * - id: the id of the request * - requestId: the request id * - activeTeamId: the active team id */ declare function parseUserRequest(inputId: string): UserRequestObject; /** * * Encrypts a plaintext string using AES-256-GCM symmetric encryption. * The function generates a random initialization vector (IV) and * returns the ciphertext, IV, and authentication tag. * The key must be 32 bytes (256 bits) long and should be provided in base64 format. * @param key * @param plaintext * @returns combined ciphertext and tag */ declare const encryptSymmetric: (key: string, plaintext: string, iv?: string) => { ciphertext: string; iv: string | undefined; }; /** * * Decrypts a ciphertext string using AES-256-GCM symmetric encryption. * The function requires the ciphertext, IV, and authentication tag * to successfully decrypt the data. * The key must be 32 bytes (256 bits) long and should be provided in base64 format. * @param key string * @param ciphertext * @param iv * @param tag * @returns */ declare const decryptSymmetric: (key: string, ciphertext: string, iv: string) => string; declare const tenantDatabase: (options?: PostgrestClientOptions) => TenantDatabase; declare const orgDatabase: (teamName: string, options?: PostgrestClientOptions) => OrgDatabase; declare const orgDatabaseFromId: (teamId: string, options?: PostgrestClientOptions) => Promise; export { type ApiKey, type Application, type Deployment, type EnvVar, type Json, type OrgDB, type OrgDBTableNames, OrgDatabase, type OrgEnums, type OrgTables, type OrgTablesInsert, type OrgTablesUpdate, type OrgViews, type ReconcilerLogEntry, type Secret, type SystemConfig, type Team, type TeamSecret, type TenantDB, type TenantDBTableNames, TenantDatabase, type TenantEnums, type TenantTables, type TenantTablesInsert, type TenantTablesUpdate, type User, type UserRequestObject, type UserTeam, createPostgrestClient, decryptSymmetric, encryptSymmetric, generateApiKey, generateRandomIdNice, maskApiKey, orgDatabase, orgDatabaseFromId, parseApiKey, parseUserRequest, tenantDatabase };