@capgo/cli 1.3.1 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.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 = "1.3.1"
4
+ version = "1.4.1"
5
5
  version_files = [
6
6
  "package.json:version",
7
7
  ".cz.toml"
package/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 1.4.1 (2022-11-21)
2
+
3
+ ### Fix
4
+
5
+ - upload without key
6
+
7
+ ## 1.4.0 (2022-11-21)
8
+
9
+ ### Feat
10
+
11
+ - add key gen method and decode
12
+
13
+ ### Fix
14
+
15
+ - path
16
+
17
+ ## 1.3.2 (2022-11-21)
18
+
19
+ ### Fix
20
+
21
+ - error formating + better import
22
+
1
23
  ## 1.3.1 (2022-11-17)
2
24
 
3
25
  ### Fix
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- (()=>{"use strict";var e={111:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkAppExistsAndHasPermission=void 0;const i=n(304);o.checkAppExistsAndHasPermission=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:r}=yield e.rpc("exist_app",{appid:o,apikey:n});t&&!r||i.program.error("No permission for this app")}))},708:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkVersionNotUsedInChannel=void 0;const i=n(304),r=n(771);o.checkVersionNotUsedInChannel=(e,o,n,a,s)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:d}=yield e.from("channels").select().eq("app_id",o).eq("created_by",n).eq("version",a.id);(t&&t.length||d)&&i.program.error(`Version ${o}@${s} is used in a channel, unlink it first ${(0,r.formatError)(d)}`)}))},314:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkVersionNotUsedInDeviceOverride=void 0;const i=n(304),r=n(771);o.checkVersionNotUsedInDeviceOverride=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:s}=yield e.from("devices_override").select().eq("app_id",o).eq("version",n.id);(t&&t.length||s)&&i.program.error(`Version ${o} @${a} is used in a device override, unlink it first ${(0,r.formatError)(s)}`)}))},109:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteFromStorage=void 0;const i=n(304);o.deleteFromStorage=(e,o,n,r,a)=>t(void 0,void 0,void 0,(function*(){const{error:t}=yield e.storage.from("apps").remove([`${o}/${n}/versions/${r.bucket_id} `]);t&&i.program.error(`Something went wrong when trying to delete ${n} @${a} ${t} `)}))},87:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.getVersionData=o.getActiveAppVersions=o.deleteSpecificVersion=o.deleteAppVersion=void 0;const i=n(304),r=n(771),a=n(708),s=n(314),d=n(109);o.deleteAppVersion=(e,o,n,r)=>t(void 0,void 0,void 0,(function*(){const{error:t}=yield e.from("app_versions").update({deleted:!0}).eq("app_id",o).eq("user_id",n).eq("name",r);t&&i.program.error(`App ${o}@${r} not found in database '${t}'`)})),o.deleteSpecificVersion=(e,n,i,r)=>t(void 0,void 0,void 0,(function*(){const t=yield(0,o.getVersionData)(e,n,i,r);yield(0,a.checkVersionNotUsedInChannel)(e,n,i,t,r),yield(0,s.checkVersionNotUsedInDeviceOverride)(e,n,t,r),yield(0,d.deleteFromStorage)(e,i,n,t,r),yield(0,o.deleteAppVersion)(e,n,i,r)})),o.getActiveAppVersions=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:r}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("deleted",!1);return r&&i.program.error(`App ${o} not found in database ${r} `),t})),o.getVersionData=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:s}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("name",a).eq("deleted",!1).single();return t&&!s||i.program.error(`Version ${o}@${a} doesn't exist ${(0,r.formatError)(s)}`),t}))},107:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.addApp=void 0;const i=n(304),r=n(113),a=n(147),s=n(470),d=n(11),p=n(771),l="assets/icon.png";o.addApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t;let{name:c,icon:u}=o;const v=o.apikey||(0,p.findSavedKey)(),f=yield(0,p.getConfig)(),g=(0,p.useLogSnag)();e=e||(null===(n=null==f?void 0:f.app)||void 0===n?void 0:n.appId),c=c||(null===(t=null==f?void 0:f.app)||void 0===t?void 0:t.appName)||"Unknown",u=u||"resources/icon.png",v||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&c||i.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,p.createSupabaseClient)(v),m=yield(0,p.verifyUser)(y,v,["write","all"]);let h,_;yield(0,p.checkPlanValid)(y,m),console.log("Adding..."),u&&(0,s.existsSync)(u)?(h=(0,a.readFileSync)(u),_=(0,d.getType)(u)||"image/png",console.warn(`Found app icon ${u}`)):(0,s.existsSync)(l)?(h=(0,a.readFileSync)(l),_=(0,d.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:w}=yield y.rpc("exist_app",{appid:e,apikey:v});(b||w)&&i.program.error(`App already exists ${(0,p.formatError)(w)}`);const k=`icon_${(0,r.randomUUID)()}`;let $="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(h&&_){const{error:o}=yield y.storage.from(`images/${m}/${e}`).upload(k,h,{contentType:_});o&&i.program.error(`Could not add app ${(0,p.formatError)(o)}`);const{data:n}=yield y.storage.from(`images/${m}/${e}`).getPublicUrl(k);$=(null==n?void 0:n.publicURL)||$}const{error:x}=yield y.from("apps").insert({icon_url:$,user_id:m,name:c,app_id:e},{returning:"minimal"});x&&i.program.error(`Could not add app ${(0,p.formatError)(x)}`);const{error:A}=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"});A&&i.program.error(`Could not add app ${(0,p.formatError)(A)}`),g.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")}))},176:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.cleanupApp=void 0;const r=n(304),a=i(n(505)),s=i(n(616)),d=n(771),p=n(87),l=n(111),c=(0,s.default)();o.cleanupApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,d.findSavedKey)(),{bundle:i,keep:s=4}=o,u=o.force||!1,v=yield(0,d.getConfig)();e=e||(null===(n=null==v?void 0:v.app)||void 0===n?void 0:n.appId),t||r.program.error("Missing API key, you need to provide an API key to delete your app"),e||r.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const f=`${a.default.inc(i,"major")}`;console.log(`Querying available versions in Capgo between ${i} and ${f}`);const g=(0,d.createSupabaseClient)(t),y=yield(0,d.verifyUser)(g,t);yield(0,l.checkAppExistsAndHasPermission)(g,e,t);const m=yield(0,p.getActiveAppVersions)(g,e,y);if(console.log(`Total active versions in Capgo: ${null==m?void 0:m.length}`),0===(null==m?void 0:m.length))return;const h=((e,o,n)=>{const t=[];return null==e||e.forEach((e=>{a.default.gte(e.name,o)&&a.default.lt(e.name,`${n}`)&&t.push(e)})),t})(m,i,f).reverse();console.log(`Active versions in Capgo between ${i} and ${f}: ${null==h?void 0:h.length}`);const _=h.slice(0,s),b=h.slice(s);if(_.forEach((e=>{console.log(`${e.name} created on ${(0,d.getHumanDate)(e)} will be kept`)})),_.length&&console.log("==================================================="),0!==b.length){if(b.forEach((e=>{console.log(`${e.name} created on ${(0,d.getHumanDate)(e)} will be removed`)})),!u&&"yes"!==c("Do you want to continue removing the versions specified? Type yes to confirm"))return void console.log("Not confirmed, aborting removal...");console.log("You have confirmed removal, removing versions now"),((e,o,n,t)=>{null==e||e.forEach((e=>{console.log(`Removing ${e.name} created on ${(0,d.getHumanDate)(e)}`),(0,p.deleteSpecificVersion)(o,n,t,e.name)}))})(b,g,e,y)}else console.log("Nothing to be removed, aborting removal...")}))},605:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteApp=void 0;const i=n(304),r=n(771),a=n(87);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const{bundle:t}=o,s=o.apikey||(0,r.findSavedKey)(),d=yield(0,r.getConfig)(),p=(0,r.useLogSnag)();e=e||(null===(n=null==d?void 0:d.app)||void 0===n?void 0:n.appId),s||i.program.error("Missing API key, you need to provide an API key to delete your app"),e||i.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const l=(0,r.createSupabaseClient)(s),c=yield(0,r.verifyUser)(l,s),{data:u,error:v}=yield l.rpc("exist_app",{appid:e,apikey:s});if(u&&!v||i.program.error("No permission to delete"),t)return console.log(`Delete ${e}@${t} from Capgo`),yield(0,a.deleteSpecificVersion)(l,e,c,t),void console.log(`${e}@${t} deleted from server`);console.log(`Delete ${e} from Capgo`);const{data:f,error:g}=yield l.from("app_versions").select().eq("app_id",e).eq("user_id",c);if(g&&i.program.error(`App ${e} not found in database ${g} `),f&&f.length){const o=f.map((o=>`${c}/${e}/versions/${o.bucket_id} `)),{error:n}=yield l.storage.from("apps").remove(o);n&&i.program.error(`Cannot delete stored version for app ${e} from storage ${n} `)}const{error:y}=yield l.from("app_versions").delete().eq("app_id",e).eq("user_id",c);y&&i.program.error(`Cannot delete version for app ${e} from database ${y} `);const{error:m}=yield l.from("apps").delete().eq("app_id",e).eq("user_id",c);m&&i.program.error(`Cannot delete from database ${m} `),p.publish({channel:"app",event:"App Deleted",icon:"😱",tags:{"user-id":c,"app-id":e},notify:!1}).catch(),console.log(`${e} deleted from server`)}))},250:function(e,o,n){var t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0});const i=n(304),r=n(107),a=n(605),s=n(327),d=n(823),p=t(n(598)),l=n(829),c=n(501),u=n(176);i.program.description("Manage packages and bundle versions in capgo Cloud").version(p.default.version),i.program.command("add [appid]").alias("a").description("Add a new app to capgo Cloud").action(r.addApp).option("-n, --name <name>","app name").option("-i, --icon <icon>","app icon path").option("-a, --apikey <apikey>","apikey to link to your account"),i.program.command("login [apikey]").alias("l").description("Save apikey to your machine or folder").action(l.login).option("--local","Only save in local folder"),i.program.command("upload [appid]").alias("u").description("Upload a new bundle to capgo Cloud").action(d.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("-b, --bundle <bundle>","bundle version number of the file to upload"),i.program.command("set [appid]").alias("s").description("Modify a channel configuration").action(s.setChannel).requiredOption("-c, --channel <channel>","channel to link to").option("-a, --apikey <apikey>","apikey to link to your account").option("-b, --bundle <bundle>","bundle version number of the file to set").option("-s, --state <state>","set the state of the channel, default or normal").option("--downgrade","Allow to downgrade to version under native one").option("--latest","get the latest version key in the package.json to set it to the channel").option("--no-downgrade","Disable downgrade to version under native one").option("--upgrade","Allow to upgrade to version above native one").option("--no-upgrade","Disable upgrade to version above native one").option("--ios","Allow sending update to ios devices").option("--no-ios","Disable sending update to ios devices").option("--android","Allow sending update to android devices").option("--no-android","Disable sending update to android devices").option("--self-assign","Allow to device to self assign to this channel").option("--no-self-assign","Disable devices to self assign to this channel"),i.program.command("delete [appid]").alias("d").description("Delete an app from capgo Cloud").action(a.deleteApp).option("-a, --apikey <apikey>","apikey to link to your account").option("-b, --bundle <bundle>","bundle version number of the app to delete"),i.program.command("list [appid]").alias("ls").description("List versions in capgo Cloud").action(c.listApp).option("-a, --apikey <apikey>","apikey to link to your account"),i.program.command("cleanup [appid]").alias("c").description("Cleanup versions in capgo Cloud").action(u.cleanupApp).requiredOption("-b, --bundle <bundle>","bundle version number of the app to delete").option("-a, --apikey <apikey>","apikey to link to your account").option("-k, --keep <keep>","number of version to keep").option("-f, --force","force removal"),i.program.parse(process.argv)},501:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.listApp=void 0;const i=n(304),r=n(771),a=n(111),s=n(87);o.listApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,r.findSavedKey)(),d=yield(0,r.getConfig)();e=e||(null===(n=null==d?void 0:d.app)||void 0===n?void 0:n.appId),t||i.program.error("Missing API key, you need to provide an API key to delete your app"),e||i.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,r.createSupabaseClient)(t),l=yield(0,r.verifyUser)(p,t);yield(0,a.checkAppExistsAndHasPermission)(p,e,t);const c=yield(0,s.getActiveAppVersions)(p,e,l);console.log(`Active versions in Capgo: ${null==c?void 0:c.length}`),null==c||c.forEach((e=>{console.log(`${e.name} created on ${(0,r.getHumanDate)(e)}`)}))}))},829:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.login=void 0;const r=n(304),a=i(n(147)),s=i(n(37)),d=n(771);o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:n}=o,t=(0,d.useLogSnag)();if(n)a.default.existsSync(".git")||r.program.error("To use local you should be in a git repository"),a.default.writeFileSync(".capgo",`${e}\n`),a.default.appendFileSync(".gitignore",".capgo\n");else{const o=s.default.homedir();a.default.writeFileSync(`${o}/.capgo`,`${e}\n`)}const i=(0,d.createSupabaseClient)(e),p=yield(0,d.verifyUser)(i,e,["write","all","upload"]);t.publish({channel:"user-login",event:"User CLI login",icon:"✅",tags:{"user-id":p},notify:!1}).catch(),console.log(`login saved into .capgo file in ${n?"local":"home"} directory`)}))},327:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.setChannel=void 0;const i=n(304),r=n(771);o.setChannel=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,a;const{bundle:s,latest:d,downgrade:p,upgrade:l,ios:c,android:u,selfAssign:v,channel:f,state:g}=o,y=o.apikey||(0,r.findSavedKey)(),m=yield(0,r.getConfig)(),h=(0,r.useLogSnag)();e=e||(null===(n=null==m?void 0:m.app)||void 0===n?void 0:n.appId),y||i.program.error("Missing API key, you need to provide a API key to add your app"),e||i.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),d&&s&&i.program.error("Cannot set latest and bundle at the same time"),void 0===s&&void 0===g&&void 0===d&&void 0===p&&void 0===l&&void 0===c&&void 0===u&&void 0===v&&i.program.error("Missing argument, you need to provide a option to set");try{const o=(0,r.createSupabaseClient)(y),n=yield(0,r.verifyUser)(o,y,["write","all"]);yield(0,r.checkPlanValid)(o,n);const _={created_by:n,app_id:e,name:f},b=d?null===(a=null===(t=null==m?void 0:m.app)||void 0===t?void 0:t.package)||void 0===a?void 0:a.version:s;if(b){const{data:t,error:r}=yield o.from("app_versions").select().eq("app_id",e).eq("name",b).eq("user_id",n).eq("deleted",!1);!r&&t&&t.length||i.program.error(`Cannot find version ${b}`),console.log(`Set ${e} channel: ${f} to @${s}`),_.version=t[0].id}void 0!==g&&("public"!==g&&"private"!==g||console.log(`Set ${e} channel: ${f} to public or private is deprecated, use default or normal instead`),console.log(`Set ${e} channel: ${f} to ${"public"===g||"default"===g?"default":"normal"}`),_.public="public"===g||"default"===g),void 0!==p&&(console.log(`Set ${e} channel: ${f} to ${p?"allow":"disallow"} downgrade`),_.disableAutoUpdateUnderNative=!p),void 0!==l&&(console.log(`Set ${e} channel: ${f} to ${l?"allow":"disallow"} upgrade`),_.disableAutoUpdateToMajor=!l),void 0!==c&&(console.log(`Set ${e} channel: ${f} to ${c?"allow":"disallow"} ios update`),_.ios=!!c),void 0!==u&&(console.log(`Set ${e} channel: ${f} to ${u?"allow":"disallow"} android update`),_.android=!!u),void 0!==v&&(console.log(`Set ${e} channel: ${f} to ${v?"allow":"disallow"} self assign to this channel`),_.allow_device_self_set=!!v);try{const{error:e}=yield(0,r.updateOrCreateChannel)(o,_,y);e&&i.program.error(`Cannot set channel ${(0,r.formatError)(e)}`)}catch(e){i.program.error(`Cannot set channel ${(0,r.formatError)(e)}`)}h.publish({channel:"app",event:"Set app",icon:"✅",tags:{"user-id":n,"app-id":e},notify:!1}).catch()}catch(e){i.program.error(`Unknow error ${(0,r.formatError)(e)}`)}console.log("Done ✅")}))},823:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.uploadVersion=void 0;const r=i(n(844)),a=n(304),s=n(113),d=i(n(295)),p=n(906),l=n(771);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,i,c;let{bundle:u,path:v,channel:f}=o;const{external:g}=o,y=o.apikey||(0,l.findSavedKey)(),m=(0,l.useLogSnag)();f=f||"dev";const h=yield(0,l.getConfig)();e=e||(null===(n=null==h?void 0:h.app)||void 0===n?void 0:n.appId),u=u||(null===(i=null===(t=null==h?void 0:h.app)||void 0===t?void 0:t.package)||void 0===i?void 0:i.version),l.regexSemver.test(u)||a.program.error(`Your bundle name ${u}, is not valid it should follow semver convention : https://semver.org/`),v=v||(null===(c=null==h?void 0:h.app)||void 0===c?void 0:c.webDir),y||a.program.error("Missing API key, you need to provide a API key to add your app"),e&&u&&v||a.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 "${v}" to Capgo cloud`);const _=(0,l.createSupabaseClient)(y),b=yield(0,l.verifyUser)(_,y,["write","all","upload"]);yield(0,l.checkPlanValid)(_,b,!1);const w=new d.default.MultiBar({clearOnComplete:!1,hideCursor:!0},d.default.Presets.shades_grey),k=w.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},d.default.Presets.shades_grey);k.start(7,0,{speed:"N/A"});const{data:$,error:x}=yield _.rpc("exist_app_versions",{apikey:y,name_version:u,appid:e});($||x)&&(w.stop(),a.program.error(`This app bundle already exist or was deleted, you cannot re-upload it ${(0,l.formatError)(x)}`)),k.increment();const{data:A,error:C}=yield _.rpc("is_trial",{userid:b}).single();(A&&A>0||C)&&w.log(`WARNING !!\nTrial expires in ${A} days, upgrade here: ${l.hostWeb}/dashboard/settings/plans\n`),k.increment();const{data:S,error:P}=yield _.rpc("exist_app",{appid:e,apikey:y});S&&!P||(w.stop(),a.program.error(`Cannot find app ${e} in your account \n${(0,l.formatError)(P)}`)),k.increment();const{data:q,error:I}=yield _.rpc("exist_app_versions",{appid:e,apikey:y,name_version:u});(q||I)&&a.program.error(`Version already exists ${(0,l.formatError)(I)}`),k.increment();const j=(0,s.randomUUID)();let M="";if(g)g&&!g.startsWith("https://")&&(w.stop(),a.program.error(`External link should should start with "https://" current is "${g}"`));else{const o=new r.default;o.addLocalFolder(v);const n=o.toBuffer();M=yield(0,p.checksum)(n,"crc32");const t=Math.floor(n.byteLength/1024/1024),i=`apps/${b}/${e}/versions`;k.increment(),t>20&&(w.log(`WARNING !!\nThe app size is ${t} 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:s}=yield _.storage.from(i).upload(j,n,{contentType:"application/zip"});s&&(w.stop(),a.program.error(`Cannot upload ${(0,l.formatError)(s)}`))}k.increment();const{data:D,error:V}=yield(0,l.updateOrCreateVersion)(_,{bucket_id:g?void 0:j,user_id:b,name:u,app_id:e,external_url:g,checksum:M},y);if(V&&(w.stop(),a.program.error(`Cannot add bundle ${(0,l.formatError)(V)}`)),k.increment(),D&&D.length){const{error:o}=yield(0,l.updateOrCreateChannel)(_,{name:f,app_id:e,created_by:b,version:D[0].id},y);o&&w.log("Cannot set bundle with upload key, use key with more rights for that\n")}else w.log("Cannot set bundle with upload key, use key with more rights for that\n");w.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 ${f} 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 bundle to make user try it first, here: ${l.hostWeb}/app/p/${U}/devices`),m.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":b,"app-id":e},notify:!1}).catch()}))},771:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(i,r){function a(e){try{d(t.next(e))}catch(e){r(e)}}function s(e){try{d(t.throw(e))}catch(e){r(e)}}function d(e){var o;e.done?i(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}d((t=t.apply(e,o||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.getHumanDate=o.verifyUser=o.useLogSnag=o.updateOrCreateChannel=o.updateOrCreateVersion=o.getConfig=o.formatError=o.findSavedKey=o.checkPlanValid=o.isTrial=o.isPaying=o.isGoodPlan=o.checkKey=o.regexSemver=o.createSupabaseClient=o.supaAnon=o.hostSupa=o.hostWeb=o.host=void 0;const r=n(778),a=n(304),s=n(885),d=i(n(867)),p=i(n(147)),l=i(n(37)),c=n(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,s.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,n,i)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:r}=yield e.rpc("is_allowed_capgkey",{apikey:n,keymode:i});t&&!r||a.program.error(`Invalid API key or insufficient permissions ${(0,o.formatError)(r)}`)})),o.isGoodPlan=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_good_plan_v2",{userid:o}).single();if(t)throw t;return n||!1})),o.isPaying=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_paying",{userid:o}).single();if(t)throw t;return n||!1})),o.isTrial=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_trial",{userid:o}).single();if(t)throw t;return n||0})),o.checkPlanValid=(e,n,i=!0)=>t(void 0,void 0,void 0,(function*(){const t=yield(0,o.isGoodPlan)(e,n),r=yield(0,o.isPaying)(e,n),s=yield(0,o.isTrial)(e,n);r&&t||!(s<0)||a.program.error(`You need to upgrade your plan to continue to use capgo.\n Upgrade here: ${o.hostWeb}/dashboard/settings/plans\n`),s>0&&i&&!r&&console.log(`WARNING !!\nTrial expires in ${s} days, upgrade here: ${o.hostWeb}/dashboard/settings/plans\n`)})),o.findSavedKey=()=>{let e=`${l.default.homedir()}/.capgo`;return p.default.existsSync(e)?p.default.readFileSync(e,"utf8").trim():(e=".capgo",p.default.existsSync(e)?p.default.readFileSync(e,"utf8").trim():null)},o.formatError=e=>e?`\n${d.default.render(e)}`:"",o.getConfig=()=>t(void 0,void 0,void 0,(function*(){let e;try{e=yield(0,r.loadConfig)()}catch(e){a.program.error("No capacitor config file found, run `cap init` first")}return e})),o.updateOrCreateVersion=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:i}=yield e.rpc("exist_app_versions",{appid:o.app_id,name_version:o.name,apikey:n});return t&&!i?(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,n)=>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:i}=yield e.rpc("exist_channel",{appid:o.app_id,name_channel:o.name,apikey:n});return t&&!i?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,n,i=["all"])=>t(void 0,void 0,void 0,(function*(){yield(0,o.checkKey)(e,n,i);const{data:t,error:r}=yield e.rpc("get_user_id",{apikey:n}),s=t?t.toString():"";return s&&!r||a.program.error(`Cannot verify user ${(0,o.formatError)(r)}`),s})),o.getHumanDate=e=>new Date(e.created_at||"").toLocaleString()},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")},616:e=>{e.exports=require("prompt-sync")},505:e=>{e.exports=require("semver/preload")},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.3.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":"4.4.0","@supabase/supabase-js":"^1.35.7","@tomasklaen/checksum":"^1.1.0","adm-zip":"^0.5.9","cli-progress":"3.11.2","commander":"9.4.1","fs-extra":"10.1.0","logsnag":"^0.1.5","mime":"^3.0.0","prettyjson":"^1.2.5","prompt-sync":"^4.2.0","semver":"^7.3.8"},"devDependencies":{"@types/adm-zip":"0.5.0","@types/cli-progress":"^3.11.0","@types/fs-extra":"^9.0.13","@types/mime":"^3.0.1","@types/node":"^18.11.9","@types/prettyjson":"^0.0.30","@types/prompt-sync":"^4.2.0","@types/semver":"^7.3.13","@typescript-eslint/eslint-plugin":"5.42.1","@typescript-eslint/parser":"5.42.1","eslint":"8.27.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^8.5.0","eslint-import-resolver-typescript":"3.5.2","eslint-plugin-import":"2.26.0","eslint-plugin-prettier":"^4.2.1","git-format-staged":"3.0.0","husky":"^8.0.2","nodemon":"2.0.20","pkg":"5.8.0","prettier":"2.7.1","ts-loader":"^9.4.1","ts-node":"^10.9.1","tsconfig-paths":"4.1.0","typescript":"4.8.4","webpack":"5.74.0","webpack-cli":"^4.10.0","webpack-node-externals":"^3.0.0"}}')}},o={};!function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t].call(r.exports,r,r.exports,n),r.exports}(250)})();
2
+ (()=>{"use strict";var e={111:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkAppExistsAndHasPermission=void 0;const r=n(304);o.checkAppExistsAndHasPermission=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:i}=yield e.rpc("exist_app",{appid:o,apikey:n});t&&!i||r.program.error("No permission for this app")}))},708:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkVersionNotUsedInChannel=void 0;const r=n(304),i=n(771);o.checkVersionNotUsedInChannel=(e,o,n,a,s)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:p}=yield e.from("channels").select().eq("app_id",o).eq("created_by",n).eq("version",a.id);(t&&t.length||p)&&r.program.error(`Version ${o}@${s} is used in a channel, unlink it first ${(0,i.formatError)(p)}`)}))},314:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.checkVersionNotUsedInDeviceOverride=void 0;const r=n(304),i=n(771);o.checkVersionNotUsedInDeviceOverride=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:s}=yield e.from("devices_override").select().eq("app_id",o).eq("version",n.id);(t&&t.length||s)&&r.program.error(`Version ${o} @${a} is used in a device override, unlink it first ${(0,i.formatError)(s)}`)}))},109:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteFromStorage=void 0;const r=n(304),i=n(771);o.deleteFromStorage=(e,o,n,a,s)=>t(void 0,void 0,void 0,(function*(){const{error:t}=yield e.storage.from("apps").remove([`${o}/${n}/versions/${a.bucket_id} `]);t&&r.program.error(`Something went wrong when trying to delete ${n} @${s} ${(0,i.formatError)(t)} `)}))},87:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.getVersionData=o.getActiveAppVersions=o.deleteSpecificVersion=o.deleteAppVersion=void 0;const r=n(304),i=n(771),a=n(708),s=n(314),p=n(109);o.deleteAppVersion=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{error:t}=yield e.from("app_versions").update({deleted:!0}).eq("app_id",o).eq("user_id",n).eq("name",a);t&&r.program.error(`App ${o}@${a} not found in database '${(0,i.formatError)(t)}'`)})),o.deleteSpecificVersion=(e,n,r,i)=>t(void 0,void 0,void 0,(function*(){const t=yield(0,o.getVersionData)(e,n,r,i);yield(0,a.checkVersionNotUsedInChannel)(e,n,r,t,i),yield(0,s.checkVersionNotUsedInDeviceOverride)(e,n,t,i),yield(0,p.deleteFromStorage)(e,r,n,t,i),yield(0,o.deleteAppVersion)(e,n,r,i)})),o.getActiveAppVersions=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:a}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("deleted",!1);return a&&r.program.error(`App ${o} not found in database ${(0,i.formatError)(a)} `),t})),o.getVersionData=(e,o,n,a)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:s}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("name",a).eq("deleted",!1).single();return t&&!s||r.program.error(`Version ${o}@${a} doesn't exist ${(0,i.formatError)(s)}`),t}))},107:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.addApp=void 0;const r=n(304),i=n(113),a=n(147),s=n(470),p=n(11),d=n(771),c="assets/icon.png";o.addApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t;let{name:l,icon:u}=o;const f=o.apikey||(0,d.findSavedKey)(),v=yield(0,d.getConfig)(),y=(0,d.useLogSnag)();e=e||(null===(n=null==v?void 0:v.app)||void 0===n?void 0:n.appId),l=l||(null===(t=null==v?void 0:v.app)||void 0===t?void 0:t.appName)||"Unknown",u=u||"resources/icon.png",f||r.program.error("Missing API key, you need to provide a API key to add your app"),e&&l||r.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 g=(0,d.createSupabaseClient)(f),m=yield(0,d.verifyUser)(g,f,["write","all"]);let h,b;yield(0,d.checkPlanValid)(g,m),console.log("Adding..."),u&&(0,s.existsSync)(u)?(h=(0,a.readFileSync)(u),b=(0,p.getType)(u)||"image/png",console.warn(`Found app icon ${u}`)):(0,s.existsSync)(c)?(h=(0,a.readFileSync)(c),b=(0,p.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 g.rpc("exist_app",{appid:e,apikey:f});(_||w)&&r.program.error(`App already exists ${(0,d.formatError)(w)}`);const k=`icon_${(0,i.randomUUID)()}`;let $="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(h&&b){const{error:o}=yield g.storage.from(`images/${m}/${e}`).upload(k,h,{contentType:b});o&&r.program.error(`Could not add app ${(0,d.formatError)(o)}`);const{data:n}=yield g.storage.from(`images/${m}/${e}`).getPublicUrl(k);$=(null==n?void 0:n.publicURL)||$}const{error:x}=yield g.from("apps").insert({icon_url:$,user_id:m,name:l,app_id:e},{returning:"minimal"});x&&r.program.error(`Could not add app ${(0,d.formatError)(x)}`);const{error:A}=yield g.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"});A&&r.program.error(`Could not add app ${(0,d.formatError)(A)}`),y.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")}))},176:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.cleanupApp=void 0;const i=n(304),a=r(n(505)),s=r(n(616)),p=n(771),d=n(87),c=n(111),l=(0,s.default)();o.cleanupApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,p.findSavedKey)(),{bundle:r,keep:s=4}=o,u=o.force||!1,f=yield(0,p.getConfig)();e=e||(null===(n=null==f?void 0:f.app)||void 0===n?void 0:n.appId),t||i.program.error("Missing API key, you need to provide an API key to delete your app"),e||i.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const v=`${a.default.inc(r,"major")}`;console.log(`Querying available versions in Capgo between ${r} and ${v}`);const y=(0,p.createSupabaseClient)(t),g=yield(0,p.verifyUser)(y,t);yield(0,c.checkAppExistsAndHasPermission)(y,e,t);const m=yield(0,d.getActiveAppVersions)(y,e,g);if(console.log(`Total active versions in Capgo: ${null==m?void 0:m.length}`),0===(null==m?void 0:m.length))return;const h=((e,o,n)=>{const t=[];return null==e||e.forEach((e=>{a.default.gte(e.name,o)&&a.default.lt(e.name,`${n}`)&&t.push(e)})),t})(m,r,v).reverse();console.log(`Active versions in Capgo between ${r} and ${v}: ${null==h?void 0:h.length}`);const b=h.slice(0,s),_=h.slice(s);if(b.forEach((e=>{console.log(`${e.name} created on ${(0,p.getHumanDate)(e)} will be kept`)})),b.length&&console.log("==================================================="),0!==_.length){if(_.forEach((e=>{console.log(`${e.name} created on ${(0,p.getHumanDate)(e)} will be removed`)})),!u&&"yes"!==l("Do you want to continue removing the versions specified? Type yes to confirm"))return void console.log("Not confirmed, aborting removal...");console.log("You have confirmed removal, removing versions now"),((e,o,n,t)=>{null==e||e.forEach((e=>{console.log(`Removing ${e.name} created on ${(0,p.getHumanDate)(e)}`),(0,d.deleteSpecificVersion)(o,n,t,e.name)}))})(_,y,e,g)}else console.log("Nothing to be removed, aborting removal...")}))},154:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.decodeZip=void 0;const i=n(304),a=n(147),s=r(n(339)),p=n(771);o.decodeZip=(e,o)=>t(void 0,void 0,void 0,(function*(){(0,a.existsSync)(e)||i.program.error(`Zip not found at the path ${e}`),o.key||(0,a.existsSync)(p.baseKey)||i.program.error(`Public Key not found at the path ${p.baseKey}`);const n="string"==typeof o.key?o.key:p.baseKey;(0,a.existsSync)(n)||i.program.error(`Cannot find public key ${n}`);const t=(0,a.readFileSync)(n),r=(0,a.readFileSync)(e),d=new s.default(t.toString()).decrypt(r);(0,a.writeFileSync)(`${e}decoded.zip`,d)}))},605:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteApp=void 0;const r=n(304),i=n(771),a=n(87);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const{bundle:t}=o,s=o.apikey||(0,i.findSavedKey)(),p=yield(0,i.getConfig)(),d=(0,i.useLogSnag)();e=e||(null===(n=null==p?void 0:p.app)||void 0===n?void 0:n.appId),s||r.program.error("Missing API key, you need to provide an API key to delete your app"),e||r.program.error("Missing argument, you need to provide a appid, or be in a capacitor project");const c=(0,i.createSupabaseClient)(s),l=yield(0,i.verifyUser)(c,s),{data:u,error:f}=yield c.rpc("exist_app",{appid:e,apikey:s});if(u&&!f||r.program.error("No permission to delete"),t)return console.log(`Delete ${e}@${t} from Capgo`),yield(0,a.deleteSpecificVersion)(c,e,l,t),void console.log(`${e}@${t} deleted from server`);console.log(`Delete ${e} from Capgo`);const{data:v,error:y}=yield c.from("app_versions").select().eq("app_id",e).eq("user_id",l);if(y&&r.program.error(`App ${e} not found in database ${(0,i.formatError)(y)} `),v&&v.length){const o=v.map((o=>`${l}/${e}/versions/${o.bucket_id} `)),{error:n}=yield c.storage.from("apps").remove(o);n&&r.program.error(`Cannot delete stored version for app ${e} from storage ${(0,i.formatError)(n)} `)}const{error:g}=yield c.from("app_versions").delete().eq("app_id",e).eq("user_id",l);g&&r.program.error(`Cannot delete version for app ${e} from database ${(0,i.formatError)(g)} `);const{error:m}=yield c.from("apps").delete().eq("app_id",e).eq("user_id",l);m&&r.program.error(`Cannot delete from database ${(0,i.formatError)(m)} `),d.publish({channel:"app",event:"App Deleted",icon:"😱",tags:{"user-id":l,"app-id":e},notify:!1}).catch(),console.log(`${e} deleted from server`)}))},250:function(e,o,n){var t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0});const r=n(304),i=n(154),a=n(107),s=n(385),p=n(605),d=n(327),c=n(823),l=t(n(598)),u=n(829),f=n(501),v=n(176);r.program.description("Manage packages and bundle versions in capgo Cloud").version(l.default.version),r.program.command("add [appid]").alias("a").description("Add a new app to capgo Cloud").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"),r.program.command("login [apikey]").alias("l").description("Save apikey to your machine or folder").action(u.login).option("--local","Only save in local folder"),r.program.command("upload [appid]").alias("u").description("Upload a new bundle to capgo Cloud").action(c.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("--key <key>","custom path for signing key").option("--no-key","ignore signing key and send clear update").option("-b, --bundle <bundle>","bundle version number of the file to upload"),r.program.command("set [appid]").alias("s").description("Modify a channel configuration").action(d.setChannel).requiredOption("-c, --channel <channel>","channel to link to").option("-a, --apikey <apikey>","apikey to link to your account").option("-b, --bundle <bundle>","bundle version number of the file to set").option("-s, --state <state>","set the state of the channel, default or normal").option("--downgrade","Allow to downgrade to version under native one").option("--latest","get the latest version key in the package.json to set it to the channel").option("--no-downgrade","Disable downgrade to version under native one").option("--upgrade","Allow to upgrade to version above native one").option("--no-upgrade","Disable upgrade to version above native one").option("--ios","Allow sending update to ios devices").option("--no-ios","Disable sending update to ios devices").option("--android","Allow sending update to android devices").option("--no-android","Disable sending update to android devices").option("--self-assign","Allow to device to self assign to this channel").option("--no-self-assign","Disable devices to self assign to this channel"),r.program.command("delete [appid]").alias("d").description("Delete an app from capgo Cloud").action(p.deleteApp).option("-a, --apikey <apikey>","apikey to link to your account").option("-b, --bundle <bundle>","bundle version number of the app to delete"),r.program.command("list [appid]").alias("ls").description("List versions in capgo Cloud").action(f.listApp).option("-a, --apikey <apikey>","apikey to link to your account"),r.program.command("cleanup [appid]").alias("c").description("Cleanup versions in capgo Cloud").action(v.cleanupApp).requiredOption("-b, --bundle <bundle>","bundle version number of the app to delete").option("-a, --apikey <apikey>","apikey to link to your account").option("-k, --keep <keep>","number of version to keep").option("-f, --force","force removal"),r.program.command("key").alias("k").description("Generate signing key for your account or app").action(s.createKey).option("-f, --force","force genrate a new one"),r.program.command("decode [zipPath]").alias("dec").description("Decode a signed zip update").action(i.decodeZip).option("--key <key>","custom path for signing key"),r.program.parse(process.argv)},385:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.createKey=void 0;const i=n(304),a=n(147),s=r(n(401)),p=n(771);o.createKey=e=>t(void 0,void 0,void 0,(function*(){(0,a.existsSync)(".git")||i.program.error("To use local you should be in a git repository");const o=new s.default,{privateKey:n,publicKey:t}=o.createPrivateAndPublicKeys();(0,a.existsSync)(p.baseKey)&&!e.force&&i.program.error("Private Key already exists, use --force to overwrite"),(0,a.writeFileSync)(p.baseKey,n),(0,a.existsSync)(p.baseKeyPub)&&!e.force&&i.program.error("Public Key already exists, use --force to overwrite"),(0,a.writeFileSync)(p.baseKeyPub,t),console.log(`public key saved into ${p.baseKeyPub} file in local directory\n`),console.log("This key will be use to sign your zip archive sent to Capgo,\nthan make them unreadable by Capgo and not modifiable by anyone\n"),console.log(`private key saved into ${p.baseKey} file in local directory,\nYou need to add it's content to capacitor.config under the key privateKey, like below:\n{\n\t"appId": "**.***.**",\n\t"appName": "Name",\n\t"plugins": {\n\t\t"CapacitorUpdater": {\n\t\t\t"privateKey": "****",\n\t\t}\n\t}\n}\n\nGood practice is to not version this files in your git repository\n`)}))},501:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.listApp=void 0;const r=n(304),i=n(771),a=n(111),s=n(87);o.listApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,i.findSavedKey)(),p=yield(0,i.getConfig)();e=e||(null===(n=null==p?void 0:p.app)||void 0===n?void 0:n.appId),t||r.program.error("Missing API key, you need to provide an API key to delete your app"),e||r.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),console.log("Querying available versions in Capgo");const d=(0,i.createSupabaseClient)(t),c=yield(0,i.verifyUser)(d,t);yield(0,a.checkAppExistsAndHasPermission)(d,e,t);const l=yield(0,s.getActiveAppVersions)(d,e,c);console.log(`Active versions in Capgo: ${null==l?void 0:l.length}`),null==l||l.forEach((e=>{console.log(`${e.name} created on ${(0,i.getHumanDate)(e)}`)}))}))},829:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.login=void 0;const r=n(304),i=n(147),a=n(37),s=n(771);o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:n}=o,t=(0,s.useLogSnag)();if(n)(0,i.existsSync)(".git")||r.program.error("To use local you should be in a git repository"),(0,i.writeFileSync)(".capgo",`${e}\n`),(0,i.appendFileSync)(".gitignore",".capgo\n");else{const o=(0,a.homedir)();(0,i.writeFileSync)(`${o}/.capgo`,`${e}\n`)}const p=(0,s.createSupabaseClient)(e),d=yield(0,s.verifyUser)(p,e,["write","all","upload"]);t.publish({channel:"user-login",event:"User CLI login",icon:"✅",tags:{"user-id":d},notify:!1}).catch(),console.log(`login saved into .capgo file in ${n?"local":"home"} directory`)}))},327:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.setChannel=void 0;const r=n(304),i=n(771);o.setChannel=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,a;const{bundle:s,latest:p,downgrade:d,upgrade:c,ios:l,android:u,selfAssign:f,channel:v,state:y}=o,g=o.apikey||(0,i.findSavedKey)(),m=yield(0,i.getConfig)(),h=(0,i.useLogSnag)();e=e||(null===(n=null==m?void 0:m.app)||void 0===n?void 0:n.appId),g||r.program.error("Missing API key, you need to provide a API key to add your app"),e||r.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),p&&s&&r.program.error("Cannot set latest and bundle at the same time"),void 0===s&&void 0===y&&void 0===p&&void 0===d&&void 0===c&&void 0===l&&void 0===u&&void 0===f&&r.program.error("Missing argument, you need to provide a option to set");try{const o=(0,i.createSupabaseClient)(g),n=yield(0,i.verifyUser)(o,g,["write","all"]);yield(0,i.checkPlanValid)(o,n);const b={created_by:n,app_id:e,name:v},_=p?null===(a=null===(t=null==m?void 0:m.app)||void 0===t?void 0:t.package)||void 0===a?void 0:a.version:s;if(_){const{data:t,error:i}=yield o.from("app_versions").select().eq("app_id",e).eq("name",_).eq("user_id",n).eq("deleted",!1);!i&&t&&t.length||r.program.error(`Cannot find version ${_}`),console.log(`Set ${e} channel: ${v} to @${s}`),b.version=t[0].id}void 0!==y&&("public"!==y&&"private"!==y||console.log(`Set ${e} channel: ${v} to public or private is deprecated, use default or normal instead`),console.log(`Set ${e} channel: ${v} to ${"public"===y||"default"===y?"default":"normal"}`),b.public="public"===y||"default"===y),void 0!==d&&(console.log(`Set ${e} channel: ${v} to ${d?"allow":"disallow"} downgrade`),b.disableAutoUpdateUnderNative=!d),void 0!==c&&(console.log(`Set ${e} channel: ${v} to ${c?"allow":"disallow"} upgrade`),b.disableAutoUpdateToMajor=!c),void 0!==l&&(console.log(`Set ${e} channel: ${v} to ${l?"allow":"disallow"} ios update`),b.ios=!!l),void 0!==u&&(console.log(`Set ${e} channel: ${v} to ${u?"allow":"disallow"} android update`),b.android=!!u),void 0!==f&&(console.log(`Set ${e} channel: ${v} to ${f?"allow":"disallow"} self assign to this channel`),b.allow_device_self_set=!!f);try{const{error:e}=yield(0,i.updateOrCreateChannel)(o,b,g);e&&r.program.error(`Cannot set channel ${(0,i.formatError)(e)}`)}catch(e){r.program.error(`Cannot set channel ${(0,i.formatError)(e)}`)}h.publish({channel:"app",event:"Set app",icon:"✅",tags:{"user-id":n,"app-id":e},notify:!1}).catch()}catch(e){r.program.error(`Unknow error ${(0,i.formatError)(e)}`)}console.log("Done ✅")}))},823:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.uploadVersion=void 0;const i=r(n(844)),a=n(304),s=n(113),p=r(n(295)),d=n(147),c=r(n(339)),l=n(906),u=n(771);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,r,f;let{bundle:v,path:y,channel:g}=o;const{external:m,key:h=!1}=o,b=o.apikey||(0,u.findSavedKey)(),_=(0,u.useLogSnag)();g=g||"dev";const w=yield(0,u.getConfig)();e=e||(null===(n=null==w?void 0:w.app)||void 0===n?void 0:n.appId),v=v||(null===(r=null===(t=null==w?void 0:w.app)||void 0===t?void 0:t.package)||void 0===r?void 0:r.version),u.regexSemver.test(v)||a.program.error(`Your bundle name ${v}, is not valid it should follow semver convention : https://semver.org/`),y=y||(null===(f=null==w?void 0:w.app)||void 0===f?void 0:f.webDir),b||a.program.error("Missing API key, you need to provide a API key to add your app"),e&&v&&y||a.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}@${v} started from path "${y}" to Capgo cloud`);const k=(0,u.createSupabaseClient)(b),$=yield(0,u.verifyUser)(k,b,["write","all","upload"]);yield(0,u.checkPlanValid)(k,$,!1);const x=new p.default.MultiBar({clearOnComplete:!1,hideCursor:!0},p.default.Presets.shades_grey),A=x.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},p.default.Presets.shades_grey);A.start(7,0,{speed:"N/A"});const{data:C,error:S}=yield k.rpc("exist_app_versions",{apikey:b,name_version:v,appid:e});(C||S)&&(x.stop(),a.program.error(`This app bundle already exist or was deleted, you cannot re-upload it ${(0,u.formatError)(S)}`)),A.increment();const{data:P,error:q}=yield k.rpc("is_trial",{userid:$}).single();(P&&P>0||q)&&x.log(`WARNING !!\nTrial expires in ${P} days, upgrade here: ${u.hostWeb}/dashboard/settings/plans\n`),A.increment();const{data:I,error:M}=yield k.rpc("exist_app",{appid:e,apikey:b});I&&!M||(x.stop(),a.program.error(`Cannot find app ${e} in your account \n${(0,u.formatError)(M)}`)),A.increment();const{data:j,error:E}=yield k.rpc("exist_app_versions",{appid:e,apikey:b,name_version:v});(j||E)&&a.program.error(`Version already exists ${(0,u.formatError)(E)}`),A.increment();const K=(0,s.randomUUID)();let D="";if(m)m&&!m.startsWith("https://")&&(x.stop(),a.program.error(`External link should should start with "https://" current is "${m}"`));else{const o=new i.default;o.addLocalFolder(y);let n=o.toBuffer();if(h||(0,d.existsSync)(u.baseKeyPub)){const e="string"==typeof h?h:u.baseKeyPub;(0,d.existsSync)(e)||a.program.error(`Cannot find public key ${e}`);const o=(0,d.readFileSync)(e);n=new c.default(o.toString()).encrypt(n)}D=yield(0,l.checksum)(n,"crc32");const t=Math.floor(n.byteLength/1024/1024),r=`apps/${$}/${e}/versions`;A.increment(),t>20&&(x.log(`WARNING !!\nThe app size is ${t} Mb, this may take a while to download for users\n`),_.publish({channel:"app-error",event:"App Too Large",icon:"🚛",tags:{"user-id":$,"app-id":e},notify:!1}).catch());const{error:s}=yield k.storage.from(r).upload(K,n,{contentType:"application/zip"});s&&(x.stop(),a.program.error(`Cannot upload ${(0,u.formatError)(s)}`))}A.increment();const{data:V,error:O}=yield(0,u.updateOrCreateVersion)(k,{bucket_id:m?void 0:K,user_id:$,name:v,app_id:e,external_url:m,checksum:D},b);if(O&&(x.stop(),a.program.error(`Cannot add bundle ${(0,u.formatError)(O)}`)),A.increment(),V&&V.length){const{error:o}=yield(0,u.updateOrCreateChannel)(k,{name:g,app_id:e,created_by:$,version:V[0].id},b);o&&x.log("Cannot set bundle with upload key, use key with more rights for that\n")}else x.log("Cannot set bundle with upload key, use key with more rights for that\n");x.stop();const U=e.replace(/\./g,"--");console.log("App uploaded to server"),console.log(`Try it in mobile app: ${u.host}/app_mobile`),console.log(`Or set the channel ${g} as public here: ${u.hostWeb}/app/package/${U}`),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: ${u.hostWeb}/app/p/${U}/devices`),_.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":$,"app-id":e},notify:!1}).catch()}))},771:function(e,o,n){var t=this&&this.__awaiter||function(e,o,n,t){return new(n||(n=Promise))((function(r,i){function a(e){try{p(t.next(e))}catch(e){i(e)}}function s(e){try{p(t.throw(e))}catch(e){i(e)}}function p(e){var o;e.done?r(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(a,s)}p((t=t.apply(e,o||[])).next())}))},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.getHumanDate=o.verifyUser=o.useLogSnag=o.updateOrCreateChannel=o.updateOrCreateVersion=o.getConfig=o.formatError=o.findSavedKey=o.checkPlanValid=o.isTrial=o.isPaying=o.isGoodPlan=o.checkKey=o.regexSemver=o.createSupabaseClient=o.supaAnon=o.hostSupa=o.hostWeb=o.host=o.baseKeyPub=o.baseKey=void 0;const i=n(778),a=n(304),s=n(885),p=r(n(867)),d=n(147),c=n(37),l=n(133);o.baseKey=".capgo_key",o.baseKeyPub=`${o.baseKey}.pub`,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,s.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,n,r)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:i}=yield e.rpc("is_allowed_capgkey",{apikey:n,keymode:r});t&&!i||a.program.error(`Invalid API key or insufficient permissions ${(0,o.formatError)(i)}`)})),o.isGoodPlan=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_good_plan_v2",{userid:o}).single();if(t)throw t;return n||!1})),o.isPaying=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_paying",{userid:o}).single();if(t)throw t;return n||!1})),o.isTrial=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:n,error:t}=yield e.rpc("is_trial",{userid:o}).single();if(t)throw t;return n||0})),o.checkPlanValid=(e,n,r=!0)=>t(void 0,void 0,void 0,(function*(){const t=yield(0,o.isGoodPlan)(e,n),i=yield(0,o.isPaying)(e,n),s=yield(0,o.isTrial)(e,n);i&&t||!(s<0)||a.program.error(`You need to upgrade your plan to continue to use capgo.\n Upgrade here: ${o.hostWeb}/dashboard/settings/plans\n`),s>0&&r&&!i&&console.log(`WARNING !!\nTrial expires in ${s} days, upgrade here: ${o.hostWeb}/dashboard/settings/plans\n`)})),o.findSavedKey=()=>{let e=`${(0,c.homedir)()}/.capgo`;return(0,d.existsSync)(e)?(0,d.readFileSync)(e,"utf8").trim():(e=".capgo",(0,d.existsSync)(e)?(0,d.readFileSync)(e,"utf8").trim():null)},o.formatError=e=>e?`\n${p.default.render(e)}`:"",o.getConfig=()=>t(void 0,void 0,void 0,(function*(){let e;try{e=yield(0,i.loadConfig)()}catch(e){a.program.error("No capacitor config file found, run `cap init` first")}return e})),o.updateOrCreateVersion=(e,o,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:r}=yield e.rpc("exist_app_versions",{appid:o.app_id,name_version:o.name,apikey:n});return t&&!r?(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,n)=>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:r}=yield e.rpc("exist_channel",{appid:o.app_id,name_channel:o.name,apikey:n});return t&&!r?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"}),o.verifyUser=(e,n,r=["all"])=>t(void 0,void 0,void 0,(function*(){yield(0,o.checkKey)(e,n,r);const{data:t,error:i}=yield e.rpc("get_user_id",{apikey:n}),s=t?t.toString():"";return s&&!i||a.program.error(`Cannot verify user ${(0,o.formatError)(i)}`),s})),o.getHumanDate=e=>new Date(e.created_at||"").toLocaleString()},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")},401:e=>{e.exports=require("encrypt-rsa")},470:e=>{e.exports=require("fs-extra")},133:e=>{e.exports=require("logsnag")},11:e=>{e.exports=require("mime")},339:e=>{e.exports=require("node-rsa")},867:e=>{e.exports=require("prettyjson")},616:e=>{e.exports=require("prompt-sync")},505:e=>{e.exports=require("semver/preload")},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.4.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":"4.4.0","@supabase/supabase-js":"^1.35.7","@tomasklaen/checksum":"^1.1.0","adm-zip":"^0.5.9","cli-progress":"3.11.2","commander":"9.4.1","encrypt-rsa":"^2.1.2","fs-extra":"10.1.0","logsnag":"^0.1.5","mime":"^3.0.0","node-rsa":"^1.1.1","prettyjson":"^1.2.5","prompt-sync":"^4.2.0","semver":"^7.3.8"},"devDependencies":{"@types/adm-zip":"0.5.0","@types/cli-progress":"^3.11.0","@types/fs-extra":"^9.0.13","@types/mime":"^3.0.1","@types/node":"^18.11.9","@types/node-rsa":"^1.1.1","@types/prettyjson":"^0.0.30","@types/prompt-sync":"^4.2.0","@types/semver":"^7.3.13","@typescript-eslint/eslint-plugin":"5.42.1","@typescript-eslint/parser":"5.42.1","eslint":"8.27.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^8.5.0","eslint-import-resolver-typescript":"3.5.2","eslint-plugin-import":"2.26.0","eslint-plugin-prettier":"^4.2.1","git-format-staged":"3.0.0","husky":"^8.0.2","nodemon":"2.0.20","pkg":"5.8.0","prettier":"2.7.1","ts-loader":"^9.4.1","ts-node":"^10.9.1","tsconfig-paths":"4.1.0","typescript":"4.8.4","webpack":"5.74.0","webpack-cli":"^4.10.0","webpack-node-externals":"^3.0.0"}}')}},o={};!function n(t){var r=o[t];if(void 0!==r)return r.exports;var i=o[t]={exports:{}};return e[t].call(i.exports,i,i.exports,n),i.exports}(250)})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/cli",
3
- "version": "1.3.1",
3
+ "version": "1.4.1",
4
4
  "description": "A CLI to upload to capgo servers",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -42,9 +42,11 @@
42
42
  "adm-zip": "^0.5.9",
43
43
  "cli-progress": "3.11.2",
44
44
  "commander": "9.4.1",
45
+ "encrypt-rsa": "^2.1.2",
45
46
  "fs-extra": "10.1.0",
46
47
  "logsnag": "^0.1.5",
47
48
  "mime": "^3.0.0",
49
+ "node-rsa": "^1.1.1",
48
50
  "prettyjson": "^1.2.5",
49
51
  "prompt-sync": "^4.2.0",
50
52
  "semver": "^7.3.8"
@@ -55,6 +57,7 @@
55
57
  "@types/fs-extra": "^9.0.13",
56
58
  "@types/mime": "^3.0.1",
57
59
  "@types/node": "^18.11.9",
60
+ "@types/node-rsa": "^1.1.1",
58
61
  "@types/prettyjson": "^0.0.30",
59
62
  "@types/prompt-sync": "^4.2.0",
60
63
  "@types/semver": "^7.3.13",
@@ -1,5 +1,6 @@
1
1
  import { SupabaseClient } from '@supabase/supabase-js';
2
2
  import { program } from 'commander';
3
+ import { formatError } from '../bin/utils';
3
4
 
4
5
  interface VersionData {
5
6
  id: number;
@@ -21,6 +22,6 @@ export const deleteFromStorage = async (supabase: SupabaseClient,
21
22
  .from('apps')
22
23
  .remove([`${userId}/${appid}/versions/${versionData.bucket_id} `]);
23
24
  if (delError) {
24
- program.error(`Something went wrong when trying to delete ${appid} @${bundle} ${delError} `);
25
+ program.error(`Something went wrong when trying to delete ${appid} @${bundle} ${formatError(delError)} `);
25
26
  }
26
27
  }
@@ -16,7 +16,7 @@ export const deleteAppVersion = async (supabase: SupabaseClient, appid: string,
16
16
  .eq('user_id', userId)
17
17
  .eq('name', bundle);
18
18
  if (delAppSpecVersionError) {
19
- program.error(`App ${appid}@${bundle} not found in database '${delAppSpecVersionError}'`);
19
+ program.error(`App ${appid}@${bundle} not found in database '${formatError(delAppSpecVersionError)}'`);
20
20
  }
21
21
  }
22
22
 
@@ -39,7 +39,7 @@ export const getActiveAppVersions = async (supabase: SupabaseClient, appid: stri
39
39
  .eq('deleted', false);
40
40
 
41
41
  if (vError) {
42
- program.error(`App ${appid} not found in database ${vError} `);
42
+ program.error(`App ${appid} not found in database ${formatError(vError)} `);
43
43
  }
44
44
  return data;
45
45
  }
@@ -0,0 +1,32 @@
1
+ import { program } from 'commander'
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs'
3
+ import NodeRSA from 'node-rsa'
4
+ import { baseKey } from './utils';
5
+
6
+ interface Options {
7
+ key?: boolean | string
8
+ }
9
+
10
+ export const decodeZip = async (zipPath: string, options: Options) => {
11
+ // write in file .capgo the apikey in home directory
12
+
13
+ if (!existsSync(zipPath)) {
14
+ program.error(`Zip not found at the path ${zipPath}`);
15
+ }
16
+
17
+ if (!options.key && !existsSync(baseKey)) {
18
+ program.error(`Public Key not found at the path ${baseKey}`);
19
+ }
20
+ const publicKey = typeof options.key === 'string' ? options.key : baseKey
21
+ // check if publicKey exist
22
+ if (!existsSync(publicKey)) {
23
+ program.error(`Cannot find public key ${publicKey}`)
24
+ }
25
+ // open with fs publicKey path
26
+ const keyFile = readFileSync(publicKey)
27
+ const zipFile = readFileSync(zipPath)
28
+ const nodeRsa = new NodeRSA(keyFile.toString())
29
+ const decodedZip = nodeRsa.decrypt(zipFile)
30
+ // write decodedZip in a file
31
+ writeFileSync(`${zipPath}decoded.zip`, decodedZip)
32
+ }
package/src/bin/delete.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { program } from 'commander';
2
- import { createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from './utils';
2
+ import { createSupabaseClient, findSavedKey, formatError, getConfig, useLogSnag, verifyUser } from './utils';
3
3
  import { definitions } from './types_supabase';
4
4
  import { deleteSpecificVersion } from '../api/versions';
5
5
 
@@ -48,7 +48,7 @@ export const deleteApp = async (appid: string, options: Options) => {
48
48
  .eq('user_id', userId)
49
49
 
50
50
  if (vError) {
51
- program.error(`App ${appid} not found in database ${vError} `)
51
+ program.error(`App ${appid} not found in database ${formatError(vError)} `)
52
52
  }
53
53
 
54
54
  if (data && data.length) {
@@ -58,7 +58,7 @@ export const deleteApp = async (appid: string, options: Options) => {
58
58
  .from('apps')
59
59
  .remove(filesToRemove)
60
60
  if (delError) {
61
- program.error(`Cannot delete stored version for app ${appid} from storage ${delError} `)
61
+ program.error(`Cannot delete stored version for app ${appid} from storage ${formatError(delError)} `)
62
62
  }
63
63
  }
64
64
 
@@ -69,7 +69,7 @@ export const deleteApp = async (appid: string, options: Options) => {
69
69
  .eq('user_id', userId)
70
70
 
71
71
  if (delAppVersionError) {
72
- program.error(`Cannot delete version for app ${appid} from database ${delAppVersionError} `)
72
+ program.error(`Cannot delete version for app ${appid} from database ${formatError(delAppVersionError)} `)
73
73
  }
74
74
 
75
75
  const { error: dbAppError } = await supabase
@@ -79,7 +79,7 @@ export const deleteApp = async (appid: string, options: Options) => {
79
79
  .eq('user_id', userId)
80
80
 
81
81
  if (dbAppError) {
82
- program.error(`Cannot delete from database ${dbAppError} `)
82
+ program.error(`Cannot delete from database ${formatError(dbAppError)} `)
83
83
  }
84
84
  snag.publish({
85
85
  channel: 'app',
package/src/bin/index.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { program } from 'commander';
2
+ import { decodeZip } from './decode';
2
3
  import { addApp } from './add';
4
+ import { createKey } from './key';
3
5
  import { deleteApp } from './delete';
4
6
  import { setChannel } from './set';
5
7
  import { uploadVersion } from './upload';
@@ -13,7 +15,8 @@ program
13
15
  .version(pack.version);
14
16
 
15
17
  program
16
- .command('add [appid]').alias('a')
18
+ .command('add [appid]')
19
+ .alias('a')
17
20
  .description('Add a new app to capgo Cloud')
18
21
  .action(addApp)
19
22
  .option('-n, --name <name>', 'app name')
@@ -21,13 +24,15 @@ program
21
24
  .option('-a, --apikey <apikey>', 'apikey to link to your account');
22
25
 
23
26
  program
24
- .command('login [apikey]').alias('l')
27
+ .command('login [apikey]')
28
+ .alias('l')
25
29
  .description('Save apikey to your machine or folder')
26
30
  .action(login)
27
31
  .option('--local', 'Only save in local folder');
28
32
 
29
33
  program
30
- .command('upload [appid]').alias('u')
34
+ .command('upload [appid]')
35
+ .alias('u')
31
36
  .description('Upload a new bundle to capgo Cloud')
32
37
  .action(uploadVersion)
33
38
  .option('-a, --apikey <apikey>', 'apikey to link to your account')
@@ -35,10 +40,13 @@ program
35
40
  .option('-c, --channel <channel>', 'channel to link to')
36
41
  .option('-e, --external <url>', 'link to external url intead of upload to capgo cloud')
37
42
  .option('-f, --format <base64|hex|binary|utf8>', 'choose the upload format default base64')
43
+ .option('--key <key>', 'custom path for signing key')
44
+ .option('--no-key', 'ignore signing key and send clear update')
38
45
  .option('-b, --bundle <bundle>', 'bundle version number of the file to upload');
39
46
 
40
47
  program
41
- .command('set [appid]').alias('s')
48
+ .command('set [appid]')
49
+ .alias('s')
42
50
  .description('Modify a channel configuration')
43
51
  .action(setChannel)
44
52
  .requiredOption('-c, --channel <channel>', 'channel to link to')
@@ -58,20 +66,23 @@ program
58
66
  .option('--no-self-assign', 'Disable devices to self assign to this channel');
59
67
 
60
68
  program
61
- .command('delete [appid]').alias('d')
69
+ .command('delete [appid]')
70
+ .alias('d')
62
71
  .description('Delete an app from capgo Cloud')
63
72
  .action(deleteApp)
64
73
  .option('-a, --apikey <apikey>', 'apikey to link to your account')
65
74
  .option('-b, --bundle <bundle>', 'bundle version number of the app to delete');
66
75
 
67
76
  program
68
- .command('list [appid]').alias('ls')
77
+ .command('list [appid]')
78
+ .alias('ls')
69
79
  .description('List versions in capgo Cloud')
70
80
  .action(listApp)
71
81
  .option('-a, --apikey <apikey>', 'apikey to link to your account');
72
82
 
73
83
  program
74
- .command('cleanup [appid]').alias('c')
84
+ .command('cleanup [appid]')
85
+ .alias('c')
75
86
  .description('Cleanup versions in capgo Cloud')
76
87
  .action(cleanupApp)
77
88
  .requiredOption('-b, --bundle <bundle>', 'bundle version number of the app to delete')
@@ -79,4 +90,18 @@ program
79
90
  .option('-k, --keep <keep>', 'number of version to keep')
80
91
  .option('-f, --force', 'force removal');
81
92
 
93
+ program
94
+ .command('key')
95
+ .alias('k')
96
+ .description('Generate signing key for your account or app')
97
+ .action(createKey)
98
+ .option('-f, --force', 'force genrate a new one');
99
+
100
+ program
101
+ .command('decode [zipPath]')
102
+ .alias('dec')
103
+ .description('Decode a signed zip update')
104
+ .action(decodeZip)
105
+ .option('--key <key>', 'custom path for signing key');
106
+
82
107
  program.parse(process.argv);
package/src/bin/key.ts ADDED
@@ -0,0 +1,44 @@
1
+ import { program } from 'commander'
2
+ import { existsSync, writeFileSync } from 'fs'
3
+ import EncryptRsa from 'encrypt-rsa'
4
+ import { baseKey, baseKeyPub } from './utils';
5
+
6
+ interface Options {
7
+ force: boolean;
8
+ }
9
+
10
+ export const createKey = async (options: Options) => {
11
+ // write in file .capgo the apikey in home directory
12
+
13
+ if (!existsSync('.git')) {
14
+ program.error('To use local you should be in a git repository');
15
+ }
16
+ const encryptRsa = new EncryptRsa();
17
+ const { privateKey, publicKey } = encryptRsa.createPrivateAndPublicKeys();
18
+
19
+ // check if baseName already exist
20
+ if (existsSync(baseKey) && !options.force) {
21
+ program.error(`Private Key already exists, use --force to overwrite`);
22
+ }
23
+ writeFileSync(baseKey, privateKey);
24
+ if (existsSync(baseKeyPub) && !options.force) {
25
+ program.error(`Public Key already exists, use --force to overwrite`);
26
+ }
27
+ writeFileSync(baseKeyPub, publicKey);
28
+
29
+ console.log(`public key saved into ${baseKeyPub} file in local directory\n`);
30
+ console.log(`This key will be use to sign your zip archive sent to Capgo,
31
+ than make them unreadable by Capgo and not modifiable by anyone\n`);
32
+ console.log(`private key saved into ${baseKey} file in local directory,
33
+ You need to add it's content to capacitor.config under the key privateKey, like below:
34
+ {
35
+ "appId": "**.***.**",
36
+ "appName": "Name",
37
+ "plugins": {
38
+ "CapacitorUpdater": {
39
+ "privateKey": "****",
40
+ }
41
+ }
42
+ }\n
43
+ Good practice is to not version this files in your git repository\n`);
44
+ }
package/src/bin/login.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { program } from 'commander';
2
- import fs from 'fs'
3
- import os from 'os'
4
- import { createSupabaseClient, formatError, useLogSnag, verifyUser } from './utils';
2
+ import { existsSync, writeFileSync, appendFileSync } from 'fs'
3
+ import { homedir } from 'os'
4
+ import { createSupabaseClient, useLogSnag, verifyUser } from './utils';
5
5
 
6
6
  interface Options {
7
7
  local: boolean;
@@ -12,14 +12,14 @@ export const login = async (apikey: string, options: Options) => {
12
12
  const snag = useLogSnag()
13
13
 
14
14
  if (local) {
15
- if (!fs.existsSync('.git')) {
15
+ if (!existsSync('.git')) {
16
16
  program.error('To use local you should be in a git repository');
17
17
  }
18
- fs.writeFileSync('.capgo', `${apikey}\n`);
19
- fs.appendFileSync('.gitignore', '.capgo\n');
18
+ writeFileSync('.capgo', `${apikey}\n`);
19
+ appendFileSync('.gitignore', '.capgo\n');
20
20
  } else {
21
- const userHomeDir = os.homedir();
22
- fs.writeFileSync(`${userHomeDir}/.capgo`, `${apikey}\n`);
21
+ const userHomeDir = homedir();
22
+ writeFileSync(`${userHomeDir}/.capgo`, `${apikey}\n`);
23
23
  }
24
24
  const supabase = createSupabaseClient(apikey)
25
25
  const userId = await verifyUser(supabase, apikey, ['write', 'all', 'upload']);
@@ -30,6 +30,8 @@ export interface paths {
30
30
  ios?: parameters["rowFilter.channels.ios"];
31
31
  android?: parameters["rowFilter.channels.android"];
32
32
  allow_device_self_set?: parameters["rowFilter.channels.allow_device_self_set"];
33
+ allow_emulator?: parameters["rowFilter.channels.allow_emulator"];
34
+ allow_dev?: parameters["rowFilter.channels.allow_dev"];
33
35
  /** Filtering Columns */
34
36
  select?: parameters["select"];
35
37
  /** Ordering */
@@ -94,6 +96,8 @@ export interface paths {
94
96
  ios?: parameters["rowFilter.channels.ios"];
95
97
  android?: parameters["rowFilter.channels.android"];
96
98
  allow_device_self_set?: parameters["rowFilter.channels.allow_device_self_set"];
99
+ allow_emulator?: parameters["rowFilter.channels.allow_emulator"];
100
+ allow_dev?: parameters["rowFilter.channels.allow_dev"];
97
101
  };
98
102
  header: {
99
103
  /** Preference */
@@ -122,6 +126,8 @@ export interface paths {
122
126
  ios?: parameters["rowFilter.channels.ios"];
123
127
  android?: parameters["rowFilter.channels.android"];
124
128
  allow_device_self_set?: parameters["rowFilter.channels.allow_device_self_set"];
129
+ allow_emulator?: parameters["rowFilter.channels.allow_emulator"];
130
+ allow_dev?: parameters["rowFilter.channels.allow_dev"];
125
131
  };
126
132
  body: {
127
133
  /** channels */
@@ -627,6 +633,8 @@ export interface paths {
627
633
  id?: parameters["rowFilter.devices_onprem.id"];
628
634
  version_build?: parameters["rowFilter.devices_onprem.version_build"];
629
635
  custom_id?: parameters["rowFilter.devices_onprem.custom_id"];
636
+ is_prod?: parameters["rowFilter.devices_onprem.is_prod"];
637
+ is_emulator?: parameters["rowFilter.devices_onprem.is_emulator"];
630
638
  /** Filtering Columns */
631
639
  select?: parameters["select"];
632
640
  /** Ordering */
@@ -688,6 +696,8 @@ export interface paths {
688
696
  id?: parameters["rowFilter.devices_onprem.id"];
689
697
  version_build?: parameters["rowFilter.devices_onprem.version_build"];
690
698
  custom_id?: parameters["rowFilter.devices_onprem.custom_id"];
699
+ is_prod?: parameters["rowFilter.devices_onprem.is_prod"];
700
+ is_emulator?: parameters["rowFilter.devices_onprem.is_emulator"];
691
701
  };
692
702
  header: {
693
703
  /** Preference */
@@ -713,6 +723,8 @@ export interface paths {
713
723
  id?: parameters["rowFilter.devices_onprem.id"];
714
724
  version_build?: parameters["rowFilter.devices_onprem.version_build"];
715
725
  custom_id?: parameters["rowFilter.devices_onprem.custom_id"];
726
+ is_prod?: parameters["rowFilter.devices_onprem.is_prod"];
727
+ is_emulator?: parameters["rowFilter.devices_onprem.is_emulator"];
716
728
  };
717
729
  body: {
718
730
  /** devices_onprem */
@@ -1830,6 +1842,8 @@ export interface paths {
1830
1842
  date_id?: parameters["rowFilter.devices.date_id"];
1831
1843
  version_build?: parameters["rowFilter.devices.version_build"];
1832
1844
  custom_id?: parameters["rowFilter.devices.custom_id"];
1845
+ is_prod?: parameters["rowFilter.devices.is_prod"];
1846
+ is_emulator?: parameters["rowFilter.devices.is_emulator"];
1833
1847
  /** Filtering Columns */
1834
1848
  select?: parameters["select"];
1835
1849
  /** Ordering */
@@ -1891,6 +1905,8 @@ export interface paths {
1891
1905
  date_id?: parameters["rowFilter.devices.date_id"];
1892
1906
  version_build?: parameters["rowFilter.devices.version_build"];
1893
1907
  custom_id?: parameters["rowFilter.devices.custom_id"];
1908
+ is_prod?: parameters["rowFilter.devices.is_prod"];
1909
+ is_emulator?: parameters["rowFilter.devices.is_emulator"];
1894
1910
  };
1895
1911
  header: {
1896
1912
  /** Preference */
@@ -1916,6 +1932,8 @@ export interface paths {
1916
1932
  date_id?: parameters["rowFilter.devices.date_id"];
1917
1933
  version_build?: parameters["rowFilter.devices.version_build"];
1918
1934
  custom_id?: parameters["rowFilter.devices.custom_id"];
1935
+ is_prod?: parameters["rowFilter.devices.is_prod"];
1936
+ is_emulator?: parameters["rowFilter.devices.is_emulator"];
1919
1937
  };
1920
1938
  body: {
1921
1939
  /** devices */
@@ -3111,6 +3129,16 @@ export interface definitions {
3111
3129
  * @default false
3112
3130
  */
3113
3131
  allow_device_self_set: boolean;
3132
+ /**
3133
+ * Format: boolean
3134
+ * @default true
3135
+ */
3136
+ allow_emulator: boolean;
3137
+ /**
3138
+ * Format: boolean
3139
+ * @default true
3140
+ */
3141
+ allow_dev: boolean;
3114
3142
  };
3115
3143
  deleted_account: {
3116
3144
  /**
@@ -3336,6 +3364,16 @@ export interface definitions {
3336
3364
  * @default
3337
3365
  */
3338
3366
  custom_id?: string;
3367
+ /**
3368
+ * Format: boolean
3369
+ * @default true
3370
+ */
3371
+ is_prod?: boolean;
3372
+ /**
3373
+ * Format: boolean
3374
+ * @default false
3375
+ */
3376
+ is_emulator?: boolean;
3339
3377
  };
3340
3378
  stats_onprem: {
3341
3379
  /**
@@ -3768,6 +3806,16 @@ export interface definitions {
3768
3806
  * @default
3769
3807
  */
3770
3808
  custom_id: string;
3809
+ /**
3810
+ * Format: boolean
3811
+ * @default true
3812
+ */
3813
+ is_prod?: boolean;
3814
+ /**
3815
+ * Format: boolean
3816
+ * @default false
3817
+ */
3818
+ is_emulator?: boolean;
3771
3819
  };
3772
3820
  app_versions_meta: {
3773
3821
  /**
@@ -3946,6 +3994,10 @@ export interface parameters {
3946
3994
  "rowFilter.channels.android": string;
3947
3995
  /** Format: boolean */
3948
3996
  "rowFilter.channels.allow_device_self_set": string;
3997
+ /** Format: boolean */
3998
+ "rowFilter.channels.allow_emulator": string;
3999
+ /** Format: boolean */
4000
+ "rowFilter.channels.allow_dev": string;
3949
4001
  /** @description deleted_account */
3950
4002
  "body.deleted_account": definitions["deleted_account"];
3951
4003
  /** Format: timestamp with time zone */
@@ -4070,6 +4122,10 @@ export interface parameters {
4070
4122
  "rowFilter.devices_onprem.version_build": string;
4071
4123
  /** Format: text */
4072
4124
  "rowFilter.devices_onprem.custom_id": string;
4125
+ /** Format: boolean */
4126
+ "rowFilter.devices_onprem.is_prod": string;
4127
+ /** Format: boolean */
4128
+ "rowFilter.devices_onprem.is_emulator": string;
4073
4129
  /** @description stats_onprem */
4074
4130
  "body.stats_onprem": definitions["stats_onprem"];
4075
4131
  /** Format: bigint */
@@ -4278,6 +4334,10 @@ export interface parameters {
4278
4334
  "rowFilter.devices.version_build": string;
4279
4335
  /** Format: text */
4280
4336
  "rowFilter.devices.custom_id": string;
4337
+ /** Format: boolean */
4338
+ "rowFilter.devices.is_prod": string;
4339
+ /** Format: boolean */
4340
+ "rowFilter.devices.is_emulator": string;
4281
4341
  /** @description app_versions_meta */
4282
4342
  "body.app_versions_meta": definitions["app_versions_meta"];
4283
4343
  /** Format: timestamp with time zone */
package/src/bin/upload.ts CHANGED
@@ -2,10 +2,13 @@ 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 { existsSync, readFileSync } from 'fs';
6
+ // import EncryptRsa from 'encrypt-rsa'
7
+ import NodeRSA from 'node-rsa'
5
8
  import { checksum as getChecksum } from '@tomasklaen/checksum';
6
9
  import {
7
10
  host, hostWeb, getConfig, createSupabaseClient,
8
- updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlanValid, useLogSnag, verifyUser, regexSemver
11
+ updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlanValid, useLogSnag, verifyUser, regexSemver, baseKeyPub
9
12
  } from './utils';
10
13
 
11
14
  interface Options {
@@ -14,13 +17,14 @@ interface Options {
14
17
  apikey: string
15
18
  channel?: string
16
19
  external?: string
20
+ key?: boolean | string
17
21
  }
18
22
 
19
23
  const alertMb = 20;
20
24
 
21
25
  export const uploadVersion = async (appid: string, options: Options) => {
22
26
  let { bundle, path, channel } = options;
23
- const { external } = options;
27
+ const { external, key = false } = options;
24
28
  const apikey = options.apikey || findSavedKey()
25
29
  const snag = useLogSnag()
26
30
 
@@ -93,7 +97,18 @@ export const uploadVersion = async (appid: string, options: Options) => {
93
97
  if (!external) {
94
98
  const zip = new AdmZip();
95
99
  zip.addLocalFolder(path);
96
- const zipped = zip.toBuffer();
100
+ let zipped = zip.toBuffer();
101
+ if (key || existsSync(baseKeyPub)) {
102
+ const publicKey = typeof key === 'string' ? key : baseKeyPub
103
+ // check if publicKey exist
104
+ if (!existsSync(publicKey)) {
105
+ program.error(`Cannot find public key ${publicKey}`)
106
+ }
107
+ // open with fs publicKey path
108
+ const keyFile = readFileSync(publicKey)
109
+ const nodeRsa = new NodeRSA(keyFile.toString())
110
+ zipped = nodeRsa.encrypt(zipped)
111
+ }
97
112
  checksum = await getChecksum(zipped, 'crc32');
98
113
  const mbSize = Math.floor(zipped.byteLength / 1024 / 1024);
99
114
  const filePath = `apps/${userId}/${appid}/versions`
package/src/bin/utils.ts CHANGED
@@ -2,11 +2,13 @@ import { loadConfig } from '@capacitor/cli/dist/config';
2
2
  import { program } from 'commander';
3
3
  import { createClient, SupabaseClient } from '@supabase/supabase-js';
4
4
  import prettyjson from 'prettyjson';
5
- import fs from 'fs';
6
- import os from 'os';
5
+ import { existsSync, readFileSync } from 'fs';
6
+ import { homedir } from 'os';
7
7
  import { LogSnag } from 'logsnag';
8
8
  import { definitions } from './types_supabase';
9
9
 
10
+ export const baseKey = '.capgo_key';
11
+ export const baseKeyPub = `${baseKey}.pub`;
10
12
  export const host = 'https://capgo.app';
11
13
  export const hostWeb = 'https://web.capgo.app';
12
14
  export const hostSupa = process.env.SUPA_DB === 'production'
@@ -82,15 +84,15 @@ export const checkPlanValid = async (supabase: SupabaseClient, userId: string, w
82
84
 
83
85
  export const findSavedKey = () => {
84
86
  // search for key in home dir
85
- const userHomeDir = os.homedir();
87
+ const userHomeDir = homedir();
86
88
  let keyPath = `${userHomeDir}/.capgo`;
87
- if (fs.existsSync(keyPath)) {
88
- const key = fs.readFileSync(keyPath, 'utf8');
89
+ if (existsSync(keyPath)) {
90
+ const key = readFileSync(keyPath, 'utf8');
89
91
  return key.trim();
90
92
  }
91
93
  keyPath = `.capgo`;
92
- if (fs.existsSync(keyPath)) {
93
- const key = fs.readFileSync(keyPath, 'utf8');
94
+ if (existsSync(keyPath)) {
95
+ const key = readFileSync(keyPath, 'utf8');
94
96
  return key.trim();
95
97
  }
96
98
  return null