{"version":3,"file":"infra.cjs","names":["join","existsSync","readFileSync","dirname","randomBytes"],"sources":["../../src/cli/infra.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { RuntimeConfig } from \"../types\";\n\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\nconst AUTH_DATABASE_SECRET = \"AUTH_DATABASE_URL\";\nconst HOST_SECRET = \"CORS_ORIGIN\";\nconst REDIS_PORT = 6379;\nconst TEST_AUTH_SECRET = \"regression-test-secret-do-not-use-in-production\";\nconst VESTIGIAL_SECRETS = new Set([\n  \"NEAR_RELAYER_PRIVATE_KEY_MAINNET\",\n  \"NEAR_RELAYER_PRIVATE_KEY_TESTNET\",\n]);\n\n/**\n * Fixed local-development database conventions. The committed\n * docker-compose.yml provisions exactly these services/ports — nothing is\n * derived from runtime config. Every non-auth `*_DATABASE_URL` secret shares\n * the api database (schema-isolated per plugin); auth gets its own.\n */\nconst DEV_API_DB_PORT = 5432;\nconst DEV_AUTH_DB_PORT = 5433;\nconst TEST_API_DB_PORT = 5434;\nconst TEST_AUTH_DB_PORT = 5435;\n\nexport interface DatabaseConvention {\n  secret: string;\n  slug: string;\n  port: number;\n  databaseName: string;\n  url: string;\n}\n\nexport interface RedisConvention {\n  secret: string;\n  slug: string;\n  port: number;\n  url: string;\n}\n\nexport interface SecretGroup {\n  section: string;\n  secrets: string[];\n}\n\ninterface DevPortState {\n  host?: number;\n  api?: number;\n  ui?: number;\n  auth?: number;\n  pluginPortStart?: number;\n}\n\nexport type { DevPortState };\n\nexport interface PortState {\n  devPorts?: DevPortState;\n}\n\nfunction uniqueSecrets(values: Array<string | undefined>): string[] {\n  const secrets: string[] = [];\n  const seen = new Set<string>();\n\n  for (const value of values) {\n    if (!value || seen.has(value)) continue;\n    seen.add(value);\n    secrets.push(value);\n  }\n\n  return secrets;\n}\n\nexport function loadPortState(configDir?: string): PortState {\n  if (!configDir) return {};\n  const statePath = join(configDir, \".bos\", \"infra-state.json\");\n  if (!existsSync(statePath)) return {};\n  try {\n    const raw = JSON.parse(readFileSync(statePath, \"utf-8\")) as Partial<PortState>;\n    return { devPorts: raw.devPorts };\n  } catch {\n    return {};\n  }\n}\n\nexport function savePortState(configDir: string, state: PortState): void {\n  const statePath = join(configDir, \".bos\", \"infra-state.json\");\n  mkdirSync(dirname(statePath), { recursive: true });\n  writeFileSync(statePath, `${JSON.stringify(state, null, 2)}\\n`);\n}\n\nexport function normalizeDatabaseSlug(secret: string): string {\n  return secret.replace(/_DATABASE_URL$/, \"\").toLowerCase();\n}\n\nfunction normalizeRedisSlug(secret: string): string {\n  return secret.replace(/_REDIS_URL$/, \"\").toLowerCase();\n}\n\nfunction databaseUrl(port: number, databaseName: string): string {\n  return `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${databaseName}`;\n}\n\nexport function buildConventionalDatabases(secrets: string[]): DatabaseConvention[] {\n  const databaseSecrets = uniqueSecrets(\n    secrets.filter((secret) => secret.endsWith(\"_DATABASE_URL\")),\n  );\n\n  return databaseSecrets\n    .sort((a, b) => normalizeDatabaseSlug(a).localeCompare(normalizeDatabaseSlug(b)))\n    .map((secret) => {\n      const slug = normalizeDatabaseSlug(secret);\n      const isAuth = secret === AUTH_DATABASE_SECRET;\n      const port = isAuth ? DEV_AUTH_DB_PORT : DEV_API_DB_PORT;\n      const databaseName = isAuth ? \"auth_db\" : \"api_db\";\n      return { secret, slug, port, databaseName, url: databaseUrl(port, databaseName) };\n    });\n}\n\nexport function buildConventionalRedis(secrets: string[]): RedisConvention[] {\n  const redisSecrets = uniqueSecrets(secrets.filter((secret) => secret.endsWith(\"_REDIS_URL\")));\n\n  return redisSecrets\n    .sort((a, b) => normalizeRedisSlug(a).localeCompare(normalizeRedisSlug(b)))\n    .map((secret) => ({\n      secret,\n      slug: normalizeRedisSlug(secret),\n      port: REDIS_PORT,\n      url: `redis://localhost:${REDIS_PORT}`,\n    }));\n}\n\nfunction testDatabaseUrl(secret: string): string {\n  const isAuth = secret === AUTH_DATABASE_SECRET;\n  const port = isAuth ? TEST_AUTH_DB_PORT : TEST_API_DB_PORT;\n  const databaseName = isAuth ? \"auth_test_db\" : \"api_test_db\";\n  return databaseUrl(port, databaseName);\n}\n\nexport function getSecretGroups(runtimeConfig: RuntimeConfig): SecretGroup[] {\n  const groups: SecretGroup[] = [];\n  const seen = new Set<string>();\n\n  const addGroup = (section: string, secrets: string[]) => {\n    const filtered = secrets.filter((s) => {\n      if (VESTIGIAL_SECRETS.has(s)) return false;\n      if (seen.has(s)) return false;\n      seen.add(s);\n      return true;\n    });\n    if (filtered.length > 0) {\n      groups.push({ section, secrets: filtered });\n    }\n  };\n\n  addGroup(\"app.host\", uniqueSecrets([...(runtimeConfig.host.secrets ?? []), HOST_SECRET]));\n\n  addGroup(\"app.api\", uniqueSecrets(runtimeConfig.api.secrets ?? []));\n\n  if (runtimeConfig.auth) {\n    addGroup(\"app.auth\", uniqueSecrets(runtimeConfig.auth.secrets ?? []));\n  }\n\n  if (runtimeConfig.plugins) {\n    for (const [pluginKey, plugin] of Object.entries(runtimeConfig.plugins)) {\n      if (plugin.secrets && plugin.secrets.length > 0) {\n        addGroup(`plugins.${pluginKey}`, plugin.secrets);\n      }\n    }\n  }\n\n  return groups;\n}\n\nfunction extractPortFromUrl(url: string): string | null {\n  const match = url.match(/:(\\d{4,5})(?:\\/|$)/);\n  return match?.[1] ?? null;\n}\n\nfunction resolveDevHostPort(runtimeConfig: RuntimeConfig): number {\n  if (typeof runtimeConfig.host?.port === \"number\") return runtimeConfig.host.port;\n  const fromUrl = runtimeConfig.host?.url ? extractPortFromUrl(runtimeConfig.host.url) : null;\n  if (fromUrl) {\n    const parsed = Number.parseInt(fromUrl, 10);\n    if (!Number.isNaN(parsed)) return parsed;\n  }\n  return 3000;\n}\n\nexport { resolveDevHostPort };\n\nfunction defaultSecretValue(\n  secret: string,\n  databases: Map<string, DatabaseConvention>,\n  redisConfigs: Map<string, RedisConvention>,\n  options: { forExample: boolean; devHostPort?: number },\n): string {\n  if (secret === \"BETTER_AUTH_SECRET\") {\n    return options.forExample ? \"\" : randomBytes(32).toString(\"base64url\");\n  }\n\n  if (secret === \"CORS_ORIGIN\") {\n    if (options.forExample) {\n      return \"http://localhost:3000\";\n    }\n    if (typeof options.devHostPort === \"number\") {\n      return `http://localhost:${options.devHostPort}`;\n    }\n    return \"http://localhost:3000\";\n  }\n\n  return databases.get(secret)?.url ?? redisConfigs.get(secret)?.url ?? \"\";\n}\n\n/**\n * Plugin `*_DATABASE_URL` secrets share the API database (the platform's\n * two-database contract), so they are not rendered as template entries —\n * the host falls back to `API_DATABASE_URL` when they are unset.\n */\nfunction isFallbackDatabaseSecret(secret: string): boolean {\n  return (\n    secret.endsWith(\"_DATABASE_URL\") &&\n    secret !== \"API_DATABASE_URL\" &&\n    secret !== \"AUTH_DATABASE_URL\"\n  );\n}\n\nfunction renderEnvFile(\n  groups: SecretGroup[],\n  options: { forExample: boolean; devHostPort?: number },\n): string {\n  const rendered = groups\n    .map((group) => ({\n      section: group.section,\n      secrets: group.secrets.filter((secret) => !isFallbackDatabaseSecret(secret)),\n    }))\n    .filter((group) => group.secrets.length > 0);\n  const allSecrets = rendered.flatMap((group) => group.secrets);\n  const databaseMap = new Map(\n    buildConventionalDatabases(allSecrets).map((entry) => [entry.secret, entry]),\n  );\n  const redisMap = new Map(\n    buildConventionalRedis(allSecrets).map((entry) => [entry.secret, entry]),\n  );\n  const lines: string[] = [\n    \"# Generated from configured bos secrets\",\n    \"# Update values as needed for your local environment\",\n    \"\",\n  ];\n\n  for (const group of rendered) {\n    lines.push(`# ${group.section}`);\n    for (const secret of group.secrets) {\n      lines.push(`${secret}=${defaultSecretValue(secret, databaseMap, redisMap, options)}`);\n    }\n    lines.push(\"\");\n  }\n\n  return `${lines.join(\"\\n\")}\\n`;\n}\n\nexport { renderEnvFile };\n\nfunction renderEnvTestFile(groups: SecretGroup[]): string {\n  const lines: string[] = [\n    \"# Generated test environment — loaded by test suites instead of .env\",\n    \"# Test databases run on dedicated *-test docker-compose services\",\n    \"\",\n  ];\n\n  for (const group of groups) {\n    const entries: string[] = [];\n    for (const secret of group.secrets) {\n      if (secret === \"BETTER_AUTH_SECRET\") {\n        entries.push(`${secret}=${TEST_AUTH_SECRET}`);\n      } else if (secret.endsWith(\"_DATABASE_URL\")) {\n        entries.push(`${secret}=${testDatabaseUrl(secret)}`);\n      }\n    }\n    if (entries.length > 0) {\n      lines.push(`# ${group.section}`);\n      lines.push(...entries);\n      lines.push(\"\");\n    }\n  }\n\n  return `${lines.join(\"\\n\")}\\n`;\n}\n\nexport { renderEnvTestFile };\n\nexport interface CiServiceSpec {\n  key: string;\n  slug: string;\n  image: string;\n  env: Record<string, string>;\n  ports: string[];\n  healthcheck?: { test: string[]; interval: string; timeout: string; retries: number };\n  volumes: string[];\n  database?: { user: string; password: string; name: string };\n}\n\nexport interface CiInfraPlan {\n  account: string;\n  gateway: string;\n  project: string;\n  env: Record<string, string>;\n  services: CiServiceSpec[];\n  generatedAt: string;\n}\n\nexport function buildCiInfraPlan(\n  runtimeConfig: RuntimeConfig,\n  options: { hostPortOverride?: number } = {},\n): CiInfraPlan {\n  const allSecrets = collectAllSecrets(runtimeConfig);\n  const databases = buildConventionalDatabases(allSecrets);\n  const redisConfigs = buildConventionalRedis(allSecrets);\n\n  const hostPort =\n    options.hostPortOverride ??\n    (Number.isFinite(Number(process.env.BOS_CI_HOST_PORT))\n      ? Number(process.env.BOS_CI_HOST_PORT)\n      : undefined) ??\n    resolveDevHostPort(runtimeConfig);\n  const env: Record<string, string> = {};\n  for (const db of databases) env[db.secret] = db.url;\n  for (const r of redisConfigs) env[r.secret] = r.url;\n\n  env.CORS_ORIGIN = `http://127.0.0.1:${hostPort}`;\n  if (!env.BETTER_AUTH_SECRET) env.BETTER_AUTH_SECRET = \"\";\n\n  const services: CiServiceSpec[] = [];\n  const seenPorts = new Set<number>();\n\n  for (const db of databases) {\n    if (seenPorts.has(db.port)) continue;\n    seenPorts.add(db.port);\n    services.push({\n      key: db.slug,\n      slug: db.slug,\n      image: \"public.ecr.aws/docker/library/postgres:17-alpine\",\n      env: {\n        POSTGRES_USER: POSTGRES_USER,\n        POSTGRES_PASSWORD: POSTGRES_PASSWORD,\n        POSTGRES_DB: db.databaseName,\n      },\n      ports: [`${db.port}:5432`],\n      healthcheck: {\n        test: [\"CMD-SHELL\", `pg_isready -U ${POSTGRES_USER} -d ${db.databaseName}`],\n        interval: \"3s\",\n        timeout: \"3s\",\n        retries: 10,\n      },\n      volumes: [`${db.slug}_data:/var/lib/postgresql/data`],\n      database: { user: POSTGRES_USER, password: POSTGRES_PASSWORD, name: db.databaseName },\n    });\n  }\n\n  for (const r of redisConfigs) {\n    services.push({\n      key: r.slug,\n      slug: r.slug,\n      image: \"public.ecr.aws/docker/library/redis:7-alpine\",\n      env: {},\n      ports: [`${r.port}:6379`],\n      healthcheck: {\n        test: [\"CMD\", \"redis-cli\", \"ping\"],\n        interval: \"3s\",\n        timeout: \"3s\",\n        retries: 10,\n      },\n      volumes: [`${r.slug}_data:/data`],\n    });\n  }\n\n  return {\n    account: runtimeConfig.account,\n    gateway: runtimeConfig.domain ?? runtimeConfig.account,\n    project: runtimeConfig.account,\n    env,\n    services,\n    generatedAt: new Date().toISOString(),\n  };\n}\n\nfunction collectAllSecrets(runtimeConfig: RuntimeConfig): string[] {\n  const all: string[] = [];\n  all.push(...(runtimeConfig.host.secrets ?? []));\n  all.push(...(runtimeConfig.api.secrets ?? []));\n  if (runtimeConfig.auth) all.push(...(runtimeConfig.auth.secrets ?? []));\n  if (runtimeConfig.plugins) {\n    for (const plugin of Object.values(runtimeConfig.plugins)) {\n      if (plugin.secrets) all.push(...plugin.secrets);\n    }\n  }\n  return all.filter((s) => !VESTIGIAL_SECRETS.has(s));\n}\n"],"mappings":"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"}