eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 8.76 kB
JavaScript
import{readFile}from"node:fs/promises";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{dirname,isAbsolute,join,relative,resolve,sep}from"node:path";import{resolveDiscoveryProject}from"#discover/project.js";import{resolvePackageSourceFilePath}from"#internal/application/package.js";import{normalizePublicRoutePrefix}from"#shared/public-route-prefix.js";import{tryReadExtensionBuildConfig}from"#internal/nitro/host/build-extension.js";import{isObject}from"#shared/guards.js";import{toErrorMessage}from"#shared/errors.js";import{createDiskRuntimeCompiledArtifactsSource}from"#runtime/compiled-artifacts-source.js";import{build,copyPublicAssets,prepare,prerender}from"nitro/builder";import{prepareEveVersionedCacheDirectory,writeEveVersionedCacheMetadata}from"#internal/application/cache-metadata.js";import{createApplicationBuildWorkspace,removeApplicationBuildWorkspace}from"#internal/application/build-workspace.js";import{ApplicationBuildProfiler,createApplicationBuildProfile,measureApplicationBuildOutput,writeApplicationBuildProfile}from"#internal/application/build-profile.js";import{RecoverablePublicationError,publishApplicationBuildArtifacts}from"#internal/application/output-publication.js";import{stageProductionCompilerArtifacts}from"#internal/application/production-compiler-artifacts.js";import{materializeVercelWorkflowFunctionOutput,normalizeEveVercelFunctionOutput}from"#internal/workflow-bundle/vercel-workflow-output.js";import{createProductionApplicationNitro}from"#internal/nitro/host/create-application-nitro.js";import{emitVercelAgentSummary}from"#internal/nitro/host/build-vercel-agent-summary.js";import{copyHostMiddlewareFunctions}from"#internal/nitro/host/copy-host-middleware.js";import{normalizeVercelServiceCrons}from"#internal/nitro/host/normalize-vercel-service-crons.js";import{prepareProductionApplicationHost}from"#internal/nitro/host/prepare-application-host.js";import{runVercelBuildPrewarm}from"#internal/nitro/host/vercel-build-prewarm.js";import{findClosestVercelOutputDirectory}from"#shared/vercel-output-directory.js";import{resolveEveServicePrefixByRoot}from"#internal/vercel/vercel-service-config-operations.js";import{parseVercelServicesConfig}from"#internal/vercel/vercel-services-config.js";function trimTrailingSlash(e){return e.replace(/[\\/]+$/,``)}async function measureBuildPhase(e,t,n){return e===void 0?n():e.measure(t,n)}function isPathInside(e,t){let n=relative(e,t);return n.length===0||!n.startsWith(`..${sep}`)&&n!==`..`&&!isAbsolute(n)}function assertProfileOutputOutsideBuildOutput(e,t){if(e!==void 0&&isPathInside(t,e))throw Error(`Build profile path ${e} must be outside the published output directory ${t}.`)}async function writeOptionalApplicationBuildProfile(e){try{assertProfileOutputOutsideBuildOutput(e.profileOutputPath,e.outputDirectory);let t=e.profiler.finish(),n=await measureApplicationBuildOutput(e.outputDirectory);await writeApplicationBuildProfile(e.profileOutputPath,createApplicationBuildProfile({output:n,target:process.env.VERCEL?`vercel`:`local`,timing:t}))}catch(t){console.warn(`eve: failed to write optional build profile to ${e.profileOutputPath}; continuing with the published build output: ${toErrorMessage(t)}`)}}async function resolveEveServicePrefixForVercelFunctionOutput(e,t){let n=Array.from(new Set([resolve(e),resolve(t)])),r=await findClosestVercelOutputDirectory(e);if(r!==void 0)try{let e=join(r,`config.json`),t=parseVercelServicesConfig(JSON.parse(await readFile(e,`utf8`)),e),i=resolveEveServicePrefixByRoot({appRoots:n,configRoot:await resolveVercelOutputConfigRoot(r),config:t});if(i!==void 0)return i}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let i=e;for(;;){for(let e of[join(i,`vercel.json`),join(i,`.vercel`,`output`,`config.json`)])try{let t=parseVercelServicesConfig(JSON.parse(await readFile(e,`utf8`)),e),r=e.endsWith(`vercel.json`)?i:await resolveVercelOutputConfigRoot(dirname(e)),a=resolveEveServicePrefixByRoot({appRoots:n,configRoot:r,config:t});if(a!==void 0)return a}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let e=dirname(i);if(e===i)return;i=e}}async function resolveVercelOutputConfigRoot(e){let t=dirname(dirname(e));try{let e=JSON.parse(await readFile(join(t,`.vercel`,`project.json`),`utf8`));if(isObject(e)&&isObject(e.settings)){let n=e.settings.rootDirectory;if(typeof n==`string`&&n.trim().length>0)return resolve(t,n)}}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}return t}async function buildNitroOutput(e,t,n){let r=trimTrailingSlash(e.options.output.dir);return await measureBuildPhase(t,`${n}.cache.prepare`,()=>prepareEveVersionedCacheDirectory(r)),await measureBuildPhase(t,`${n}.prepare`,()=>prepare(e)),await measureBuildPhase(t,`${n}.public-assets`,()=>copyPublicAssets(e)),await measureBuildPhase(t,`${n}.prerender`,()=>prerender(e)),await measureBuildPhase(t,`${n}.bundle`,()=>build(e)),await measureBuildPhase(t,`${n}.cache.write`,()=>writeEveVersionedCacheMetadata(r)),r}async function buildApplication(e,t){let n=t.profileOutputPath===void 0?void 0:resolve(t.profileOutputPath),r=n===void 0?void 0:new ApplicationBuildProfiler,i=await measureBuildPhase(r,`extension.check`,()=>tryReadExtensionBuildConfig(e));if(i!==null)throw Error(`Package "${i.packageName}" is an eve extension. Run \`eve extension build\` instead of \`eve build\`.`);let a=await measureBuildPhase(r,`project.resolve`,()=>resolveDiscoveryProject(e)),o=await measureBuildPhase(r,`workspace.create`,()=>createApplicationBuildWorkspace(a.appRoot,t.vercelServiceOutput?.serviceOutputDirectory)),s=!1,c;try{c=await buildApplicationInWorkspace(o,t,r)}catch(e){throw s=e instanceof RecoverablePublicationError,e}finally{s||await measureBuildPhase(r,`workspace.remove`,()=>removeApplicationBuildWorkspace(o))}return r!==void 0&&n!==void 0&&await writeOptionalApplicationBuildProfile({outputDirectory:c,profileOutputPath:n,profiler:r}),c}async function buildApplicationInWorkspace(e,t,n){let r=await measureBuildPhase(n,`host.prepare`,()=>prepareProductionApplicationHost(e)),i=!!process.env.VERCEL,a=i?await measureBuildPhase(n,`vercel.service-prefix.resolve`,()=>resolveEveServicePrefixForVercelFunctionOutput(r.appRoot,r.compileResult.project.agentRoot)):void 0,o=normalizePublicRoutePrefix(a),s=o===EVE_ROUTE_PREFIX?void 0:o;if(t.publicRoutePrefix!==void 0&&s!==void 0&&t.publicRoutePrefix!==s)throw Error(`EVE_PUBLIC_ROUTE_PREFIX ${JSON.stringify(t.publicRoutePrefix)} conflicts with the configured Vercel service prefix ${JSON.stringify(a)}.`);let c=t.publicRoutePrefix??s,l=await measureBuildPhase(n,`nitro.create`,()=>createProductionApplicationNitro(r,{buildDir:e.nitro.buildDir,outputDir:e.publication.output.stagedDir,publicRoutePrefix:c,workspaceMember:t.workspaceMember}));try{i&&!t.skipVercelSandboxPrewarm&&await measureBuildPhase(n,`sandbox.prewarm`,()=>runVercelBuildPrewarm({appRoot:r.appRoot,compiledArtifactsSource:createDiskRuntimeCompiledArtifactsSource(e.compiler.rootDir,{moduleMapLoaderPath:resolvePackageSourceFilePath(`src/internal/authored-module-map-loader.ts`),sandboxAppRoot:r.appRoot}),log(e){console.log(e)}})),await buildNitroOutput(l,n,`nitro`),i&&await measureBuildPhase(n,`vercel.workflow-function.materialize`,()=>materializeVercelWorkflowFunctionOutput(e.publication.output.stagedDir)),a!==void 0&&await measureBuildPhase(n,`vercel.functions.normalize`,()=>normalizeEveVercelFunctionOutput(e.publication.output.stagedDir,{servicePrefix:a}));let o=t.vercelServiceOutput;o!==void 0&&(await measureBuildPhase(n,`vercel.service-crons.normalize`,()=>normalizeVercelServiceCrons({publicRoutePrefix:c,serviceOutputDirectory:e.publication.output.stagedDir})),await measureBuildPhase(n,`vercel.host-middleware.copy`,()=>copyHostMiddlewareFunctions({hostOutputDirectory:o.hostOutputDirectory,serviceOutputDirectory:e.publication.output.stagedDir}))),await measureBuildPhase(n,`agent-summary.emit`,()=>emitVercelAgentSummary({manifest:r.compileResult.manifest,outputPath:e.publication.summary.stagedPath})),i||await measureBuildPhase(n,`compiler-artifacts.stage`,()=>stageProductionCompilerArtifacts({compilerArtifactsRoot:e.compiler.artifactsDir,outputDir:e.publication.output.stagedDir}))}finally{await measureBuildPhase(n,`nitro.close`,()=>l.close())}return await measureBuildPhase(n,`output.publish`,()=>publishCompletedApplicationBuild(e)),e.publication.output.finalDir}async function publishCompletedApplicationBuild(e){await publishApplicationBuildArtifacts({appRoot:e.appRoot,finalOutputDir:e.publication.output.finalDir,finalSummaryPath:e.publication.summary.finalPath,scratchDir:e.rootDir,stagedOutputDir:e.publication.output.stagedDir,stagedSummaryPath:e.publication.summary.stagedPath})}export{buildApplication};