import {z} from 'zod' export type DbaasServiceName = string; export type GetApiDbaasPostgresNameArgs = {name: DbaasServiceName}; export type GetApiDbaasPostgresNameOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const jsonSchemaPgbouncer = z.object({min_pool_size: z.number().int().gte(0).lte(10000).optional(), ignore_startup_parameters: z.array(z.enum(["extra_float_digits", "search_path"])).optional(), server_lifetime: z.number().int().gte(60).lte(86400).optional(), autodb_pool_mode: z.enum(["transaction", "session", "statement"]).optional(), server_idle_timeout: z.number().int().gte(0).lte(86400).optional(), autodb_max_db_connections: z.number().int().gte(0).lte(2147483647).optional(), max_prepared_statements: z.number().int().gte(0).lte(3000).optional(), server_reset_query_always: z.boolean().optional(), autodb_pool_size: z.number().int().gte(0).lte(10000).optional(), autodb_idle_timeout: z.number().int().gte(0).lte(86400).optional()}); export const dbaasIntegration = z.object({description: z.string().optional(), settings: z.object({}).optional(), type: z.string().optional(), "is-enabled": z.boolean().optional(), source: z.string().optional(), "is-active": z.boolean().optional(), status: z.string().optional(), id: z.string().optional(), dest: z.string().optional()}); export const dbaasNodeStateProgressUpdate = z.object({completed: z.boolean(), current: z.number().int().gte(0).optional(), max: z.number().int().gte(0).optional(), min: z.number().int().gte(0).optional(), phase: z.enum(["stream", "basebackup", "prepare", "finalize"]), unit: z.string().optional()}); export const dbaasNodeState = z.object({name: z.string(), "progress-updates": z.array(dbaasNodeStateProgressUpdate).optional(), role: z.enum(["standby", "master", "read-replica"]).optional(), state: z.enum(["leaving", "running", "syncing_data", "setting_up_vm", "unknown"])}); export const dbaasServiceName = z.string().max(63); export const dbaasDatabaseName = z.string().min(1).max(40); export const enumPgPoolMode = z.enum(["transaction", "statement", "session"]); export const dbaasPgPoolName = z.string().min(1).max(63); export const dbaasPgPoolSize = z.number().int().gte(1).lte(10000); export const dbaasPgPoolUsername = z.string().min(1).max(64); export const dbaasServiceTypeName = z.string().max(64); export const enumServiceState = z.enum(["running", "rebuilding", "rebalancing", "poweroff"]); export const jsonSchemaTimescaledb = z.object({max_background_workers: z.number().int().gte(1).lte(4096).optional()}); export const dbaasServiceBackup = z.object({"backup-name": z.string(), "backup-time": z.string(), "data-size": z.number().int().gte(0)}); export const jsonSchemaPgaudit = z.object({role: z.string().max(64).optional(), log_parameter: z.boolean().optional(), log_rows: z.boolean().optional(), log_level: z.enum(["debug1", "debug2", "debug3", "debug4", "debug5", "info", "notice", "warning", "log"]).optional(), log_relation: z.boolean().optional(), log_statement_once: z.boolean().optional(), log_max_string_length: z.number().int().gte(-1).lte(102400).optional(), log_catalog: z.boolean().optional(), log_nested_statements: z.boolean().optional(), log_statement: z.boolean().optional(), log_client: z.boolean().optional(), feature_enabled: z.boolean().optional(), log: z.array(z.enum(["all", "ddl", "function", "misc", "misc_set", "read", "role", "write"])).optional(), log_parameter_max_size: z.number().int().optional()}); export const dbaasServiceNotification = z.object({level: z.enum(["warning", "notice"]), message: z.string().min(1).max(1024), type: z.enum(["service_powered_off_removal", "service_end_of_life"]), metadata: z.object({})}); export const enumComponentRoute = z.enum(["dynamic", "private", "public", "privatelink"]); export const enumComponentUsage = z.enum(["primary", "replica"]); export const enumPgSynchronousReplication = z.enum(["quorum", "off"]); export const jsonSchemaPglookout = z.object({max_failover_replication_time_lag: z.number().int().gte(10).lte(9223372036854776000).optional()}); export const dbaasServiceUpdate = z.object({description: z.string().optional(), deadline: z.string().optional(), "start-after": z.string().optional(), "start-at": z.string().optional()}); export const dbaasServiceMaintenance = z.object({dow: z.enum(["saturday", "tuesday", "never", "wednesday", "sunday", "friday", "monday", "thursday"]), time: z.string().min(8).max(8), updates: z.array(dbaasServiceUpdate)}); export const jsonSchemaPg = z.object({track_activity_query_size: z.number().int().gte(1024).lte(10240).optional(), timezone: z.string().max(64).optional(), track_io_timing: z.enum(["off", "on"]).optional(), "pg_stat_monitor.pgsm_enable_query_plan": z.boolean().optional(), max_files_per_process: z.number().int().gte(1000).lte(4096).optional(), "pg_stat_monitor.pgsm_max_buckets": z.number().int().gte(1).lte(10).optional(), io_max_concurrency: z.number().int().gte(-1).lte(1024).optional(), wal: z.object({max_slot_wal_keep_size: z.number().int().gte(-1).lte(2147483647).optional(), max_wal_senders: z.number().int().gte(20).lte(256).optional(), wal_sender_timeout: z.number().int().gte(0).lte(10800000).optional(), wal_writer_delay: z.number().int().gte(10).lte(200).optional()}).optional(), default_toast_compression: z.enum(["lz4", "pglz"]).optional(), deadlock_timeout: z.number().int().gte(500).lte(1800000).optional(), idle_in_transaction_session_timeout: z.number().int().gte(0).lte(604800000).optional(), max_pred_locks_per_transaction: z.number().int().gte(64).lte(5120).optional(), max_replication_slots: z.number().int().gte(8).lte(256).optional(), max_sync_workers_per_subscription: z.number().int().gte(2).lte(8).optional(), autovacuum: z.object({log_autovacuum_min_duration: z.number().int().gte(-1).lte(2147483647).optional(), autovacuum_vacuum_cost_limit: z.number().int().gte(-1).lte(10000).optional(), autovacuum_max_workers: z.number().int().gte(1).lte(20).optional(), autovacuum_vacuum_threshold: z.number().int().gte(0).lte(2147483647).optional(), autovacuum_naptime: z.number().int().gte(1).lte(86400).optional(), autovacuum_vacuum_scale_factor: z.number().gte(0).lte(1).optional(), autovacuum_vacuum_cost_delay: z.number().int().gte(-1).lte(100).optional(), autovacuum_analyze_scale_factor: z.number().gte(0).lte(1).optional(), autovacuum_analyze_threshold: z.number().int().gte(0).lte(2147483647).optional(), autovacuum_freeze_max_age: z.number().int().gte(200000000).lte(1500000000).optional()}).optional(), max_parallel_workers_per_gather: z.number().int().gte(0).lte(96).optional(), io_combine_limit: z.number().int().gte(1).lte(32).optional(), password_encryption: z.enum(["md5", "scram-sha-256"]).nullable().optional(), io_workers: z.number().int().gte(1).lte(32).optional(), "pg_partman_bgw.interval": z.number().int().gte(3600).lte(604800).optional(), log_line_prefix: z.enum(["'pid=%p,user=%u,db=%d,app=%a,client=%h '", "'pid=%p,user=%u,db=%d,app=%a,client=%h,txid=%x,qid=%Q '", "'%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '", "'%m [%p] %q[user=%u,db=%d,app=%a] '"]).optional(), log_temp_files: z.number().int().gte(-1).lte(2147483647).optional(), max_locks_per_transaction: z.number().int().gte(64).lte(6400).optional(), track_commit_timestamp: z.enum(["off", "on"]).optional(), track_functions: z.enum(["all", "pl", "none"]).optional(), io_max_combine_limit: z.number().int().gte(1).lte(128).optional(), io_method: z.enum(["worker", "sync", "io_uring"]).optional(), max_stack_depth: z.number().int().gte(2097152).lte(6291456).optional(), max_parallel_workers: z.number().int().gte(0).lte(96).optional(), "pg_partman_bgw.role": z.string().max(64).optional(), max_logical_replication_workers: z.number().int().gte(4).lte(256).optional(), max_prepared_transactions: z.number().int().gte(0).lte(10000).optional(), max_worker_processes: z.number().int().gte(8).lte(288).optional(), "pg_stat_statements.track": z.enum(["all", "top", "none"]).optional(), temp_file_limit: z.number().int().gte(-1).lte(2147483647).optional(), log_error_verbosity: z.enum(["TERSE", "DEFAULT", "VERBOSE"]).optional(), log_min_duration_statement: z.number().int().gte(-1).lte(86400000).optional(), max_standby_streaming_delay: z.number().int().gte(1).lte(43200000).optional(), jit: z.boolean().optional(), max_standby_archive_delay: z.number().int().gte(1).lte(43200000).optional(), "bg-writer": z.object({bgwriter_delay: z.number().int().gte(10).lte(10000).optional(), bgwriter_flush_after: z.number().int().gte(0).lte(2048).optional(), bgwriter_lru_maxpages: z.number().int().gte(0).lte(1073741823).optional(), bgwriter_lru_multiplier: z.number().gte(0).lte(10).optional()}).optional()}); export const dbaasServicePg = z.object({"pgbouncer-settings": jsonSchemaPgbouncer.optional(), "updated-at": z.string().optional(), "node-count": z.number().int().gte(0).optional(), "connection-info": z.object({uri: z.array(z.string()).optional(), params: z.array(z.record(z.string(), z.string())).optional(), standby: z.array(z.string()).optional(), syncing: z.array(z.string()).optional()}).optional(), "backup-schedule": z.object({"backup-hour": z.number().int().gte(0).lte(23).optional(), "backup-minute": z.number().int().gte(0).lte(59).optional()}).optional(), "node-cpu-count": z.number().int().gte(0).optional(), "prometheus-uri": z.object({host: z.string().optional(), port: z.number().int().gte(0).lte(65535).optional()}), integrations: z.array(dbaasIntegration).optional(), zone: z.string().optional(), "node-states": z.array(dbaasNodeState).optional(), name: dbaasServiceName, "connection-pools": z.array(z.object({"connection-uri": z.string(), database: dbaasDatabaseName, mode: enumPgPoolMode, name: dbaasPgPoolName, size: dbaasPgPoolSize, username: dbaasPgPoolUsername})).optional(), type: dbaasServiceTypeName, state: enumServiceState.optional(), "timescaledb-settings": jsonSchemaTimescaledb.optional(), databases: z.array(dbaasDatabaseName).optional(), "ip-filter": z.array(z.string()).optional(), backups: z.array(dbaasServiceBackup).optional(), "termination-protection": z.boolean().optional(), "pgaudit-settings": jsonSchemaPgaudit.optional(), notifications: z.array(dbaasServiceNotification).optional(), components: z.array(z.object({component: z.string(), host: z.string(), port: z.number().int().gte(0).lte(65535), route: enumComponentRoute, usage: enumComponentUsage})).optional(), "synchronous-replication": enumPgSynchronousReplication.optional(), "pglookout-settings": jsonSchemaPglookout.optional(), maintenance: dbaasServiceMaintenance.optional(), "disk-size": z.number().int().gte(0).optional(), "node-memory": z.number().int().gte(0).optional(), uri: z.string().optional(), "uri-params": z.object({}).optional(), version: z.string().optional(), "created-at": z.string().optional(), plan: z.string(), "work-mem": z.number().int().gte(1).lte(1024).optional(), "shared-buffers-percentage": z.number().int().gte(20).lte(60).optional(), "pg-settings": jsonSchemaPg.optional(), "max-connections": z.number().int().gt(0).optional(), users: z.array(z.object({type: z.string(), username: z.string(), password: z.string().optional(), "allow-replication": z.boolean().optional()})).optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Get a DBaaS PostgreSQL service * * GET /dbaas-postgres/{name} */ export const getApiDbaasPostgresName = async (args: GetApiDbaasPostgresNameArgs, options?: GetApiDbaasPostgresNameOptions) => { const {baseUrl = "https://api-ch-gva-2.exoscale.com/v2", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/dbaas-postgres/${encodeURIComponent(String(args.name))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(dbaasServicePg, await res.json()) };