eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 10.8 kB
JavaScript
import{resolvePackageRoot,resolvePackageSourceFilePath}from"#internal/application/package.js";import{dirname,isAbsolute,join,relative,resolve,sep}from"node:path";import{tryReadExtensionBuildConfig}from"#internal/nitro/host/build-extension.js";import{readFile}from"node:fs/promises";import{toErrorMessage}from"#shared/errors.js";import{resolveDiscoveryProject}from"#discover/project.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{WorkflowBundleBuilder}from"#internal/workflow-bundle/builder.js";import{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{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";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)}`)}}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function normalizeEntrypoint(e,t){return typeof t!=`string`||t.trim().length===0?null:resolve(e,t)}function normalizeServiceRoot(e,t){return typeof t.root==`string`&&t.root.trim().length>0?resolve(e,t.root):normalizeEntrypoint(e,t.entrypoint)}function normalizeServicePrefix(e){return typeof e.routePrefix==`string`?e.routePrefix.trim():typeof e.mount==`string`?e.mount.trim():isRecord(e.mount)&&typeof e.mount.path==`string`&&e.mount.path.trim().length>0?e.mount.path.trim():``}function normalizeServiceCollection(e){if(isRecord(e))return Object.values(e).filter(isRecord);if(Array.isArray(e))return e.filter(isRecord)}function resolveCoDeployedEveServicePrefix(e){if(!isRecord(e.config))return;let t=normalizeServiceCollection(e.config.experimentalServices)??normalizeServiceCollection(e.config.experimentalServicesV2)??normalizeServiceCollection(e.config.services);if(t===void 0)return;let n=!1,r;for(let i of t){if(i.framework!==`eve`){n=!0;continue}let t=normalizeServiceRoot(e.configRoot,i),a=normalizeServicePrefix(i);t!==null&&e.appRoots.includes(t)&&a.length>0&&a!==`/`&&(r=a)}return n?r:void 0}async function resolveCoDeployedEveServicePrefixForVercelFunctionOutput(e,t){let r=Array.from(new Set([resolve(e),resolve(t)])),a=await findClosestVercelOutputDirectory(e);if(a!==void 0)try{let e=JSON.parse(await readFile(join(a,`config.json`),`utf8`)),t=resolveCoDeployedEveServicePrefix({appRoots:r,configRoot:await resolveVercelOutputConfigRoot(a),config:e});if(t!==void 0)return t}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let s=e;for(;;){for(let e of[join(s,`vercel.json`),join(s,`.vercel`,`output`,`config.json`)])try{let t=JSON.parse(await readFile(e,`utf8`)),i=resolveCoDeployedEveServicePrefix({appRoots:r,configRoot:e.endsWith(`vercel.json`)?s:await resolveVercelOutputConfigRoot(dirname(e)),config:t});if(i!==void 0)return i}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let e=dirname(s);if(e===s)return;s=e}}async function readVercelServerRuntime(e){try{return JSON.parse(await readFile(join(e,`functions`,`__server.func`,`.vc-config.json`),`utf8`)).runtime}catch{return}}async function resolveVercelOutputConfigRoot(e){let t=dirname(dirname(e));try{let e=JSON.parse(await readFile(join(t,`.vercel`,`project.json`),`utf8`));if(isRecord(e)&&isRecord(e.settings)&&typeof e.settings.rootDirectory==`string`&&e.settings.rootDirectory.trim().length>0)return resolve(t,e.settings.rootDirectory)}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}return t}async function emitVercelWorkflowFunctions(t){let n=new WorkflowBundleBuilder({agentName:t.agentName,appRoot:t.appRoot,compiledArtifactsBootstrapPath:t.compiledArtifactsBootstrapPath,outDir:t.workflowBuildDir,publicRoutePrefix:t.publicRoutePrefix,rootDir:resolvePackageRoot(),watch:!1}),r=await readVercelServerRuntime(t.outputDir);await n.buildVercelOutput({flowNitroOutputDir:t.flowNitroOutputDir,outputDir:t.outputDir,runtime:r})}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 buildVercelNitroSurface(e,t,n,r){let a=`nitro.${n}`,o=await measureBuildPhase(r,`${a}.create`,()=>createProductionApplicationNitro(e,{buildDir:join(t.nitro.buildDir,n),outputDir:join(t.nitro.surfaceOutputDir,n),surface:n}));try{return await buildNitroOutput(o,r,a)}finally{await measureBuildPhase(r,`${a}.close`,()=>o.close())}}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)),s=await measureBuildPhase(r,`workspace.create`,()=>createApplicationBuildWorkspace(a.appRoot,t.vercelServiceOutput?.serviceOutputDirectory)),l=!1,u;try{u=await buildApplicationInWorkspace(s,t,r)}catch(e){throw l=e instanceof RecoverablePublicationError,e}finally{l||await measureBuildPhase(r,`workspace.remove`,()=>removeApplicationBuildWorkspace(s))}return r!==void 0&&n!==void 0&&await writeOptionalApplicationBuildProfile({outputDirectory:u,profileOutputPath:n,profiler:r}),u}async function buildApplicationInWorkspace(e,n,r){let a=await measureBuildPhase(r,`host.prepare`,()=>prepareProductionApplicationHost(e));if(!process.env.VERCEL){let t=await measureBuildPhase(r,`nitro.all.create`,()=>createProductionApplicationNitro(a,{buildDir:e.nitro.buildDir,outputDir:e.publication.output.stagedDir,surface:`all`}));try{await buildNitroOutput(t,r,`nitro.all`),await measureBuildPhase(r,`agent-summary.emit`,()=>emitVercelAgentSummary({manifest:a.compileResult.manifest,outputPath:e.publication.summary.stagedPath})),await measureBuildPhase(r,`compiler-artifacts.stage`,()=>stageProductionCompilerArtifacts({compilerArtifactsRoot:e.compiler.artifactsDir,outputDir:e.publication.output.stagedDir}))}finally{await measureBuildPhase(r,`nitro.all.close`,()=>t.close())}return await measureBuildPhase(r,`output.publish`,()=>publishCompletedApplicationBuild(e)),e.publication.output.finalDir}let o=await measureBuildPhase(r,`vercel.service-prefix.resolve`,()=>resolveCoDeployedEveServicePrefixForVercelFunctionOutput(a.appRoot,a.compileResult.project.agentRoot)),s=await measureBuildPhase(r,`nitro.app.create`,()=>createProductionApplicationNitro(a,{buildDir:join(e.nitro.buildDir,`app`),outputDir:e.publication.output.stagedDir,surface:`app`}));try{await buildNitroOutput(s,r,`nitro.app`),n.skipVercelSandboxPrewarm||await measureBuildPhase(r,`sandbox.prewarm`,()=>runVercelBuildPrewarm({appRoot:a.appRoot,compiledArtifactsSource:createDiskRuntimeCompiledArtifactsSource(e.compiler.rootDir,{moduleMapLoaderPath:resolvePackageSourceFilePath(`src/internal/authored-module-map-loader.ts`),sandboxAppRoot:a.appRoot}),log(e){console.log(e)}}));let i=await buildVercelNitroSurface(a,e,`flow`,r);await measureBuildPhase(r,`workflow.emit`,()=>emitVercelWorkflowFunctions({agentName:a.compileResult.manifest.config.name,appRoot:a.appRoot,compiledArtifactsBootstrapPath:a.compiledArtifacts.bootstrapPath,flowNitroOutputDir:i,outputDir:e.publication.output.stagedDir,publicRoutePrefix:n.publicRoutePrefix,workflowBuildDir:e.workflow.buildDir})),o!==void 0&&await measureBuildPhase(r,`vercel.functions.normalize`,()=>normalizeEveVercelFunctionOutput(e.publication.output.stagedDir,{servicePrefix:o}));let c=n.vercelServiceOutput;c!==void 0&&await measureBuildPhase(r,`vercel.host-middleware.copy`,()=>copyHostMiddlewareFunctions({hostOutputDirectory:c.hostOutputDirectory,serviceOutputDirectory:e.publication.output.stagedDir})),await measureBuildPhase(r,`agent-summary.emit`,()=>emitVercelAgentSummary({manifest:a.compileResult.manifest,outputPath:e.publication.summary.stagedPath}))}finally{await measureBuildPhase(r,`nitro.app.close`,()=>s.close())}return await measureBuildPhase(r,`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};