@overlayed/cli 0.1.1 → 0.3.1
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.
- package/README.md +4 -0
- package/dist/cli.js +12 -11
- package/package.json +11 -9
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Builtins as e,Cli as t,Command as n,UsageError as r}from"clipanion";import i from"chalk";import a,{createReadStream as ee}from"node:fs";import{scope as te,type as o}from"arktype";import s,{createWriteStream as ne,existsSync as c,mkdirSync as l,readdirSync as u,unlinkSync as d,writeFileSync as f}from"fs";import{ensureFileSync as re}from"fs-extra";import p,{join as m}from"path";import h from"node:path";import{glob as g}from"glob";import ie,{fileURLToPath as ae}from"node:url";import{createJiti as oe}from"jiti";import se from"jszip";import{password as ce}from"@inquirer/prompts";import _,{isXiorError as v}from"xior";import{exec as y}from"child_process";import{promisify as b}from"util";const x={deployment:`deployment`};function S(e){return{all:e=e||new Map,on:function(t,n){var r=e.get(t);r?r.push(n):e.set(t,[n])},off:function(t,n){var r=e.get(t);r&&(n?r.splice(r.indexOf(n)>>>0,1):e.set(t,[]))},emit:function(t,n){var r=e.get(t);r&&r.slice().map(function(e){e(n)}),(r=e.get(`*`))&&r.slice().map(function(e){e(t,n)})}}}function C(e){return Object.prototype.toString.call(e)===`[object Object]`}function w(e){return e?Array.isArray(e)?e:[e]:[]}var T=class{data=[];constructor(){}get size(){return this.data.length}add(e){this.data.push(e)}next(){return this.data.shift()}clear(){this.data.length=0}*flush(){for(;this.size>0;){let e=this.next();e&&(yield e)}}},E=class{emitter;constructor(){this.emitter=S()}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}emit(e,t){this.emitter.emit(e,t)}removeAllListeners(){this.emitter.all.clear()}};function D(e,...t){let n=class extends e{static _instance;static getInstance(){return this._instance||(this._instance=new e(...t)),this._instance}static clearInstance(){this._instance=void 0}};return n}var O=class extends E{destroy(){this.removeAllListeners()}fatal(e,t,n){this.emit(`fatal`,{code:t,message:e,data:n,timestamp:Date.now()})}error(e,t,n){this.emit(`error`,{code:t,message:e,data:n,timestamp:Date.now()})}warn(e,t,n){this.emit(`warning`,{code:t,message:e,data:n,timestamp:Date.now()})}};const k=D(O);var A=class{data;_schema;_defaultValue;_path;constructor(e){let{schema:t,default:n,path:r}=e;this._schema=t,this._defaultValue=n,this._path=r}set(e){let t=this._schema[`~standard`].validate(e);if(t instanceof Promise)throw Error(`StructuredConfigFile does not support async validation`);if(t.issues){this.reportInvalidConfigFile(t.issues);return}this.data=this.onBeforeSave(e),this.save(e)}get(){return this.data?this.data:this.load()}getKey(e){let t=this.get();return t[e]}save(e){let t=this.onBeforeSave(e);try{re(this.getFilePath()),s.writeFileSync(this.getFilePath(),JSON.stringify(t,void 0,2))}catch{return}return this.data=t}load(){if(!this.fileExists(this.getFilePath())||!this.canReadWriteFile(this.getFilePath())){this.save(this._defaultValue);let e=this.onAfterLoad(this._defaultValue);return this.data=e,e}try{let e=s.readFileSync(this.getFilePath(),`utf8`),t=this.onAfterLoad(this.parseStoredData(e));return this.data=t,t}catch{return this.data=this._defaultValue}}onBeforeSave(e){return e}onAfterLoad(e){return e}getFilePath(){return this._path}parseStoredData(e){try{let t=o(`string.json.parse`).to(`object`),n=t(e);if(n instanceof o.errors)return this._defaultValue;let r=this._schema[`~standard`].validate(n);if(r instanceof Promise)throw Error(`StructuredConfigFile does not support async validation`);return r.issues?this.migrate(n,this._defaultValue):this.migrate(r.value,this._defaultValue)}catch{return this._defaultValue}}canReadWriteFile(e){try{return s.accessSync(e,s.constants.R_OK|s.constants.W_OK),!0}catch{return!1}}fileExists(e){try{return s.accessSync(e,s.constants.F_OK),!0}catch{return!1}}migrate(e,t){let n={...e};for(let r in t){if(!Object.prototype.hasOwnProperty.call(t,r))continue;r in e?e[r]!==null&&t[r]!==null&&typeof e[r]==`object`&&typeof t[r]==`object`&&!Array.isArray(e[r])&&!Array.isArray(t[r])?n[r]=this.migrate(e[r],t[r]):Array.isArray(t[r])&&(n[r]=e[r]):n[r]=t[r]}return n}reportInvalidConfigFile(e){k.getInstance().error(`Invalid config file`,`INVALID_CONFIG_FILE`,{issues:e.map(e=>e.message),filePath:this._path,data:this.data})}},j=class e extends E{stream;logPath;baseFileName;currentDate;rotationCheckInterval;isRotating=!1;constructor(e,t){super(),this.logPath=e,this.baseFileName=t.replace(`.log`,``),this.currentDate=this.getDateString(new Date),this.ensureLogDirectory(),this.ensureLogFile(),this.stream=this.createStream(),this.rotationCheckInterval=this.startRotationCheck(),this.cleanupOldLogs()}static scope(t,n){return new e(t,n)}log(...e){this.write(`log`,...e)}error(...e){this.write(`error`,...e)}warn(...e){this.write(`warn`,...e)}info(...e){this.write(`info`,...e)}debug(...e){this.write(`debug`,...e)}async close(){clearInterval(this.rotationCheckInterval),await new Promise(e=>{this.stream.end(()=>e())})}getCurrentFileName(){return this.getFileName(this.currentDate)}getFileName(e){return`${this.baseFileName}-${e}.log`}ensureLogDirectory(){try{l(this.logPath,{recursive:!0})}catch(e){throw console.error(`Failed to create log directory ${this.logPath}:`,e),e}}ensureLogFile(){let e=m(this.logPath,this.getFileName(this.currentDate));if(!c(e))try{f(e,``,`utf8`)}catch(t){throw console.error(`Failed to create log file ${e}:`,t),t}}getDateString(e){return e.toISOString().split(`T`)[0]}createStream(){let e=m(this.logPath,this.getFileName(this.currentDate));return ne(e,{flags:`a`,encoding:`utf8`})}async rotateLogs(){if(this.isRotating)return;this.isRotating=!0;let e=this.getDateString(new Date);e!==this.currentDate&&await new Promise(t=>{this.stream.end(()=>{this.currentDate=e,this.stream=this.createStream(),this.cleanupOldLogs(),t()})}),this.isRotating=!1}startRotationCheck(){return setInterval(()=>this.rotateLogs(),6e4)}cleanupOldLogs(){let e=u(this.logPath),t=new Date;t.setDate(t.getDate()-3),e.filter(e=>e.startsWith(this.baseFileName)&&e.endsWith(`.log`)).filter(e=>{let n=e.replace(`${this.baseFileName}-`,``).replace(`.log`,``),r=new Date(n);return r<t}).forEach(e=>{try{d(m(this.logPath,e))}catch(t){console.error(`Failed to delete old log file ${e}:`,t)}})}write(e,...t){let n=new Date,r=n.toISOString().replace(`T`,` `).replace(/\.\d+Z$/,``)+`.${n.getMilliseconds().toString().padStart(3,`0`)}`,i=t.map(e=>typeof e==`object`?JSON.stringify(e,void 0,2):String(e)).join(` `),a=`[${r}] [${e}] ${i}\n`;this.stream.write(a,e=>{e?this.emit(`error`,e):this.emit(`write`,a)})}};const M=()=>h.join(process.env.APPDATA??``,`overlayed`),N=e=>h.join(M(),`apps`,e),P=e=>h.join(N(e),`logs`);var F=class{fileLogger;path;appId;messageQueue=new T;fileName;constructor(e){this.fileName=e}init(e){this.appId=e,this.path=P(e),this.fileLogger=new j(this.path,this.fileName),this.messageQueue.flush().forEach(e=>{this.fileLogger?.[e.type](...e.args)})}scope(e){if(!this.appId||!this.path)throw Error(`Logger not initialized`);let t=`[${e}]`;return{scope:e=>this.scope(e),error:(...e)=>this.error(t,...e),warn:(...e)=>this.warn(t,...e),info:(...e)=>this.info(t,...e),log:(...e)=>this.log(t,...e)}}error(...e){this.handle(`error`,...e)}warn(...e){this.handle(`warn`,...e)}info(...e){this.handle(`log`,...e)}debug(...e){this.handle(`debug`,...e)}log(...e){this.handle(`log`,...e)}handle(e,...t){console[e](...t),this.fileLogger?this.fileLogger[e](...t):this.messageQueue.add({type:e,args:t})}};D(F,`main.log`);const I=`**/overlayed.config.{js,ts,mts}`;async function L(){let e=z(),t=oe(import.meta.url),n=await Promise.all(e.map(async e=>{if(e.endsWith(`.ts`)){let n=await t.import(e,{default:!0});return n}else{let t=await import(ie.pathToFileURL(e).toString());return t.default}}));return n.filter(R)}function R(e){return C(e)&&`app`in e}function z(){let e=g.globSync(I,{absolute:!0,cwd:process.cwd()});return e}var B=class{pattern;options;constructor(e,t){this.pattern=e,this.options=t}},V=class{patterns=[];addGlobPattern(e,t){let n=this.resolveOptions(t),r=w(e);this.patterns.push(new B(r,n))}async bundle(){let e=new se;for(let t of this.patterns){let n={...t.options},r;r=n.cwd?typeof n.cwd==`string`?n.cwd:ae(n.cwd):process.cwd(),h.isAbsolute(r)||(r=h.resolve(r)),n.absolute=!0,n.cwd=r;let i=await g(t.pattern,n);await Promise.all(i.map(async t=>{let n=h.relative(r,t),i=ee(t,`binary`);e.file(n,i,{compression:`DEFLATE`})}))}return e}resolveOptions(e){return e}},H=class extends Error{constructor(){super(`package.json not found in bundle`),this.name=`PackageJsonNotFoundError`}},U=class extends V{installerFolderGlob=`**/installer/**`;constructor(){super(),this.addGlobPattern(`package.json`)}async bundle(){let e=await super.bundle(),t=e.file(`package.json`);if(!t)throw new H;return e}resolveOptions(e){if(!e)return{ignore:this.installerFolderGlob};let t=typeof e.ignore==`string`?[e.ignore]:e.ignore??[];return t.push(this.installerFolderGlob),e.ignore=t,e}},W=class extends n{static paths=[[`bundle`]];static usage=n.Usage({category:x.deployment,description:`Bundle the app and site for deployment.`,details:`
|
|
2
|
+
import{Builtins as e,Cli as t,Command as n,UsageError as r}from"clipanion";import{scope as i,type as a}from"arktype";import o,{createWriteStream as s,existsSync as ee,mkdirSync as te,readdirSync as ne,unlinkSync as c,writeFileSync as l}from"fs";import{ensureFileSync as u}from"fs-extra";import d,{join as f}from"path";import p from"node:path";import m from"chalk";import{createReadStream as h,existsSync as g,lstatSync as _}from"node:fs";import{glob as v}from"glob";import y,{fileURLToPath as re}from"node:url";import{createJiti as ie}from"jiti";import ae from"jszip";import b,{isXiorError as x}from"xior";import{checkbox as oe,password as se}from"@inquirer/prompts";import{Listr as S}from"listr2";import{ListrInquirerPromptAdapter as ce}from"@listr2/prompt-adapter-inquirer";import{exec as le}from"child_process";import{promisify as ue}from"util";const de={deployment:`deployment`};function C(e){throw e}function w(e){return Object.prototype.toString.call(e)===`[object Object]`}function T(e){return e?Array.isArray(e)?e:[e]:[]}var E=class{data=[];constructor(){}get size(){return this.data.length}add(e){this.data.push(e)}next(){return this.data.shift()}clear(){this.data.length=0}*flush(){for(;this.size>0;){let e=this.next();e&&(yield e)}}};function D(e){return{all:e=e||new Map,on:function(t,n){var r=e.get(t);r?r.push(n):e.set(t,[n])},off:function(t,n){var r=e.get(t);r&&(n?r.splice(r.indexOf(n)>>>0,1):e.set(t,[]))},emit:function(t,n){var r=e.get(t);r&&r.slice().map(function(e){e(n)}),(r=e.get(`*`))&&r.slice().map(function(e){e(t,n)})}}}var O=class{emitter;constructor(){this.emitter=D()}on(e,t){T(e).forEach(e=>{this.emitter.on(e,t)})}off(e,t){T(e).forEach(e=>{this.emitter.off(e,t)})}emit(e,t){T(e).forEach(e=>{this.emitter.emit(e,t)})}removeAllListeners(){this.emitter.all.clear()}};function k(e,...t){let n=class extends e{static _instance;static getInstance(){return this._instance||(this._instance=new e(...t)),this._instance}static clearInstance(){this._instance=void 0}};return n}var A=class extends O{destroy(){this.removeAllListeners()}fatal(e,t,n){this.emit(`fatal`,{code:t,message:e,data:n,timestamp:Date.now()})}error(e,t,n){this.emit(`error`,{code:t,message:e,data:n,timestamp:Date.now()})}warn(e,t,n){this.emit(`warning`,{code:t,message:e,data:n,timestamp:Date.now()})}};const j=k(A);var M=class{data;_schema;_defaultValue;_path;constructor(e){let{schema:t,default:n,path:r}=e;this._schema=t,this._defaultValue=n,this._path=r}set(e){let t=this._schema[`~standard`].validate(e);if(t instanceof Promise)throw Error(`StructuredConfigFile does not support async validation`);if(t.issues){this.reportInvalidConfigFile(t.issues);return}this.data=this.onBeforeSave(e),this.save(e)}get(){return this.data?this.data:this.load()}getKey(e){let t=this.get();return t[e]}save(e){let t=this.onBeforeSave(e);try{u(this.getFilePath()),o.writeFileSync(this.getFilePath(),JSON.stringify(t,void 0,2))}catch{return}return this.data=t}load(){if(!this.fileExists(this.getFilePath())||!this.canReadWriteFile(this.getFilePath())){this.save(this._defaultValue);let e=this.onAfterLoad(this._defaultValue);return this.data=e,e}try{let e=o.readFileSync(this.getFilePath(),`utf8`),t=this.onAfterLoad(this.parseStoredData(e));return this.data=t,t}catch{return this.data=this._defaultValue}}onBeforeSave(e){return e}onAfterLoad(e){return e}getFilePath(){return this._path}parseStoredData(e){try{let t=a(`string.json.parse`).to(`object`),n=t(e);if(n instanceof a.errors)return this._defaultValue;let r=this._schema[`~standard`].validate(n);if(r instanceof Promise)throw Error(`StructuredConfigFile does not support async validation`);return r.issues?this.migrate(n,this._defaultValue):this.migrate(r.value,this._defaultValue)}catch{return this._defaultValue}}canReadWriteFile(e){try{return o.accessSync(e,o.constants.R_OK|o.constants.W_OK),!0}catch{return!1}}fileExists(e){try{return o.accessSync(e,o.constants.F_OK),!0}catch{return!1}}migrate(e,t){let n={...e};for(let r in t){if(!Object.prototype.hasOwnProperty.call(t,r))continue;r in e?e[r]!==null&&t[r]!==null&&typeof e[r]==`object`&&typeof t[r]==`object`&&!Array.isArray(e[r])&&!Array.isArray(t[r])?n[r]=this.migrate(e[r],t[r]):Array.isArray(t[r])&&(n[r]=e[r]):n[r]=t[r]}return n}reportInvalidConfigFile(e){j.getInstance().error(`Invalid config file`,`INVALID_CONFIG_FILE`,{issues:e.map(e=>e.message),filePath:this._path,data:this.data})}},N=class e extends O{stream;logPath;baseFileName;currentDate;rotationCheckInterval;isRotating=!1;constructor(e,t){super(),this.logPath=e,this.baseFileName=t.replace(`.log`,``),this.currentDate=this.getDateString(new Date),this.ensureLogDirectory(),this.ensureLogFile(),this.stream=this.createStream(),this.rotationCheckInterval=this.startRotationCheck(),this.cleanupOldLogs()}static scope(t,n){return new e(t,n)}log(...e){this.write(`log`,...e)}error(...e){this.write(`error`,...e)}warn(...e){this.write(`warn`,...e)}info(...e){this.write(`info`,...e)}debug(...e){this.write(`debug`,...e)}async close(){clearInterval(this.rotationCheckInterval),await new Promise(e=>{this.stream.end(()=>e())})}getCurrentFileName(){return this.getFileName(this.currentDate)}static getMessageElements(e,...t){let n=new Date,r=n.toISOString().replace(`T`,` `).replace(/\.\d+Z$/,``)+`.${n.getMilliseconds().toString().padStart(3,`0`)}`,i=t.map(e=>typeof e==`object`?JSON.stringify(e,void 0,2):String(e)).join(` `);return{timestamp:r,level:e,message:i}}getFileName(e){return`${this.baseFileName}-${e}.log`}ensureLogDirectory(){try{te(this.logPath,{recursive:!0})}catch(e){throw console.error(`Failed to create log directory ${this.logPath}:`,e),e}}ensureLogFile(){let e=f(this.logPath,this.getFileName(this.currentDate));if(!ee(e))try{l(e,``,`utf8`)}catch(t){throw console.error(`Failed to create log file ${e}:`,t),t}}getDateString(e){return e.toISOString().split(`T`)[0]}createStream(){let e=f(this.logPath,this.getFileName(this.currentDate));return s(e,{flags:`a`,encoding:`utf8`})}async rotateLogs(){if(this.isRotating)return;this.isRotating=!0;let e=this.getDateString(new Date);e!==this.currentDate&&await new Promise(t=>{this.stream.end(()=>{this.currentDate=e,this.stream=this.createStream(),this.cleanupOldLogs(),t()})}),this.isRotating=!1}startRotationCheck(){return setInterval(()=>this.rotateLogs(),6e4)}cleanupOldLogs(){let e=ne(this.logPath),t=new Date;t.setDate(t.getDate()-7);let n=e.filter(e=>e.startsWith(this.baseFileName)&&e.endsWith(`.log`)).filter(e=>{let n=e.replace(`${this.baseFileName}-`,``).replace(`.log`,``),r=new Date(n);return r<t});n.forEach(e=>{try{c(f(this.logPath,e))}catch(t){console.error(`Failed to delete old log file ${e}:`,t)}})}write(t,...n){let{timestamp:r,message:i}=e.getMessageElements(t,...n),a=`[${r}] [${t}] ${i}\n`;this.stream.write(a,e=>{e?this.emit(`error`,e):this.emit(`write`,a)})}};const P=()=>p.join(process.env.APPDATA??``,`overlayed`),F=e=>p.join(P(),`apps`,e),I=e=>p.join(F(e),`logs`);var L=class{fileLogger;path;appId;messageQueue=new E;fileName;_debug=!1;silent=!1;constructor(e){this.fileName=e}init(e,t=!1,n=!1){this.appId=e,this._debug=t,this.silent=n,this.path=I(e),this.fileLogger=new N(this.path,this.fileName),this.messageQueue.flush().forEach(e=>{this.fileLogger?.[e.type](...e.args)})}scope(e){if(!this.appId||!this.path)throw Error(`Logger not initialized`);let t=`[${e}]`;return{scope:e=>this.scope(e),error:(...e)=>this.error(t,...e),warn:(...e)=>this.warn(t,...e),info:(...e)=>this.info(t,...e),log:(...e)=>this.log(t,...e),debug:(...e)=>this.debug(t,...e)}}error(...e){this.handle(`error`,...e)}warn(...e){this.handle(`warn`,...e)}info(...e){this.handle(`log`,...e)}debug(...e){this._debug&&this.handle(`debug`,...e)}log(...e){this.handle(`log`,...e)}handle(e,...t){this.logToConsole(e,...t),this.fileLogger?this.fileLogger[e](...t):this.messageQueue.add({type:e,args:t})}logToConsole(e,...t){let n={error:m.red,warn:m.yellow,debug:m.blue,log:m.white};if(this.silent&&!this._debug)return;let{timestamp:r,message:i}=N.getMessageElements(e,...t),a=console[e],o=n[e];a(`${m.gray(r)} ${o(i)}`)}};k(L,`overlayed.log`);const R=`**/overlayed.config.{js,ts,mts}`;async function z(){let e=V(),t=ie(import.meta.url),n=await Promise.all(e.map(async e=>{if(e.endsWith(`.ts`)){let n=await t.import(e,{default:!0});return[n,e]}else{let t=await import(y.pathToFileURL(e).toString());return[t.default,e]}}));return n.filter(([e])=>B(e)).map(([e,t])=>[e,t])}function B(e){return w(e)&&`app`in e}function V(){let e=v.globSync(R,{absolute:!0,cwd:process.cwd()});return e}var H=class{pattern;options;constructor(e,t){this.pattern=e,this.options=t}},U=class{defaultIgnore=[`overlayed.config.ts`];patterns=[];addGlobPattern(e,t){let n=this.resolveOptions(t),r=T(e);this.patterns.push(new H(r,n))}async bundle(){let e=new ae;for(let t of this.patterns){let n={...t.options},r;r=n.cwd?typeof n.cwd==`string`?n.cwd:re(n.cwd):process.cwd(),p.isAbsolute(r)||(r=p.resolve(r)),n.absolute=!0,n.cwd=r;let i=await v(t.pattern,n);await Promise.all(i.map(async t=>{if(!g(t)){let n=p.relative(r,t);e.file(n,``,{compression:`DEFLATE`});return}if(_(t).isDirectory()){let i=await v(t+`/**`,n);await Promise.all(i.map(async t=>{if(!g(t)||_(t).isDirectory())return;let n=p.relative(r,t),i=h(t,`binary`);e.file(n,i,{compression:`DEFLATE`})}));return}let i=p.relative(r,t),a=h(t,`binary`);e.file(i,a,{compression:`DEFLATE`})}))}return e}resolveOptions(e){return{...e,ignore:[...T(e?.ignore),...this.defaultIgnore]}}},fe=class extends Error{constructor(){super(`package.json not found in bundle`),this.name=`PackageJsonNotFoundError`}},pe=class extends U{defaultIgnore=[`overlayed.config.ts`,`**/installer/**`];constructor(){super(),this.addGlobPattern(`package.json`)}async bundle(){let e=await super.bundle(),t=e.file(`package.json`);if(!t)throw new fe;return e}};const me=b.create({baseURL:`https://updater.stats.cc`,headers:{Accept:`application/json`,"Accept-Encoding":`gzip, deflate, br`}});me.interceptors.request.use(e=>e);const W=b.create({baseURL:`https://api.overlayed.gg`,headers:{Accept:`application/json`,"Accept-Encoding":`gzip, deflate, br`}});let G;function K(e){G=e}W.interceptors.request.use(e=>{let t=G?.();return e.headers??={},t&&(e.headers[`X-Api-Key`]=t),e});function he(e){return e}function q(e){return e?t=>(e(t),t):he}q(),q();function ge(e,t){return W.post(`/v1/applications/${e}/bundles/upload`,t)}function _e(e,t){return W.post(`/v1/applications/${e}/bundles/queue`,{name:t})}function ve(e,t){return W.put(e,t,{headers:{"Content-Type":`application/zip`,"Content-Length":t.length}})}q();const ye=q();q();function J(){return W.get(`/v1/auth/me`)}q();const be=d.normalize(`${process.env.APPDATA||process.env.HOME||`.`}/.overlayed/config.json`),xe=i({Account:a({email:`string`,apiKey:`string`})}),Se=xe.type({currentAccount:`Account | undefined`,accounts:`Account[]`}).or(`undefined`),Y=new M({path:be,default:void 0,schema:Se});async function X(){let e=Y.get();if(!e?.currentAccount)throw new r(`Not authenticated. Run 'overlayed login' to authenticate.`);try{let e=await J(),t=e.data.email;return t}catch(e){if(!x(e))throw e;let t=e.response?.status;switch(t){case 401:case 403:throw new r(`Authentication failed. Your API key may be invalid or expired. Run 'overlayed login' to re-authenticate.`);default:throw Error(`API error occurred. Please try again later.`)}}}async function Ce(e){let t=await z();if(t.length===0)throw new r(`No config file found matching `+R);return t.length>1&&e.stdout.write(m.yellow(`
|
|
3
|
+
Multiple config files found matching ${R}, using the first one.
|
|
4
|
+
`)),t.at(0)}var we=class extends n{static paths=[[`bundle`]];static usage=n.Usage({category:de.deployment,description:`Bundle the app and site for deployment.`,details:`
|
|
3
5
|
Bundle the app and site for deployment.
|
|
4
6
|
|
|
5
7
|
[Docs](http://docs.overlayed.gg/cli/bundle)
|
|
6
|
-
`,examples:[[`Basic usage`,`$0 bundle`]]});async execute(){let e=await this.resolveConfig(),t
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
`,examples:[[`Basic usage`,`$0 bundle`]]});async execute(){await X();let e=new S([{title:`Authenticating`,task:X},{title:`Locating overlayed.config.ts`,task:async e=>e.config=await this.resolveConfig()},{task:async(e,t)=>{let n=await t.prompt(ce).run(...this.getTargetBundles(e.config));e.targetBundles=n,this.context.stdout.write(m.green(`Selected bundles: `)+m.bold(n.join(`, `)))}}]),t=await e.run(),n=new S([{title:`Uploading bundles`,task:e=>new S(e.targetBundles.map((e,t)=>({title:`Uploading ${e} bundle`,task:async n=>{let r=await this.uploadBundle(n.config,e);n.taskIds??=[],n.taskIds[t]=r}})),{concurrent:!0,rendererOptions:{collapseSubtasks:!1}})},{title:`Waiting for bundles to be processed`,task:e=>new S(e.taskIds.map((t,n)=>({title:`Waiting for ${m.bold(e.targetBundles[n])} bundle to be processed. This may take some time - you can wait for the bundle to appear in the dashboard here: ${m.blue(`https://dashboard.overlayed.gg/applications/${e.config.applicationId}/bundles?taskId=${t}`)}`,task:async()=>{await new Promise(e=>setTimeout(e,3e3))}})),{concurrent:!0,rendererOptions:{collapseSubtasks:!1}})}]);await n.run(t)}async uploadBundle(e,t){let n=await ge(e.applicationId,{type:t}),r=await e[t]?.bundle()??C(Error(`No bundle found for `+t)),i=await r.generateAsync({type:`nodebuffer`});await ve(n.data.upload_url,i);let a=await _e(e.applicationId,n.data.asset_bundle_name);return a.data.task_id}getTargetBundles(e){let t=e=>`(Disabled: No config found for "${e}" in overlayed.config.ts)`;return[oe,{message:`Select your desired bundles to create and upload.`,shortcuts:{all:`a`,invert:`i`},choices:[{name:`App`,value:`app`,disabled:e.app?void 0:t(`app`)},{name:`Site`,value:`site`,disabled:e.site?void 0:t(`site`)}]}]}async resolveConfig(){let[e,t]=await Ce(this.context);return{applicationId:ye(e.applicationId),app:this.getAppBundler(e,t),site:this.getSiteBundler(e,t)}}getAppBundler(e,t){let n=new pe;return n.addGlobPattern(e.app.include,{ignore:e.app.exclude,cwd:d.dirname(t)}),n}getSiteBundler(e,t){if(!e.site)return;let n=new U;return n.addGlobPattern(e.site.include,{ignore:e.site.exclude,cwd:d.dirname(t)}),n}async catch(e){if(x(e)){let t=e.response?.status,n=(e.config?.baseURL??``)+(e.config?.url??``);throw Error(`Request to ${n} failed with status ${t}. ${e.response?.data}`)}throw e}};function Te(e){return`https://dashboard.overlayed.gg${e}`}const Z={normal:Ee,success:De,error:Oe,warning:ke,info:Ae};function Ee(...e){return m.gray(e,`
|
|
9
|
+
`)}function De(...e){return[m.green(`✔`),...e,`
|
|
10
|
+
`].join(` `)}function Oe(...e){return[m.red(`✘`),...e,`
|
|
11
|
+
`].join(` `)}function ke(...e){return[m.yellow(`⚠`),...e,`
|
|
12
|
+
`].join(` `)}function Ae(...e){return[m.blue(`ℹ`),...e,`
|
|
13
|
+
`].join(` `)}const je=ue(le);var Q=class extends n{static paths=[[`login`]];static usage=n.Usage({description:`Authenticate with the Overlayed platform.`,details:`
|
|
9
14
|
Authenticate with the Overlayed platform.
|
|
10
|
-
`,examples:[[`Basic usage`,`$0 login`]]});async execute(){let e=
|
|
15
|
+
`,examples:[[`Basic usage`,`$0 login`]]});async execute(){let e=Te(`/settings/api-keys`);await this.openUrl(e);let t=await se({message:`To authenticate, you'll need an API Key. We've opened the page to create one in your browser.\n\n${Z.info(e)}\n\nOnce you have it, enter it here:`,async validate(e){K(()=>e);try{let t=await J(),n=t.data.email,r={email:n,apiKey:e},i=Y.get();Y.set({...i,currentAccount:r,accounts:i?.accounts.concat(r)??[r]})}catch(e){if(!x(e))return`Unknown error has occurred: ${e}`;let t=e.response?.status;switch(t){case 401:case 403:return`Invalid API key, please try again.`;default:return`API error, please try again later.`}}return K(()=>Y.get()?.currentAccount?.apiKey),!0}});if(!t)throw Error(`Login unknown error - this should never happen`);let n=Y.get();if(!n?.currentAccount)throw Error(`Could not get config after login`);let r=n.currentAccount.email;this.context.stdout.write(Z.success(`Authentication Complete - Logged in as ${r}`))}async openUrl(e){let t=process.platform,n;switch(t){case`darwin`:n=`open "${e}"`;break;case`win32`:n=`start "" "${e}"`;break;default:n=`xdg-open "${e}"`;break}try{await je(n)}catch{}}},Me=class extends n{static paths=[[`logout`]];static usage=n.Usage({description:`Log out of the currently authenticated account.`,details:`
|
|
11
16
|
Log out of the currently authenticated account.
|
|
12
|
-
`,examples:[[`Basic usage`,`$0 logout`]]});async execute(){let e=
|
|
13
|
-
`));return}let{currentAccount:t}=e,n=t.email,r=e.accounts.filter(e=>e.email!==t.email);Q.set({...e,currentAccount:void 0,accounts:r}),this.context.stdout.write(`Logged out from ${i.bold(n)}\n`)}},ye=class extends n{static paths=[[`whoami`]];static usage=n.Usage({description:`Display information about the currently authenticated user.`,details:`
|
|
17
|
+
`,examples:[[`Basic usage`,`$0 logout`]]});async execute(){let e=await X(),t=Y.get();if(!t){this.context.stdout.write(Z.normal(`Not currently logged in.`));return}let n=t.accounts.filter(t=>t.email!==e);Y.set({...t,currentAccount:void 0,accounts:n}),this.context.stdout.write(Z.normal(`Logged out from ${e}`))}},Ne=class extends n{static paths=[[`whoami`]];static usage=n.Usage({description:`Display information about the currently authenticated user.`,details:`
|
|
14
18
|
Display information about the currently authenticated user.
|
|
15
19
|
|
|
16
20
|
[Docs](http://docs.overlayed.gg/cli/whoami)
|
|
17
|
-
`,examples:[[`Basic usage`,`$0 whoami`]]});async execute(){let e=
|
|
18
|
-
`));return}try{let e=await X(),t=e.data.email;this.context.stdout.write(`Logged in as ${i.bold(t)}\n`)}catch(e){if(!v(e)){this.context.stderr.write(i.red(`Unknown error occurred: ${e}\n`));return}let t=e.response?.status;switch(t){case 401:case 403:this.context.stderr.write(i.red(`Authentication failed. Your API key may be invalid or expired. Run 'overlayed login' to re-authenticate.
|
|
19
|
-
`));break;default:this.context.stderr.write(i.red(`API error occurred. Please try again later.
|
|
20
|
-
`));break}}}};const be=process.argv.slice(2),$=new t({binaryName:`overlayed`,binaryLabel:`Overlayed`});[W,_e,ve,ye,e.HelpCommand].forEach(e=>{$.register(e)}),J(()=>Q.get()?.currentAccount?.apiKey),$.runExit(be);
|
|
21
|
+
`,examples:[[`Basic usage`,`$0 whoami`]]});async execute(){let e=await X();this.context.stdout.write(Z.normal(`Logged in as ${e}`))}};const Pe=process.argv.slice(2),$=new t({binaryName:`overlayed`,binaryLabel:`Overlayed`});[we,Q,Me,Ne,e.HelpCommand].forEach(e=>{$.register(e)}),K(()=>Y.get()?.currentAccount?.apiKey),$.runExit(Pe);export{};
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"keywords": [
|
|
11
11
|
"typescript"
|
|
12
12
|
],
|
|
13
|
-
"version": "0.
|
|
13
|
+
"version": "0.3.1",
|
|
14
14
|
"description": "Overlayed CLI",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"bin": {
|
|
@@ -23,24 +23,26 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@ark/attest": "^0.
|
|
26
|
+
"@ark/attest": "^0.48.2",
|
|
27
27
|
"@types/fs-extra": "^11.0.4",
|
|
28
|
-
"tsdown": "^0.
|
|
29
|
-
"typescript": "^5.
|
|
30
|
-
"vitest": "^3.
|
|
28
|
+
"tsdown": "^0.14.2",
|
|
29
|
+
"typescript": "^5.9.2",
|
|
30
|
+
"vitest": "^3.2.4",
|
|
31
31
|
"@overlayed/api": "0.0.3",
|
|
32
32
|
"@overlayed/utils": "0.0.3",
|
|
33
33
|
"@overlayed/utils-node": "0.0.3"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@inquirer/prompts": "^7.
|
|
36
|
+
"@inquirer/prompts": "^7.8.4",
|
|
37
|
+
"@listr2/prompt-adapter-inquirer": "^3.0.1",
|
|
37
38
|
"arktype": "^2.1.20",
|
|
38
|
-
"chalk": "^5.
|
|
39
|
+
"chalk": "^5.6.0",
|
|
39
40
|
"clipanion": "4.0.0-rc.4",
|
|
40
|
-
"fs-extra": "^11.3.
|
|
41
|
+
"fs-extra": "^11.3.1",
|
|
41
42
|
"glob": "^11.0.3",
|
|
42
|
-
"jiti": "^2.
|
|
43
|
+
"jiti": "^2.5.1",
|
|
43
44
|
"jszip": "^3.10.1",
|
|
45
|
+
"listr2": "^9.0.1",
|
|
44
46
|
"xior": "^0.7.8"
|
|
45
47
|
},
|
|
46
48
|
"engines": {
|