diff --git a/lib/coolify.ts b/lib/coolify.ts index 1203c9d..ad0a979 100644 --- a/lib/coolify.ts +++ b/lib/coolify.ts @@ -402,8 +402,14 @@ export async function setApplicationDomains( domains: string[], opts: { forceOverride?: boolean } = {} ): Promise<{ uuid: string }> { + // Coolify validates each entry as a URL, so bare hostnames need a scheme. + const normalized = domains.map(d => { + const trimmed = d.trim(); + if (/^https?:\/\//i.test(trimmed)) return trimmed; + return `https://${trimmed}`; + }); return updateApplication(uuid, { - domains: domains.join(','), + domains: normalized.join(','), force_domain_override: opts.forceOverride ?? true, is_force_https_enabled: true, }); @@ -710,16 +716,37 @@ export async function getServiceInProject( return svc; } -/** Response shape of GET /projects/{uuid}/{envName}. */ +/** + * Response shape of GET /projects/{uuid}/{envName}. + * Coolify splits databases by flavor across sibling arrays. + */ interface CoolifyProjectEnvResources { id: number; uuid: string; name: string; applications?: CoolifyApplication[]; - databases?: CoolifyDatabase[]; services?: CoolifyService[]; + postgresqls?: CoolifyDatabase[]; + mysqls?: CoolifyDatabase[]; + mariadbs?: CoolifyDatabase[]; + mongodbs?: CoolifyDatabase[]; + redis?: CoolifyDatabase[]; + keydbs?: CoolifyDatabase[]; + dragonflies?: CoolifyDatabase[]; + clickhouses?: CoolifyDatabase[]; } +const DB_ARRAY_KEYS: Array = [ + 'postgresqls', + 'mysqls', + 'mariadbs', + 'mongodbs', + 'redis', + 'keydbs', + 'dragonflies', + 'clickhouses', +]; + async function getProjectEnvResources( projectUuid: string, envName: string @@ -727,22 +754,15 @@ async function getProjectEnvResources( return coolifyFetch(`/projects/${projectUuid}/${encodeURIComponent(envName)}`); } -/** - * List all apps/dbs/services across all environments of a project. - * Uses one `/projects/{uuid}` call + one call per environment. - */ -async function listResourcesInProject( +async function forEachEnv( projectUuid: string, - key: K -): Promise> { + collect: (envResources: CoolifyProjectEnvResources) => T[] +): Promise { const project = await getProject(projectUuid); - const out: NonNullable = [] as never; + const out: T[] = []; for (const env of project.environments ?? []) { const envResources = await getProjectEnvResources(projectUuid, env.name); - const list = envResources[key]; - if (Array.isArray(list)) { - (out as unknown[]).push(...list); - } + out.push(...collect(envResources)); } return out; } @@ -750,19 +770,26 @@ async function listResourcesInProject { - return listResourcesInProject(projectUuid, 'applications'); + return forEachEnv(projectUuid, r => r.applications ?? []); } export async function listDatabasesInProject( projectUuid: string ): Promise { - return listResourcesInProject(projectUuid, 'databases'); + return forEachEnv(projectUuid, r => { + const out: CoolifyDatabase[] = []; + for (const k of DB_ARRAY_KEYS) { + const arr = r[k]; + if (Array.isArray(arr)) out.push(...(arr as CoolifyDatabase[])); + } + return out; + }); } export async function listServicesInProject( projectUuid: string ): Promise { - return listResourcesInProject(projectUuid, 'services'); + return forEachEnv(projectUuid, r => r.services ?? []); } /** @deprecated Use getApplicationInProject / ensureResourceInProject instead. */