import{createRequire}from"node:module";import{dirname,join,relative}from"node:path";import{readFile,readdir,stat}from"node:fs/promises";import{execFile}from"node:child_process";import{promisify}from"node:util";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"#discover/filesystem.js";async function emitExtensionDeclarations(e){let t=await resolveTypeScriptBinary(e.appRoot),n=join(e.appRoot,`tsconfig.json`),r=await stat(n).then(e=>e.isFile()).catch(()=>!1),i=[`--declaration`,`--emitDeclarationOnly`,`--noEmit`,`false`,`--noEmitOnError`,`true`,`--rootDir`,e.appRoot,`--outDir`,e.declarationsRoot,`--pretty`,`false`],s=r?[`--project`,n,...i]:[...i,`--allowJs`,`--checkJs`,`false`,`--module`,`esnext`,`--moduleResolution`,`bundler`,`--target`,`ES2022`,`--skipLibCheck`,`true`,...await collectDeclarationInputs(e.sourceRoot)];try{await promisify(execFile)(process.execPath,[t,...s],{cwd:e.appRoot,maxBuffer:10*1024*1024})}catch(e){let t=declarationEmitOutput(e);throw Error(`Cannot emit extension declarations${t.length>0?`:\n${t}`:`.`}`,{cause:e})}await assertModuleDeclarationsEmitted(e)}async function assertModuleDeclarationsEmitted(e){let t=relative(e.appRoot,e.sourceRoot),r=(await Promise.all(e.moduleLogicalPaths.map(async n=>await stat(join(e.declarationsRoot,t,declarationLogicalPath(n))).then(e=>e.isFile()).catch(()=>!1)?void 0:n))).filter(e=>e!==void 0);if(r.length===0)return;if(r.length===e.moduleLogicalPaths.length)throw Error(`TypeScript emitted no declarations for "${t}". Ensure the package tsconfig.json \`include\` covers every module under \`eve.extension.source\`.`);let i=r.length===1?`module`:`modules`;throw Error(`TypeScript emitted no declaration for extension ${i} ${r.map(e=>JSON.stringify(e)).join(`, `)}. Include ${r.length===1?`it`:`them`} in the package tsconfig.json before publishing the extension.`)}function declarationLogicalPath(e){if(e.endsWith(`.mts`)||e.endsWith(`.mjs`))return`${e.slice(0,-4)}.d.mts`;if(e.endsWith(`.cts`)||e.endsWith(`.cjs`))return`${e.slice(0,-4)}.d.cts`;if(e.endsWith(`.ts`)||e.endsWith(`.js`))return`${e.slice(0,-3)}.d.ts`;throw Error(`Unsupported extension module path "${e}".`)}async function collectDeclarationInputs(e){let t=[];for(let n of await readdir(e,{withFileTypes:!0})){let r=join(e,n.name);n.isDirectory()?t.push(...await collectDeclarationInputs(r)):n.isFile()&&SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS.some(e=>n.name.endsWith(e))&&t.push(r)}return t.sort()}function declarationEmitOutput(e){if(!(e instanceof Error))return String(e);let t=e;return[t.stdout,t.stderr,t.message].filter(e=>typeof e==`string`&&e.trim().length>0).join(`
`).trim()}async function resolveTypeScriptBinary(n){for(let i of[join(n,`package.json`),import.meta.url]){let n;try{n=createRequire(i).resolve(`typescript/package.json`)}catch{continue}let a=JSON.parse(await readFile(n,`utf8`)),o=typeof a.bin==`string`?a.bin:a.bin?.tsc;if(o!==void 0)return join(dirname(n),o)}throw Error("Cannot build an eve extension without TypeScript. Add `typescript` to the package's devDependencies.")}export{emitExtensionDeclarations};