101 lines
2.4 KiB
TypeScript
101 lines
2.4 KiB
TypeScript
import { defineCommand } from "citty";
|
|
import { apiRequest, type ApiRequestInit } from "../lib/api";
|
|
import { ctx } from "../lib/context";
|
|
import {
|
|
DATABASE_HOST,
|
|
DATABASE_PORT,
|
|
buildDatabaseUrl,
|
|
getComposePostgresClaims,
|
|
type PostgresClaim,
|
|
type RoleCredentials,
|
|
} from "../lib/database";
|
|
import { toTable } from "../lib/format";
|
|
|
|
export type DbApiRequest = <T>(
|
|
path: string,
|
|
init?: ApiRequestInit,
|
|
) => Promise<T>;
|
|
|
|
export function getDatabaseCredentials(
|
|
project: string,
|
|
claim: PostgresClaim,
|
|
request: DbApiRequest = apiRequest,
|
|
): Promise<RoleCredentials> {
|
|
return request<RoleCredentials>(
|
|
`/workspaces/${encodeURIComponent(project)}/databases/credentials`,
|
|
{ method: "POST", json: { claim } },
|
|
);
|
|
}
|
|
|
|
const list = defineCommand({
|
|
meta: {
|
|
name: "ls",
|
|
description: "List database volumes used by this project",
|
|
},
|
|
async run() {
|
|
const claims = getComposePostgresClaims(await ctx().compose());
|
|
if (claims.length === 0) {
|
|
console.log("No database volumes declared");
|
|
return;
|
|
}
|
|
|
|
console.log(
|
|
toTable(
|
|
claims.map((claim) => ({
|
|
service: claim.service,
|
|
username: claim.username,
|
|
database: claim.database,
|
|
secret: claim.secretName,
|
|
})),
|
|
),
|
|
);
|
|
},
|
|
});
|
|
|
|
const creds = defineCommand({
|
|
meta: {
|
|
name: "creds",
|
|
description: "Print database credentials for a service",
|
|
},
|
|
async run({ args }) {
|
|
const service = args._[0];
|
|
if (!service) throw new Error("Service name is required");
|
|
|
|
const context = ctx();
|
|
const claim = getComposePostgresClaims(await context.compose()).find(
|
|
(entry) => entry.service === service,
|
|
);
|
|
if (!claim) {
|
|
throw new Error(`Service ${service} does not declare a database volume.`);
|
|
}
|
|
|
|
const credentials = await getDatabaseCredentials(context.project, claim);
|
|
const url = buildDatabaseUrl(claim, credentials);
|
|
|
|
console.log(
|
|
toTable([
|
|
{
|
|
service: claim.service,
|
|
username: credentials.username,
|
|
database: claim.database,
|
|
host: DATABASE_HOST,
|
|
port: DATABASE_PORT,
|
|
secret: claim.secretName,
|
|
},
|
|
]),
|
|
);
|
|
console.log(`DATABASE_URL=${url}`);
|
|
},
|
|
});
|
|
|
|
export const db = defineCommand({
|
|
meta: {
|
|
name: "db",
|
|
description: "View project databases and credentials",
|
|
},
|
|
subCommands: {
|
|
creds,
|
|
ls: list,
|
|
},
|
|
});
|