@overlayed/cli 0.0.0-canary-20260207042615

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/LICENSE.md ADDED
@@ -0,0 +1,16 @@
1
+ # Proprietary License
2
+
3
+ Copyright (c) 2023-present OVERLAYED LLC. All rights reserved.
4
+
5
+ This software and associated documentation files (the "Software") are the proprietary and confidential information of
6
+ OVERLAYED LLC. You may not use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software
7
+ without explicit written permission from OVERLAYED LLC.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
10
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
11
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
12
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
+
14
+ Unauthorized copying, transfer, or reproduction of the contents of this Software, via any medium is strictly prohibited.
15
+
16
+ All rights not expressly granted herein are reserved by OVERLAYED LLC.
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # @overlayed/cli
2
+
3
+ CLI for bundling overlayed applications
4
+
5
+ ## Testing Locally
6
+
7
+ Best way I've found to run locally is do `moon run cli:run -- <sub commands here>`, e.g. `moon run cli:run -- login`
package/dist/cli.mjs ADDED
@@ -0,0 +1,17 @@
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,readdirSync as s,unlinkSync as c,writeFileSync as ee}from"fs";import{ensureDirSync as l,ensureFileSync as u}from"fs-extra";import d,{join as te}from"path";import*as f from"node:path";import p from"node:path";import m from"picocolors";import*as h from"node:fs";import g,{createReadStream as _,existsSync as v,lstatSync as y,readFileSync as b}from"node:fs";import{glob as x}from"glob";import ne,{fileURLToPath as re}from"node:url";import{createJiti as ie}from"jiti";import ae,{isXiorError as S}from"xior";import oe from"update-notifier";import{readdir as se}from"node:fs/promises";import ce from"jszip";import{checkbox as le,password as ue}from"@inquirer/prompts";import{Listr as C}from"listr2";import{ListrInquirerPromptAdapter as de}from"@listr2/prompt-adapter-inquirer";import{exec as fe}from"child_process";import{promisify as pe}from"util";function me(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(){return this.data?this.data:this.load()}getKey(e){return this.get()[e]}save(e){let t=this.onBeforeSave(e);try{u(this.getFilePath()),r.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=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=ie(import.meta.url);return(await Promise.all(e.map(async e=>e.endsWith(`.ts`)?[await t.import(e,{default:!0}),e]:[(await import(ne.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 x.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=ae.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 he(e){return e}function ge(e){return e?t=>(e(t),t):he}function _e(e,t){return L.post(`/v1/applications/${e}/bundles/jobs/upload`,t)}function ve(e,t){return L.post(`/v1/applications/${e}/bundles/jobs/confirm`,{name:t})}function ye(e,t){return L.get(`/v1/applications/${e}/bundles/jobs/${t}`)}const B=ge();function be(e){return L.get(`/v1/public/applications/${e}`)}function V(){return L.get(`/v1/auth/me`)}async function xe(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 Se(n);throw Error(`Presigned upload failed (${n.status} ${n.statusText})${e?`: ${e}`:``}`)}}async function Se(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 Ce=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 Ce(r,n))}async bundle(){let e=new ce;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 x(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(/^(\.\.\\|\.\.\/)+/,``),!v(n)){t.file(r,``,{compression:`DEFLATE`});return}if(!await this.validateFilePath(n))return;let i=_(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(!v(e)||!y(e).isDirectory())return[e];let t=await se(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`}},we=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=g.readFileSync(e,`utf-8`),r=n(`string.json.parse`).to({main:`string`,devDependencies:{"@overlayed/electron":`string`}})(t);if(r instanceof n.errors)throw new Te(r.summary);this.mainFile=r.main}async validateMainFile(e){if(!this.mainFile)throw new W;if(!e.file(d.normalize(this.mainFile)))throw new Ee(this.mainFile)}async validateNoInstallFolder(e){let t=e.folder(`install`);if(t&&t.length>0)throw new De}async validateNoReservedFiles(e){for(let t of[`meta.json`,`app-update.yml`])if(e.file(t))throw new Oe(t)}},W=class extends U{constructor(){super(`package.json not found in bundle`),this.name=`PackageJsonNotFoundError`}},Te=class extends U{constructor(e){super(`package.json is invalid: ${e}`),this.name=`PackageJsonInvalidError`}},Ee=class extends U{constructor(e){super(`referenced package.json main file ${e} not found in bundle`),this.name=`MainFileNotFoundError`}},De=class extends U{constructor(){super("folder `install` found in bundle is not allowed and is reserved for the installer"),this.name=`InstallFolderFoundError`}},Oe=class extends U{constructor(e){super(`file \`${e}\` found in bundle is not allowed and is reserved for internal use`),this.name=`ReservedFileFoundError`}};const G=new class{write(e){process.stdout.write(e)}error(e){process.stderr.write(e)}},K={normal:ke,success:Ae,error:je,warning:Me,info:Ne};function ke(...e){return m.gray([...e,`
3
+ `].join(` `))}function Ae(...e){return[m.green(`✔`),...e,`
4
+ `].join(` `)}function je(...e){return[m.red(`✘`),...e,`
5
+ `].join(` `)}function Me(...e){return[m.yellow(`⚠`),...e,`
6
+ `].join(` `)}function Ne(...e){return[m.blue(`ℹ`),...e,`
7
+ `].join(` `)}async function q(){let e=process.env.OVERLAYED_API_KEY,t=I.get();if(e&&t?.currentAccount&&G.write(K.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(!S(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 J(){let e=await M();if(e.length===0)throw new U(`No config file found matching `+j);return e.length>1&&G.write(m.yellow(`
8
+ Multiple config files found matching ${j}, using the first one.
9
+ `)),e.at(0)}var Pe=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 Fe;return e}},Fe=class extends Error{constructor(){super(`Site bundle must contain at least one HTML file`)}};async function Ie(e={}){await q();try{await Le(e)}catch(e){if(e instanceof U&&process.exit(1),S(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 Le(e){let t=await new C([{title:`Locating overlayed.config.ts`,task:async t=>t.config=await Be(e)},{task:async(t,n)=>{if(e.app||e.site){let n=[];if(e.app&&(t.config.app?n.push(`app`):G.write(K.warning(`${m.bold(`--app`)} flag provided but no app config found in overlayed.config.ts`))),e.site&&(t.config.site?n.push(`site`):G.write(K.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,G.write(m.green(`Selected bundles: `)+m.bold(n.join(`, `)))}else{let e=await n.prompt(de).run(...ze(t.config));t.targetBundles=e,G.write(m.green(`Selected bundles: `)+m.bold(e.join(`, `)))}}}]).run();function n(e,t){let n=new URL(`https://overlay.dev/jobs`);n.searchParams.set(`applicationId`,e);for(let e of t)n.searchParams.append(`jobId`,e);return n.toString()}await new C([{title:`Uploading bundles`,task:e=>new C(e.targetBundles.map((e,t)=>({title:`Uploading ${e} bundle`,task:async n=>{n.jobIds??=[];let r=await Re(n.config,e);r&&(n.jobIds[t]=r.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);G.write(m.yellow(`Skipping wait. Check bundle status in the dashboard: `)+m.blue(e))}return}return new C(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 ye(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)}async function Re(e,t){let n=await _e(e.applicationId,{type:t}),r=await e[t]?.bundle()??me(Error(`No bundle found for `+t));e.debug&&r.forEach(e=>{console.log(`Zipping: `,e)});let i=await r.generateAsync({type:`nodebuffer`});if(e.debug){let e=`.overlayed/tmp`;l(e),ee(`${e}/debug-${t}.zip`,i);return}return await xe(n.data.upload_request,i),(await ve(e.applicationId,n.data.asset_bundle_name)).data}function ze(e){let t=e=>`(Disabled: No config found for "${e}" in overlayed.config.ts)`;return[le,{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 Be(e){let[t,n]=await J();return{...t,applicationId:B(t.applicationId),app:Ve(t,n,e),site:He(t,n,e),debug:e.debug}}function Ve(e,t,n){let r=new we(e),i=Y(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 He(e,t,n){if(!e.site)return;let r=new Pe(e),i=Y(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 Y(e,t){return t?d.resolve(d.dirname(e),t):d.dirname(e)}const Ue=new e(`bundle`).description(`Bundle the app and site for deployment.`).addHelpText(`after`,`
10
+ Documentation:
11
+ http://docs.overlayed.gg/cli/bundle
12
+ `).helpCommand(`overlayed bundle`).option(`--debug`,`Enable debug mode`,!1).option(`--app`,`Bundle the app`,!1).option(`--site`,`Bundle the site`,!1).option(`--no-wait`,`Skip waiting for bundle processing to complete`).action(Ie);async function We(){await q();let[e]=await J(),t=F({...(await be(B(e.applicationId))).data,siteUrl:``});G.write(K.success(`Initialized development environment for ${t.application.name}`))}const X=new e(`init`).description(`Initialize the local development environment.`).action(We);function Ge(e){return`https://overlay.dev${e}`}const Ke=pe(fe);async function qe(){let e=Ge(`/user-settings/api-keys?cli=true`);if(await Je(e),!await ue({message:`To authenticate, you'll need an API Key. We've opened the page to create one in your browser.\n\n${K.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(!S(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;G.write(K.success(`Authentication Complete - Logged in as ${n}`))}async function Je(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 Ke(n)}catch{}}const Ye=new e(`login`).description(`Authenticate with the Overlayed platform.`).helpCommand(`overlayed login`).action(qe);async function Xe(){let e=await q(),t=I.get();if(!t){G.write(K.normal(`Not currently logged in.`));return}let n=t.accounts.filter(t=>t.email!==e);I.set({...t,currentAccount:void 0,accounts:n}),G.write(K.normal(`Logged out from ${e}`))}const Ze=new e(`logout`).description(`Log out of the currently authenticated account.`).helpCommand(`overlayed logout`).action(Xe);async function Qe(){let e=await q();return G.write(K.normal(`Logged in as ${e}`)),e}const $e=new e(`whoami`).description(`Display information about the currently authenticated user.`).addHelpText(`after`,`
13
+ Documentation:
14
+ http://docs.overlayed.gg/cli/whoami
15
+ `).helpCommand(`overlayed whoami`).action(()=>{Qe()});let Z=null;function et(){if(Z)return Z;try{let e=new URL(`../package.json`,import.meta.url),t=JSON.parse(b(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=et();oe({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
+ ${m.bold(m.cyan(`Overlayed`))} is revolutionizing game overlays.
17
+ `).action(()=>$.help()),$.addCommand(Ue).addCommand(X).addCommand(Ye).addCommand(Ze).addCommand($e).configureOutput({writeErr:e=>process.stderr.write(e)});try{await $.parseAsync(process.argv)}catch(e){e instanceof U&&(process.stderr.write(K.error(e.message)),process.exit(1)),console.error(`Unexpected error:`),console.error(e),process.exit(1)}export{};
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@overlayed/cli",
3
+ "author": "overlayed.gg",
4
+ "homepage": "https://overlayed.gg",
5
+ "license": "SEE LICENSE IN LICENSE.md",
6
+ "repository": {
7
+ "url": "https://github.com/overlayed-gg/overlayed-typescript",
8
+ "type": "git"
9
+ },
10
+ "keywords": [
11
+ "typescript"
12
+ ],
13
+ "version": "0.0.0-canary-20260207042615",
14
+ "description": "Overlayed CLI",
15
+ "type": "module",
16
+ "bin": {
17
+ "overlayed": "./dist/cli.mjs"
18
+ },
19
+ "files": [
20
+ "dist/**/*"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "devDependencies": {
26
+ "@ark/attest": "^0.49.0",
27
+ "@types/fs-extra": "^11.0.4",
28
+ "@types/update-notifier": "^6.0.8",
29
+ "tsdown": "0.18.1",
30
+ "typescript": "^5.9.3",
31
+ "vitest": "^3.2.4",
32
+ "@overlayed/api": "0.0.5",
33
+ "@overlayed/shared-node": "0.0.4",
34
+ "@overlayed/utils": "0.0.4",
35
+ "@overlayed/utils-node": "0.0.4"
36
+ },
37
+ "dependencies": {
38
+ "@commander-js/extra-typings": "^14.0.0",
39
+ "@inquirer/prompts": "^7.10.1",
40
+ "@listr2/prompt-adapter-inquirer": "^3.0.5",
41
+ "arktype": "^2.1.29",
42
+ "commander": "^14.0.2",
43
+ "fs-extra": "^11.3.2",
44
+ "glob": "^11.1.0",
45
+ "jiti": "^2.6.1",
46
+ "jszip": "^3.10.1",
47
+ "listr2": "^9.0.5",
48
+ "picocolors": "^1.1.1",
49
+ "update-notifier": "^7.3.1",
50
+ "xior": "^0.7.8"
51
+ },
52
+ "engines": {
53
+ "node": ">=20.10.0"
54
+ }
55
+ }