modelence 0.26.0 → 0.26.1-nd.dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,10 +10,10 @@ Guide: ${kt}`;async function xt(){let e=join(process.cwd(),A),t;try{t=await prom
10
10
  Next step \u2014 run the app on this machine:
11
11
  `),console.log(" npm install (if you haven't already)"),console.log(` npm run dev (starts the app)
12
12
  `));}catch(t){console.error(`Setup failed: ${t instanceof Error?t.message:"Unknown error"}`),process.exit(1);}}var Dt=z$1.object({serverDir:z$1.string(),serverEntry:z$1.string(),postBuildCommand:z$1.string().optional()});async function he(){let e=join(process.cwd(),"modelence.config.ts"),o=await createJiti(import.meta.url,{interopDefault:true,requireCache:false}).import(e);if(typeof o!="object")throw new Error("modelence.config.ts should export an object");return Dt.parse(o)}var ye=null,X=null;function we(){if(!X)throw new Error("Configuration not loaded");return X}function v(){let{serverDir:e,serverEntry:t}=we();return join(e,t).replace(/\\/g,"/")}function ve(){return we().postBuildCommand}function M(e){let t=Z("build");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}function E(e){return join(process.cwd(),e).replace(/\\/g,"/")}function Z(e){let t=E(".modelence");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}async function b(){try{X=await he();}catch(e){throw console.error(e),new Error("Unable to load modelence.config.ts")}try{let e=await Ee.readFile(join(process.cwd(),".modelence.env"),"utf-8");ye=parse(e);}catch(e){if(e.code==="ENOENT")ye={};else throw e}}async function Mt(){let e=ve();if(e){console.log("Running post-build command..."),execSync(e);return}await Ft(),await Rt();}async function Ft(){console.log("Building client with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),t={build:{outDir:Q.resolve(process.cwd(),".modelence/build/client").replace(/\\/g,"/"),emptyOutDir:true,ssrManifest:true}};await build$1(mergeConfig(e?.config||{},t,true));}async function Rt(){console.log("Building SSR bundle with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),o={build:{ssr:Q.resolve(process.cwd(),"src/client/index.tsx").replace(/\\/g,"/"),outDir:Q.resolve(process.cwd(),".modelence/build/ssr").replace(/\\/g,"/"),emptyOutDir:true,rollupOptions:{output:{format:"esm",entryFileNames:"index.mjs"}}}};await build$1(mergeConfig(e?.config||{},o,true));}async function jt(){return console.log("Building server with tsup..."),new Promise(e=>{build({entry:[v()],format:"esm",sourcemap:true,minify:process.env.NODE_ENV==="production",outDir:".modelence/build",clean:true,watch:false,bundle:true,skipNodeModulesBundle:true,treeshake:true,platform:"node",outExtension:()=>({js:".mjs"}),onSuccess:async()=>{e(void 0);}});})}async function F(){console.log("Building Modelence project...");try{let e=M();await Ee.rm(e,{recursive:!0,force:!0}),await jt(),await Mt(),console.log("Build completed successfully!");}catch(e){throw console.error(e),new Error("Build failed")}try{await Ee.access(Z());}catch{throw new Error("Could not find the .modelence directory. Looks like something went wrong during the build.")}}var Kt="auth.json",Vt=40*60*1e3;function R(){let e=process.env.MODELENCE_HOME||join(Ut.homedir(),".modelence");return join(e,Kt)}async function j(){try{let e=JSON.parse(await promises.readFile(R(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return {}}}async function te(e){let t=R();await promises.mkdir(dirname(t),{recursive:true,mode:448}),await promises.writeFile(t,JSON.stringify(e,null,2)+`
13
- `,{mode:384});}async function ke(e){let{hosts:t={}}=await j(),o=t[e];return !o?.token||!o.expiresAt||new Date(o.expiresAt).getTime()-Vt<=Date.now()?null:o.token}async function xe(e){let{hosts:t={}}=await j();return Object.entries(t).filter(([o,n])=>(!e||o===e)&&!!n?.token).map(([o,n])=>({host:o,token:n.token}))}async function Ae(e,t,o){let n=await j();await te({...n,hosts:{...n.hosts,[e]:{token:t,expiresAt:o}}});}async function U(e){if(!e){await te({});return}let t=await j(),{[e]:o,...n}=t.hosts??{};await te({...t,hosts:n});}var De=promisify(execFile),$e=200*1024*1024,Xt=[".git","node_modules",".modelence/build",".modelence/tmp",".modelence/cache"],Zt=[/^\.modelence(\.[^/]+)?\.env$/];function _e(e){return /^\.env(?:\.|$)/.test(e)&&!/\.(example|sample|template)$/.test(e)}function Qt(e){return e.split(/\r?\n/).some(t=>{if(/^\s*[#;]/.test(t))return false;let o=/https?:\/\/([^/\s]+)@/.exec(t)?.[1];if(o&&o.replace(/\$\{[A-Za-z_][A-Za-z0-9_]*\}/g,"").replace(/:/g,"")!=="")return true;let n=/^\s*[^=]*?(?:_authToken|_auth|_password|npmAuthToken|npmAuthIdent)["']?\s*[=:]\s*(.*?)\s*$/i.exec(t);if(!n)return false;let r=n[1].replace(/\s+#.*$/,"").replace(/^["']|["']$/g,"").trim();return r!==""&&!/^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(r)})}function B(e){return e.split(sep).join("/")}function eo(e){return ne(e)||_e(B(e).split("/").at(-1)??"")}function ne(e){let t=B(e),o=t.split("/");for(let r of Xt)if(r.split("/").length===1){if(o.slice(0,-1).includes(r))return true}else if(t===r||t.startsWith(`${r}/`))return true;let n=o[o.length-1];return Zt.some(r=>r.test(n))}async function to(e){try{let{stdout:t}=await De("git",["rev-parse","--is-inside-work-tree"],{cwd:e});return t.trim()==="true"}catch{return false}}async function Ie(e,t){let{stdout:o}=await De("git",["ls-files",...t,"-z"],{cwd:e,maxBuffer:67108864});return o.split("\0").filter(n=>n.length>0)}async function Ne(e,t=""){let o=await promises.readdir(join(e,t),{withFileTypes:true}),n=[];for(let r of o){let i=t?`${t}/${r.name}`:r.name;r.isDirectory()?eo(`${i}/x`)||n.push(...await Ne(e,i)):(r.isFile()||r.isSymbolicLink())&&n.push(i);}return n}async function oo(e,t){let o=join(e,t),n=await promises.readlink(o),r=resolve(dirname(o),n),i=relative(e,r);return i.startsWith("..")||isAbsolute(i)?null:{path:t,target:B(relative(dirname(o),r))||"."}}async function no(e=process.cwd()){let t=await to(e),o=new Set(t?await Ie(e,["--cached"]):[]),n=t?[...o,...await Ie(e,["--others","--exclude-standard"])]:await Ne(e),r={files:[],symlinks:[],usedGit:t,excludedFiles:[],skipped:[],committedEnvFiles:[]};for(let i of n){let l=i.split("/").at(-1)??"",c=_e(l);if(ne(i)||c&&!o.has(i)){r.excludedFiles.push(i);continue}let s;try{s=await promises.lstat(join(e,i));}catch{continue}if(s.isSymbolicLink()){if(ne(`${i}/x`)){r.excludedFiles.push(i);continue}let a=await oo(e,i);a?r.symlinks.push(a):r.skipped.push({path:i,reason:"symlink to outside the project"});}else if(s.isDirectory())r.skipped.push({path:i,reason:"git submodule"});else if(s.isFile()){if([".npmrc",".yarnrc.yml",".yarnrc"].includes(l)&&Qt(await promises.readFile(join(e,i),"utf8"))){r.excludedFiles.push(i);continue}r.files.push(i),c&&r.committedEnvFiles.push(i);}}return {...r,files:r.files.sort(),symlinks:r.symlinks.sort((i,l)=>i.path.localeCompare(l.path)),excludedFiles:r.excludedFiles.sort(),committedEnvFiles:r.committedEnvFiles.sort()}}async function Oe(e,t){let{files:o,symlinks:n,...r}=await no(e);if(o.length===0)throw new Error("No files to upload");await promises.mkdir(join(t,".."),{recursive:true}),await promises.rm(t,{force:true});let i=createWriteStream(t),l=Yt("zip",{zlib:{level:6}}),c=new Promise((a,p)=>{i.on("close",a),i.on("error",p),l.on("error",p);});l.pipe(i);for(let a of o)l.file(join(e,a),{name:B(relative("",a))});for(let a of n)l.symlink(a.path,a.target,511);await Promise.all([l.finalize(),c]);let{size:s}=await promises.stat(t);if(s>$e)throw await promises.rm(t,{force:true}),new Error(`Source is ${(s/1024/1024).toFixed(0)} MB compressed; the limit is ${$e/1024/1024} MB. Add build output and large assets to .gitignore.`);return {...r,fileCount:o.length+n.length,sizeBytes:s}}var d="modelence.config.json",ao=1,$="https://docs.modelence.com/deploy/setup",K=`Use ${$}.md to set up Modelence deployment for this project`;function Fe(e){return `${e.replace(/\/$/,"")}/schema/${d}?version=${ao}`}function V(e=process.cwd()){return join(e,d)}async function z(e=process.cwd()){let t;try{t=await promises.readFile(V(e),"utf8");}catch{return null}let o=[],n=parse$1(t,o,{allowTrailingComma:true,disallowComments:false});if(o.length>0)throw new Error(`${d} is not valid JSON: ${co(t,o[0])}`);if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`${d} must contain a JSON object`);return n}function co(e,t){let o=e.slice(0,t.offset),n=o.split(`
13
+ `,{mode:384});}async function ke(e){let{hosts:t={}}=await j(),o=t[e];return !o?.token||!o.expiresAt||new Date(o.expiresAt).getTime()-Vt<=Date.now()?null:o.token}async function xe(e){let{hosts:t={}}=await j();return Object.entries(t).filter(([o,n])=>(!e||o===e)&&!!n?.token).map(([o,n])=>({host:o,token:n.token}))}async function Ae(e,t,o){let n=await j();await te({...n,hosts:{...n.hosts,[e]:{token:t,expiresAt:o}}});}async function U(e){if(!e){await te({});return}let t=await j(),{[e]:o,...n}=t.hosts??{};await te({...t,hosts:n});}var De=promisify(execFile),$e=200*1024*1024,Xt=[".git","node_modules",".modelence/build",".modelence/tmp",".modelence/cache"],Zt=[/^\.modelence(\.[^/]+)?\.env$/];function _e(e){return /^\.env(?:\.|$)/.test(e)&&!/\.(example|sample|template)$/.test(e)}function Qt(e){return e.split(/\r?\n/).some(t=>{if(/^\s*[#;]/.test(t))return false;let o=/https?:\/\/([^/\s]+)@/.exec(t)?.[1];if(o&&o.replace(/\$\{[A-Za-z_][A-Za-z0-9_]*\}/g,"").replace(/:/g,"")!=="")return true;let n=/^\s*[^=]*?(?:_authToken|_auth|_password|npmAuthToken|npmAuthIdent)["']?\s*[=:]\s*(.*?)\s*$/i.exec(t);if(!n)return false;let r=n[1].replace(/\s+#.*$/,"").replace(/^["']|["']$/g,"").trim();return r!==""&&!/^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(r)})}function B(e){return e.split(sep).join("/")}function eo(e){return ne(e)||_e(B(e).split("/").at(-1)??"")}function ne(e){let t=B(e),o=t.split("/");for(let r of Xt)if(r.split("/").length===1){if(o.slice(0,-1).includes(r))return true}else if(t===r||t.startsWith(`${r}/`))return true;let n=o[o.length-1];return Zt.some(r=>r.test(n))}async function to(e){try{let{stdout:t}=await De("git",["rev-parse","--is-inside-work-tree"],{cwd:e});return t.trim()==="true"}catch{return false}}async function Ie(e,t){let{stdout:o}=await De("git",["ls-files",...t,"-z"],{cwd:e,maxBuffer:67108864});return o.split("\0").filter(n=>n.length>0)}async function Ne(e,t=""){let o=await promises.readdir(join(e,t),{withFileTypes:true}),n=[];for(let r of o){let i=t?`${t}/${r.name}`:r.name;r.isDirectory()?eo(`${i}/x`)||n.push(...await Ne(e,i)):(r.isFile()||r.isSymbolicLink())&&n.push(i);}return n}async function oo(e,t){let o=join(e,t),n=await promises.readlink(o),r=resolve(dirname(o),n),i=relative(e,r);return i.startsWith("..")||isAbsolute(i)?null:{path:t,target:B(relative(dirname(o),r))||"."}}async function no(e=process.cwd()){let t=await to(e),o=new Set(t?await Ie(e,["--cached"]):[]),n=t?[...o,...await Ie(e,["--others","--exclude-standard"])]:await Ne(e),r={files:[],symlinks:[],usedGit:t,excludedFiles:[],skipped:[],committedEnvFiles:[]};for(let i of n){let l=i.split("/").at(-1)??"",c=_e(l);if(ne(i)||c&&!o.has(i)){r.excludedFiles.push(i);continue}let s;try{s=await promises.lstat(join(e,i));}catch{continue}if(s.isSymbolicLink()){if(ne(`${i}/x`)){r.excludedFiles.push(i);continue}let a=await oo(e,i);a?r.symlinks.push(a):r.skipped.push({path:i,reason:"symlink to outside the project"});}else if(s.isDirectory())r.skipped.push({path:i,reason:"git submodule"});else if(s.isFile()){if([".npmrc",".yarnrc.yml",".yarnrc"].includes(l)&&Qt(await promises.readFile(join(e,i),"utf8"))){r.excludedFiles.push(i);continue}r.files.push(i),c&&r.committedEnvFiles.push(i);}}return {...r,files:r.files.sort(),symlinks:r.symlinks.sort((i,l)=>i.path.localeCompare(l.path)),excludedFiles:r.excludedFiles.sort(),committedEnvFiles:r.committedEnvFiles.sort()}}async function Oe(e,t){let{files:o,symlinks:n,...r}=await no(e);if(o.length===0)throw new Error("No files to upload");await promises.mkdir(join(t,".."),{recursive:true}),await promises.rm(t,{force:true});let i=createWriteStream(t),l=Yt("zip",{zlib:{level:6}}),c=new Promise((a,p)=>{i.on("close",a),i.on("error",p),l.on("error",p);});l.pipe(i);for(let a of o)l.file(join(e,a),{name:B(relative("",a))});for(let a of n)l.symlink(a.path,a.target,511);await Promise.all([l.finalize(),c]);let{size:s}=await promises.stat(t);if(s>$e)throw await promises.rm(t,{force:true}),new Error(`Source is ${(s/1024/1024).toFixed(0)} MB compressed; the limit is ${$e/1024/1024} MB. Add build output and large assets to .gitignore.`);return {...r,fileCount:o.length+n.length,sizeBytes:s}}var d="modelence.config.json",ao=1,Fe=`https://raw.githubusercontent.com/modelence/modelence/main/schema/v${ao}/modelence.config.json`,$="https://docs.modelence.com/deploy/setup",K=`Use ${$}.md to set up Modelence deployment for this project`;function V(e=process.cwd()){return join(e,d)}async function z(e=process.cwd()){let t;try{t=await promises.readFile(V(e),"utf8");}catch{return null}let o=[],n=parse$1(t,o,{allowTrailingComma:true,disallowComments:false});if(o.length>0)throw new Error(`${d} is not valid JSON: ${co(t,o[0])}`);if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`${d} must contain a JSON object`);return n}function co(e,t){let o=e.slice(0,t.offset),n=o.split(`
14
14
  `).length,r=t.offset-o.lastIndexOf(`
15
15
  `);return `${printParseErrorCode(t.error)} at line ${n}, column ${r}`}async function Re(e,t=process.cwd()){await promises.writeFile(V(t),JSON.stringify(e,null,2)+`
16
16
  `);}function je(e){let t=[],o=Object.entries(e.resources??{});for(let[n,r]of o){o.length>1&&t.push(` resource: ${n}`),t.push(` image: ${r.image??"default (node-22-slim)"}`),r.root&&r.root!=="."&&t.push(` root: ${r.root}`),t.push(...Le("build",r.build,"default (npm install)")),t.push(...Le("start",r.start,"(none)"));for(let i of r.static??[])t.push(` static: ${i.path} -> ${i.dir}/`);}for(let[n,r]of Object.entries(e.env??{}))t.push(` env: ${n} (${r.type??"text"})`);return t}function Le(e,t,o){let n=` ${`${e}:`.padEnd(8)} `;return t?t.commands.length===0?[`${n}(none)`]:t.commands.map(r=>`${n}${r}`):[`${n}${o}`]}async function Ke(e,t="."){if(typeof t!="string"||isAbsolute(t))throw new Error("root must be a relative directory inside the project.");let o=await promises.realpath(e),n=resolve(o,t);if(!Ue(o,n))throw new Error("root must stay inside the project.");let r;try{r=await promises.realpath(n);}catch{throw new Error(`root "${t}" does not exist.`)}if(!Ue(o,r)||!(await promises.stat(r)).isDirectory())throw new Error("root must be a directory inside the project.");return r}function Ue(e,t){let o=relative(e,t);return o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}var Ve=["$schema","resources","env"];async function ze(e){let t=await z(e);if(!t)throw new Error(mo(e));fo(t);for(let o of Object.values(t.resources??{}))o?.root!==void 0&&await Ke(e,o.root);console.log(`Build plan (${d}):`);for(let o of je(t))console.log(o);return t}function mo(e){return [`${d} not found in ${e}.`,"Modelence Cloud builds and runs your app exactly as this file describes (install, build and start commands, Node.js version, static directories).","Ask your coding agent to create it with this prompt:","",` ${K}`,"",`Reference: ${$}`].join(`
17
17
  `)}function fo(e){let t=Object.keys(e).filter(o=>!Ve.includes(o));if(t.length>0)throw new Error(`${d} has unknown key "${t[0]}" (allowed: ${Ve.join(", ")}).`);for(let o of ["resources","env"]){let n=e[o];if(n!==void 0&&(!n||typeof n!="object"||Array.isArray(n)))throw new Error(`${d}: "${o}" must be an object.`)}for(let[o,n]of Object.entries(e.resources??{})){if(!Je(n))throw new Error(`${d}: "resources.${o}" must be an object.`);for(let r of ["build","start"])go(n[r],`resources.${o}.${r}`);}}function go(e,t){if(e!==void 0){if(!Je(e)||!Array.isArray(e.commands))throw new Error(`${d}: "${t}" must be an object with a "commands" array, e.g. { "commands": ["npm ci"] }.`);e.commands.forEach((o,n)=>{if(typeof o!="string")throw new Error(`${d}: "${t}.commands.${n}" must be a string.`);if(o.trim()==="")throw new Error(`${d}: "${t}.commands.${n}" must not be empty.`)});}}function Je(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}async function Ge(e,t){return t.prebuilt?{kind:"bundle",reason:"prebuilt-flag"}:await z(e)!==null?{kind:"source",reason:"spec-file"}:await wo(e)?{kind:"bundle",reason:"modelence-dependency"}:{kind:"source",reason:"default"}}function qe(e){return e.reason!=="modelence-dependency"?null:`No ${d} found; this is a Modelence app, so it is built locally and uploaded as before. Add a ${d} to build it on Modelence Cloud instead.`}async function wo(e){let t;try{t=await promises.readFile(join(e,"package.json"),"utf8");}catch{return false}let o;try{o=JSON.parse(t);}catch{return false}if(!o||typeof o!="object")return false;let n=o;return ["dependencies","devDependencies"].some(r=>{let i=n[r];return !!(i&&typeof i=="object"&&"modelence"in i)})}function We(e,t){if(e.app&&e.env)return {appAlias:e.app,envAlias:e.env};if(e.env&&t.deploy?.appAlias)return {appAlias:t.deploy.appAlias,envAlias:e.env};if(e.env&&t.appId)return {appId:t.appId,envAlias:e.env};if(e.app||e.env)throw new Error("Pass both --app and --env, or neither to pick the target in the browser.");return t.deploy?.environmentId?{environmentId:t.deploy.environmentId}:null}function He(e,t){if("environmentId"in e){let o=t.deploy;return `${o?.environmentId===e.environmentId?`${o.appAlias}/${o.envAlias}`:e.environmentId} (saved in .modelence/project.json)`}return "appAlias"in e?`${e.appAlias}/${e.envAlias}`:e.envAlias}function Ye(e,t){let o=t.deploy;return !o||"environmentId"in e?false:"appAlias"in e&&e.appAlias!==o.appAlias?true:e.envAlias!==o.envAlias}function J(){return !process.env.CI&&!!process.stdin.isTTY}async function Xe(e){let t=createInterface({input:process.stdin,output:process.stdout}),o=await new Promise(n=>t.question(`${e} (y/N) `,n));return t.close(),o.trim().toLowerCase()==="y"}var y=class extends Error{constructor(o,n){super(o);this.status=n;this.name="StudioApiError";}};async function g(e,t,{method:o="GET",token:n,body:r,query:i}={}){let l=new URL(t,e);for(let[a,p]of Object.entries(i??{}))l.searchParams.set(a,String(p));let c={};n&&(c.Authorization=`Bearer ${n}`),r!==void 0&&(c["Content-Type"]="application/json");let s=await fetch(l,{method:o,headers:c,body:r===void 0?void 0:JSON.stringify(r)});if(!s.ok){let a=await s.text(),p=a||s.statusText;try{let m=JSON.parse(a);p=m.error||m.message||p;}catch{}throw new y(p,s.status)}return await s.json()}var Co="https://cloud.modelence.com";function G(e){return e instanceof y&&e.status===401}async function Ze(e){return process.env.MODELENCE_TOKEN?process.env.MODELENCE_TOKEN:await ke(e)}async function ie(e,t,o){if(o)try{await Ae(e,t,o);}catch(n){console.warn("Could not save the login for next time:",n);}}async function se(e){let t={environmentId:e.environmentId,appAlias:e.appAlias,envAlias:e.envAlias};try{await _({deploy:t,..."appId"in e?{appId:e.appId}:{}});}catch(o){console.warn("Could not record the deploy target in .modelence/project.json:",o);}}async function Qe(e,t){if(e)return e.replace(/\/$/,"");if(process.env.MODELENCE_SERVICE_ENDPOINT)return process.env.MODELENCE_SERVICE_ENDPOINT.replace(/\/$/,"");try{let o=parse(await promises.readFile(join(t,".modelence.env"),"utf8"));if(o.MODELENCE_SERVICE_ENDPOINT)return o.MODELENCE_SERVICE_ENDPOINT.replace(/\/$/,"")}catch{}return Co}var et=3e3,Po=30*60*1e3,ko=10*60*1e3;async function tt(e,t,o){let n=Date.now()+ko,r=false;for(;Date.now()<n;){let i;try{({status:i}=await g(e,"/api/environment/status",{token:t,query:{environmentId:o}}));}catch(l){if(l instanceof y&&l.status===404)return false;throw l}if(i==="ready")return r;if(i==="failed")throw new Error("The environment failed to provision; check it in the dashboard.");r||(console.log("Waiting for the environment to finish provisioning..."),r=true),await new Promise(l=>setTimeout(l,et));}throw new Error("Timed out waiting for the environment to be ready.")}async function ot(e,t,o,n){let r=Date.now()+Po,i="",l="",c=null,s=false;for(;Date.now()<r;){let a;try{a=await g(e.host,"/api/deploy/status",{token:e.token,query:{environmentId:o,buildId:n,...c?{logCursor:c}:{}}});}catch(p){if(!G(p)||s)throw p;s=true,await t();continue}for(let p of a.logs)process.stdout.write(` \u2502 ${p.replace(/\n$/,"")}
18
- `);if(c=a.logCursor??c,a.status!==i){i=a.status;let p=xo(a);p&&p!==l&&(l=p,console.log(p));}if(a.status==="deploy-completed"){a.siteUrl&&console.log(`Live at ${a.siteUrl}`);return}if(a.status==="build-failed"||a.status==="deploy-failed"){for(let p of a.errors)console.error(` ${p}`);if(a.containerLogs&&a.containerLogs.length>0){console.error("Container output:");for(let p of a.containerLogs)console.error(` \u2502 ${p.replace(/\n$/,"")}`);}process.exitCode=1;return}await new Promise(p=>setTimeout(p,et));}console.error("Timed out waiting for the deployment; check the dashboard for its status."),process.exitCode=1;}function xo(e){switch(e.status){case "build-pending":return "Building image...";case "deploy-pending":case "deploying":return "Image built. Deploying containers...";case "rolling-out":return "Rolling out new containers...";case "deploy-completed":return "Deployed successfully.";case "build-failed":return "Build failed.";case "deploy-failed":return "Deployment failed.";default:return null}}async function ae({session:e,target:t,kind:o,archivePath:n,spec:r}){let{host:i,token:l}=e,c=()=>g(i,"/api/upload-bundle",{method:"POST",token:l,body:{...t,kind:o}}),s=await c();if(!s.environmentId)throw new Error("Modelence Cloud is too old for this CLI version (no environment id from /api/upload-bundle). Try again later, or deploy with modelence@0.25.");await tt(i,l,s.environmentId)&&(s=await c()),console.log(`Uploading to ${s.appAlias}/${s.envAlias}...`);let a=await openAsBlob(n,{type:"application/zip"}),p=await fetch(s.uploadUrl,{method:"PUT",body:a,headers:{"Content-Type":"application/zip"}});if(!p.ok)throw new Error(`Failed to upload: ${await To(p)}`);let m=await g(i,"/api/deploy",{method:"POST",token:l,body:{environmentId:s.environmentId,bundleName:s.bundleName,kind:o,spec:r}});return console.log(`Deployment started: ${m.deploymentUrl}`),{environmentId:m.environmentId,buildId:m.buildId}}async function To(e){let t=await e.text().catch(()=>""),o=t.match(/<Code>([^<]+)<\/Code>/)?.[1],n=t.match(/<Message>([^<]+)<\/Message>/)?.[1],r=e.statusText||`HTTP ${e.status}`;return o?`${r} (${o}${n?`: ${n}`:""})`:r}async function st(e){let t=process.cwd(),o=await Qe(e.host,t),n=await Ge(t,e),r=n.kind,i=qe(n);i&&console.log(i);let l=await x(t),c=We(e,l),s=await Ze(o);if((!s||!c)&&!J())throw new Error(Do(!!s,!!c));await _o(c,l,e.yes);let a,p=join(t,".modelence","tmp",`${r}.zip`);r==="bundle"?(await b(),await F(),await Oo(p)):(a=await ze(t),No(await Oe(t,p)));try{if(!s||!c){let u=await P(o,{pick:c?void 0:"deploy",purpose:"deploy",appId:l.appId});s=u.token,await ie(o,u.token,u.expiresAt),u.target&&(c={environmentId:u.target.environmentId},await se(u.target));}if(!c)throw new Error("No deploy target selected. Run again and pick an environment in the browser, or pass --app and --env.");let m={host:o,token:s},le=async()=>{if(await U(o),!J())throw new Error("Modelence Cloud rejected the token (expired or revoked), and nobody is at the terminal to sign in again. Set a fresh MODELENCE_TOKEN. A deployment that already started keeps running; check the dashboard.");console.log("Your saved login has expired; please sign in again.");let u=await P(o,{pick:c?void 0:"deploy",purpose:"deploy",appId:l.appId});await ie(o,u.token,u.expiresAt),u.target&&(c={environmentId:u.target.environmentId},await se(u.target)),m.token=u.token;},C;try{C=await ae({session:m,target:c,kind:r,archivePath:p,spec:a});}catch(u){if(!G(u))throw u;await le(),C=await ae({session:m,target:c,kind:r,archivePath:p,spec:a});}C.buildId&&await ot(m,le,C.environmentId,C.buildId);}finally{await promises.rm(p,{force:true});}}function Do(e,t){return `Nobody is at the terminal to sign in or pick a target in the browser (CI or a non-interactive shell). To deploy from here, ${[t?null:"pass --app and --env",e?null:"set MODELENCE_TOKEN"].filter(Boolean).join(" and ")}.`}async function _o(e,t,o){if(!e)return;let n=He(e,t);if(console.log(`Deploying to ${n}`),o||!Ye(e,t)||!J())return;let r=`${t.deploy?.appAlias}/${t.deploy?.envAlias}`;if(!await Xe(`This project normally deploys to ${r}. Deploy to ${n} instead?`))throw new Error("Cancelled.")}var nt=10;function rt(e){let t=e.slice(0,nt).join(", "),o=e.length-nt;return o>0?`${t} and ${o} more`:t}function No(e){console.log(`Packed ${e.fileCount} files (${at(e.sizeBytes)})`+(e.usedGit?" from git":"; not a git repository, so only default exclusions applied")),e.excludedFiles.length>0&&console.log(`Not uploaded (local, generated or credentials; store secrets in the target environment): ${rt(e.excludedFiles)}`),e.committedEnvFiles.length>0&&console.log(`Uploaded environment files committed to git: ${rt(e.committedEnvFiles)}`);for(let{path:t,reason:o}of e.skipped)console.warn(`Warning: ${t} is not uploaded (${o}).`);}function at(e){return `${(e/1024/1024).toFixed(2)} MB`}async function Oo(e){await promises.rm(e,{force:true}),console.log("Creating deployment bundle..."),await promises.mkdir(join(e,".."),{recursive:true});let t=createWriteStream(e),o=Yt("zip",{zlib:{level:9}}),n=new Promise((c,s)=>{t.on("close",c),t.on("error",s),o.on("error",s);});o.pipe(t);let r=["package.json","package-lock.json","next.config.js","next.config.ts","modelence.config.ts"],i=["public","server","scripts",join(".modelence","build"),".next"];for(let c of r)await it(E(c))&&o.file(E(c),{name:c});for(let c of i)await it(E(c))&&o.directory(E(c),c);await o.finalize(),await n;let l=await promises.stat(e);console.log(`Deployment bundle created (${at(l.size)})`);}async function it(e){try{return await promises.access(e),!0}catch{return false}}function ct(e={}){console.log("Starting Modelence dev server...");let t=v(),o=Q.resolve("./node_modules/.bin/tsx");execSync(`"${o}" watch --ignore "vite.config.ts.timestamp-*" "${t}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"development",...e.takeover?{MODELENCE_TAKEOVER:"1"}:{}}});}function pt(){console.log("Starting Modelence production server...");let e=v(),t=Q.basename(e,Q.extname(e)),o=M(`${t}.mjs`);execSync(`node "${o}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"production"}});}async function dt(e){let t=await xe(e.host);await Promise.all(t.map(({host:o,token:n})=>Ro(o,n))),await U(e.host),console.log(e.host?`Removed the saved login for ${e.host}.`:`Removed saved logins (${R()}).`);}async function Ro(e,t){try{await g(e,"/api/cli/logout",{method:"POST",token:t});}catch{}}var Uo="https://cloud.modelence.com";async function ut(e){let t=process.cwd(),o=V(t);if(!e.force&&await Bo(o))throw new Error(`${d} already exists; pass --force to overwrite it.`);let n={$schema:Fe(e.host??Uo),resources:{app:{type:"service",image:"node-22-slim",build:{commands:["npm ci"]},static:[]}},env:{}};await Re(n,t),console.log(`Wrote a ${d} template.`),console.log("Ask your coding agent to fill it in with this prompt:"),console.log(""),console.log(` ${K}`),console.log(""),console.log(`Reference: ${$}`),console.log(`Once ${d} describes your app, run \`modelence deploy\`.`);}async function Bo(e){try{return await promises.access(e),!0}catch{return false}}var qo=fileURLToPath(import.meta.url),Wo=dirname(qo),Ho=JSON.parse(readFileSync(join(Wo,"../../package.json"),"utf-8")),h=new Command().name("modelence").description("Modelence CLI tool").version(Ho.version);h.command("setup").description("Setup Modelence environment variables").option("-t, --token <token>","Modelence setup token (omit to authorize in the browser)").option("-h, --host <host>","Modelence host","https://cloud.modelence.com").action(async e=>{await ge(e);});h.command("build").description("Build the application").action(async()=>{await b(),await F();});h.command("deploy").description("Deploy the project described by modelence.config.json to Modelence Cloud (picks the target in the browser on first run)").option("-a, --app <app>","Application alias").option("-e, --env <env>","Environment alias").option("-h, --host <host>","Modelence host").option("--prebuilt","Build locally and upload the .modelence/build bundle (Modelence apps only)").option("-y, --yes","Deploy to the given --app/--env without asking, even if it is not the saved target").action(async e=>{try{await st(e);}catch(t){console.error(`Deploy failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});h.command("init").description("Create a modelence.config.json template for this project").option("--force","Overwrite an existing modelence.config.json").option("-h, --host <host>","Modelence host used for the schema URL").action(async e=>{try{await ut(e);}catch(t){console.error(`Init failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});h.command("logout").description("Forget the saved Modelence Cloud login").option("-h, --host <host>","Only forget the login for this host").action(async e=>{await dt(e);});h.command("dev").description("Start development server").option("--takeover","Disconnect any instance currently holding the environment and connect this one").action(async e=>{await b(),ct(e);});h.command("start").description("Start production server").action(async()=>{await b(),pt();});h.parse(process.argv);//# sourceMappingURL=modelence.js.map
18
+ `);if(c=a.logCursor??c,a.status!==i){i=a.status;let p=xo(a);p&&p!==l&&(l=p,console.log(p));}if(a.status==="deploy-completed"){a.siteUrl&&console.log(`Live at ${a.siteUrl}`);return}if(a.status==="build-failed"||a.status==="deploy-failed"){for(let p of a.errors)console.error(` ${p}`);if(a.containerLogs&&a.containerLogs.length>0){console.error("Container output:");for(let p of a.containerLogs)console.error(` \u2502 ${p.replace(/\n$/,"")}`);}process.exitCode=1;return}await new Promise(p=>setTimeout(p,et));}console.error("Timed out waiting for the deployment; check the dashboard for its status."),process.exitCode=1;}function xo(e){switch(e.status){case "build-pending":return "Building image...";case "deploy-pending":case "deploying":return "Image built. Deploying containers...";case "rolling-out":return "Rolling out new containers...";case "deploy-completed":return "Deployed successfully.";case "build-failed":return "Build failed.";case "deploy-failed":return "Deployment failed.";default:return null}}async function ae({session:e,target:t,kind:o,archivePath:n,spec:r}){let{host:i,token:l}=e,c=()=>g(i,"/api/upload-bundle",{method:"POST",token:l,body:{...t,kind:o}}),s=await c();if(!s.environmentId)throw new Error("Modelence Cloud is too old for this CLI version (no environment id from /api/upload-bundle). Try again later, or deploy with modelence@0.25.");await tt(i,l,s.environmentId)&&(s=await c()),console.log(`Uploading to ${s.appAlias}/${s.envAlias}...`);let a=await openAsBlob(n,{type:"application/zip"}),p=await fetch(s.uploadUrl,{method:"PUT",body:a,headers:{"Content-Type":"application/zip"}});if(!p.ok)throw new Error(`Failed to upload: ${await To(p)}`);let m=await g(i,"/api/deploy",{method:"POST",token:l,body:{environmentId:s.environmentId,bundleName:s.bundleName,kind:o,spec:r}});return console.log(`Deployment started: ${m.deploymentUrl}`),{environmentId:m.environmentId,buildId:m.buildId}}async function To(e){let t=await e.text().catch(()=>""),o=t.match(/<Code>([^<]+)<\/Code>/)?.[1],n=t.match(/<Message>([^<]+)<\/Message>/)?.[1],r=e.statusText||`HTTP ${e.status}`;return o?`${r} (${o}${n?`: ${n}`:""})`:r}async function st(e){let t=process.cwd(),o=await Qe(e.host,t),n=await Ge(t,e),r=n.kind,i=qe(n);i&&console.log(i);let l=await x(t),c=We(e,l),s=await Ze(o);if((!s||!c)&&!J())throw new Error(Do(!!s,!!c));await _o(c,l,e.yes);let a,p=join(t,".modelence","tmp",`${r}.zip`);r==="bundle"?(await b(),await F(),await Oo(p)):(a=await ze(t),No(await Oe(t,p)));try{if(!s||!c){let u=await P(o,{pick:c?void 0:"deploy",purpose:"deploy",appId:l.appId});s=u.token,await ie(o,u.token,u.expiresAt),u.target&&(c={environmentId:u.target.environmentId},await se(u.target));}if(!c)throw new Error("No deploy target selected. Run again and pick an environment in the browser, or pass --app and --env.");let m={host:o,token:s},le=async()=>{if(await U(o),!J())throw new Error("Modelence Cloud rejected the token (expired or revoked), and nobody is at the terminal to sign in again. Set a fresh MODELENCE_TOKEN. A deployment that already started keeps running; check the dashboard.");console.log("Your saved login has expired; please sign in again.");let u=await P(o,{pick:c?void 0:"deploy",purpose:"deploy",appId:l.appId});await ie(o,u.token,u.expiresAt),u.target&&(c={environmentId:u.target.environmentId},await se(u.target)),m.token=u.token;},C;try{C=await ae({session:m,target:c,kind:r,archivePath:p,spec:a});}catch(u){if(!G(u))throw u;await le(),C=await ae({session:m,target:c,kind:r,archivePath:p,spec:a});}C.buildId&&await ot(m,le,C.environmentId,C.buildId);}finally{await promises.rm(p,{force:true});}}function Do(e,t){return `Nobody is at the terminal to sign in or pick a target in the browser (CI or a non-interactive shell). To deploy from here, ${[t?null:"pass --app and --env",e?null:"set MODELENCE_TOKEN"].filter(Boolean).join(" and ")}.`}async function _o(e,t,o){if(!e)return;let n=He(e,t);if(console.log(`Deploying to ${n}`),o||!Ye(e,t)||!J())return;let r=`${t.deploy?.appAlias}/${t.deploy?.envAlias}`;if(!await Xe(`This project normally deploys to ${r}. Deploy to ${n} instead?`))throw new Error("Cancelled.")}var nt=10;function rt(e){let t=e.slice(0,nt).join(", "),o=e.length-nt;return o>0?`${t} and ${o} more`:t}function No(e){console.log(`Packed ${e.fileCount} files (${at(e.sizeBytes)})`+(e.usedGit?" from git":"; not a git repository, so only default exclusions applied")),e.excludedFiles.length>0&&console.log(`Not uploaded (local, generated or credentials; store secrets in the target environment): ${rt(e.excludedFiles)}`),e.committedEnvFiles.length>0&&console.log(`Uploaded environment files committed to git: ${rt(e.committedEnvFiles)}`);for(let{path:t,reason:o}of e.skipped)console.warn(`Warning: ${t} is not uploaded (${o}).`);}function at(e){return `${(e/1024/1024).toFixed(2)} MB`}async function Oo(e){await promises.rm(e,{force:true}),console.log("Creating deployment bundle..."),await promises.mkdir(join(e,".."),{recursive:true});let t=createWriteStream(e),o=Yt("zip",{zlib:{level:9}}),n=new Promise((c,s)=>{t.on("close",c),t.on("error",s),o.on("error",s);});o.pipe(t);let r=["package.json","package-lock.json","next.config.js","next.config.ts","modelence.config.ts"],i=["public","server","scripts",join(".modelence","build"),".next"];for(let c of r)await it(E(c))&&o.file(E(c),{name:c});for(let c of i)await it(E(c))&&o.directory(E(c),c);await o.finalize(),await n;let l=await promises.stat(e);console.log(`Deployment bundle created (${at(l.size)})`);}async function it(e){try{return await promises.access(e),!0}catch{return false}}function ct(e={}){console.log("Starting Modelence dev server...");let t=v(),o=Q.resolve("./node_modules/.bin/tsx");execSync(`"${o}" watch --ignore "vite.config.ts.timestamp-*" "${t}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"development",...e.takeover?{MODELENCE_TAKEOVER:"1"}:{}}});}function pt(){console.log("Starting Modelence production server...");let e=v(),t=Q.basename(e,Q.extname(e)),o=M(`${t}.mjs`);execSync(`node "${o}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"production"}});}async function dt(e){let t=await xe(e.host);await Promise.all(t.map(({host:o,token:n})=>Ro(o,n))),await U(e.host),console.log(e.host?`Removed the saved login for ${e.host}.`:`Removed saved logins (${R()}).`);}async function Ro(e,t){try{await g(e,"/api/cli/logout",{method:"POST",token:t});}catch{}}async function ut(e){let t=process.cwd(),o=V(t);if(!e.force&&await Uo(o))throw new Error(`${d} already exists; pass --force to overwrite it.`);await Re({$schema:Fe,resources:{app:{type:"service",image:"node-22-slim",build:{commands:["npm ci"]},static:[]}},env:{}},t),console.log(`Wrote a ${d} template.`),console.log("Ask your coding agent to fill it in with this prompt:"),console.log(""),console.log(` ${K}`),console.log(""),console.log(`Reference: ${$}`),console.log(`Once ${d} describes your app, run \`npx modelence@latest deploy\`.`);}async function Uo(e){try{return await promises.access(e),!0}catch{return false}}var Go=fileURLToPath(import.meta.url),qo=dirname(Go),Wo=JSON.parse(readFileSync(join(qo,"../../package.json"),"utf-8")),h=new Command().name("modelence").description("Modelence CLI tool").version(Wo.version);h.command("setup").description("Setup Modelence environment variables").option("-t, --token <token>","Modelence setup token (omit to authorize in the browser)").option("-h, --host <host>","Modelence host","https://cloud.modelence.com").action(async e=>{await ge(e);});h.command("build").description("Build the application").action(async()=>{await b(),await F();});h.command("deploy").description("Deploy the project described by modelence.config.json to Modelence Cloud (picks the target in the browser on first run)").option("-a, --app <app>","Application alias").option("-e, --env <env>","Environment alias").option("-h, --host <host>","Modelence host").option("--prebuilt","Build locally and upload the .modelence/build bundle (Modelence apps only)").option("-y, --yes","Deploy to the given --app/--env without asking, even if it is not the saved target").action(async e=>{try{await st(e);}catch(t){console.error(`Deploy failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});h.command("init").description("Create a modelence.config.json template for this project").option("--force","Overwrite an existing modelence.config.json").action(async e=>{try{await ut(e);}catch(t){console.error(`Init failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});h.command("logout").description("Forget the saved Modelence Cloud login").option("-h, --host <host>","Only forget the login for this host").action(async e=>{await dt(e);});h.command("dev").description("Start development server").option("--takeover","Disconnect any instance currently holding the environment and connect this one").action(async e=>{await b(),ct(e);});h.command("start").description("Start production server").action(async()=>{await b(),pt();});h.parse(process.argv);//# sourceMappingURL=modelence.js.map
19
19
  //# sourceMappingURL=modelence.js.map