import{dirname,join,relative}from"node:path";import{mkdir,readFile,writeFile}from"node:fs/promises";import{findClosestLinkedVercelDirectory,findClosestVercelOutputDirectory}from"#shared/vercel-output-directory.js";const VERCEL_JSON_FILE_NAME=`vercel.json`,VERCEL_OUTPUT_CONFIG_FILE_NAME=`.vercel/output/config.json`;function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasServices(e){return e!==void 0&&Object.keys(e).length>0}function resolveRelativeEntrypoint(e,t){let r=relative(e,t);return r.length===0?`.`:r.replaceAll(`\\`,`/`)}async function resolveVercelOutputConfigLocation(n){let r=await findClosestLinkedVercelDirectory(n),i=r===void 0?n:dirname(r),a=await findClosestVercelOutputDirectory(n);return a===void 0?r===void 0?{outputConfigPath:join(n,VERCEL_OUTPUT_CONFIG_FILE_NAME),projectRoot:i}:{outputConfigPath:join(r,`output`,`config.json`),projectRoot:i}:{outputConfigPath:join(a,`config.json`),projectRoot:i}}function normalizeVercelServicesConfig(e,t){if(!isRecord(e))throw Error(`${t} must contain a JSON object.`);let n=e.experimentalServices;if(n!==void 0&&!isRecord(n))throw Error(`${t} experimentalServices must be a JSON object.`);return e}async function readVercelServicesConfig(e,t){try{return normalizeVercelServicesConfig(JSON.parse(await readFile(e,`utf8`)),t)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{};throw e}}function findServiceByFramework(e,t){return Object.values(e).find(e=>e.framework===t)}function resolveServicePrefix(e){if(e!==void 0){if(typeof e.routePrefix==`string`&&e.routePrefix.trim().length>0)return e.routePrefix.trim();if(typeof e.mount==`string`&&e.mount.trim().length>0)return e.mount.trim();if(isRecord(e.mount)&&typeof e.mount.path==`string`&&e.mount.path.trim().length>0)return e.mount.path.trim()}}function resolveConfiguredServicePrefix(e){return resolveServicePrefix(findServiceByFramework(e.services,`eve`))??e.servicePrefix}function assertRootServicesAreComplete(e){let t=findServiceByFramework(e.services,`eve`),n=findServiceByFramework(e.services,`nextjs`);if(t!==void 0&&n!==void 0)return resolveServicePrefix(t)??e.servicePrefix;throw Error(`${VERCEL_JSON_FILE_NAME} already defines experimentalServices, so withEve cannot add generated services through ${VERCEL_OUTPUT_CONFIG_FILE_NAME}. Add both the Next.js and Eve services to ${VERCEL_JSON_FILE_NAME}, or remove experimentalServices from ${VERCEL_JSON_FILE_NAME}.`)}async function ensureEveVercelOutputConfig(n){let{outputConfigPath:i,projectRoot:o}=await resolveVercelOutputConfigLocation(n.nextRoot),s=(await readVercelServicesConfig(join(o,VERCEL_JSON_FILE_NAME),VERCEL_JSON_FILE_NAME)).experimentalServices;if(hasServices(s))return{servicePrefix:assertRootServicesAreComplete({services:s,servicePrefix:n.servicePrefix})};let c=await readVercelServicesConfig(i,VERCEL_OUTPUT_CONFIG_FILE_NAME),l=resolveRelativeEntrypoint(n.nextRoot,n.appRoot),u=c.experimentalServices??{},d=findServiceByFramework(u,`eve`),f=findServiceByFramework(u,`nextjs`),p=resolveConfiguredServicePrefix({services:u,servicePrefix:n.servicePrefix}),m={...u};f===void 0&&(m.web={entrypoint:`.`,framework:`nextjs`,mount:`/`,type:`web`}),d===void 0&&(m.eve={buildCommand:n.eveBuildCommand,entrypoint:l,framework:`eve`,mount:p,type:`web`});let h={...c,version:3,experimentalServices:m};return JSON.stringify(c)!==JSON.stringify(h)&&(await mkdir(dirname(i),{recursive:!0}),await writeFile(i,`${JSON.stringify(h,null,2)}\n`)),{servicePrefix:p}}export{ensureEveVercelOutputConfig};