{"version":3,"file":"author-config.mjs","names":[],"sources":["../../../../../src/services/scaffold/upgrade-audit/steps/author-config.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport type { PluginInventory } from \"../domain\";\nimport { readText, writeText } from \"../fs\";\n\ninterface BosConfig {\n  readonly extends?: string;\n  readonly account?: string;\n  readonly domain?: string;\n  readonly title?: string;\n  readonly description?: string;\n  readonly testnet?: unknown;\n  readonly staging?: unknown;\n  readonly repository?: string;\n  readonly ci?: unknown;\n  readonly app?: {\n    readonly ui?: { readonly development?: string };\n    readonly api?: { readonly development?: string; readonly secrets?: string[] };\n  };\n  readonly plugins?: Record<\n    string,\n    {\n      readonly development?: string;\n      readonly extends?: string;\n      readonly variables?: Record<string, unknown>;\n      readonly secrets?: string[];\n    }\n  >;\n}\n\nexport interface StepResult {\n  readonly writes: readonly string[];\n  readonly deletes: readonly string[];\n  readonly notes: readonly string[];\n}\n\nconst targetedRef = (ref: string, key: string): string =>\n  ref.includes(\"#\") ? ref : `${ref}#plugins.${key}`;\n\nconst translatePlugins = (config: BosConfig): Record<string, unknown> => {\n  const plugins: Record<string, unknown> = {};\n  for (const [key, entry] of Object.entries(config.plugins ?? {})) {\n    const development = typeof entry.development === \"string\" ? entry.development : \"\";\n    const localMatch = development.match(/^local:plugins\\/([^/]+)$/);\n    if (localMatch) {\n      plugins[key] = {\n        path: `plugins/${localMatch[1]}`,\n        ...(entry.variables ? { variables: entry.variables } : {}),\n        ...(entry.secrets ? { secrets: entry.secrets } : {}),\n      };\n      continue;\n    }\n    if (typeof entry.extends === \"string\") {\n      plugins[key] = {\n        extends: targetedRef(entry.extends, key),\n        ...(entry.variables ? { variables: entry.variables } : {}),\n      };\n      continue;\n    }\n    plugins[key] = { extends: targetedRef(`${config.extends}`, key) };\n  }\n  return plugins;\n};\n\nconst descriptorBody = (config: BosConfig, _inventory: readonly PluginInventory[]) => {\n  const localApi = config.app?.api?.development === \"local:api\";\n  const localUi = config.app?.ui?.development === \"local:ui\";\n  return {\n    name: config.domain,\n    extends: config.extends,\n    account: config.account,\n    domain: config.domain,\n    ...(config.title ? { title: config.title } : {}),\n    ...(config.description ? { description: config.description } : {}),\n    ...(config.testnet ? { testnet: config.testnet } : {}),\n    ...(config.staging ? { staging: config.staging } : {}),\n    ...(config.repository ? { repository: config.repository } : {}),\n    ...(config.ci ? { ci: config.ci } : {}),\n    ...(localUi ? { ui: { path: \"ui\" } } : {}),\n    ...(localApi\n      ? {\n          api: {\n            path: \"api\",\n            secrets: config.app?.api?.secrets ?? [],\n          },\n        }\n      : {}),\n    plugins: translatePlugins(config),\n  };\n};\n\nconst renderBosAppTs = (body: Record<string, unknown>): string =>\n  [\n    'import { App } from \"everything-dev/descriptor\";',\n    \"\",\n    \"// Authored app descriptor. The published config is canonicalized to JSON\",\n    \"// from this file; dev-only overrides live in bos.dev.ts (never published).\",\n    `export default App(${JSON.stringify(body, null, 2)});`,\n    \"\",\n  ].join(\"\\n\");\n\nconst renderBosDevTs = (): string =>\n  [\n    'import type { AppDescriptor } from \"everything-dev/descriptor\";',\n    \"\",\n    \"/**\",\n    \" * Dev overlay for the everything.dev runtime (bos.app.ts) — merged\",\n    \" * child-wins over the resolved config when the environment is development.\",\n    \" * Never published.\",\n    \" */\",\n    \"export default {} satisfies Partial<AppDescriptor>;\",\n    \"\",\n  ].join(\"\\n\");\n\nexport const authorConfig = (\n  projectDir: string,\n  inventory: readonly PluginInventory[],\n  dryRun: boolean,\n): Effect.Effect<StepResult, Error> =>\n  Effect.gen(function* () {\n    const config = JSON.parse(yield* readText(projectDir, \"bos.config.json\")) as BosConfig;\n    if (!config.extends || !config.account || !config.domain) {\n      return yield* Effect.fail(\n        new Error(\n          \"bos.config.json missing extends/account/domain — audit gate should have caught this\",\n        ),\n      );\n    }\n\n    const bosApp = renderBosAppTs(descriptorBody(config, inventory));\n    const bosDev = renderBosDevTs();\n\n    if (dryRun) {\n      return {\n        writes: [\"bos.app.ts\", \"bos.dev.ts\"],\n        deletes: [],\n        notes: [\n          \"bos.config.json deletion deferred until after first successful types:gen from the descriptor\",\n        ],\n      };\n    }\n    yield* writeText(projectDir, \"bos.app.ts\", bosApp);\n    yield* writeText(projectDir, \"bos.dev.ts\", bosDev);\n    return {\n      writes: [\"bos.app.ts\", \"bos.dev.ts\"],\n      deletes: [],\n      notes: [\n        \"bos.config.json deletion deferred until after first successful types:gen from the descriptor\",\n      ],\n    };\n  });\n"],"mappings":"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"}