UNPKG

@cdwr/fly-node

Version:

The flyctl node wrapper for programmatic deployments to fly.io.

365 lines (364 loc) 12.9 kB
import { SpawnOptions, SpawnPtyOptions } from '@codeware/core/utils'; import type { AppOrConfig, Config, CreateAppOptions, DeployAppOptions, DeployResponse, DestroyAppOptions, ListAppResponse, ListCertForAllResponse, ListCertForAppResponse, ListSecretForAllResponse, ListSecretForAppResponse, SetAppSecretsOptions, ShowConfigOptions, ShowConfigResponse, StatusExtendedResponse, StatusResponse, UnsetAppSecretsOptions } from './types'; export type ExecFlyOptions = SpawnOptions & SpawnPtyOptions; /** * Manages deployments to Fly.io using the `flyctl` CLI tool. */ export declare class Fly { /** Use underscore to avoid conflict with public `config` property */ private _config; /** * Whether a user is authenticated via local login. * In this case a token is not needed, though it can still have been provided. */ private authByLogin; private initialized; private logger; /** * Get the app name from the instance config */ private get instanceApp(); /** * Get the config file path from the instance config */ private get instanceConfig(); constructor(config?: Config); /** * Verify that the Fly client is ready to use. * * This means that the Fly CLI is installed and authenticated to Fly.io. * * Use as ad-hoc check when needed instead of waiting for the first Fly command to run. * * @param mode - Whether to use assertion mode instead of returning `false` * @returns `true` if the Fly client is ready, `false` otherwise * @throws An error in assertion mode if the Fly client is not ready */ isReady(mode?: 'assert'): Promise<boolean>; /** * Manage the Fly CLI tool */ cli: { /** * Check if the Fly CLI tool is installed * * @returns `true` if the Fly CLI tool is installed, `false` otherwise */ isInstalled: () => Promise<boolean>; }; /** * Manage apps */ apps: { /** * Create a new application with a generated name when not provided. * * @param options - Options for creating an application * @returns The name of the created application * @throws An error if the application cannot be created */ create: (options?: CreateAppOptions) => Promise<string>; /** * Destroy an application and make sure it gets detached from any Postgres clusters * * @param app - The name of the app to destroy * @param options - Options for destroying an application * @throws An error if the app cannot be destroyed */ destroy: (app: string, options?: DestroyAppOptions) => Promise<void>; /** * List all applications * * @returns A list of applications * @throws An error if listing applications fails */ list: () => Promise<Array<ListAppResponse>>; }; /** * Manage certificates */ certs: { /** * Add a certificate for a domain to an application * * @param hostname - The hostname to add a certificate for * @param options - Options for adding a certificate * @throws An error if the certificate cannot be added */ add: (hostname: string, options?: AppOrConfig) => Promise<void>; /** * List certificates for an application * * @param options - List certificates for an application or all certificates * @returns A list of certificates * @throws An error if listing certificates fails */ list: <T extends AppOrConfig | "all">(options?: T) => Promise<T extends "all" ? Array<ListCertForAllResponse> : Array<ListCertForAppResponse>>; /** * Remove a certificate for a domain from an application * * @param hostname - The hostname to remove a certificate for * @param options - Options for removing a certificate * @throws An error if the certificate cannot be removed */ remove: (hostname: string, options?: AppOrConfig) => Promise<void>; }; /** * Manage an app's configuration */ config: { /** * Show an application's configuration. * * @param options - Options for showing an application's configuration * @returns The application's JSON configuration * @throws An error if the configuration cannot be found or parsed */ show: (options?: ShowConfigOptions) => Promise<ShowConfigResponse>; }; /** * Deploy an application. * * A valid config file is required but the app doesn't have to exist, * since it gets created if needed. * * The app name is selected from: * 1. Provided app name * 2. Instance app name * 3. App name from the provided config file * * Existing secrets are preserved. * * @param options - Options for deploying an application * @throws An error if the deployment fails */ deploy: (options?: DeployAppOptions) => Promise<DeployResponse>; postgres: { detach: (cluster: string, app: string) => Promise<void>; }; /** * Manage application secrets */ secrets: { /** * Set secrets for an application * * @param secrets - The secrets to set * @param options - Options for setting secrets * @throws An error if the secrets cannot be set */ set: (secrets: Record<string, string>, options?: SetAppSecretsOptions) => Promise<void>; /** * List secrets for an application * * @param options - List secrets for an application or all secrets * @returns A list of secrets * @throws An error if listing secrets fails */ list: <T extends AppOrConfig | "all">(options?: T) => Promise<T extends "all" ? Array<ListSecretForAllResponse> : Array<ListSecretForAppResponse>>; /** * Unset secrets for an application * * @param keys - The keys to unset * @param options - Options for unsetting secrets * @throws An error if the secrets cannot be unset */ unset: (keys: string | Array<string>, options?: UnsetAppSecretsOptions) => Promise<void>; }; /** * Get the status details of an application * * @param options - Options for getting app status * @returns The app status, or `null` if an app could not be found */ status: (options?: AppOrConfig) => Promise<StatusResponse | null>; /** * Get the extended details of an application * * @param options - Options for getting app details * @returns The app details, or `null` if an app could not be found */ statusExtended: (options?: AppOrConfig) => Promise<StatusExtendedResponse | null>; /** * @private * A name will be generated when not provided. * @returns The name of the created application * @throws An error if the application cannot be created */ private createApp; /** * @private * @returns The name of the deployed application * @throws An error if the deployment fails */ private deployApp; /** * @private * @throws An error if the Postgres database cannot be attached */ private attachPostgres; /** * @private * @throws An error if the app cannot be destroyed */ private destroyApp; /** * @private * @returns Log output from the detach process * @throws An error if the Postgres database cannot be detached from an app */ private detachPostgres; /** * @private * @returns The name of the application * @throws An error if the secrets cannot be set */ private setAppSecrets; /** * @private * @returns The name of the application * @throws An error if the secrets cannot be unset */ private unsetAppSecrets; /** * @private * @returns The name of the application * @throws An error if the domain cannot be added */ private addAppCertificate; /** * @private * @returns The name of the application * @throws An error if the domain cannot be removed */ private removeAppCertificate; /** * @private * @returns A list of all applications or `null` if listing applications fails and `nullOnError` is used * @throws An error if listing applications fails and `throwOnError` is used */ private fetchAllApps; /** * @private * @returns All certificates for all apps or `null` if the certificates cannot be retrieved and `nullOnError` is used * @throws An error if the certificates cannot be retrieved */ private fetchAllCerts; /** * @private * @returns All postgres clusters or `null` if the clusters cannot be retrieved and `nullOnError` is used * @throws An error if the clusters cannot be retrieved */ private fetchAllPostgres; /** * @private * @returns All secrets for all apps or `null` if the secrets cannot be retrieved and `nullOnError` is used * @throws An error if the secrets cannot be retrieved */ private fetchAllSecrets; /** * @private * @returns The app status or `null` if the app cannot be found and `nullOnError` is used * @throws An error if the app cannot be found and `throwOnError` is used */ private fetchAppStatus; /** * @private * @returns The certificates for an app or `null` if the certificates cannot be retrieved and `nullOnError` is used * @throws An error if the certificates cannot be retrieved and `throwOnError` is used */ private fetchAppCerts; /** * @private * @returns The secrets for an app or `null` if the secrets cannot be retrieved and `nullOnError` is used * @throws An error if the secrets cannot be retrieved and `throwOnError` is used */ private fetchAppSecrets; /** * **Important!** User/app names containing dashes are returned as underscores. * * @private * @returns The users for a postgres database app or `null` if the users cannot be retrieved and `nullOnError` is used * @throws An error if the users cannot be retrieved and `throwOnError` is used */ private fetchPostgresUsers; /** * @private * @returns The config or `null` if the config cannot be retrieved and `nullOnError` is used * @throws An error if the config cannot be retrieved and `throwOnError` is used */ private showConfig; /** * @private * Ensure Fly CLI is installed and authenticated * * @throws An error if Fly CLI is not installed or authentication fails */ private ensureInitialized; /** * @private * Execute a fly command and optionally return the output as JSON * * @param command - The fly command to execute (empty array items are ignored) * @returns The JSON output of the command, or the raw output if not JSON * @throws An error if the command fails */ private execFly; /** * @private * Get the arguments for `AppOrConfig` options * where either the application or configuration can be provided * but not both. * * First check `options` and then the class configuration. * * Should be used in Fly commands with optional flags * - `--app` * - `--config` * * @param options - Options to get the arguments for * @returns The arguments to use in a fly command */ private getAppOrConfigArgs; /** * @private * Get the Postgres clusters attached to an app * * @param app - The app to get the attached Postgres clusters for * @returns The attached Postgres clusters * @throws An error if the Postgres clusters cannot be retrieved */ private getAttachedPostgresClusters; /** * @private * Check if the Fly CLI is installed * * @returns `true` if the Fly CLI is installed, `false` otherwise */ private isInstalled; /** * @private * Normalize the options matching `AppOrConfig` type. * * A missing value gets an empty string. * * @param options - The options to normalize * @returns The normalized options */ private normalizeOptions; /** * Escape an argument for Fly cli * * @param arg - The argument to escape * @returns The escaped argument */ private safeArg; /** * @private * Trace the CLI calls, mocks and results * * @param type - The type of trace * @param msg - The message to trace */ private traceCLI; }