@capgo/cli 0.16.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.4"
4
+ version = "1.0.0"
5
5
  version_files = [
6
6
  "package.json:version",
7
7
  ".cz.toml"
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 1.0.0 (2022-10-05)
2
+
3
+ ### Feat
4
+
5
+ - rename version in bundle to remove arg conflict
6
+
7
+ ## 0.16.5 (2022-10-02)
8
+
9
+ ### Fix
10
+
11
+ - semver issue use official regex
12
+
1
13
  ## 0.16.4 (2022-09-06)
2
14
 
3
15
  ### Fix
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 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)})();
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)(),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),c=c||(null===(n=null==f?void 0:f.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)}`),v.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 bundle 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{bundle: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:f}=yield d.from("app_versions").select().eq("app_id",e).eq("user_id",l);if(f&&t.program.error(`App ${e} not found in database ${f} `),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:v}=yield d.from("app_versions").delete().eq("app_id",e).eq("user_id",l);v&&t.program.error(`Cannot delete version for app ${e} from database ${v} `);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{bundle: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=r(906),l=r(233);o.uploadVersion=(e,o)=>n(void 0,void 0,void 0,(function*(){var r,n,t,c;let{bundle:u,path:g,channel:f}=o;const{external:v}=o,y=o.apikey||(0,l.findSavedKey)(),m=(0,l.useLogSnag)();f=f||"dev";const h=yield(0,l.getConfig)();e=e||(null===(r=null==h?void 0:h.app)||void 0===r?void 0:r.appId),u=u||(null===(t=null===(n=null==h?void 0:h.app)||void 0===n?void 0:n.package)||void 0===t?void 0:t.version),l.regexSemver.test(u)||i.program.error(`Your bundle name ${u}, is not valid it should follow semver convention : https://semver.org/`),g=g||(null===(c=null==h?void 0:h.app)||void 0===c?void 0:c.webDir),y||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&u&&g||i.program.error("Missing argument, you need to provide a appid and a bundle and a path, or be in a capacitor project"),console.log(`Upload ${e}@${u} started from path "${g}" to Capgo cloud`);const _=(0,l.createSupabaseClient)(y),b=yield(0,l.verifyUser)(_,y,["write","all","upload"]);yield(0,l.checkPlan)(_,b,!1);const k=new s.default.MultiBar({clearOnComplete:!1,hideCursor:!0},s.default.Presets.shades_grey),$=k.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 _.rpc("exist_app_versions",{apikey:y,name_version:u,appid:e});(w||x)&&(k.stop(),i.program.error(`This app bundle already exist or was deleted, you cannot re-upload it ${(0,l.formatError)(x)}`)),$.increment();const{data:C,error:A}=yield _.rpc("is_trial",{userid:b}).single();(C&&C>0||A)&&k.log(`WARNING !!\nTrial expires in ${C} days, upgrade here: ${l.hostWeb}/app/usage\n`),$.increment();const{data:S,error:q}=yield _.rpc("exist_app",{appid:e,apikey:y});S&&!q||(k.stop(),i.program.error(`Cannot find app ${e} in your account \n${(0,l.formatError)(q)}`)),$.increment();const{data:P,error:I}=yield _.rpc("exist_app_versions",{appid:e,apikey:y,name_version:u});(P||I)&&i.program.error(`Version already exists ${(0,l.formatError)(I)}`),$.increment();const j=(0,p.randomUUID)();let M="";if(v)v&&!v.startsWith("https://")&&(k.stop(),i.program.error(`External link should should start with "https://" current is "${v}"`));else{const o=new a.default;o.addLocalFolder(g);const r=o.toBuffer();M=yield(0,d.checksum)(r,"crc32");const n=Math.floor(r.byteLength/1024/1024),t=`apps/${b}/${e}/versions`;$.increment(),n>20&&(k.log(`WARNING !!\nThe app size is ${n} Mb, this may take a while to download for users\n`),m.publish({channel:"app-error",event:"App Too Large",icon:"🚛",tags:{"user-id":b,"app-id":e},notify:!1}).catch());const{error:p}=yield _.storage.from(t).upload(j,r,{contentType:"application/zip"});p&&(k.stop(),i.program.error(`Cannot upload ${(0,l.formatError)(p)}`))}$.increment();const{data:E,error:U}=yield(0,l.updateOrCreateVersion)(_,{bucket_id:v?void 0:j,user_id:b,name:u,app_id:e,external_url:v,checksum:M},y);if(U&&(k.stop(),i.program.error(`Cannot add bundle ${(0,l.formatError)(U)}`)),$.increment(),E&&E.length){const{error:o}=yield(0,l.updateOrCreateChannel)(_,{name:f,app_id:e,created_by:b,version:E[0].id},y);o&&k.log("Cannot set bundle with upload key, use key with more rights for that\n")}else k.log("Cannot set bundle with upload key, use key with more rights for that\n");k.stop();const O=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 ${f} as public here: ${l.hostWeb}/app/package/${O}`),console.log("To use with live update in your own app"),console.log(`You can link specific device to this bundle to make user try it first, here: ${l.hostWeb}/app/p/${O}/devices`),m.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":b,"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.regexSemver=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.regexSemver=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,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")},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":"1.0.0","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","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.4",
3
+ "version": "1.0.0",
4
4
  "description": "A CLI to upload to capgo servers",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -48,7 +48,6 @@
48
48
  "mime": "^3.0.0",
49
49
  "node-stream-zip": "^1.15.0",
50
50
  "prettyjson": "^1.2.5",
51
- "semver": "^7.3.7",
52
51
  "upath": "^2.0.1"
53
52
  },
54
53
  "devDependencies": {
package/src/bin/add.ts CHANGED
@@ -117,5 +117,5 @@ export const addApp = async (appid: string, options: Options) => {
117
117
  },
118
118
  notify: false,
119
119
  }).catch()
120
- console.log("App added to server, you can upload a version now")
120
+ console.log("App added to server, you can upload a bundle now")
121
121
  }
package/src/bin/delete.ts CHANGED
@@ -4,11 +4,11 @@ import { definitions } from './types_supabase'
4
4
 
5
5
  interface Options {
6
6
  apikey: string;
7
- version: string;
7
+ bundle: string;
8
8
  }
9
9
 
10
10
  export const deleteApp = async (appid: string, options: Options) => {
11
- const { version } = options;
11
+ const { bundle } = options;
12
12
  const apikey = options.apikey || findSavedKey()
13
13
  const config = await getConfig();
14
14
  const snag = useLogSnag()
@@ -31,19 +31,19 @@ export const deleteApp = async (appid: string, options: Options) => {
31
31
  program.error('No permission to delete')
32
32
  }
33
33
 
34
- if (version) {
35
- console.log(`Delete ${appid}@${version} from Capgo`);
34
+ if (bundle) {
35
+ console.log(`Delete ${appid}@${bundle} from Capgo`);
36
36
 
37
37
  const { data: versionData, error: versionIdError } = await supabase
38
38
  .from<definitions['app_versions']>('app_versions')
39
39
  .select()
40
40
  .eq('app_id', appid)
41
41
  .eq('user_id', userId)
42
- .eq('name', version)
42
+ .eq('name', bundle)
43
43
  .eq('deleted', false)
44
44
  .single()
45
45
  if (!versionData || versionIdError) {
46
- program.error(`Version ${appid}@${version} doesn't exist ${formatError(versionIdError)}`)
46
+ program.error(`Version ${appid}@${bundle} doesn't exist ${formatError(versionIdError)}`)
47
47
  }
48
48
  const { data: channelFound, error: errorChannel } = await supabase
49
49
  .from<definitions['channels']>('channels')
@@ -52,7 +52,7 @@ export const deleteApp = async (appid: string, options: Options) => {
52
52
  .eq('created_by', userId)
53
53
  .eq('version', versionData.id)
54
54
  if ((channelFound && channelFound.length) || errorChannel) {
55
- program.error(`Version ${appid}@${version} is used in a channel, unlink it first ${formatError(errorChannel)}`)
55
+ program.error(`Version ${appid}@${bundle} is used in a channel, unlink it first ${formatError(errorChannel)}`)
56
56
  }
57
57
  const { data: deviceFound, error: errorDevice } = await supabase
58
58
  .from<definitions['devices_override']>('devices_override')
@@ -60,7 +60,7 @@ export const deleteApp = async (appid: string, options: Options) => {
60
60
  .eq('app_id', appid)
61
61
  .eq('version', versionData.id)
62
62
  if ((deviceFound && deviceFound.length) || errorDevice) {
63
- program.error(`Version ${appid} @${version} is used in a device override, unlink it first ${formatError(errorDevice)}`)
63
+ program.error(`Version ${appid} @${bundle} is used in a device override, unlink it first ${formatError(errorDevice)}`)
64
64
  }
65
65
  // Delete only a specific version in storage
66
66
  const { error: delError } = await supabase
@@ -68,7 +68,7 @@ export const deleteApp = async (appid: string, options: Options) => {
68
68
  .from('apps')
69
69
  .remove([`${userId}/${appid}/versions/${versionData.bucket_id} `])
70
70
  if (delError) {
71
- program.error(`Something went wrong when trying to delete ${appid} @${version} ${delError} `)
71
+ program.error(`Something went wrong when trying to delete ${appid} @${bundle} ${delError} `)
72
72
  }
73
73
 
74
74
  const { error: delAppSpecVersionError } = await supabase
@@ -78,11 +78,11 @@ export const deleteApp = async (appid: string, options: Options) => {
78
78
  })
79
79
  .eq('app_id', appid)
80
80
  .eq('user_id', userId)
81
- .eq('name', version)
81
+ .eq('name', bundle)
82
82
  if (delAppSpecVersionError) {
83
- program.error(`App ${appid}@${version} not found in database '${delAppSpecVersionError}'`)
83
+ program.error(`App ${appid}@${bundle} not found in database '${delAppSpecVersionError}'`)
84
84
  }
85
- console.log(`${appid}@${version} deleted from server`)
85
+ console.log(`${appid}@${bundle} deleted from server`)
86
86
  return
87
87
  }
88
88
 
package/src/bin/set.ts CHANGED
@@ -1,26 +1,26 @@
1
1
  import { program } from 'commander';
2
2
  import {
3
3
  getConfig, createSupabaseClient, updateOrCreateChannel,
4
- host, formatError, findSavedKey, checkPlan, checkKey, useLogSnag, verifyUser
4
+ host, formatError, findSavedKey, checkPlan, useLogSnag, verifyUser
5
5
  } from './utils';
6
6
  import { definitions } from './types_supabase';
7
7
 
8
8
  interface Options {
9
9
  apikey: string;
10
- version: string;
10
+ bundle: string;
11
11
  state: string;
12
12
  channel?: string;
13
13
  }
14
14
 
15
15
  export const setChannel = async (appid: string, options: Options) => {
16
- let { version } = options;
16
+ let { bundle } = options;
17
17
  const { state, channel = 'dev' } = options;
18
18
  const apikey = options.apikey || findSavedKey()
19
19
  const config = await getConfig();
20
20
  const snag = useLogSnag()
21
21
 
22
22
  appid = appid || config?.app?.appId
23
- version = version || config?.app?.package?.version
23
+ bundle = bundle || config?.app?.package?.version
24
24
  let parsedState
25
25
  if (state === 'public' || state === 'private')
26
26
  parsedState = state === 'public'
@@ -30,11 +30,11 @@ export const setChannel = async (appid: string, options: Options) => {
30
30
  if (!appid) {
31
31
  program.error("Missing argument, you need to provide a appid, or be in a capacitor project");
32
32
  }
33
- if (!version && !parsedState) {
33
+ if (!bundle && !parsedState) {
34
34
  program.error("Missing argument, you need to provide a state or a version");
35
35
  }
36
- if (version) {
37
- console.log(`Set ${channel} to @${version} in ${appid}`);
36
+ if (bundle) {
37
+ console.log(`Set ${channel} to @${bundle} in ${appid}`);
38
38
  } else {
39
39
  console.log(`Set${channel} to @${state} in ${appid}`);
40
40
  }
@@ -47,16 +47,16 @@ export const setChannel = async (appid: string, options: Options) => {
47
47
  app_id: appid,
48
48
  name: channel,
49
49
  }
50
- if (version) {
50
+ if (bundle) {
51
51
  const { data, error: vError } = await supabase
52
52
  .from<definitions['app_versions']>('app_versions')
53
53
  .select()
54
54
  .eq('app_id', appid)
55
- .eq('name', version)
55
+ .eq('name', bundle)
56
56
  .eq('user_id', userId)
57
57
  .eq('deleted', false)
58
58
  if (vError || !data || !data.length)
59
- program.error(`Cannot find version ${version}`);
59
+ program.error(`Cannot find version ${bundle}`);
60
60
  channelPayload.version = data[0].id
61
61
  }
62
62
  if (parsedState !== undefined)
@@ -82,7 +82,7 @@ export const setChannel = async (appid: string, options: Options) => {
82
82
  } catch (err) {
83
83
  program.error(`Unknow error ${formatError(err)}`);
84
84
  }
85
- if (version) {
85
+ if (bundle) {
86
86
  console.log(`Done ✅`);
87
87
  } else {
88
88
  console.log(`You can use now is channel in your app with the url: ${host}/api/latest?appid=${appid}&channel=${channel}`);
package/src/bin/upload.ts CHANGED
@@ -2,15 +2,14 @@ import AdmZip from 'adm-zip';
2
2
  import { program } from 'commander';
3
3
  import { randomUUID } from 'crypto';
4
4
  import cliProgress from 'cli-progress';
5
- import semver from 'semver'
6
5
  import { checksum as getChecksum } from '@tomasklaen/checksum';
7
6
  import {
8
7
  host, hostWeb, getConfig, createSupabaseClient,
9
- updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlan, checkKey, useLogSnag, verifyUser
8
+ updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlan, useLogSnag, verifyUser, regexSemver
10
9
  } from './utils';
11
10
 
12
11
  interface Options {
13
- version: string
12
+ bundle: string
14
13
  path: string
15
14
  apikey: string
16
15
  channel?: string
@@ -20,7 +19,7 @@ interface Options {
20
19
  const alertMb = 20;
21
20
 
22
21
  export const uploadVersion = async (appid: string, options: Options) => {
23
- let { version, path, channel } = options;
22
+ let { bundle, path, channel } = options;
24
23
  const { external } = options;
25
24
  const apikey = options.apikey || findSavedKey()
26
25
  const snag = useLogSnag()
@@ -28,20 +27,19 @@ export const uploadVersion = async (appid: string, options: Options) => {
28
27
  channel = channel || 'dev';
29
28
  const config = await getConfig();
30
29
  appid = appid || config?.app?.appId
31
- version = version || config?.app?.package?.version
32
- const versionClean = semver.clean(version)
33
- // check if version is valid
34
- if (!semver.valid(version) || versionClean !== version) {
35
- program.error(`Your version name ${version}, is not valid it should follow semver convention : https://semver.org/`);
30
+ bundle = bundle || config?.app?.package?.version
31
+ // check if bundle is valid
32
+ if (!regexSemver.test(bundle)) {
33
+ program.error(`Your bundle name ${bundle}, is not valid it should follow semver convention : https://semver.org/`);
36
34
  }
37
35
  path = path || config?.app?.webDir
38
36
  if (!apikey) {
39
37
  program.error("Missing API key, you need to provide a API key to add your app");
40
38
  }
41
- if (!appid || !version || !path) {
42
- program.error("Missing argument, you need to provide a appid and a version and a path, or be in a capacitor project");
39
+ if (!appid || !bundle || !path) {
40
+ program.error("Missing argument, you need to provide a appid and a bundle and a path, or be in a capacitor project");
43
41
  }
44
- console.log(`Upload ${appid}@${version} started from path "${path}" to Capgo cloud`);
42
+ console.log(`Upload ${appid}@${bundle} started from path "${path}" to Capgo cloud`);
45
43
 
46
44
  const supabase = createSupabaseClient(apikey)
47
45
  const userId = await verifyUser(supabase, apikey, ['write', 'all', 'upload']);
@@ -61,11 +59,11 @@ export const uploadVersion = async (appid: string, options: Options) => {
61
59
 
62
60
  // checking if user has access rights before uploading
63
61
  const { data: versionExist, error: versionExistError } = await supabase
64
- .rpc('exist_app_versions', { apikey, name_version: version, appid })
62
+ .rpc('exist_app_versions', { apikey, name_version: bundle, appid })
65
63
 
66
64
  if (versionExist || versionExistError) {
67
65
  multibar.stop()
68
- program.error(`This app version already exist or was deleted, you cannot re-upload it ${formatError(versionExistError)}`);
66
+ program.error(`This app bundle already exist or was deleted, you cannot re-upload it ${formatError(versionExistError)}`);
69
67
  }
70
68
  b1.increment();
71
69
  const { data: isTrial, error: isTrialsError } = await supabase
@@ -85,7 +83,7 @@ export const uploadVersion = async (appid: string, options: Options) => {
85
83
  b1.increment();
86
84
  // check if app already exist
87
85
  const { data: appVersion, error: appVersionError } = await supabase
88
- .rpc<string>('exist_app_versions', { appid, apikey, name_version: version })
86
+ .rpc<string>('exist_app_versions', { appid, apikey, name_version: bundle })
89
87
  if (appVersion || appVersionError) {
90
88
  program.error(`Version already exists ${formatError(appVersionError)}`)
91
89
  }
@@ -131,14 +129,14 @@ export const uploadVersion = async (appid: string, options: Options) => {
131
129
  const { data: versionData, error: dbError } = await updateOrCreateVersion(supabase, {
132
130
  bucket_id: external ? undefined : fileName,
133
131
  user_id: userId,
134
- name: version,
132
+ name: bundle,
135
133
  app_id: appid,
136
134
  external_url: external,
137
135
  checksum,
138
136
  }, apikey)
139
137
  if (dbError) {
140
138
  multibar.stop()
141
- program.error(`Cannot add version ${formatError(dbError)}`)
139
+ program.error(`Cannot add bundle ${formatError(dbError)}`)
142
140
  }
143
141
  b1.increment();
144
142
  if (versionData && versionData.length) {
@@ -149,10 +147,10 @@ export const uploadVersion = async (appid: string, options: Options) => {
149
147
  version: versionData[0].id,
150
148
  }, apikey)
151
149
  if (dbError3) {
152
- multibar.log('Cannot set version with upload key, use key with more rights for that\n');
150
+ multibar.log('Cannot set bundle with upload key, use key with more rights for that\n');
153
151
  }
154
152
  } else {
155
- multibar.log('Cannot set version with upload key, use key with more rights for that\n');
153
+ multibar.log('Cannot set bundle with upload key, use key with more rights for that\n');
156
154
  }
157
155
  multibar.stop()
158
156
  const appidWeb = appid.replace(/\./g, '--')
@@ -160,7 +158,7 @@ export const uploadVersion = async (appid: string, options: Options) => {
160
158
  console.log(`Try it in mobile app: ${host}/app_mobile`)
161
159
  console.log(`Or set the channel ${channel} as public here: ${hostWeb}/app/package/${appidWeb}`)
162
160
  console.log("To use with live update in your own app")
163
- console.log(`You can link specific device to this version to make user try it first, here: ${hostWeb}/app/p/${appidWeb}/devices`)
161
+ console.log(`You can link specific device to this bundle to make user try it first, here: ${hostWeb}/app/p/${appidWeb}/devices`)
164
162
  snag.publish({
165
163
  channel: 'app',
166
164
  event: 'App Uploaded',
package/src/bin/utils.ts CHANGED
@@ -27,6 +27,9 @@ export const createSupabaseClient = (apikey: string) => createClient(hostSupa, s
27
27
  capgkey: apikey,
28
28
  }
29
29
  })
30
+ // eslint-disable-next-line max-len
31
+ export const regexSemver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
32
+
30
33
 
31
34
  export const checkKey = async (supabase: SupabaseClient, apikey: string, keymode: string[]) => {
32
35
  const { data: apiAccess, error: apiAccessError } = await supabase
@@ -0,0 +1,13 @@
1
+ // import semver from 'semver'
2
+
3
+ // eslint-disable-next-line max-len
4
+ const regex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
5
+ const bundles = ['20220929.0.0+7c146f40', 'v1.2.3']
6
+ // check if bundle is valid
7
+ for (const bundle of bundles) {
8
+ if (!regex.test(bundle)) {
9
+ console.log(`Your bundle name ${bundle}, is not valid it should follow semver convention : https://semver.org/`);
10
+ } else {
11
+ console.log('valid')
12
+ }
13
+ }