import{basename,dirname,join,resolve,sep}from"node:path";import{discoverExtensionMountDeclarations}from"#discover/discover-agent.js";import{buildExtensionPackage,tryReadExtensionBuildConfig}from"#internal/nitro/host/build-extension.js";import{realpath,stat}from"node:fs/promises";import{resolveDiscoveryProject}from"#discover/project.js";import{createDiskProjectSource}from"#discover/project-source.js";import{locateExtensionMountPackage}from"#discover/extensions.js";import{isAuthoredSourcePath,resolveDevelopmentSourceRoot}from"#internal/nitro/dev-runtime-source-snapshot.js";import{resolveTsConfigDependencyPaths}from"#internal/application/tsconfig-dependencies.js";async function prepareDevelopmentWorkspaceExtensions(e){let t=resolve(e.appRoot),n=await resolveDiscoveryProject(t),i=createDiskProjectSource(),s=await discoverExtensionMountDeclarations({agentRoot:n.agentRoot,source:i}),c=await toCanonicalPath(resolveDevelopmentSourceRoot(t)),l=new Map;for(let e of s.mounts){let r=await resolveWorkspaceExtension({appRoot:t,agentRoot:n.agentRoot,mount:e,source:i,workspaceSourceRoot:c});r!==void 0&&l.set(r.packageRoot,r)}let u=[...l.values()].sort((e,t)=>e.packageRoot.localeCompare(t.packageRoot)),d=new Map(e.previousExtensions?.map(e=>[e.packageRoot,e])),f=e.changedPaths===void 0?void 0:await Promise.all(e.changedPaths.map(async e=>await toCanonicalPath(e))),p=e.previousExtensions===void 0||f?.length===0;return await Promise.all(u.map(async e=>{let t=d.get(e.packageRoot);(p===!0||t===void 0||!sameBuildInputs(t,e)||f?.some(t=>affectsExtensionBuild(t,e))===!0)&&await buildExtensionPackage(e.packageRoot,e.config)})),u}async function resolveWorkspaceExtension(e){let t=await locateExtensionMountPackage({source:e.source,agentRoot:e.agentRoot,appRoot:e.appRoot,mount:e.mount.mountRef,namespace:e.mount.namespace});if(t.location?.authoredSourceRoot===void 0)return;let i=await realpath(t.location.packageRoot).catch(()=>void 0);if(i===void 0||!isAuthoredSourcePath(i,e.workspaceSourceRoot))return;let a=await tryReadExtensionBuildConfig(i);if(a===null||(await stat(a.sourceRoot).catch(()=>void 0))?.isDirectory()!==!0)return;let o=[join(i,`package.json`),join(i,`tsconfig.json`),...await resolveTsConfigDependencyPaths(i)];return{config:a,packageRoot:i,buildConfigPaths:[...new Set(o.map(e=>resolve(e)))].sort((e,t)=>e.localeCompare(t))}}function affectsExtensionBuild(e,t){return isPathInsideOrEqual(e,t.config.sourceRoot)||t.buildConfigPaths.includes(e)}function sameBuildConfig(e,t){return e.sourceRoot===t.sourceRoot&&e.distRoot===t.distRoot&&e.outDir===t.outDir&&e.packageName===t.packageName&&e.shortName===t.shortName&&e.runtimeDependencies.length===t.runtimeDependencies.length&&e.runtimeDependencies.every((e,n)=>e===t.runtimeDependencies[n])}function sameBuildInputs(e,t){return sameBuildConfig(e.config,t.config)&&e.buildConfigPaths.length===t.buildConfigPaths.length&&e.buildConfigPaths.every((e,n)=>e===t.buildConfigPaths[n])}function isPathInsideOrEqual(e,t){let n=resolve(e),a=resolve(t);return n===a||n.startsWith(`${a}${sep}`)}async function toCanonicalPath(i){let a=resolve(i),o=[];for(;;)try{return join(await realpath(a),...o.reverse())}catch{let n=dirname(a);if(n===a)return resolve(i);o.push(basename(a)),a=n}}export{prepareDevelopmentWorkspaceExtensions};