@capgo/cli 0.16.1 → 0.16.4

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/.cz.toml CHANGED
@@ -1,7 +1,7 @@
1
1
  [tool.commitizen]
2
2
  name = "cz_conventional_commits"
3
3
  tag_format = "$major.$minor.$patch$prerelease"
4
- version = "0.16.1"
4
+ version = "0.16.4"
5
5
  version_files = [
6
6
  "package.json:version",
7
7
  ".cz.toml"
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 0.16.4 (2022-09-06)
2
+
3
+ ### Fix
4
+
5
+ - remove dup code + fix list display
6
+
7
+ ## 0.16.3 (2022-09-06)
8
+
9
+ ### Fix
10
+
11
+ - CLI log
12
+
13
+ ## 0.16.2 (2022-09-06)
14
+
15
+ ### Fix
16
+
17
+ - validation issue semver
18
+
1
19
  ## 0.16.1 (2022-08-21)
2
20
 
3
21
  ### Fix
package/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Capgo CLI
2
2
  <a href="https://capgo.app/"><img src='https://raw.githubusercontent.com/Cap-go/capgo/main/assets/capgo_banner.png' alt='Capgo - Instant updates for capacitor'/></a>
3
-
3
+
4
+ <div align="center">
5
+ <h2><a href="https://capgo.app/">Check out: Capgo — Instant updates for capacitor</a></h2>
6
+ </div>
7
+
4
8
  A CLI to upload and download files from the Capacitor go Cloud.
5
9
 
6
10
  ## Usage
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- (()=>{"use strict";var e={548:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.addApp=void 0;const n=r(304),a=r(113),i=r(147),p=r(470),s=r(11),d=r(233),c="assets/icon.png";o.addApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t;let{name:l,icon:u}=o;const g=o.apikey||(0,d.findSavedKey)(),f=yield(0,d.getConfig)(),v=(0,d.useLogSnag)();e=e||(null===(r=null==f?void 0:f.app)||void 0===r?void 0:r.appId),l=l||(null===(t=null==f?void 0:f.app)||void 0===t?void 0:t.appName)||"Unknown",u=u||"resources/icon.png",g||n.program.error("Missing API key, you need to provide a API key to add your app"),e&&l||n.program.error("Missing argument, you need to provide a appid and a name, or be in a capacitor project"),console.log(`Add ${e} to Capgo`);const m=(0,d.createSupabaseClient)(g);yield(0,d.checkKey)(m,g,["write","all"]);const{data:y,error:h}=yield m.rpc("get_user_id",{apikey:g}),_=y?y.toString():"";let k,b;_&&!h||n.program.error(`Cannot verify user ${(0,d.formatError)(h)}`),yield(0,d.checkPlan)(m,_),console.log("Adding..."),u&&(0,p.existsSync)(u)?(k=(0,i.readFileSync)(u),b=(0,s.getType)(u)||"image/png",console.warn(`Found app icon ${u}`)):(0,p.existsSync)(c)?(k=(0,i.readFileSync)(c),b=(0,s.getType)(c)||"image/png",console.warn(`Found app icon ${c}`)):console.warn(`Cannot find app icon in any of the following locations: ${u}, ${c}`);const{data:$,error:w}=yield m.rpc("exist_app",{appid:e,apikey:g});($||w)&&n.program.error(`App already exists ${(0,d.formatError)(w)}`);const x=`icon_${(0,a.randomUUID)()}`;let C="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(k&&b){const{error:o}=yield m.storage.from(`images/${_}/${e}`).upload(x,k,{contentType:b});o&&n.program.error(`Could not add app ${(0,d.formatError)(o)}`);const{data:r}=yield m.storage.from(`images/${_}/${e}`).getPublicUrl(x);C=(null==r?void 0:r.publicURL)||C}const{error:S}=yield m.from("apps").insert({icon_url:C,user_id:_,name:l,app_id:e},{returning:"minimal"});S&&n.program.error(`Could not add app ${(0,d.formatError)(S)}`);const{error:q}=yield m.from("app_versions").insert([{user_id:_,deleted:!0,name:"unknown",app_id:e},{user_id:_,deleted:!0,name:"builtin",app_id:e}],{returning:"minimal"});q&&n.program.error(`Could not add app ${(0,d.formatError)(q)}`),v.publish({channel:"app",event:"App Added",icon:"🎉",tags:{"user-id":_,"app-id":e},notify:!1}).catch(),console.log("App added to server, you can upload a version now")}))},453:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteApp=void 0;const n=r(304),a=r(233);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var r;const{version:t}=o,i=o.apikey||(0,a.findSavedKey)(),p=yield(0,a.getConfig)(),s=(0,a.useLogSnag)();e=e||(null===(r=null==p?void 0:p.app)||void 0===r?void 0:r.appId),i||n.program.error("Missing API key, you need to provide an API key to delete your app"),e||n.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),console.log(`Delete ${e} to Capgo`);const d=(0,a.createSupabaseClient)(i);yield(0,a.checkKey)(d,i,["all"]);const{data:c,error:l}=yield d.rpc("get_user_id",{apikey:i}),u=c?c.toString():"";u&&!l||n.program.error(`Cannot verify user ${(0,a.formatError)(l)}`);const{data:g,error:f}=yield d.rpc("exist_app",{appid:e,apikey:i});if(g&&!f||n.program.error("No permission to delete"),t){const{data:o,error:r}=yield d.from("app_versions").select().eq("app_id",e).eq("user_id",u).eq("name",t).eq("deleted",!1).single();o&&!r||n.program.error(`Version ${e}@${t} don't exist ${(0,a.formatError)(r)}`);const{data:i,error:p}=yield d.from("channels").select().eq("app_id",e).eq("created_by",u).eq("version",o.id);(i&&i.length||p)&&n.program.error(`Version ${e}@${t} is used in a channel, unlink it first ${(0,a.formatError)(p)}`);const{data:s,error:c}=yield d.from("devices_override").select().eq("app_id",e).eq("version",o.id);(s&&s.length||c)&&n.program.error(`Version ${e} @${t} is used in a device override, unlink it first ${(0,a.formatError)(c)}`);const{error:l}=yield d.storage.from("apps").remove([`${u}/${e}/versions/${o.bucket_id} `]);l&&n.program.error(`Something went wrong when trying to delete ${e} @${t} ${l} `);const{error:g}=yield d.from("app_versions").update({deleted:!0}).eq("app_id",e).eq("user_id",u).eq("name",t);return g&&n.program.error(`App ${e}@${t} not found in database '${g}'`),void console.log("App version deleted from server")}const{data:v,error:m}=yield d.from("app_versions").select().eq("app_id",e).eq("user_id",u);if(m&&n.program.error(`App ${e} not found in database ${m} `),v&&v.length){const o=v.map((o=>`${u}/${e}/versions/${o.bucket_id} `)),{error:r}=yield d.storage.from("apps").remove(o);r&&n.program.error(`Cannot delete stored version for app ${e} from storage ${r} `)}const{error:y}=yield d.from("app_versions").delete().eq("app_id",e).eq("user_id",u);y&&n.program.error(`Cannot delete version for app ${e} from database ${y} `);const{error:h}=yield d.from("apps").delete().eq("app_id",e).eq("user_id",u);h&&n.program.error(`Cannot delete from database ${h} `),s.publish({channel:"app",event:"App Deleted",icon:"😱",tags:{"user-id":u,"app-id":e},notify:!1}).catch(),console.log("App deleted from server")}))},473:function(e,o,r){var t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0});const n=r(304),a=r(548),i=r(453),p=r(666),s=r(310),d=t(r(598)),c=r(937);n.program.version(d.default.version).command("add [appid]").alias("a").action(a.addApp).option("-n, --name <name>","app name").option("-i, --icon <icon>","app icon path").option("-a, --apikey <apikey>","apikey to link to your account"),n.program.version(d.default.version).command("login [apikey]").alias("l").action(c.login).option("--local","Only save in local folder"),n.program.command("upload [appid]").alias("u").action(s.uploadVersion).option("-a, --apikey <apikey>","apikey to link to your account").option("-p, --path <path>","path of the file to upload").option("-c, --channel <channel>","channel to link to").option("-e, --external <url>","link to external url intead of upload to capgo cloud").option("-f, --format <base64|hex|binary|utf8>","choose the upload format default base64").option("-v, --version <version>","version number of the file to upload"),n.program.command("set [appid]").alias("s").action(p.setChannel).option("-c, --channel <channel>","channel to link to").option("-v, --version <version>","version number of the file to upload").option("-s, --state <state>","set the state of the channel, public or private").option("-a, --apikey <apikey>","apikey to link to your account"),n.program.description("Manage package and version in capgo Cloud").command("delete [appid]").alias("d").action(i.deleteApp).option("-a, --apikey <apikey>","apikey to link to your account").option("-v, --version <version>","version number of the app to delete"),n.program.parse(process.argv)},937:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.login=void 0;const a=r(304),i=n(r(147)),p=n(r(37)),s=r(233);o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:r}=o,t=(0,s.useLogSnag)();if(r)i.default.existsSync(".git")||a.program.error("To use local you should be in a git repository"),i.default.writeFileSync(".capgo",`${e}\n`),i.default.appendFileSync(".gitignore",".capgo\n");else{const o=p.default.homedir();i.default.writeFileSync(`${o}/.capgo`,`${e}\n`)}const n=(0,s.createSupabaseClient)(e),{data:d,error:c}=yield n.rpc("get_user_id",{apikey:e}),l=d?d.toString():"";l&&!c||a.program.error(`Cannot verify user ${(0,s.formatError)(c)}`),t.publish({channel:"user-login",event:"User CLI login",icon:"✅",tags:{"user-id":l},notify:!1}).catch(),console.log(`login saved into .capgo file in ${r?"local":"home"} directory`)}))},666:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.setChannel=void 0;const n=r(304),a=r(233);o.setChannel=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t,i;let{version:p}=o;const{state:s,channel:d="dev"}=o,c=o.apikey||(0,a.findSavedKey)(),l=yield(0,a.getConfig)(),u=(0,a.useLogSnag)();let g;e=e||(null===(r=null==l?void 0:l.app)||void 0===r?void 0:r.appId),p=p||(null===(i=null===(t=null==l?void 0:l.app)||void 0===t?void 0:t.package)||void 0===i?void 0:i.version),"public"!==s&&"private"!==s||(g="public"===s),c||n.program.error("Missing API key, you need to provide a API key to add your app"),e||n.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),p||g||n.program.error("Missing argument, you need to provide a state or a version"),p?console.log(`Set ${d} to @${p} in ${e}`):console.log(`Set${d} to @${s} in ${e}`);try{const o=(0,a.createSupabaseClient)(c);yield(0,a.checkKey)(o,c,["write","all"]);const{data:r,error:t}=yield o.rpc("get_user_id",{apikey:c}),i=r?r.toString():"";i&&!t||n.program.error(`Cannot verify user ${(0,a.formatError)(t)}`),yield(0,a.checkPlan)(o,i);const s={created_by:i,app_id:e,name:d};if(p){const{data:r,error:t}=yield o.from("app_versions").select().eq("app_id",e).eq("name",p).eq("user_id",i).eq("deleted",!1);!t&&r&&r.length||n.program.error(`Cannot find version ${p}`),s.version=r[0].id}void 0!==g&&(s.public=g);try{const{error:e}=yield(0,a.updateOrCreateChannel)(o,s,c);e&&n.program.error(`Cannot set channel ${(0,a.formatError)(e)}`)}catch(e){n.program.error(`Cannot set channel ${(0,a.formatError)(e)}`)}u.publish({channel:"app",event:"Set app",icon:"✅",tags:{"user-id":i,"app-id":e},notify:!1}).catch()}catch(e){n.program.error(`Unknow error ${(0,a.formatError)(e)}`)}p?console.log("Done ✅"):console.log(`You can use now is channel in your app with the url: ${a.host}/api/latest?appid=${e}&channel=${d}`)}))},310:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.uploadVersion=void 0;const a=n(r(844)),i=r(304),p=r(113),s=n(r(295)),d=n(r(912)),c=r(906),l=r(233);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t,n,u;let{version:g,path:f,channel:v}=o;const{external:m}=o,y=o.apikey||(0,l.findSavedKey)(),h=(0,l.useLogSnag)();v=v||"dev";const _=yield(0,l.getConfig)();e=e||(null===(r=null==_?void 0:_.app)||void 0===r?void 0:r.appId),g=g||(null===(n=null===(t=null==_?void 0:_.app)||void 0===t?void 0:t.package)||void 0===n?void 0:n.version),d.default.valid(g)||i.program.error(`Your version name ${g}, is not valid it should follow semver convention : https://semver.org/`),f=f||(null===(u=null==_?void 0:_.app)||void 0===u?void 0:u.webDir),y||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&g&&f||i.program.error("Missing argument, you need to provide a appid and a version and a path, or be in a capacitor project"),console.log(`Upload ${e}@${g} started from path "${f}" to Capgo cloud`);const k=(0,l.createSupabaseClient)(y);yield(0,l.checkKey)(k,y,["write","all"]);const b=new s.default.MultiBar({clearOnComplete:!1,hideCursor:!0},s.default.Presets.shades_grey),$=b.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},s.default.Presets.shades_grey);$.start(7,0,{speed:"N/A"});const{data:w,error:x}=yield k.rpc("exist_app_versions",{apikey:y,name_version:g,appid:e});(w||x)&&(b.stop(),i.program.error(`This app version already exist or was deleted, you cannot re-upload it ${(0,l.formatError)(x)}`)),$.increment();const{data:C,error:S}=yield k.rpc("get_user_id",{apikey:y}),q=C?C.toString():"";q&&!S||(b.stop(),i.program.error(`Cannot verify user ${(0,l.formatError)(S)}`)),yield(0,l.checkPlan)(k,q,!1);const{data:A,error:P}=yield k.rpc("is_trial",{userid:q}).single();(A&&A>0||P)&&b.log(`WARNING !!\nTrial expires in ${A} days, upgrade here: ${l.hostWeb}/app/usage\n`),$.increment();const{data:I,error:j}=yield k.rpc("exist_app",{appid:e,apikey:y});I&&!j||(b.stop(),i.program.error(`Cannot find app ${e} in your account \n${(0,l.formatError)(j)}`)),$.increment();const{data:E,error:M}=yield k.rpc("exist_app_versions",{appid:e,apikey:y,name_version:g});(E||M)&&i.program.error(`Version already exists ${(0,l.formatError)(M)}`),$.increment();const O=(0,p.randomUUID)();let T="";if(m)m&&!m.startsWith("https://")&&(b.stop(),i.program.error(`External link should should start with "https://" current is "${m}"`));else{const o=new a.default;o.addLocalFolder(f);const r=o.toBuffer();T=yield(0,c.checksum)(r,"crc32");const t=Math.floor(r.byteLength/1024/1024),n=`apps/${q}/${e}/versions`;$.increment(),t>20&&(b.log(`WARNING !!\nThe app size is ${t} Mb, this may take a while to download for users\n`),h.publish({channel:"app-error",event:"App Too Large",icon:"🚛",tags:{"user-id":q,"app-id":e},notify:!1}).catch());const{error:p}=yield k.storage.from(n).upload(O,r,{contentType:"application/zip"});p&&(b.stop(),i.program.error(`Cannot upload ${(0,l.formatError)(p)}`))}$.increment();const{data:N,error:z}=yield(0,l.updateOrCreateVersion)(k,{bucket_id:m?void 0:O,user_id:q,name:g,app_id:e,external_url:m,checksum:T},y);if(z&&(b.stop(),i.program.error(`Cannot add version ${(0,l.formatError)(z)}`)),$.increment(),N&&N.length){const{error:o}=yield(0,l.updateOrCreateChannel)(k,{name:v,app_id:e,created_by:q,version:N[0].id},y);o&&b.log("Cannot set version with upload key, use key with more rights for that\n")}else b.log("Cannot set version with upload key, use key with more rights for that\n");b.stop();const U=e.replace(/\./g,"--");console.log("App uploaded to server"),console.log(`Try it in mobile app: ${l.host}/app_mobile`),console.log(`Or set the channel ${v} as public here: ${l.hostWeb}/app/package/${U}`),console.log("To use with live update in your own app"),console.log(`You can link specific device to this version to make user try it first, here: ${l.hostWeb}/app/p/${U}/devices`),h.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":q,"app-id":e},notify:!1}).catch()}))},233:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.useLogSnag=o.updateOrCreateChannel=o.updateOrCreateVersion=o.getConfig=o.formatError=o.findSavedKey=o.checkPlan=o.isTrial=o.isGoodPlan=o.checkKey=o.createSupabaseClient=o.supaAnon=o.hostSupa=o.hostWeb=o.host=void 0;const a=r(778),i=r(304),p=r(885),s=n(r(867)),d=n(r(147)),c=n(r(37)),l=r(133);o.host="https://capgo.app",o.hostWeb="https://web.capgo.app",o.hostSupa="https://xvwzpoazmxkqosrdewyv.supabase.co",o.supaAnon="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNzgwNTAwOSwiZXhwIjoxOTUzMzgxMDA5fQ.8tgID1d4jodPwuo_fz4KHN4o1XKB9fnqyt0_GaJSj-w",o.createSupabaseClient=e=>(0,p.createClient)(o.hostSupa,o.supaAnon,{headers:{capgkey:e}}),o.checkKey=(e,r,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:a}=yield e.rpc("is_allowed_capgkey",{apikey:r,keymode:n});t&&!a||i.program.error(`Invalid API key or insufficient permissions ${(0,o.formatError)(a)}`)})),o.isGoodPlan=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:r,error:t}=yield e.rpc("is_good_plan",{userid:o}).single();if(t)throw t;return r||!1})),o.isTrial=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:r,error:t}=yield e.rpc("is_trial",{userid:o}).single();if(t)throw t;return r||0})),o.checkPlan=(e,r,n=!0)=>t(void 0,void 0,void 0,(function*(){let t=yield(0,o.isGoodPlan)(e,r);const a=yield(0,o.isTrial)(e,r);a>0&&(t=!0),t||i.program.error(`You need to upgrade your plan to continue to use capgo.\n Upgrade here: ${o.hostWeb}/app/usage\n`),a>0&&n&&console.log(`WARNING !!\nTrial expires in ${a} days, upgrade here: ${o.hostWeb}/app/usage\n`)})),o.findSavedKey=()=>{let e=`${c.default.homedir()}/.capgo`;return d.default.existsSync(e)?d.default.readFileSync(e,"utf8").trim():(e=".capgo",d.default.existsSync(e)?d.default.readFileSync(e,"utf8").trim():null)},o.formatError=e=>e?`\n${s.default.render(e)}`:"",o.getConfig=()=>t(void 0,void 0,void 0,(function*(){let e;try{e=yield(0,a.loadConfig)()}catch(e){i.program.error("No capacitor config file found, run `cap init` first")}return e})),o.updateOrCreateVersion=(e,o,r)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:n}=yield e.rpc("exist_app_versions",{appid:o.app_id,name_version:o.name,apikey:r});return t&&!n?(o.deleted=!1,e.from("app_versions").update(o).eq("app_id",o.app_id).eq("name",o.name)):e.from("app_versions").insert(o)})),o.updateOrCreateChannel=(e,o,r)=>t(void 0,void 0,void 0,(function*(){if(!o.app_id||!o.name||!o.created_by)return console.error("missing app_id, name, or created_by"),Promise.reject(new Error("missing app_id, name, or created_by"));const{data:t,error:n}=yield e.rpc("exist_channel",{appid:o.app_id,name_channel:o.name,apikey:r});return t&&!n?e.from("channels").update(o,{returning:"minimal"}).eq("app_id",o.app_id).eq("name",o.name).eq("created_by",o.created_by):e.from("channels").insert(o,{returning:"minimal"})})),o.useLogSnag=()=>new l.LogSnag({token:"c124f5e9d0ce5bdd14bbb48f815d5583",project:"capgo"})},778:e=>{e.exports=require("@capacitor/cli/dist/config")},885:e=>{e.exports=require("@supabase/supabase-js")},906:e=>{e.exports=require("@tomasklaen/checksum")},844:e=>{e.exports=require("adm-zip")},295:e=>{e.exports=require("cli-progress")},304:e=>{e.exports=require("commander")},470:e=>{e.exports=require("fs-extra")},133:e=>{e.exports=require("logsnag")},11:e=>{e.exports=require("mime")},867:e=>{e.exports=require("prettyjson")},912:e=>{e.exports=require("semver")},113:e=>{e.exports=require("crypto")},147:e=>{e.exports=require("fs")},37:e=>{e.exports=require("os")},598:e=>{e.exports=JSON.parse('{"name":"@capgo/cli","version":"0.16.1","description":"A CLI to upload to capgo servers","main":"dist/index.js","bin":{"capgo":"dist/index.js"},"repository":{"type":"git","url":"git+https://github.com/Cap-go/capgo-cli.git"},"bugs":{"url":"https://github.com/Cap-go/capgo-cli/issues"},"keywords":["appflow alternative","ionic","capacitor","auto update","live update","capgo","cli","upload","capgo-cli"],"scripts":{"dev":"set NODE_ENV=development && npx webpack --config webpack.config.js","no-debug":"node dist/index.js","build":"npx webpack --config webpack.config.js","dev-build":"SUPA_DB=development npx webpack --config webpack.config.js","pack":"pkg","test_rls":"ts-node ./test/test_headers_rls.ts","lint":"eslint . --ext .ts --fix"},"author":"github.com/riderx","license":"Apache 2.0","dependencies":{"@capacitor/cli":"3.5.1","@supabase/supabase-js":"^1.35.3","@tomasklaen/checksum":"^1.1.0","adm-zip":"^0.5.9","cli-progress":"3.11.0","commander":"9.2.0","form-data":"^4.0.0","fs-extra":"10.1.0","logsnag":"^0.1.2","mime":"^3.0.0","node-stream-zip":"^1.15.0","prettyjson":"^1.2.5","semver":"^7.3.7","upath":"^2.0.1"},"devDependencies":{"@types/adm-zip":"0.5.0","@types/cli-progress":"^3.11.0","@types/fs-extra":"^9.0.13","@types/mime":"^2.0.3","@types/node":"^17.0.31","@types/prettyjson":"^0.0.30","@types/semver":"^7.3.10","@typescript-eslint/eslint-plugin":"5.22.0","@typescript-eslint/parser":"5.22.0","eslint":"8.14.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^8.5.0","eslint-import-resolver-typescript":"2.7.1","eslint-plugin-import":"2.26.0","eslint-plugin-prettier":"^4.0.0","git-format-staged":"3.0.0","husky":"^7.0.4","nodemon":"2.0.16","pkg":"5.6.0","prettier":"2.6.2","ts-loader":"^9.3.0","ts-node":"^10.7.0","tsconfig-paths":"4.0.0","typescript":"4.6.4","webpack":"5.72.0","webpack-cli":"^4.9.2","webpack-node-externals":"^3.0.0"}}')}},o={};!function r(t){var n=o[t];if(void 0!==n)return n.exports;var a=o[t]={exports:{}};return e[t].call(a.exports,a,a.exports,r),a.exports}(473)})();
2
+ (()=>{"use strict";var e={548:function(e,o,r){var n=this&&this.__awaiter||function(e,o,r,n){return new(r||(r=Promise))((function(t,a){function i(e){try{s(n.next(e))}catch(e){a(e)}}function p(e){try{s(n.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?t(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((n=n.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.addApp=void 0;const t=r(304),a=r(113),i=r(147),p=r(470),s=r(11),d=r(233),l="assets/icon.png";o.addApp=(e,o)=>n(void 0,void 0,void 0,(function*(){var r,n;let{name:c,icon:u}=o;const g=o.apikey||(0,d.findSavedKey)(),v=yield(0,d.getConfig)(),f=(0,d.useLogSnag)();e=e||(null===(r=null==v?void 0:v.app)||void 0===r?void 0:r.appId),c=c||(null===(n=null==v?void 0:v.app)||void 0===n?void 0:n.appName)||"Unknown",u=u||"resources/icon.png",g||t.program.error("Missing API key, you need to provide a API key to add your app"),e&&c||t.program.error("Missing argument, you need to provide a appid and a name, or be in a capacitor project"),console.log(`Add ${e} to Capgo`);const y=(0,d.createSupabaseClient)(g),m=yield(0,d.verifyUser)(y,g,["write","all"]);let h,_;yield(0,d.checkPlan)(y,m),console.log("Adding..."),u&&(0,p.existsSync)(u)?(h=(0,i.readFileSync)(u),_=(0,s.getType)(u)||"image/png",console.warn(`Found app icon ${u}`)):(0,p.existsSync)(l)?(h=(0,i.readFileSync)(l),_=(0,s.getType)(l)||"image/png",console.warn(`Found app icon ${l}`)):console.warn(`Cannot find app icon in any of the following locations: ${u}, ${l}`);const{data:b,error:k}=yield y.rpc("exist_app",{appid:e,apikey:g});(b||k)&&t.program.error(`App already exists ${(0,d.formatError)(k)}`);const $=`icon_${(0,a.randomUUID)()}`;let w="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(h&&_){const{error:o}=yield y.storage.from(`images/${m}/${e}`).upload($,h,{contentType:_});o&&t.program.error(`Could not add app ${(0,d.formatError)(o)}`);const{data:r}=yield y.storage.from(`images/${m}/${e}`).getPublicUrl($);w=(null==r?void 0:r.publicURL)||w}const{error:x}=yield y.from("apps").insert({icon_url:w,user_id:m,name:c,app_id:e},{returning:"minimal"});x&&t.program.error(`Could not add app ${(0,d.formatError)(x)}`);const{error:C}=yield y.from("app_versions").insert([{user_id:m,deleted:!0,name:"unknown",app_id:e},{user_id:m,deleted:!0,name:"builtin",app_id:e}],{returning:"minimal"});C&&t.program.error(`Could not add app ${(0,d.formatError)(C)}`),f.publish({channel:"app",event:"App Added",icon:"🎉",tags:{"user-id":m,"app-id":e},notify:!1}).catch(),console.log("App added to server, you can upload a version now")}))},453:function(e,o,r){var n=this&&this.__awaiter||function(e,o,r,n){return new(r||(r=Promise))((function(t,a){function i(e){try{s(n.next(e))}catch(e){a(e)}}function p(e){try{s(n.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?t(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((n=n.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteApp=void 0;const t=r(304),a=r(233);o.deleteApp=(e,o)=>n(void 0,void 0,void 0,(function*(){var r;const{version:n}=o,i=o.apikey||(0,a.findSavedKey)(),p=yield(0,a.getConfig)(),s=(0,a.useLogSnag)();e=e||(null===(r=null==p?void 0:p.app)||void 0===r?void 0:r.appId),i||t.program.error("Missing API key, you need to provide an API key to delete your app"),e||t.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const d=(0,a.createSupabaseClient)(i),l=yield(0,a.verifyUser)(d,i),{data:c,error:u}=yield d.rpc("exist_app",{appid:e,apikey:i});if(c&&!u||t.program.error("No permission to delete"),n){console.log(`Delete ${e}@${n} from Capgo`);const{data:o,error:r}=yield d.from("app_versions").select().eq("app_id",e).eq("user_id",l).eq("name",n).eq("deleted",!1).single();o&&!r||t.program.error(`Version ${e}@${n} doesn't exist ${(0,a.formatError)(r)}`);const{data:i,error:p}=yield d.from("channels").select().eq("app_id",e).eq("created_by",l).eq("version",o.id);(i&&i.length||p)&&t.program.error(`Version ${e}@${n} is used in a channel, unlink it first ${(0,a.formatError)(p)}`);const{data:s,error:c}=yield d.from("devices_override").select().eq("app_id",e).eq("version",o.id);(s&&s.length||c)&&t.program.error(`Version ${e} @${n} is used in a device override, unlink it first ${(0,a.formatError)(c)}`);const{error:u}=yield d.storage.from("apps").remove([`${l}/${e}/versions/${o.bucket_id} `]);u&&t.program.error(`Something went wrong when trying to delete ${e} @${n} ${u} `);const{error:g}=yield d.from("app_versions").update({deleted:!0}).eq("app_id",e).eq("user_id",l).eq("name",n);return g&&t.program.error(`App ${e}@${n} not found in database '${g}'`),void console.log(`${e}@${n} deleted from server`)}console.log(`Delete ${e} from Capgo`);const{data:g,error:v}=yield d.from("app_versions").select().eq("app_id",e).eq("user_id",l);if(v&&t.program.error(`App ${e} not found in database ${v} `),g&&g.length){const o=g.map((o=>`${l}/${e}/versions/${o.bucket_id} `)),{error:r}=yield d.storage.from("apps").remove(o);r&&t.program.error(`Cannot delete stored version for app ${e} from storage ${r} `)}const{error:f}=yield d.from("app_versions").delete().eq("app_id",e).eq("user_id",l);f&&t.program.error(`Cannot delete version for app ${e} from database ${f} `);const{error:y}=yield d.from("apps").delete().eq("app_id",e).eq("user_id",l);y&&t.program.error(`Cannot delete from database ${y} `),s.publish({channel:"app",event:"App Deleted",icon:"😱",tags:{"user-id":l,"app-id":e},notify:!1}).catch(),console.log(`${e} deleted from server`)}))},473:function(e,o,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0});const t=r(304),a=r(548),i=r(453),p=r(666),s=r(310),d=n(r(598)),l=r(937),c=r(546);t.program.version(d.default.version).command("add [appid]").alias("a").action(a.addApp).option("-n, --name <name>","app name").option("-i, --icon <icon>","app icon path").option("-a, --apikey <apikey>","apikey to link to your account"),t.program.version(d.default.version).command("login [apikey]").alias("l").action(l.login).option("--local","Only save in local folder"),t.program.command("upload [appid]").alias("u").action(s.uploadVersion).option("-a, --apikey <apikey>","apikey to link to your account").option("-p, --path <path>","path of the file to upload").option("-c, --channel <channel>","channel to link to").option("-e, --external <url>","link to external url intead of upload to capgo cloud").option("-f, --format <base64|hex|binary|utf8>","choose the upload format default base64").option("-v, --version <version>","version number of the file to upload"),t.program.command("set [appid]").alias("s").action(p.setChannel).option("-c, --channel <channel>","channel to link to").option("-v, --version <version>","version number of the file to upload").option("-s, --state <state>","set the state of the channel, public or private").option("-a, --apikey <apikey>","apikey to link to your account"),t.program.description("Manage package and version in capgo Cloud").command("delete [appid]").alias("d").action(i.deleteApp).option("-a, --apikey <apikey>","apikey to link to your account").option("-v, --version <version>","version number of the app to delete"),t.program.description("List versions in capgo Cloud").command("list [appid]").alias("ls").action(c.listApp).option("-a, --apikey <apikey>","apikey to link to your account"),t.program.parse(process.argv)},546:function(e,o,r){var n=this&&this.__awaiter||function(e,o,r,n){return new(r||(r=Promise))((function(t,a){function i(e){try{s(n.next(e))}catch(e){a(e)}}function p(e){try{s(n.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?t(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((n=n.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.listApp=void 0;const t=r(304),a=r(233);o.listApp=(e,o)=>n(void 0,void 0,void 0,(function*(){var r;const n=o.apikey||(0,a.findSavedKey)(),i=yield(0,a.getConfig)();e=e||(null===(r=null==i?void 0:i.app)||void 0===r?void 0:r.appId),n||t.program.error("Missing API key, you need to provide an API key to delete your app"),e||t.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),console.log("Querying available versions in Capgo");const p=(0,a.createSupabaseClient)(n),s=yield(0,a.verifyUser)(p,n),{data:d,error:l}=yield p.rpc("exist_app",{appid:e,apikey:n});d&&!l||t.program.error("No permission for this app");const{data:c,error:u}=yield p.from("app_versions").select().eq("app_id",e).eq("user_id",s).eq("deleted",!1);console.log(`Active versions in Capgo: ${null==c?void 0:c.length}`),null==c||c.forEach((e=>{const o=new Date(e.created_at||"").toLocaleString();console.log(`${e.name} created on ${o}`)})),u&&t.program.error(`App ${e} not found in database ${u} `)}))},937:function(e,o,r){var n=this&&this.__awaiter||function(e,o,r,n){return new(r||(r=Promise))((function(t,a){function i(e){try{s(n.next(e))}catch(e){a(e)}}function p(e){try{s(n.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?t(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((n=n.apply(e,o||[])).next())}))},t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.login=void 0;const a=r(304),i=t(r(147)),p=t(r(37)),s=r(233);o.login=(e,o)=>n(void 0,void 0,void 0,(function*(){const{local:r}=o,n=(0,s.useLogSnag)();if(r)i.default.existsSync(".git")||a.program.error("To use local you should be in a git repository"),i.default.writeFileSync(".capgo",`${e}\n`),i.default.appendFileSync(".gitignore",".capgo\n");else{const o=p.default.homedir();i.default.writeFileSync(`${o}/.capgo`,`${e}\n`)}const t=(0,s.createSupabaseClient)(e),d=yield(0,s.verifyUser)(t,e,["write","all","upload"]);n.publish({channel:"user-login",event:"User CLI login",icon:"✅",tags:{"user-id":d},notify:!1}).catch(),console.log(`login saved into .capgo file in ${r?"local":"home"} directory`)}))},666:function(e,o,r){var n=this&&this.__awaiter||function(e,o,r,n){return new(r||(r=Promise))((function(t,a){function i(e){try{s(n.next(e))}catch(e){a(e)}}function p(e){try{s(n.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?t(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((n=n.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.setChannel=void 0;const t=r(304),a=r(233);o.setChannel=(e,o)=>n(void 0,void 0,void 0,(function*(){var r,n,i;let{version:p}=o;const{state:s,channel:d="dev"}=o,l=o.apikey||(0,a.findSavedKey)(),c=yield(0,a.getConfig)(),u=(0,a.useLogSnag)();let g;e=e||(null===(r=null==c?void 0:c.app)||void 0===r?void 0:r.appId),p=p||(null===(i=null===(n=null==c?void 0:c.app)||void 0===n?void 0:n.package)||void 0===i?void 0:i.version),"public"!==s&&"private"!==s||(g="public"===s),l||t.program.error("Missing API key, you need to provide a API key to add your app"),e||t.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),p||g||t.program.error("Missing argument, you need to provide a state or a version"),p?console.log(`Set ${d} to @${p} in ${e}`):console.log(`Set${d} to @${s} in ${e}`);try{const o=(0,a.createSupabaseClient)(l),r=yield(0,a.verifyUser)(o,l,["write","all"]);yield(0,a.checkPlan)(o,r);const n={created_by:r,app_id:e,name:d};if(p){const{data:a,error:i}=yield o.from("app_versions").select().eq("app_id",e).eq("name",p).eq("user_id",r).eq("deleted",!1);!i&&a&&a.length||t.program.error(`Cannot find version ${p}`),n.version=a[0].id}void 0!==g&&(n.public=g);try{const{error:e}=yield(0,a.updateOrCreateChannel)(o,n,l);e&&t.program.error(`Cannot set channel ${(0,a.formatError)(e)}`)}catch(e){t.program.error(`Cannot set channel ${(0,a.formatError)(e)}`)}u.publish({channel:"app",event:"Set app",icon:"✅",tags:{"user-id":r,"app-id":e},notify:!1}).catch()}catch(e){t.program.error(`Unknow error ${(0,a.formatError)(e)}`)}p?console.log("Done ✅"):console.log(`You can use now is channel in your app with the url: ${a.host}/api/latest?appid=${e}&channel=${d}`)}))},310:function(e,o,r){var n=this&&this.__awaiter||function(e,o,r,n){return new(r||(r=Promise))((function(t,a){function i(e){try{s(n.next(e))}catch(e){a(e)}}function p(e){try{s(n.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?t(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((n=n.apply(e,o||[])).next())}))},t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.uploadVersion=void 0;const a=t(r(844)),i=r(304),p=r(113),s=t(r(295)),d=t(r(912)),l=r(906),c=r(233);o.uploadVersion=(e,o)=>n(void 0,void 0,void 0,(function*(){var r,n,t,u;let{version:g,path:v,channel:f}=o;const{external:y}=o,m=o.apikey||(0,c.findSavedKey)(),h=(0,c.useLogSnag)();f=f||"dev";const _=yield(0,c.getConfig)();e=e||(null===(r=null==_?void 0:_.app)||void 0===r?void 0:r.appId),g=g||(null===(t=null===(n=null==_?void 0:_.app)||void 0===n?void 0:n.package)||void 0===t?void 0:t.version);const b=d.default.clean(g);d.default.valid(g)&&b===g||i.program.error(`Your version name ${g}, is not valid it should follow semver convention : https://semver.org/`),v=v||(null===(u=null==_?void 0:_.app)||void 0===u?void 0:u.webDir),m||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&g&&v||i.program.error("Missing argument, you need to provide a appid and a version and a path, or be in a capacitor project"),console.log(`Upload ${e}@${g} started from path "${v}" to Capgo cloud`);const k=(0,c.createSupabaseClient)(m),$=yield(0,c.verifyUser)(k,m,["write","all","upload"]);yield(0,c.checkPlan)(k,$,!1);const w=new s.default.MultiBar({clearOnComplete:!1,hideCursor:!0},s.default.Presets.shades_grey),x=w.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},s.default.Presets.shades_grey);x.start(7,0,{speed:"N/A"});const{data:C,error:S}=yield k.rpc("exist_app_versions",{apikey:m,name_version:g,appid:e});(C||S)&&(w.stop(),i.program.error(`This app version already exist or was deleted, you cannot re-upload it ${(0,c.formatError)(S)}`)),x.increment();const{data:q,error:A}=yield k.rpc("is_trial",{userid:$}).single();(q&&q>0||A)&&w.log(`WARNING !!\nTrial expires in ${q} days, upgrade here: ${c.hostWeb}/app/usage\n`),x.increment();const{data:P,error:I}=yield k.rpc("exist_app",{appid:e,apikey:m});P&&!I||(w.stop(),i.program.error(`Cannot find app ${e} in your account \n${(0,c.formatError)(I)}`)),x.increment();const{data:j,error:M}=yield k.rpc("exist_app_versions",{appid:e,apikey:m,name_version:g});(j||M)&&i.program.error(`Version already exists ${(0,c.formatError)(M)}`),x.increment();const E=(0,p.randomUUID)();let U="";if(y)y&&!y.startsWith("https://")&&(w.stop(),i.program.error(`External link should should start with "https://" current is "${y}"`));else{const o=new a.default;o.addLocalFolder(v);const r=o.toBuffer();U=yield(0,l.checksum)(r,"crc32");const n=Math.floor(r.byteLength/1024/1024),t=`apps/${$}/${e}/versions`;x.increment(),n>20&&(w.log(`WARNING !!\nThe app size is ${n} Mb, this may take a while to download for users\n`),h.publish({channel:"app-error",event:"App Too Large",icon:"🚛",tags:{"user-id":$,"app-id":e},notify:!1}).catch());const{error:p}=yield k.storage.from(t).upload(E,r,{contentType:"application/zip"});p&&(w.stop(),i.program.error(`Cannot upload ${(0,c.formatError)(p)}`))}x.increment();const{data:O,error:T}=yield(0,c.updateOrCreateVersion)(k,{bucket_id:y?void 0:E,user_id:$,name:g,app_id:e,external_url:y,checksum:U},m);if(T&&(w.stop(),i.program.error(`Cannot add version ${(0,c.formatError)(T)}`)),x.increment(),O&&O.length){const{error:o}=yield(0,c.updateOrCreateChannel)(k,{name:f,app_id:e,created_by:$,version:O[0].id},m);o&&w.log("Cannot set version with upload key, use key with more rights for that\n")}else w.log("Cannot set version with upload key, use key with more rights for that\n");w.stop();const N=e.replace(/\./g,"--");console.log("App uploaded to server"),console.log(`Try it in mobile app: ${c.host}/app_mobile`),console.log(`Or set the channel ${f} as public here: ${c.hostWeb}/app/package/${N}`),console.log("To use with live update in your own app"),console.log(`You can link specific device to this version to make user try it first, here: ${c.hostWeb}/app/p/${N}/devices`),h.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":$,"app-id":e},notify:!1}).catch()}))},233:function(e,o,r){var n=this&&this.__awaiter||function(e,o,r,n){return new(r||(r=Promise))((function(t,a){function i(e){try{s(n.next(e))}catch(e){a(e)}}function p(e){try{s(n.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?t(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((n=n.apply(e,o||[])).next())}))},t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.verifyUser=o.useLogSnag=o.updateOrCreateChannel=o.updateOrCreateVersion=o.getConfig=o.formatError=o.findSavedKey=o.checkPlan=o.isTrial=o.isGoodPlan=o.checkKey=o.createSupabaseClient=o.supaAnon=o.hostSupa=o.hostWeb=o.host=void 0;const a=r(778),i=r(304),p=r(885),s=t(r(867)),d=t(r(147)),l=t(r(37)),c=r(133);o.host="https://capgo.app",o.hostWeb="https://web.capgo.app",o.hostSupa="https://xvwzpoazmxkqosrdewyv.supabase.co",o.supaAnon="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNzgwNTAwOSwiZXhwIjoxOTUzMzgxMDA5fQ.8tgID1d4jodPwuo_fz4KHN4o1XKB9fnqyt0_GaJSj-w",o.createSupabaseClient=e=>(0,p.createClient)(o.hostSupa,o.supaAnon,{headers:{capgkey:e}}),o.checkKey=(e,r,t)=>n(void 0,void 0,void 0,(function*(){const{data:n,error:a}=yield e.rpc("is_allowed_capgkey",{apikey:r,keymode:t});n&&!a||i.program.error(`Invalid API key or insufficient permissions ${(0,o.formatError)(a)}`)})),o.isGoodPlan=(e,o)=>n(void 0,void 0,void 0,(function*(){const{data:r,error:n}=yield e.rpc("is_good_plan",{userid:o}).single();if(n)throw n;return r||!1})),o.isTrial=(e,o)=>n(void 0,void 0,void 0,(function*(){const{data:r,error:n}=yield e.rpc("is_trial",{userid:o}).single();if(n)throw n;return r||0})),o.checkPlan=(e,r,t=!0)=>n(void 0,void 0,void 0,(function*(){let n=yield(0,o.isGoodPlan)(e,r);const a=yield(0,o.isTrial)(e,r);a>0&&(n=!0),n||i.program.error(`You need to upgrade your plan to continue to use capgo.\n Upgrade here: ${o.hostWeb}/app/usage\n`),a>0&&t&&console.log(`WARNING !!\nTrial expires in ${a} days, upgrade here: ${o.hostWeb}/app/usage\n`)})),o.findSavedKey=()=>{let e=`${l.default.homedir()}/.capgo`;return d.default.existsSync(e)?d.default.readFileSync(e,"utf8").trim():(e=".capgo",d.default.existsSync(e)?d.default.readFileSync(e,"utf8").trim():null)},o.formatError=e=>e?`\n${s.default.render(e)}`:"",o.getConfig=()=>n(void 0,void 0,void 0,(function*(){let e;try{e=yield(0,a.loadConfig)()}catch(e){i.program.error("No capacitor config file found, run `cap init` first")}return e})),o.updateOrCreateVersion=(e,o,r)=>n(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("exist_app_versions",{appid:o.app_id,name_version:o.name,apikey:r});return n&&!t?(o.deleted=!1,e.from("app_versions").update(o).eq("app_id",o.app_id).eq("name",o.name)):e.from("app_versions").insert(o)})),o.updateOrCreateChannel=(e,o,r)=>n(void 0,void 0,void 0,(function*(){if(!o.app_id||!o.name||!o.created_by)return console.error("missing app_id, name, or created_by"),Promise.reject(new Error("missing app_id, name, or created_by"));const{data:n,error:t}=yield e.rpc("exist_channel",{appid:o.app_id,name_channel:o.name,apikey:r});return n&&!t?e.from("channels").update(o,{returning:"minimal"}).eq("app_id",o.app_id).eq("name",o.name).eq("created_by",o.created_by):e.from("channels").insert(o,{returning:"minimal"})})),o.useLogSnag=()=>new c.LogSnag({token:"c124f5e9d0ce5bdd14bbb48f815d5583",project:"capgo"}),o.verifyUser=(e,r,t=["all"])=>n(void 0,void 0,void 0,(function*(){yield(0,o.checkKey)(e,r,t);const{data:n,error:a}=yield e.rpc("get_user_id",{apikey:r}),p=n?n.toString():"";return p&&!a||i.program.error(`Cannot verify user ${(0,o.formatError)(a)}`),p}))},778:e=>{e.exports=require("@capacitor/cli/dist/config")},885:e=>{e.exports=require("@supabase/supabase-js")},906:e=>{e.exports=require("@tomasklaen/checksum")},844:e=>{e.exports=require("adm-zip")},295:e=>{e.exports=require("cli-progress")},304:e=>{e.exports=require("commander")},470:e=>{e.exports=require("fs-extra")},133:e=>{e.exports=require("logsnag")},11:e=>{e.exports=require("mime")},867:e=>{e.exports=require("prettyjson")},912:e=>{e.exports=require("semver")},113:e=>{e.exports=require("crypto")},147:e=>{e.exports=require("fs")},37:e=>{e.exports=require("os")},598:e=>{e.exports=JSON.parse('{"name":"@capgo/cli","version":"0.16.4","description":"A CLI to upload to capgo servers","main":"dist/index.js","bin":{"capgo":"dist/index.js"},"repository":{"type":"git","url":"git+https://github.com/Cap-go/capgo-cli.git"},"bugs":{"url":"https://github.com/Cap-go/capgo-cli/issues"},"keywords":["appflow alternative","ionic","capacitor","auto update","live update","capgo","cli","upload","capgo-cli"],"scripts":{"dev":"set NODE_ENV=development && npx webpack --config webpack.config.js","no-debug":"node dist/index.js","build":"npx webpack --config webpack.config.js","dev-build":"SUPA_DB=development npx webpack --config webpack.config.js","pack":"pkg","test_rls":"ts-node ./test/test_headers_rls.ts","lint":"eslint . --ext .ts --fix"},"author":"github.com/riderx","license":"Apache 2.0","dependencies":{"@capacitor/cli":"3.5.1","@supabase/supabase-js":"^1.35.3","@tomasklaen/checksum":"^1.1.0","adm-zip":"^0.5.9","cli-progress":"3.11.0","commander":"9.2.0","form-data":"^4.0.0","fs-extra":"10.1.0","logsnag":"^0.1.2","mime":"^3.0.0","node-stream-zip":"^1.15.0","prettyjson":"^1.2.5","semver":"^7.3.7","upath":"^2.0.1"},"devDependencies":{"@types/adm-zip":"0.5.0","@types/cli-progress":"^3.11.0","@types/fs-extra":"^9.0.13","@types/mime":"^2.0.3","@types/node":"^17.0.31","@types/prettyjson":"^0.0.30","@types/semver":"^7.3.10","@typescript-eslint/eslint-plugin":"5.22.0","@typescript-eslint/parser":"5.22.0","eslint":"8.14.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^8.5.0","eslint-import-resolver-typescript":"2.7.1","eslint-plugin-import":"2.26.0","eslint-plugin-prettier":"^4.0.0","git-format-staged":"3.0.0","husky":"^7.0.4","nodemon":"2.0.16","pkg":"5.6.0","prettier":"2.6.2","ts-loader":"^9.3.0","ts-node":"^10.7.0","tsconfig-paths":"4.0.0","typescript":"4.6.4","webpack":"5.72.0","webpack-cli":"^4.9.2","webpack-node-externals":"^3.0.0"}}')}},o={};!function r(n){var t=o[n];if(void 0!==t)return t.exports;var a=o[n]={exports:{}};return e[n].call(a.exports,a,a.exports,r),a.exports}(473)})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/cli",
3
- "version": "0.16.1",
3
+ "version": "0.16.4",
4
4
  "description": "A CLI to upload to capgo servers",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/bin/add.ts CHANGED
@@ -4,7 +4,7 @@ import { readFileSync } from 'fs';
4
4
  import { existsSync } from 'fs-extra';
5
5
  import { getType } from 'mime';
6
6
  import { definitions } from './types_supabase'
7
- import { getConfig, createSupabaseClient, formatError, findSavedKey, checkPlan, checkKey, useLogSnag } from './utils';
7
+ import { getConfig, createSupabaseClient, formatError, findSavedKey, checkPlan, checkKey, useLogSnag, verifyUser } from './utils';
8
8
 
9
9
  interface Options {
10
10
  apikey: string;
@@ -31,13 +31,7 @@ export const addApp = async (appid: string, options: Options) => {
31
31
 
32
32
  const supabase = createSupabaseClient(apikey)
33
33
 
34
- await checkKey(supabase, apikey, ['write', 'all']);
35
- const { data: dataUser, error: userIdError } = await supabase
36
- .rpc<string>('get_user_id', { apikey })
37
- const userId = dataUser ? dataUser.toString() : '';
38
- if (!userId || userIdError) {
39
- program.error(`Cannot verify user ${formatError(userIdError)}`);
40
- }
34
+ const userId = await verifyUser(supabase, apikey, ['write', 'all']);
41
35
  await checkPlan(supabase, userId)
42
36
 
43
37
  console.log('Adding...');
package/src/bin/delete.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { program } from 'commander';
2
- import { getConfig, createSupabaseClient, formatError, findSavedKey, checkKey, useLogSnag } from './utils';
2
+ import { getConfig, createSupabaseClient, formatError, findSavedKey, useLogSnag, verifyUser } from './utils';
3
3
  import { definitions } from './types_supabase'
4
4
 
5
5
  interface Options {
@@ -20,20 +20,10 @@ export const deleteApp = async (appid: string, options: Options) => {
20
20
  if (!appid) {
21
21
  program.error('Missing argument, you need to provide a appid, or be in a capacitor project');
22
22
  }
23
- console.log(`Delete ${appid} to Capgo`);
24
23
 
25
24
  const supabase = createSupabaseClient(apikey)
26
25
 
27
- await checkKey(supabase, apikey, ['all']);
28
-
29
- const { data: dataUser, error: userIdError } = await supabase
30
- .rpc<string>('get_user_id', { apikey })
31
-
32
- const userId = dataUser ? dataUser.toString() : '';
33
-
34
- if (!userId || userIdError) {
35
- program.error(`Cannot verify user ${formatError(userIdError)}`);
36
- }
26
+ const userId = await verifyUser(supabase, apikey);
37
27
 
38
28
  const { data: app, error: dbError0 } = await supabase
39
29
  .rpc<string>('exist_app', { appid, apikey })
@@ -42,6 +32,8 @@ export const deleteApp = async (appid: string, options: Options) => {
42
32
  }
43
33
 
44
34
  if (version) {
35
+ console.log(`Delete ${appid}@${version} from Capgo`);
36
+
45
37
  const { data: versionData, error: versionIdError } = await supabase
46
38
  .from<definitions['app_versions']>('app_versions')
47
39
  .select()
@@ -51,7 +43,7 @@ export const deleteApp = async (appid: string, options: Options) => {
51
43
  .eq('deleted', false)
52
44
  .single()
53
45
  if (!versionData || versionIdError) {
54
- program.error(`Version ${appid}@${version} don't exist ${formatError(versionIdError)}`)
46
+ program.error(`Version ${appid}@${version} doesn't exist ${formatError(versionIdError)}`)
55
47
  }
56
48
  const { data: channelFound, error: errorChannel } = await supabase
57
49
  .from<definitions['channels']>('channels')
@@ -90,10 +82,11 @@ export const deleteApp = async (appid: string, options: Options) => {
90
82
  if (delAppSpecVersionError) {
91
83
  program.error(`App ${appid}@${version} not found in database '${delAppSpecVersionError}'`)
92
84
  }
93
- console.log("App version deleted from server")
85
+ console.log(`${appid}@${version} deleted from server`)
94
86
  return
95
87
  }
96
88
 
89
+ console.log(`Delete ${appid} from Capgo`);
97
90
  const { data, error: vError } = await supabase
98
91
  .from<definitions['app_versions']>('app_versions')
99
92
  .select()
@@ -144,5 +137,5 @@ export const deleteApp = async (appid: string, options: Options) => {
144
137
  },
145
138
  notify: false,
146
139
  }).catch()
147
- console.log("App deleted from server")
140
+ console.log(`${appid} deleted from server`)
148
141
  }
package/src/bin/index.ts CHANGED
@@ -5,6 +5,7 @@ import { setChannel } from './set';
5
5
  import { uploadVersion } from './upload';
6
6
  import pack from '../../package.json'
7
7
  import { login } from './login';
8
+ import { listApp } from './list';
8
9
 
9
10
  program
10
11
  .version(pack.version)
@@ -45,4 +46,10 @@ program
45
46
  .option('-a, --apikey <apikey>', 'apikey to link to your account')
46
47
  .option('-v, --version <version>', 'version number of the app to delete');
47
48
 
49
+ program
50
+ .description('List versions in capgo Cloud')
51
+ .command('list [appid]').alias('ls')
52
+ .action(listApp)
53
+ .option('-a, --apikey <apikey>', 'apikey to link to your account');
54
+
48
55
  program.parse(process.argv);
@@ -0,0 +1,54 @@
1
+ import { program } from 'commander';
2
+ import { getConfig, createSupabaseClient, findSavedKey, verifyUser } from './utils';
3
+ import { definitions } from './types_supabase'
4
+
5
+ interface Options {
6
+ apikey: string;
7
+ version: string;
8
+ }
9
+
10
+ export const listApp = async (appid: string, options: Options) => {
11
+ const apikey = options.apikey || findSavedKey()
12
+ const config = await getConfig();
13
+
14
+ appid = appid || config?.app?.appId
15
+ if (!apikey) {
16
+ program.error('Missing API key, you need to provide an API key to delete your app');
17
+ }
18
+ if (!appid) {
19
+ program.error('Missing argument, you need to provide a appid, or be in a capacitor project');
20
+ }
21
+ console.log(`Querying available versions in Capgo`);
22
+
23
+ const supabase = createSupabaseClient(apikey)
24
+
25
+ const userId = await verifyUser(supabase, apikey);
26
+
27
+ const { data: app, error: dbError0 } = await supabase
28
+ .rpc<string>('exist_app', { appid, apikey })
29
+ if (!app || dbError0) {
30
+ program.error('No permission for this app')
31
+ }
32
+
33
+ const { data, error: vError } = await supabase
34
+ .from<definitions['app_versions']>('app_versions')
35
+ .select()
36
+ .eq('app_id', appid)
37
+ .eq('user_id', userId)
38
+ .eq('deleted', false)
39
+
40
+ console.log(`Active versions in Capgo: ${data?.length}`);
41
+
42
+ data?.forEach(row => {
43
+ // convert created_at to human time
44
+ const date = new Date(row.created_at || '');
45
+ const humanDate = date.toLocaleString();
46
+ console.log(`${row.name} created on ${humanDate}`);
47
+ });
48
+
49
+ if (vError) {
50
+ program.error(`App ${appid} not found in database ${vError} `)
51
+ }
52
+
53
+
54
+ }
package/src/bin/login.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { program } from 'commander';
2
2
  import fs from 'fs'
3
3
  import os from 'os'
4
- import { createSupabaseClient, formatError, useLogSnag } from './utils';
4
+ import { createSupabaseClient, formatError, useLogSnag, verifyUser } from './utils';
5
5
 
6
6
  interface Options {
7
7
  local: boolean;
@@ -22,12 +22,7 @@ export const login = async (apikey: string, options: Options) => {
22
22
  fs.writeFileSync(`${userHomeDir}/.capgo`, `${apikey}\n`);
23
23
  }
24
24
  const supabase = createSupabaseClient(apikey)
25
- const { data: dataUser, error: userIdError } = await supabase
26
- .rpc<string>('get_user_id', { apikey })
27
- const userId = dataUser ? dataUser.toString() : '';
28
- if (!userId || userIdError) {
29
- program.error(`Cannot verify user ${formatError(userIdError)}`);
30
- }
25
+ const userId = await verifyUser(supabase, apikey, ['write', 'all', 'upload']);
31
26
  snag.publish({
32
27
  channel: 'user-login',
33
28
  event: 'User CLI login',
package/src/bin/set.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { program } from 'commander';
2
2
  import {
3
3
  getConfig, createSupabaseClient, updateOrCreateChannel,
4
- host, formatError, findSavedKey, checkPlan, checkKey, useLogSnag
4
+ host, formatError, findSavedKey, checkPlan, checkKey, useLogSnag, verifyUser
5
5
  } from './utils';
6
6
  import { definitions } from './types_supabase';
7
7
 
@@ -40,15 +40,7 @@ export const setChannel = async (appid: string, options: Options) => {
40
40
  }
41
41
  try {
42
42
  const supabase = createSupabaseClient(apikey)
43
- await checkKey(supabase, apikey, ['write', 'all']);
44
- const { data: dataUser, error: userIdError } = await supabase
45
- .rpc<string>('get_user_id', { apikey })
46
-
47
- const userId = dataUser ? dataUser.toString() : '';
48
-
49
- if (!userId || userIdError) {
50
- program.error(`Cannot verify user ${formatError(userIdError)}`)
51
- }
43
+ const userId = await verifyUser(supabase, apikey, ['write', 'all']);
52
44
  await checkPlan(supabase, userId)
53
45
  const channelPayload: Partial<definitions['channels']> = {
54
46
  created_by: userId,
package/src/bin/upload.ts CHANGED
@@ -6,7 +6,7 @@ import semver from 'semver'
6
6
  import { checksum as getChecksum } from '@tomasklaen/checksum';
7
7
  import {
8
8
  host, hostWeb, getConfig, createSupabaseClient,
9
- updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlan, checkKey, useLogSnag
9
+ updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlan, checkKey, useLogSnag, verifyUser
10
10
  } from './utils';
11
11
 
12
12
  interface Options {
@@ -29,8 +29,9 @@ export const uploadVersion = async (appid: string, options: Options) => {
29
29
  const config = await getConfig();
30
30
  appid = appid || config?.app?.appId
31
31
  version = version || config?.app?.package?.version
32
+ const versionClean = semver.clean(version)
32
33
  // check if version is valid
33
- if (!semver.valid(version)) {
34
+ if (!semver.valid(version) || versionClean !== version) {
34
35
  program.error(`Your version name ${version}, is not valid it should follow semver convention : https://semver.org/`);
35
36
  }
36
37
  path = path || config?.app?.webDir
@@ -43,7 +44,8 @@ export const uploadVersion = async (appid: string, options: Options) => {
43
44
  console.log(`Upload ${appid}@${version} started from path "${path}" to Capgo cloud`);
44
45
 
45
46
  const supabase = createSupabaseClient(apikey)
46
- await checkKey(supabase, apikey, ['write', 'all']);
47
+ const userId = await verifyUser(supabase, apikey, ['write', 'all', 'upload']);
48
+ await checkPlan(supabase, userId, false)
47
49
  const multibar = new cliProgress.MultiBar({
48
50
  clearOnComplete: false,
49
51
  hideCursor: true
@@ -66,16 +68,6 @@ export const uploadVersion = async (appid: string, options: Options) => {
66
68
  program.error(`This app version already exist or was deleted, you cannot re-upload it ${formatError(versionExistError)}`);
67
69
  }
68
70
  b1.increment();
69
-
70
- const { data, error: userIdError } = await supabase
71
- .rpc<string>('get_user_id', { apikey })
72
-
73
- const userId = data ? data.toString() : '';
74
- if (!userId || userIdError) {
75
- multibar.stop()
76
- program.error(`Cannot verify user ${formatError(userIdError)}`);
77
- }
78
- await checkPlan(supabase, userId, false)
79
71
  const { data: isTrial, error: isTrialsError } = await supabase
80
72
  .rpc<number>('is_trial', { userid: userId })
81
73
  .single()
package/src/bin/utils.ts CHANGED
@@ -159,3 +159,17 @@ export const useLogSnag = (): LogSnag => {
159
159
  })
160
160
  return logsnag
161
161
  }
162
+
163
+ export const verifyUser = async (supabase: SupabaseClient, apikey: string, keymod: string[] = ['all']) => {
164
+ await checkKey(supabase, apikey, keymod);
165
+
166
+ const { data: dataUser, error: userIdError } = await supabase
167
+ .rpc<string>('get_user_id', { apikey });
168
+
169
+ const userId = dataUser ? dataUser.toString() : '';
170
+
171
+ if (!userId || userIdError) {
172
+ program.error(`Cannot verify user ${formatError(userIdError)}`);
173
+ }
174
+ return userId;
175
+ }