/**
 * Railway-secret provisioning helpers.
 *
 * Phase 2 of the secrets refactor: every Railway deploy needs both
 * STUDIOGRAPH_JWT_SECRET (existing, plan §1) and STUDIOGRAPH_MASTER_KEY
 * (new — encrypts secrets.db) provisioned. We generate them client-side
 * via crypto.randomBytes(32) and POST through the existing GraphQL
 * variableCollectionUpsert mutation.
 *
 * Idempotent: pulls the current variable list first; only sets the keys
 * that are missing. Caller controls how missing vars are surfaced
 * (auto-provision in deploy.ts, prompt in redeploy.ts).
 */
import { randomBytes } from 'crypto';
/**
 * Variables our deploy paths must guarantee exist. Pre-approved set.
 * Extend here when a new bootstrap-classified env-var lands in the
 * registry.
 */
export const REQUIRED_RAILWAY_SECRETS = [
    {
        name: 'STUDIOGRAPH_JWT_SECRET',
        generate: () => randomBytes(32).toString('base64'),
        description: 'JWT signing secret (auth-service)',
    },
    {
        name: 'STUDIOGRAPH_MASTER_KEY',
        generate: () => randomBytes(32).toString('base64'),
        description: 'Master key (encrypts secrets.db)',
    },
];
/**
 * Read the current variable map for a Railway service+environment.
 *
 * Railway's GraphQL exposes per-service variables via the `variables`
 * query. The shape changed across API versions; this helper deals with
 * the modern projectId/environmentId/serviceId triple.
 */
export async function fetchRailwayVariables(query, ctx) {
    const data = await query(`query($projectId: String!, $environmentId: String!, $serviceId: String!) {
      variables(projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId)
    }`, { ...ctx });
    // The `variables` query returns a JSON object map.
    if (data && typeof data.variables === 'object' && data.variables !== null) {
        return data.variables;
    }
    return {};
}
/**
 * Determine which of the required secrets are missing from the supplied
 * variable map. Empty-string counts as missing — Railway sometimes emits
 * empty values for variables that were defined but never set.
 */
export function missingRequiredSecrets(existing) {
    return REQUIRED_RAILWAY_SECRETS.filter((req) => !existing[req.name]?.trim());
}
/**
 * Provision any required secret that is missing from the service's
 * environment. Returns the names of the secrets that were generated and
 * set on this call (an empty array means everything was already set).
 *
 * Idempotent — a re-deploy that already has both vars set is a no-op.
 */
export async function provisionRequiredRailwaySecrets(query, ctx) {
    const existing = await fetchRailwayVariables(query, ctx);
    const missing = missingRequiredSecrets(existing);
    if (missing.length === 0)
        return [];
    const variables = {};
    for (const req of missing) {
        variables[req.name] = req.generate();
    }
    await query(`mutation($input: VariableCollectionUpsertInput!) {
      variableCollectionUpsert(input: $input)
    }`, {
        input: {
            projectId: ctx.projectId,
            environmentId: ctx.environmentId,
            serviceId: ctx.serviceId,
            variables,
        },
    });
    return missing.map((m) => m.name);
}
//# sourceMappingURL=railway-provisioning.js.map