@overlayed/cli 1.0.1 → 1.0.2
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/dist/cli.mjs +10 -10
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as e}from"@commander-js/extra-typings";import{scope as t,type as n}from"arktype";import r,{createWriteStream as i,existsSync as a,mkdirSync as o,
|
|
3
|
-
`].join(` `))}function
|
|
4
|
-
`].join(` `)}function
|
|
5
|
-
`].join(` `)}function
|
|
6
|
-
`].join(` `)}function
|
|
7
|
-
`].join(` `)}async function
|
|
2
|
+
import{Command as e}from"@commander-js/extra-typings";import{scope as t,type as n}from"arktype";import r,{createWriteStream as i,existsSync as a,mkdirSync as o,readFileSync as s,readdirSync as c,unlinkSync as ee,writeFileSync as l}from"fs";import{ensureDirSync as u,ensureFileSync as te}from"fs-extra";import d,{join as ne}from"path";import*as f from"node:path";import p from"node:path";import m from"picocolors";import*as h from"node:fs";import re,{createReadStream as ie,existsSync as g,lstatSync as ae,readFileSync as oe}from"node:fs";import{glob as _}from"glob";import se,{fileURLToPath as ce}from"node:url";import{createJiti as le}from"jiti";import ue,{isXiorError as v}from"xior";import de from"update-notifier";import{readdir as y}from"node:fs/promises";import fe from"jszip";import{checkbox as pe,input as me,password as he}from"@inquirer/prompts";import{Listr as b}from"listr2";import{ListrInquirerPromptAdapter as x}from"@listr2/prompt-adapter-inquirer";import{exec as ge,execSync as _e}from"child_process";import{promisify as S}from"util";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]:[]}function E(e){return{all: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 D=class{emitter;constructor(){this.emitter=E()}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 O(e,...t){return class extends e{static _instance;static getInstance(){return this._instance||=new e(...t),this._instance}static clearInstance(){this._instance=void 0}}}const k=O(class extends D{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()})}});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(e={}){return this.data?this.data:this.load(e)}getKey(e,t={}){return this.get(t)[e]}save(e){let t=this.onBeforeSave(e);try{te(this.getFilePath()),r.writeFileSync(this.getFilePath(),JSON.stringify(t,void 0,2))}catch{return}return this.data=t}load(e={}){let{createIfMissing:t=!0}=e;if(!this.fileExists(this.getFilePath())||!this.canReadWriteFile(this.getFilePath())){t&&this.save(this._defaultValue);let e=this.onAfterLoad(this._defaultValue);return t&&(this.data=e),e}try{let e=r.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=n(`string.json.parse`).to(`object`)(e);if(t instanceof n.errors)return this._defaultValue;let r=this._schema[`~standard`].validate(t);if(r instanceof Promise)throw Error(`StructuredConfigFile does not support async validation`);return r.issues?this.migrate(t,this._defaultValue):this.migrate(r.value,this._defaultValue)}catch{return this._defaultValue}}canReadWriteFile(e){try{return r.accessSync(e,r.constants.R_OK|r.constants.W_OK),!0}catch{return!1}}fileExists(e){try{return r.accessSync(e,r.constants.F_OK),!0}catch{return!1}}migrate(e,t){let n={...e};for(let r in t)Object.prototype.hasOwnProperty.call(t,r)&&(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})}};const j=`**/overlayed.config.{js,ts,mts}`;async function M(){let e=P(),t=le(import.meta.url);return(await Promise.all(e.map(async e=>e.endsWith(`.ts`)?[await t.import(e,{default:!0}),e]:[(await import(se.pathToFileURL(e).toString())).default,e]))).filter(([e])=>N(e)).map(([e,t])=>[e,t])}function N(e){return w(e)&&`app`in e}function P(){return _.globSync(j,{absolute:!0,cwd:process.cwd()})}function F(e,t){let n=t?.cwd??process.cwd(),r=f.join(n,`.overlayed`);h.existsSync(r)||h.mkdirSync(r,{recursive:!0});let i={application:{id:e.id,name:e.name,slug:e.slug,siteUrl:e.siteUrl},release:{id:null,channel:`local`,version:`0.0.0`}},a=f.join(r,`meta.json`);return h.writeFileSync(a,JSON.stringify(i,null,2)),i}const I=new A({path:d.normalize(`${process.env.APPDATA||process.env.HOME||`.`}/.overlayed/config.json`),default:void 0,schema:t({Account:n({email:`string`,apiKey:`string`})}).type({currentAccount:`Account | undefined`,accounts:`Account[]`}).or(`undefined`)}),L=ue.create({baseURL:`https://api.overlayed.gg`,headers:{Accept:`application/json`,"Accept-Encoding":`gzip, deflate, br`}});let R;function z(e){R=e}L.interceptors.request.use(e=>{let t=R?.();return e.headers??={},t&&(e.headers[`X-Api-Key`]=t),e});function ve(e){return e}function ye(e){return e?t=>(e(t),t):ve}function be(e,t){return L.post(`/v1/applications/${e}/bundles/jobs/upload`,t)}function xe(e,t){return L.post(`/v1/applications/${e}/bundles/jobs/confirm`,{name:t})}function Se(e,t){return L.get(`/v1/applications/${e}/bundles/jobs/${t}`)}const B=ye();function Ce(e){return L.get(`/v1/public/applications/${e}`)}function V(){return L.get(`/v1/auth/me`)}async function we(e,t){if(e.method!==`PUT`)throw Error(`Unsupported presigned request method: ${e.method}`);let n=await fetch(e.url,{method:e.method,headers:{...e.headers,"Content-Length":t.byteLength.toString()},body:t});if(!n.ok){let e=await Te(n);throw Error(`Presigned upload failed (${n.status} ${n.statusText})${e?`: ${e}`:``}`)}}async function Te(e){try{let t=(await e.text()).trim();if(t.length===0)return;let n=2048;return t.length>n?`${t.slice(0,n)}…`:t}catch{return}}var Ee=class{pattern;options;constructor(e,t){this.pattern=e,this.options=t}},H=class{defaultIgnore=[`overlayed.config.ts`];patterns=[];constructor(e){this.config=e}addGlobPattern(e,t){let n=this.resolveOptions(t),r=T(e);this.patterns.push(new Ee(r,n))}async bundle(){let e=new fe;for(let t of this.patterns){let n={...t.options},r;r=n.cwd?typeof n.cwd==`string`?n.cwd:ce(n.cwd):process.cwd(),p.isAbsolute(r)||(r=p.resolve(r)),n.absolute=!0,n.cwd=r;let i=await _(t.pattern,n),a=await this.getFilesPathsFromPaths(i);await Promise.all(a.map(async t=>{await this.zipFile(r,e,t)}))}return e}async validateFilePath(e){return Promise.resolve(!0)}async zipFile(e,t,n){let r=p.relative(e,n);if(r=r.replace(/^(\.\.\\|\.\.\/)+/,``),!g(n)){t.file(r,``,{compression:`DEFLATE`});return}if(!await this.validateFilePath(n))return;let i=ie(n,`binary`);t.file(r,i,{compression:`DEFLATE`})}resolveOptions(e){return{...e,ignore:[...T(e?.ignore),...this.defaultIgnore]}}async getFilesPathsFromPaths(e){return Promise.all(e.map(async e=>await this.getFilePathsFromPathRecursive(e))).then(e=>e.flat())}async getFilePathsFromPathRecursive(e){if(!g(e)||!ae(e).isDirectory())return[e];let t=await y(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=p.join(e,t.name);return t.isDirectory()?await this.getFilePathsFromPathRecursive(n):[n]}))).flat()}},U=class extends Error{constructor(e){super(e),this.name=`CLIError`}},De=class extends H{defaultIgnore=[`overlayed.config.ts`,`**/installer/**`];mainFile;constructor(e){super(e),this.addGlobPattern(`package.json`),this.addGlobPattern(`node_modules/@overlayed/app`)}async bundle(){let e=await super.bundle();return await this.validateZip(e),e}async validateFilePath(e){return e.endsWith(`package.json`)&&!e.includes(`node_modules`)&&await this.validatePackageJson(e),!0}async validateZip(e){await Promise.all([this.validateNoInstallFolder(e),this.validateMainFile(e),this.validateNoReservedFiles(e)])}async validatePackageJson(e){if(!e)throw new W;let t=re.readFileSync(e,`utf-8`),r=n(`string.json.parse`).to({main:`string`,devDependencies:{"@overlayed/electron":`string`}})(t);if(r instanceof n.errors)throw new Oe(r.summary);this.mainFile=r.main}async validateMainFile(e){if(!this.mainFile)throw new W;if(!e.file(d.normalize(this.mainFile)))throw new ke(this.mainFile)}async validateNoInstallFolder(e){let t=e.folder(`install`);if(t&&t.length>0)throw new G}async validateNoReservedFiles(e){for(let t of[`meta.json`,`app-update.yml`])if(e.file(t))throw new Ae(t)}},W=class extends U{constructor(){super(`package.json not found in bundle`),this.name=`PackageJsonNotFoundError`}},Oe=class extends U{constructor(e){super(`package.json is invalid: ${e}`),this.name=`PackageJsonInvalidError`}},ke=class extends U{constructor(e){super(`referenced package.json main file ${e} not found in bundle`),this.name=`MainFileNotFoundError`}},G=class extends U{constructor(){super("folder `install` found in bundle is not allowed and is reserved for the installer"),this.name=`InstallFolderFoundError`}},Ae=class extends U{constructor(e){super(`file \`${e}\` found in bundle is not allowed and is reserved for internal use`),this.name=`ReservedFileFoundError`}};const K=new class{write(e){process.stdout.write(e)}error(e){process.stderr.write(e)}},q={normal:je,success:Me,error:Ne,warning:Pe,info:Fe};function je(...e){return m.gray([...e,`
|
|
3
|
+
`].join(` `))}function Me(...e){return[m.green(`✔`),...e,`
|
|
4
|
+
`].join(` `)}function Ne(...e){return[m.red(`✘`),...e,`
|
|
5
|
+
`].join(` `)}function Pe(...e){return[m.yellow(`⚠`),...e,`
|
|
6
|
+
`].join(` `)}function Fe(...e){return[m.blue(`ℹ`),...e,`
|
|
7
|
+
`].join(` `)}async function J(){let e=process.env.OVERLAYED_API_KEY,t=I.get();if(e&&t?.currentAccount&&K.write(q.warning(`Using OVERLAYED_API_KEY environment variable instead of stored credentials.`)),!e&&!t?.currentAccount)throw new U(`Not authenticated. Run 'overlayed login' or set OVERLAYED_API_KEY.`);try{return(await V()).data.email}catch(t){if(!v(t))throw t;switch(t.response?.status){case 401:case 403:throw e?new U(`Authentication failed. Your OVERLAYED_API_KEY may be invalid or expired.`):new U(`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 Y(){let e=await M();if(e.length===0)throw new U(`No config file found matching `+j);return e.length>1&&K.write(m.yellow(`
|
|
8
8
|
Multiple config files found matching ${j}, using the first one.
|
|
9
|
-
`)),e.at(0)}var
|
|
9
|
+
`)),e.at(0)}var Ie=class extends H{defaultIgnore=[`overlayed.config.ts`];constructor(e){super(e)}async bundle(){let e=await super.bundle();if(!Object.keys(e.files).some(e=>e.endsWith(`.html`)))throw new Le;return e}},Le=class extends Error{constructor(){super(`Site bundle must contain at least one HTML file`)}};async function Re(e={}){await J();try{await ze(e)}catch(e){if(e instanceof U&&process.exit(1),v(e)){let t=e.response?.status;throw new U(`Request to ${(e.config?.baseURL??``)+(e.config?.url??``)} failed with status ${t}. ${JSON.stringify(e.response?.data,null,2)}`)}throw e}}async function ze(e){let t=await new b([{title:`Locating overlayed.config.ts`,task:async t=>t.config=await He(e)},{task:async(t,n)=>{if(e.app||e.site){let n=[];if(e.app&&(t.config.app?n.push(`app`):K.write(q.warning(`${m.bold(`--app`)} flag provided but no app config found in overlayed.config.ts`))),e.site&&(t.config.site?n.push(`site`):K.write(q.warning(`${m.bold(`--site`)} flag provided but no site config found in overlayed.config.ts`))),n.length===0)throw Error(`No valid bundles selected. Ensure the selected bundle types have valid config in overlayed.config.ts`);t.targetBundles=n,K.write(m.green(`Selected bundles: `)+m.bold(n.join(`, `)))}else{let e=await n.prompt(x).run(...Ve(t.config));t.targetBundles=e,K.write(m.green(`Selected bundles: `)+m.bold(e.join(`, `)))}}},{task:async(t,n)=>{t.bundleNames={};for(let r of t.targetBundles){let i=r===`app`?e.app:e.site;if(typeof i==`string`)t.bundleNames[r]=i;else if(e.wait===!1)t.bundleNames[r]=void 0;else{let e=await n.prompt(x).run(me,{message:`Enter a name for the ${r} bundle (leave empty for random name):`});t.bundleNames[r]=e.trim()||void 0}}},rendererOptions:{persistentOutput:!0}}]).run();function n(e,t){let n=new URL(`https://overlay.dev/deployments/jobs`);n.searchParams.set(`applicationId`,e);for(let e of t)n.searchParams.append(`jobId`,e);return n.toString()}let r=await new b([{title:`Uploading bundles`,task:e=>new b(e.targetBundles.map((e,t)=>({title:`Uploading ${e} bundle`,task:async n=>{n.jobIds??=[];let r=n.bundleNames[e],i=await Be(n.config,e,r);i&&(n.jobIds[t]=i.id)}})),{concurrent:!0,rendererOptions:{collapseSubtasks:!1}})},{title:`Waiting for bundles to be processed.`,task:t=>{if(e.wait===!1){if(t.jobIds.length>0){let e=n(t.config.applicationId,t.jobIds);K.write(m.yellow(`Skipping wait. Check bundle status in the dashboard: `)+m.blue(e))}return}return new b(t.jobIds.map((e,r)=>({title:`Waiting for ${m.bold(t.targetBundles[r])} bundle to be processed. This may take a couple minutes - you can wait for the bundles to appear in the dashboard here: ${m.blue(n(t.config.applicationId,t.jobIds))}`,task:async(t,i)=>{let a=0,o=t.targetBundles[r],s=n(t.config.applicationId,t.jobIds),c;for(;;){if(a++>100){i.title=`${m.red(`Timeout`)} - ${m.bold(o)} bundle processing is taking longer than expected. Check the dashboard: ${m.blue(s)}`;return}c=await Se(t.config.applicationId,e);let n=c.data.status;if(n===`completed`){i.title=`${m.green(`Completed`)} - ${m.bold(o)} bundle has been processed successfully.`;break}if(n===`failed`){i.title=`${m.red(`Failed`)} - ${m.bold(o)} bundle processing failed.`;break}n===`pending`?i.title=`${m.yellow(`Queued`)} - ${m.bold(o)} bundle is queued for processing. Dashboard: ${m.blue(s)}`:n===`running`&&(i.title=`${m.green(`Running`)} - ${m.bold(o)} bundle is being processed. Dashboard: ${m.blue(s)}`),await new Promise(e=>setTimeout(e,3e3))}if(c.data.status===`failed`){let e=`An unknown error occurred.`;c.data.runs.length>0&&(e=c.data.runs[c.data.runs.length-1].error_message??e),i.title=`${m.red(`Failed`)} - ${m.bold(o)} bundle processing failed: ${e}`}}})),{concurrent:!0,exitOnError:!1,rendererOptions:{collapseSubtasks:!1}})}}]).run(t);if(r.jobIds.length>0){let e=n(r.config.applicationId,r.jobIds);K.write(``),K.write(m.green(`Bundle dashboard: `)+m.blue(e))}}async function Be(e,t,n){let r=(e.resolveCommitHash??qe)(),i;if(t===`app`){let{appPackageVersion:a,electronPackageVersion:o}=Ge(e.configPath,e.rawConfig);i={type:t,name:n,commit_hash:r,app_package_version:a,electron_package_version:o}}else i={type:t,name:n,commit_hash:r};let a=await be(e.applicationId,i),o=await e[t]?.bundle()??C(Error(`No bundle found for `+t));e.debug&&o.forEach(e=>{console.log(`Zipping: `,e)});let s=await o.generateAsync({type:`nodebuffer`});if(e.debug){let e=`.overlayed/tmp`;u(e),l(`${e}/debug-${t}.zip`,s);return}return await we(a.data.upload_request,s),(await xe(e.applicationId,a.data.asset_bundle_name)).data}function Ve(e){let t=e=>`(Disabled: No config found for "${e}" in overlayed.config.ts)`;return[pe,{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 function He(e){let[t,n]=await Y();return{...t,applicationId:B(t.applicationId),configPath:n,rawConfig:t,resolveCommitHash:t.resolveCommitHash,app:Ue(t,n,e),site:We(t,n,e),debug:e.debug}}function Ue(e,t,n){let r=new De(e),i=X(t,e.app.baseDir);return n.debug&&console.log(`[App] Bundling files from: `,i),r.addGlobPattern(e.app.include,{ignore:e.app.exclude,cwd:i}),r}function We(e,t,n){if(!e.site)return;let r=new Ie(e),i=X(t,e.site.baseDir);return n.debug&&console.log(`[Site] Bundling files from: `,i),r.addGlobPattern(e.site.include,{ignore:e.site.exclude,cwd:i}),r}function X(e,t){return t?d.resolve(d.dirname(e),t):d.dirname(e)}function Ge(e,t){let n=X(e,t.app.baseDir),r=t.app.resolvePackageVersion??((e,n)=>Ke(n,e,t.app.nodeModulesDir));return{appPackageVersion:r(`@overlayed/app`,n),electronPackageVersion:r(`@overlayed/electron`,n)}}function Ke(e,t,n){let r=d.resolve(e,n??`node_modules`,...t.split(`/`),`package.json`);try{let e=JSON.parse(s(r,`utf-8`)).version;if(typeof e!=`string`)throw new U(`Could not determine installed ${t} version`);return e}catch(e){throw e instanceof U?e:new U(`Could not read installed ${t} package at ${r}`)}}function qe(){try{return _e(`git rev-parse HEAD`,{encoding:`utf-8`}).trim()}catch{return}}const Je=new e(`bundle`).description(`Bundle the app and site for deployment.`).addHelpText(`after`,`
|
|
10
10
|
Documentation:
|
|
11
11
|
http://docs.overlayed.gg/cli/bundle
|
|
12
|
-
`).helpCommand(`overlayed bundle`).option(`--debug`,`Enable debug mode`,!1).option(`--app [name]`,`Bundle the app (optional: provide a custom name, random if omitted)`).option(`--site [name]`,`Bundle the site (optional: provide a custom name, random if omitted)`).option(`--no-wait`,`Skip waiting for bundle processing to complete`).action(
|
|
12
|
+
`).helpCommand(`overlayed bundle`).option(`--debug`,`Enable debug mode`,!1).option(`--app [name]`,`Bundle the app (optional: provide a custom name, random if omitted)`).option(`--site [name]`,`Bundle the site (optional: provide a custom name, random if omitted)`).option(`--no-wait`,`Skip waiting for bundle processing to complete`).action(Re);async function Ye(){await J();let[e]=await Y(),t=F({...(await Ce(B(e.applicationId))).data,siteUrl:``});K.write(q.success(`Initialized development environment for ${t.application.name}`))}const Xe=new e(`init`).description(`Initialize the local development environment.`).action(Ye);function Ze(e){return`https://overlay.dev${e}`}const Qe=S(ge);async function $e(){let e=Ze(`/user-settings/api-keys?cli=true`);if(await et(e),!await he({message:`To authenticate, you'll need an API Key. We've opened the page to create one in your browser.\n\n${q.info(e)}\n\nOnce you have it, enter it here:`,async validate(e){z(()=>e);try{let t={email:(await V()).data.email,apiKey:e},n=I.get();I.set({...n,currentAccount:t,accounts:n?.accounts.concat(t)??[t]})}catch(e){if(!v(e))return`Unknown error has occurred: ${e}`;switch(e.response?.status){case 401:case 403:return`Invalid API key, please try again.`;default:return`API error, please try again later.`}}return z(()=>I.get()?.currentAccount?.apiKey),!0}}))throw Error(`Login unknown error - this should never happen`);let t=I.get();if(!t?.currentAccount)throw Error(`Could not get config after login`);let n=t.currentAccount.email;K.write(q.success(`Authentication Complete - Logged in as ${n}`))}async function et(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 Qe(n)}catch{}}const tt=new e(`login`).description(`Authenticate with the Overlayed platform.`).helpCommand(`overlayed login`).action($e);async function nt(){let e=await J(),t=I.get();if(!t){K.write(q.normal(`Not currently logged in.`));return}let n=t.accounts.filter(t=>t.email!==e);I.set({...t,currentAccount:void 0,accounts:n}),K.write(q.normal(`Logged out from ${e}`))}const rt=new e(`logout`).description(`Log out of the currently authenticated account.`).helpCommand(`overlayed logout`).action(nt);async function it(){let e=await J();return K.write(q.normal(`Logged in as ${e}`)),e}const at=new e(`whoami`).description(`Display information about the currently authenticated user.`).addHelpText(`after`,`
|
|
13
13
|
Documentation:
|
|
14
14
|
http://docs.overlayed.gg/cli/whoami
|
|
15
|
-
`).helpCommand(`overlayed whoami`).action(()=>{
|
|
15
|
+
`).helpCommand(`overlayed whoami`).action(()=>{it()});let Z=null;function ot(){if(Z)return Z;try{let e=new URL(`../package.json`,import.meta.url),t=JSON.parse(oe(e,`utf8`));if(typeof t==`object`&&t&&`name`in t&&`version`in t&&typeof t.name==`string`&&typeof t.version==`string`)return Z={name:t.name,version:t.version},Z;throw Error(`Invalid package.json structure`)}catch{throw Error(`Failed to read package.json`)}}const Q=ot();de({pkg:Q}).notify({defer:!0}),z(()=>process.env.OVERLAYED_API_KEY??I.get()?.currentAccount?.apiKey);const $=new e;$.name(`overlayed`).description(`Overlayed CLI`).version(Q.version,`-v, --version`).addHelpText(`before`,`
|
|
16
16
|
${m.bold(m.cyan(`Overlayed`))} is revolutionizing game overlays.
|
|
17
|
-
`).action(()=>$.help()),$.addCommand(
|
|
17
|
+
`).action(()=>$.help()),$.addCommand(Je).addCommand(Xe).addCommand(tt).addCommand(rt).addCommand(at).configureOutput({writeErr:e=>process.stderr.write(e)});try{await $.parseAsync(process.argv)}catch(e){e instanceof U&&(process.stderr.write(q.error(e.message)),process.exit(1)),console.error(`Unexpected error:`),console.error(e),process.exit(1)}export{};
|