{"version":3,"file":"index.cjs","names":["globalDoomConfigDirectory","resolveDoomConfigurationRoot","readSyncDrift","readSyncRegistration","parseDoomServerBundle","fs","path","crypto","parseCompiledContracts","loadMajorModesConfig","resolveLayers","createApiDocuments","canonicalContractJson"],"sources":["../../../src/builders/apiContractExport/index.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { globalDoomConfigDirectory } from '@agimon-ai/doompi-config/config';\nimport { loadMajorModesConfig, resolveLayers } from '@agimon-ai/doompi-config/majorModes';\nimport {\n  canonicalContractJson,\n  createApiDocuments,\n  parseCompiledContracts,\n  type ApiContractSelection,\n  type ApiDocuments,\n} from '@agimon-ai/doompi-core/api-contracts';\nimport { parseDoomServerBundle } from '@agimon-ai/doompi-core/server-facet';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/sync-registration';\n\nimport { resolveDoomConfigurationRoot } from '../../composition/repository';\nimport { readSyncDrift } from '../../composition/syncDrift';\n\n/** Read only published generations. Export must never implicitly sync or activate a facet. */\nexport function exportApiContracts(options: {\n  cwd: string;\n  homeDirectory: string;\n  outputDirectory: string;\n  majorMode?: string;\n}): ApiDocuments['manifest'] {\n  const globalRoot = globalDoomConfigDirectory(options.homeDirectory);\n  const workspaceRoot = resolveDoomConfigurationRoot(options.cwd, options.homeDirectory);\n  const read = (root: string) => {\n    const drift = readSyncDrift({\n      repoRoot: root,\n      homeDirectory: options.homeDirectory,\n      requireFreshSources: false,\n    });\n    if (!drift.fresh)\n      throw new Error(`Run doompi sync for '${root}' before exporting API contracts: ${drift.reasons.join(', ')}`);\n    const registration = readSyncRegistration(root, options.homeDirectory);\n    if (!registration?.serverBundle) throw new Error(`No synced server bundle for '${root}'`);\n    const descriptor = parseDoomServerBundle(JSON.parse(fs.readFileSync(registration.serverBundle.path, 'utf8')));\n    if (!descriptor.contracts) throw new Error(`Resync '${root}' to generate API contracts`);\n    const file = path.resolve(path.dirname(registration.serverBundle.path), descriptor.contracts.file);\n    const bytes = fs.readFileSync(file);\n    if (crypto.createHash('sha256').update(bytes).digest('hex') !== descriptor.contracts.sha256)\n      throw new Error(`API contract checksum mismatch for '${root}'`);\n    return {\n      compiled: parseCompiledContracts(JSON.parse(bytes.toString('utf8'))),\n      config: loadMajorModesConfig(root, options.homeDirectory),\n    };\n  };\n  const global = read(globalRoot);\n  const workspace = globalRoot === workspaceRoot ? global : read(workspaceRoot);\n  const sessionMode = options.majorMode ?? workspace.config.defaultMajorMode;\n  const selection = (\n    source: typeof global,\n    scope: ApiContractSelection['scope'],\n    majorMode: string,\n  ): ApiContractSelection => ({\n    scope,\n    majorMode,\n    activeLayers: resolveLayers(source.config, majorMode),\n    compiled: source.compiled,\n  });\n  // A typo must not silently export an empty session surface.\n  if (!Object.hasOwn(workspace.config.majorMode, sessionMode)) throw new Error(`Unknown major mode '${sessionMode}'`);\n  const documents = createApiDocuments([\n    selection(global, 'global', global.config.defaultMajorMode),\n    selection(workspace, 'workspace', workspace.config.defaultMajorMode),\n    selection(workspace, 'session', sessionMode),\n  ]);\n  const files = {\n    'openapi.json': canonicalContractJson(documents.openapi),\n    'asyncapi.json': canonicalContractJson(documents.asyncapi),\n  };\n  const manifest = {\n    ...documents.manifest,\n    artifacts: Object.fromEntries(\n      Object.entries(files).map(([name, bytes]) => [\n        name,\n        {\n          sha256: crypto.createHash('sha256').update(bytes).digest('hex'),\n        },\n      ]),\n    ),\n  };\n  fs.mkdirSync(options.outputDirectory, { recursive: true });\n  // Write the manifest last. Consumers verify both checksums before accepting the bundle.\n  for (const [name, bytes] of Object.entries({ ...files, 'manifest.json': canonicalContractJson(manifest) })) {\n    const target = path.join(options.outputDirectory, name);\n    const temporary = `${target}.${crypto.randomUUID()}.tmp`;\n    try {\n      fs.writeFileSync(temporary, bytes, { flag: 'wx' });\n      fs.renameSync(temporary, target);\n    } finally {\n      fs.rmSync(temporary, { force: true });\n    }\n  }\n  return documents.manifest;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAoBA,SAAgB,mBAAmB,SAKN;CAC3B,MAAM,cAAA,GAAaA,gCAAAA,0BAAAA,CAA0B,QAAQ,aAAa;CAClE,MAAM,gBAAgBC,cAAAA,6BAA6B,QAAQ,KAAK,QAAQ,aAAa;CACrF,MAAM,QAAQ,SAAiB;EAC7B,MAAM,QAAQC,gBAAAA,cAAc;GAC1B,UAAU;GACV,eAAe,QAAQ;GACvB,qBAAqB;EACvB,CAAC;EACD,IAAI,CAAC,MAAM,OACT,MAAM,IAAI,MAAM,wBAAwB,KAAK,oCAAoC,MAAM,QAAQ,KAAK,IAAI,GAAG;EAC7G,MAAM,gBAAA,GAAeC,yCAAAA,qBAAAA,CAAqB,MAAM,QAAQ,aAAa;EACrE,IAAI,CAAC,cAAc,cAAc,MAAM,IAAI,MAAM,gCAAgC,KAAK,EAAE;EACxF,MAAM,cAAA,GAAaC,oCAAAA,sBAAAA,CAAsB,KAAK,MAAMC,QAAAA,QAAG,aAAa,aAAa,aAAa,MAAM,MAAM,CAAC,CAAC;EAC5G,IAAI,CAAC,WAAW,WAAW,MAAM,IAAI,MAAM,WAAW,KAAK,4BAA4B;EACvF,MAAM,OAAOC,UAAAA,QAAK,QAAQA,UAAAA,QAAK,QAAQ,aAAa,aAAa,IAAI,GAAG,WAAW,UAAU,IAAI;EACjG,MAAM,QAAQD,QAAAA,QAAG,aAAa,IAAI;EAClC,IAAIE,YAAAA,QAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,MAAM,WAAW,UAAU,QACnF,MAAM,IAAI,MAAM,uCAAuC,KAAK,EAAE;EAChE,OAAO;GACL,WAAA,GAAUC,qCAAAA,uBAAAA,CAAuB,KAAK,MAAM,MAAM,SAAS,MAAM,CAAC,CAAC;GACnE,SAAA,GAAQC,oCAAAA,qBAAAA,CAAqB,MAAM,QAAQ,aAAa;EAC1D;CACF;CACA,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,YAAY,eAAe,gBAAgB,SAAS,KAAK,aAAa;CAC5E,MAAM,cAAc,QAAQ,aAAa,UAAU,OAAO;CAC1D,MAAM,aACJ,QACA,OACA,eAC0B;EAC1B;EACA;EACA,eAAA,GAAcC,oCAAAA,cAAAA,CAAc,OAAO,QAAQ,SAAS;EACpD,UAAU,OAAO;CACnB;CAEA,IAAI,CAAC,OAAO,OAAO,UAAU,OAAO,WAAW,WAAW,GAAG,MAAM,IAAI,MAAM,uBAAuB,YAAY,EAAE;CAClH,MAAM,aAAA,GAAYC,qCAAAA,mBAAAA,CAAmB;EACnC,UAAU,QAAQ,UAAU,OAAO,OAAO,gBAAgB;EAC1D,UAAU,WAAW,aAAa,UAAU,OAAO,gBAAgB;EACnE,UAAU,WAAW,WAAW,WAAW;CAC7C,CAAC;CACD,MAAM,QAAQ;EACZ,iBAAA,GAAgBC,qCAAAA,sBAAAA,CAAsB,UAAU,OAAO;EACvD,kBAAA,GAAiBA,qCAAAA,sBAAAA,CAAsB,UAAU,QAAQ;CAC3D;CACA,MAAM,WAAW;EACf,GAAG,UAAU;EACb,WAAW,OAAO,YAChB,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW,CAC3C,MACA,EACE,QAAQL,YAAAA,QAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,EAChE,CACF,CAAC,CACH;CACF;CACA,QAAA,QAAG,UAAU,QAAQ,iBAAiB,EAAE,WAAW,KAAK,CAAC;CAEzD,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ;EAAE,GAAG;EAAO,kBAAA,GAAiBK,qCAAAA,sBAAAA,CAAsB,QAAQ;CAAE,CAAC,GAAG;EAC1G,MAAM,SAASN,UAAAA,QAAK,KAAK,QAAQ,iBAAiB,IAAI;EACtD,MAAM,YAAY,GAAG,OAAO,GAAGC,YAAAA,QAAO,WAAW,EAAE;EACnD,IAAI;GACF,QAAA,QAAG,cAAc,WAAW,OAAO,EAAE,MAAM,KAAK,CAAC;GACjD,QAAA,QAAG,WAAW,WAAW,MAAM;EACjC,UAAU;GACR,QAAA,QAAG,OAAO,WAAW,EAAE,OAAO,KAAK,CAAC;EACtC;CACF;CACA,OAAO,UAAU;AACnB"}