@capgo/cli 0.14.0 → 0.16.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.14.0"
4
+ version = "0.16.0"
5
5
  version_files = [
6
6
  "package.json:version",
7
7
  ".cz.toml"
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 0.16.0 (2022-08-16)
2
+
3
+ ### Feat
4
+
5
+ - remove upload limit
6
+
7
+ ## 0.15.1 (2022-08-03)
8
+
9
+ ### Fix
10
+
11
+ - logsnag
12
+
13
+ ## 0.15.0 (2022-08-03)
14
+
15
+ ### Feat
16
+
17
+ - add logsnag
18
+
1
19
  ## 0.14.0 (2022-08-02)
2
20
 
3
21
  ### Feat
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- (()=>{"use strict";var e={548:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.addApp=void 0;const n=r(304),a=r(113),i=r(147),p=r(470),s=r(11),d=r(233),l="assets/icon.png";o.addApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t;let{name:c,icon:u}=o;const m=o.apikey||(0,d.findSavedKey)(),f=yield(0,d.getConfig)();e=e||(null===(r=null==f?void 0:f.app)||void 0===r?void 0:r.appId),c=c||(null===(t=null==f?void 0:f.app)||void 0===t?void 0:t.appName)||"Unknown",u=u||"resources/icon.png",m||n.program.error("Missing API key, you need to provide a API key to add your app"),e&&c||n.program.error("Missing argument, you need to provide a appid and a name, or be in a capacitor project"),console.log(`Add ${e} to Capgo`);const g=(0,d.createSupabaseClient)(m);yield(0,d.checkKey)(g,m,["write","all"]);const{data:v,error:y}=yield g.rpc("get_user_id",{apikey:m}),h=v?v.toString():"";let _,k;h&&!y||n.program.error(`Cannot verify user ${(0,d.formatError)(y)}`),yield(0,d.checkPlan)(g,h),console.log("Adding..."),u&&(0,p.existsSync)(u)?(_=(0,i.readFileSync)(u),k=(0,s.getType)(u)||"image/png",console.warn(`Found app icon ${u}`)):(0,p.existsSync)(l)?(_=(0,i.readFileSync)(l),k=(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:$}=yield g.rpc("exist_app",{appid:e,apikey:m});(b||$)&&n.program.error(`App already exists ${(0,d.formatError)($)}`);const w=`icon_${(0,a.randomUUID)()}`;let x="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(_&&k){const{error:o}=yield g.storage.from(`images/${h}/${e}`).upload(w,_,{contentType:k});o&&n.program.error(`Could not add app ${(0,d.formatError)(o)}`);const{data:r}=yield g.storage.from(`images/${h}/${e}`).getPublicUrl(w);x=(null==r?void 0:r.publicURL)||x}const{error:C}=yield g.from("apps").insert({icon_url:x,user_id:h,name:c,app_id:e},{returning:"minimal"});C&&n.program.error(`Could not add app ${(0,d.formatError)(C)}`);const{error:q}=yield g.from("app_versions").insert([{user_id:h,deleted:!0,name:"unknown",app_id:e},{user_id:h,deleted:!0,name:"builtin",app_id:e}],{returning:"minimal"});q&&n.program.error(`Could not add app ${(0,d.formatError)(q)}`),console.log("App added to server, you can upload a version now")}))},453:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteApp=void 0;const n=r(304),a=r(233);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var r;const{version:t}=o,i=o.apikey||(0,a.findSavedKey)(),p=yield(0,a.getConfig)();e=e||(null===(r=null==p?void 0:p.app)||void 0===r?void 0:r.appId),i||n.program.error("Missing API key, you need to provide an API key to delete your app"),e||n.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),console.log(`Delete ${e} to Capgo`);const s=(0,a.createSupabaseClient)(i);yield(0,a.checkKey)(s,i,["all"]);const{data:d,error:l}=yield s.rpc("get_user_id",{apikey:i}),c=d?d.toString():"";c&&!l||n.program.error(`Cannot verify user ${(0,a.formatError)(l)}`);const{data:u,error:m}=yield s.rpc("exist_app",{appid:e,apikey:i});if(u&&!m||n.program.error("No permission to delete"),t){const{data:o,error:r}=yield s.from("app_versions").select().eq("app_id",e).eq("user_id",c).eq("name",t).eq("deleted",!1).single();o&&!r||n.program.error(`Version ${e}@${t} don't exist ${(0,a.formatError)(r)}`);const{data:i,error:p}=yield s.from("channels").select().eq("app_id",e).eq("created_by",c).eq("version",o.id);(i&&i.length||p)&&n.program.error(`Version ${e}@${t} is used in a channel, unlink it first ${(0,a.formatError)(p)}`);const{data:d,error:l}=yield s.from("devices_override").select().eq("app_id",e).eq("version",o.id);(d&&d.length||l)&&n.program.error(`Version ${e} @${t} is used in a device override, unlink it first ${(0,a.formatError)(l)}`);const{error:u}=yield s.storage.from("apps").remove([`${c}/${e}/versions/${o.bucket_id} `]);u&&n.program.error(`Something went wrong when trying to delete ${e} @${t} ${u} `);const{error:m}=yield s.from("app_versions").update({deleted:!0}).eq("app_id",e).eq("user_id",c).eq("name",t);return m&&n.program.error(`App ${e}@${t} not found in database '${m}'`),void console.log("App version deleted from server")}const{data:f,error:g}=yield s.from("app_versions").select().eq("app_id",e).eq("user_id",c);if(g&&n.program.error(`App ${e} not found in database ${g} `),f&&f.length){const o=f.map((o=>`${c}/${e}/versions/${o.bucket_id} `)),{error:r}=yield s.storage.from("apps").remove(o);r&&n.program.error(`Cannot delete stored version for app ${e} from storage ${r} `)}const{error:v}=yield s.from("app_versions").delete().eq("app_id",e).eq("user_id",c);v&&n.program.error(`Cannot delete version for app ${e} from database ${v} `);const{error:y}=yield s.from("apps").delete().eq("app_id",e).eq("user_id",c);y&&n.program.error(`Cannot delete from database ${y} `),console.log("App deleted from server")}))},473:function(e,o,r){var t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0});const n=r(304),a=r(548),i=r(453),p=r(666),s=r(310),d=t(r(598)),l=r(937);n.program.version(d.default.version).command("add [appid]").alias("a").action(a.addApp).option("-n, --name <name>","app name").option("-i, --icon <icon>","app icon path").option("-a, --apikey <apikey>","apikey to link to your account"),n.program.version(d.default.version).command("login [apikey]").alias("l").action(l.login).option("--local","Only save in local folder"),n.program.command("upload [appid]").alias("u").action(s.uploadVersion).option("-a, --apikey <apikey>","apikey to link to your account").option("-p, --path <path>","path of the file to upload").option("-c, --channel <channel>","channel to link to").option("-e, --external <url>","link to external url intead of upload to capgo cloud").option("-f, --format <base64|hex|binary|utf8>","choose the upload format default base64").option("-v, --version <version>","version number of the file to upload"),n.program.command("set [appid]").alias("s").action(p.setChannel).option("-c, --channel <channel>","channel to link to").option("-v, --version <version>","version number of the file to upload").option("-s, --state <state>","set the state of the channel, public or private").option("-a, --apikey <apikey>","apikey to link to your account"),n.program.description("Manage package and version in capgo Cloud").command("delete [appid]").alias("d").action(i.deleteApp).option("-a, --apikey <apikey>","apikey to link to your account").option("-v, --version <version>","version number of the app to delete"),n.program.parse(process.argv)},937:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.login=void 0;const a=r(304),i=n(r(147)),p=n(r(37));o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:r}=o;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`)}console.log(`login saved into .capgo file in ${r?"local":"home"} directory`)}))},666:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.setChannel=void 0;const n=r(304),a=r(233);o.setChannel=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t,i;let{version:p}=o;const{state:s,channel:d="dev"}=o,l=o.apikey||(0,a.findSavedKey)(),c=yield(0,a.getConfig)();let u;e=e||(null===(r=null==c?void 0:c.app)||void 0===r?void 0:r.appId),p=p||(null===(i=null===(t=null==c?void 0:c.app)||void 0===t?void 0:t.package)||void 0===i?void 0:i.version),"public"!==s&&"private"!==s||(u="public"===s),l||n.program.error("Missing API key, you need to provide a API key to add your app"),e||n.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),p||u||n.program.error("Missing argument, you need to provide a state or a version"),p?console.log(`Set ${d} to @${p} in ${e}`):console.log(`Set${d} to @${s} in ${e}`);try{const o=(0,a.createSupabaseClient)(l);yield(0,a.checkKey)(o,l,["write","all"]);const{data:r,error:t}=yield o.rpc("get_user_id",{apikey:l}),i=r?r.toString():"";i&&!t||n.program.error(`Cannot verify user ${(0,a.formatError)(t)}`),yield(0,a.checkPlan)(o,i);const s={created_by:i,app_id:e,name:d};if(p){const{data:r,error:t}=yield o.from("app_versions").select().eq("app_id",e).eq("name",p).eq("user_id",i).eq("deleted",!1);!t&&r&&r.length||n.program.error(`Cannot find version ${p}`),s.version=r[0].id}void 0!==u&&(s.public=u);try{const{error:e}=yield(0,a.updateOrCreateChannel)(o,s,l);e&&n.program.error(`Cannot set channel ${(0,a.formatError)(e)}`)}catch(e){n.program.error(`Cannot set channel ${(0,a.formatError)(e)}`)}}catch(e){n.program.error(`Unknow error ${(0,a.formatError)(e)}`)}p?console.log("Done ✅"):console.log(`You can use now is channel in your app with the url: ${a.host}/api/latest?appid=${e}&channel=${d}`)}))},310:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.uploadVersion=void 0;const a=n(r(844)),i=r(304),p=r(113),s=n(r(295)),d=n(r(912)),l=r(906),c=r(233);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t,n,u;let{version:m,path:f,channel:g}=o;const{external:v}=o,y=o.apikey||(0,c.findSavedKey)();g=g||"dev";const h=yield(0,c.getConfig)();e=e||(null===(r=null==h?void 0:h.app)||void 0===r?void 0:r.appId),m=m||(null===(n=null===(t=null==h?void 0:h.app)||void 0===t?void 0:t.package)||void 0===n?void 0:n.version),d.default.valid(m)||i.program.error(`Your version name ${m}, is not valid it should follow semver convention : https://semver.org/`),f=f||(null===(u=null==h?void 0:h.app)||void 0===u?void 0:u.webDir),y||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&m&&f||i.program.error("Missing argument, you need to provide a appid and a version and a path, or be in a capacitor project"),console.log(`Upload ${e}@${m} started from path "${f}" to Capgo cloud`);const _=(0,c.createSupabaseClient)(y);yield(0,c.checkKey)(_,y,["write","all"]);const k=new s.default.MultiBar({clearOnComplete:!1,hideCursor:!0},s.default.Presets.shades_grey),b=k.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},s.default.Presets.shades_grey);b.start(7,0,{speed:"N/A"});const{data:$,error:w}=yield _.rpc("exist_app_versions",{apikey:y,name_version:m,appid:e});($||w)&&(k.stop(),i.program.error(`This app version already exist or was deleted, you cannot re-upload it ${(0,c.formatError)(w)}`)),b.increment();const{data:x,error:C}=yield _.rpc("get_user_id",{apikey:y}),q=x?x.toString():"";q&&!C||(k.stop(),i.program.error(`Cannot verify user ${(0,c.formatError)(C)}`)),yield(0,c.checkPlan)(_,q,!1);const{data:S,error:A}=yield _.rpc("is_trial",{userid:q}).single();(S&&S>0||A)&&k.log(`WARNING !!\nTrial expires in ${S} days, upgrade here: ${c.hostWeb}/app/usage\n`),b.increment();const{data:P,error:I}=yield _.rpc("exist_app",{appid:e,apikey:y});P&&!I||(k.stop(),i.program.error(`Cannot find app ${e} in your account \n${(0,c.formatError)(I)}`)),b.increment();const{data:M,error:j}=yield _.rpc("exist_app_versions",{appid:e,apikey:y,name_version:m});(M||j)&&i.program.error(`Version already exists ${(0,c.formatError)(j)}`),b.increment();const E=(0,p.randomUUID)();let O="";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(f);const r=o.toBuffer();O=yield(0,l.checksum)(r,"crc32");const t=Math.floor(r.byteLength/1024/1024),n=`apps/${q}/${e}/versions`;b.increment(),t>30&&(k.stop(),i.program.error(`The app is too big, the limit is 30 Mb, your is ${t} Mb`)),t>25&&k.log(`WARNING !!\nThe app size is ${t} Mb, the limit is 30 Mb\n`);const{error:p}=yield _.storage.from(n).upload(E,r,{contentType:"application/zip"});p&&(k.stop(),i.program.error(`Cannot upload ${(0,c.formatError)(p)}`))}b.increment();const{data:T,error:N}=yield(0,c.updateOrCreateVersion)(_,{bucket_id:v?void 0:E,user_id:q,name:m,app_id:e,external_url:v,checksum:O},y);if(N&&(k.stop(),i.program.error(`Cannot add version ${(0,c.formatError)(N)}`)),b.increment(),T&&T.length){const{error:o}=yield(0,c.updateOrCreateChannel)(_,{name:g,app_id:e,created_by:q,version:T[0].id},y);o&&k.log("Cannot set version with upload key, use key with more rights for that\n")}else k.log("Cannot set version with upload key, use key with more rights for that\n");k.stop();const z=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 ${g} as public here: ${c.hostWeb}/app/package/${z}`),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/${z}/devices`)}))},233:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.updateOrCreateChannel=o.updateOrCreateVersion=o.getConfig=o.formatError=o.findSavedKey=o.checkPlan=o.isTrial=o.isGoodPlan=o.checkKey=o.createSupabaseClient=o.supaAnon=o.hostSupa=o.hostWeb=o.host=void 0;const a=r(778),i=r(304),p=r(885),s=n(r(867)),d=n(r(147)),l=n(r(37));o.host="https://capgo.app",o.hostWeb="https://web.capgo.app",o.hostSupa="https://xvwzpoazmxkqosrdewyv.supabase.co",o.supaAnon="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNzgwNTAwOSwiZXhwIjoxOTUzMzgxMDA5fQ.8tgID1d4jodPwuo_fz4KHN4o1XKB9fnqyt0_GaJSj-w",o.createSupabaseClient=e=>(0,p.createClient)(o.hostSupa,o.supaAnon,{headers:{capgkey:e}}),o.checkKey=(e,r,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:a}=yield e.rpc("is_allowed_capgkey",{apikey:r,keymode:n});t&&!a||i.program.error(`Invalid API key or insufficient permissions ${(0,o.formatError)(a)}`)})),o.isGoodPlan=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:r,error:t}=yield e.rpc("is_good_plan",{userid:o}).single();if(t)throw t;return r||!1})),o.isTrial=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:r,error:t}=yield e.rpc("is_trial",{userid:o}).single();if(t)throw t;return r||0})),o.checkPlan=(e,r,n=!0)=>t(void 0,void 0,void 0,(function*(){let t=yield(0,o.isGoodPlan)(e,r);const a=yield(0,o.isTrial)(e,r);a>0&&(t=!0),t||i.program.error(`You need to upgrade your plan to continue to use capgo.\n Upgrade here: ${o.hostWeb}/app/usage\n`),a>0&&n&&console.log(`WARNING !!\nTrial expires in ${a} days, upgrade here: ${o.hostWeb}/app/usage\n`)})),o.findSavedKey=()=>{let e=`${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=()=>t(void 0,void 0,void 0,(function*(){let e;try{e=yield(0,a.loadConfig)()}catch(e){i.program.error("No capacitor config file found, run `cap init` first")}return e})),o.updateOrCreateVersion=(e,o,r)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:n}=yield e.rpc("exist_app_versions",{appid:o.app_id,name_version:o.name,apikey:r});return t&&!n?(o.deleted=!1,e.from("app_versions").update(o).eq("app_id",o.app_id).eq("name",o.name)):e.from("app_versions").insert(o)})),o.updateOrCreateChannel=(e,o,r)=>t(void 0,void 0,void 0,(function*(){if(!o.app_id||!o.name||!o.created_by)return console.error("missing app_id, name, or created_by"),Promise.reject(new Error("missing app_id, name, or created_by"));const{data:t,error:n}=yield e.rpc("exist_channel",{appid:o.app_id,name_channel:o.name,apikey:r});return t&&!n?e.from("channels").update(o,{returning:"minimal"}).eq("app_id",o.app_id).eq("name",o.name).eq("created_by",o.created_by):e.from("channels").insert(o,{returning:"minimal"})}))},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")},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.14.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","mime":"^3.0.0","node-stream-zip":"^1.15.0","prettyjson":"^1.2.5","semver":"^7.3.7","upath":"^2.0.1"},"devDependencies":{"@types/adm-zip":"0.5.0","@types/cli-progress":"^3.11.0","@types/fs-extra":"^9.0.13","@types/mime":"^2.0.3","@types/node":"^17.0.31","@types/prettyjson":"^0.0.30","@types/semver":"^7.3.10","@typescript-eslint/eslint-plugin":"5.22.0","@typescript-eslint/parser":"5.22.0","eslint":"8.14.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^8.5.0","eslint-import-resolver-typescript":"2.7.1","eslint-plugin-import":"2.26.0","eslint-plugin-prettier":"^4.0.0","git-format-staged":"3.0.0","husky":"^7.0.4","nodemon":"2.0.16","pkg":"5.6.0","prettier":"2.6.2","ts-loader":"^9.3.0","ts-node":"^10.7.0","tsconfig-paths":"4.0.0","typescript":"4.6.4","webpack":"5.72.0","webpack-cli":"^4.9.2","webpack-node-externals":"^3.0.0"}}')}},o={};!function r(t){var n=o[t];if(void 0!==n)return n.exports;var a=o[t]={exports:{}};return e[t].call(a.exports,a,a.exports,r),a.exports}(473)})();
2
+ (()=>{"use strict";var e={548:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.addApp=void 0;const n=r(304),a=r(113),i=r(147),p=r(470),s=r(11),d=r(233),c="assets/icon.png";o.addApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t;let{name:l,icon:u}=o;const g=o.apikey||(0,d.findSavedKey)(),f=yield(0,d.getConfig)(),v=(0,d.useLogSnag)();e=e||(null===(r=null==f?void 0:f.app)||void 0===r?void 0:r.appId),l=l||(null===(t=null==f?void 0:f.app)||void 0===t?void 0:t.appName)||"Unknown",u=u||"resources/icon.png",g||n.program.error("Missing API key, you need to provide a API key to add your app"),e&&l||n.program.error("Missing argument, you need to provide a appid and a name, or be in a capacitor project"),console.log(`Add ${e} to Capgo`);const m=(0,d.createSupabaseClient)(g);yield(0,d.checkKey)(m,g,["write","all"]);const{data:y,error:h}=yield m.rpc("get_user_id",{apikey:g}),_=y?y.toString():"";let k,b;_&&!h||n.program.error(`Cannot verify user ${(0,d.formatError)(h)}`),yield(0,d.checkPlan)(m,_),console.log("Adding..."),u&&(0,p.existsSync)(u)?(k=(0,i.readFileSync)(u),b=(0,s.getType)(u)||"image/png",console.warn(`Found app icon ${u}`)):(0,p.existsSync)(c)?(k=(0,i.readFileSync)(c),b=(0,s.getType)(c)||"image/png",console.warn(`Found app icon ${c}`)):console.warn(`Cannot find app icon in any of the following locations: ${u}, ${c}`);const{data:$,error:w}=yield m.rpc("exist_app",{appid:e,apikey:g});($||w)&&n.program.error(`App already exists ${(0,d.formatError)(w)}`);const x=`icon_${(0,a.randomUUID)()}`;let C="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(k&&b){const{error:o}=yield m.storage.from(`images/${_}/${e}`).upload(x,k,{contentType:b});o&&n.program.error(`Could not add app ${(0,d.formatError)(o)}`);const{data:r}=yield m.storage.from(`images/${_}/${e}`).getPublicUrl(x);C=(null==r?void 0:r.publicURL)||C}const{error:S}=yield m.from("apps").insert({icon_url:C,user_id:_,name:l,app_id:e},{returning:"minimal"});S&&n.program.error(`Could not add app ${(0,d.formatError)(S)}`);const{error:q}=yield m.from("app_versions").insert([{user_id:_,deleted:!0,name:"unknown",app_id:e},{user_id:_,deleted:!0,name:"builtin",app_id:e}],{returning:"minimal"});q&&n.program.error(`Could not add app ${(0,d.formatError)(q)}`),v.publish({channel:"app",event:"App Added",icon:"🎉",tags:{"user-id":_,"app-id":e},notify:!1}).catch(),console.log("App added to server, you can upload a version now")}))},453:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.deleteApp=void 0;const n=r(304),a=r(233);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var r;const{version:t}=o,i=o.apikey||(0,a.findSavedKey)(),p=yield(0,a.getConfig)(),s=(0,a.useLogSnag)();e=e||(null===(r=null==p?void 0:p.app)||void 0===r?void 0:r.appId),i||n.program.error("Missing API key, you need to provide an API key to delete your app"),e||n.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),console.log(`Delete ${e} to Capgo`);const d=(0,a.createSupabaseClient)(i);yield(0,a.checkKey)(d,i,["all"]);const{data:c,error:l}=yield d.rpc("get_user_id",{apikey:i}),u=c?c.toString():"";u&&!l||n.program.error(`Cannot verify user ${(0,a.formatError)(l)}`);const{data:g,error:f}=yield d.rpc("exist_app",{appid:e,apikey:i});if(g&&!f||n.program.error("No permission to delete"),t){const{data:o,error:r}=yield d.from("app_versions").select().eq("app_id",e).eq("user_id",u).eq("name",t).eq("deleted",!1).single();o&&!r||n.program.error(`Version ${e}@${t} don't exist ${(0,a.formatError)(r)}`);const{data:i,error:p}=yield d.from("channels").select().eq("app_id",e).eq("created_by",u).eq("version",o.id);(i&&i.length||p)&&n.program.error(`Version ${e}@${t} is used in a channel, unlink it first ${(0,a.formatError)(p)}`);const{data:s,error:c}=yield d.from("devices_override").select().eq("app_id",e).eq("version",o.id);(s&&s.length||c)&&n.program.error(`Version ${e} @${t} is used in a device override, unlink it first ${(0,a.formatError)(c)}`);const{error:l}=yield d.storage.from("apps").remove([`${u}/${e}/versions/${o.bucket_id} `]);l&&n.program.error(`Something went wrong when trying to delete ${e} @${t} ${l} `);const{error:g}=yield d.from("app_versions").update({deleted:!0}).eq("app_id",e).eq("user_id",u).eq("name",t);return g&&n.program.error(`App ${e}@${t} not found in database '${g}'`),void console.log("App version deleted from server")}const{data:v,error:m}=yield d.from("app_versions").select().eq("app_id",e).eq("user_id",u);if(m&&n.program.error(`App ${e} not found in database ${m} `),v&&v.length){const o=v.map((o=>`${u}/${e}/versions/${o.bucket_id} `)),{error:r}=yield d.storage.from("apps").remove(o);r&&n.program.error(`Cannot delete stored version for app ${e} from storage ${r} `)}const{error:y}=yield d.from("app_versions").delete().eq("app_id",e).eq("user_id",u);y&&n.program.error(`Cannot delete version for app ${e} from database ${y} `);const{error:h}=yield d.from("apps").delete().eq("app_id",e).eq("user_id",u);h&&n.program.error(`Cannot delete from database ${h} `),s.publish({channel:"app",event:"App Deleted",icon:"😱",tags:{"user-id":u,"app-id":e},notify:!1}).catch(),console.log("App deleted from server")}))},473:function(e,o,r){var t=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0});const n=r(304),a=r(548),i=r(453),p=r(666),s=r(310),d=t(r(598)),c=r(937);n.program.version(d.default.version).command("add [appid]").alias("a").action(a.addApp).option("-n, --name <name>","app name").option("-i, --icon <icon>","app icon path").option("-a, --apikey <apikey>","apikey to link to your account"),n.program.version(d.default.version).command("login [apikey]").alias("l").action(c.login).option("--local","Only save in local folder"),n.program.command("upload [appid]").alias("u").action(s.uploadVersion).option("-a, --apikey <apikey>","apikey to link to your account").option("-p, --path <path>","path of the file to upload").option("-c, --channel <channel>","channel to link to").option("-e, --external <url>","link to external url intead of upload to capgo cloud").option("-f, --format <base64|hex|binary|utf8>","choose the upload format default base64").option("-v, --version <version>","version number of the file to upload"),n.program.command("set [appid]").alias("s").action(p.setChannel).option("-c, --channel <channel>","channel to link to").option("-v, --version <version>","version number of the file to upload").option("-s, --state <state>","set the state of the channel, public or private").option("-a, --apikey <apikey>","apikey to link to your account"),n.program.description("Manage package and version in capgo Cloud").command("delete [appid]").alias("d").action(i.deleteApp).option("-a, --apikey <apikey>","apikey to link to your account").option("-v, --version <version>","version number of the app to delete"),n.program.parse(process.argv)},937:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.login=void 0;const a=r(304),i=n(r(147)),p=n(r(37)),s=r(233);o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:r}=o,t=(0,s.useLogSnag)();if(r)i.default.existsSync(".git")||a.program.error("To use local you should be in a git repository"),i.default.writeFileSync(".capgo",`${e}\n`),i.default.appendFileSync(".gitignore",".capgo\n");else{const o=p.default.homedir();i.default.writeFileSync(`${o}/.capgo`,`${e}\n`)}const n=(0,s.createSupabaseClient)(e),{data:d,error:c}=yield n.rpc("get_user_id",{apikey:e}),l=d?d.toString():"";l&&!c||a.program.error(`Cannot verify user ${(0,s.formatError)(c)}`),t.publish({channel:"user-login",event:"User CLI login",icon:"✅",tags:{"user-id":l},notify:!1}).catch(),console.log(`login saved into .capgo file in ${r?"local":"home"} directory`)}))},666:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))};Object.defineProperty(o,"__esModule",{value:!0}),o.setChannel=void 0;const n=r(304),a=r(233);o.setChannel=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t,i;let{version:p}=o;const{state:s,channel:d="dev"}=o,c=o.apikey||(0,a.findSavedKey)(),l=yield(0,a.getConfig)(),u=(0,a.useLogSnag)();let g;e=e||(null===(r=null==l?void 0:l.app)||void 0===r?void 0:r.appId),p=p||(null===(i=null===(t=null==l?void 0:l.app)||void 0===t?void 0:t.package)||void 0===i?void 0:i.version),"public"!==s&&"private"!==s||(g="public"===s),c||n.program.error("Missing API key, you need to provide a API key to add your app"),e||n.program.error("Missing argument, you need to provide a appid, or be in a capacitor project"),p||g||n.program.error("Missing argument, you need to provide a state or a version"),p?console.log(`Set ${d} to @${p} in ${e}`):console.log(`Set${d} to @${s} in ${e}`);try{const o=(0,a.createSupabaseClient)(c);yield(0,a.checkKey)(o,c,["write","all"]);const{data:r,error:t}=yield o.rpc("get_user_id",{apikey:c}),i=r?r.toString():"";i&&!t||n.program.error(`Cannot verify user ${(0,a.formatError)(t)}`),yield(0,a.checkPlan)(o,i);const s={created_by:i,app_id:e,name:d};if(p){const{data:r,error:t}=yield o.from("app_versions").select().eq("app_id",e).eq("name",p).eq("user_id",i).eq("deleted",!1);!t&&r&&r.length||n.program.error(`Cannot find version ${p}`),s.version=r[0].id}void 0!==g&&(s.public=g);try{const{error:e}=yield(0,a.updateOrCreateChannel)(o,s,c);e&&n.program.error(`Cannot set channel ${(0,a.formatError)(e)}`)}catch(e){n.program.error(`Cannot set channel ${(0,a.formatError)(e)}`)}u.publish({channel:"app",event:"Set app",icon:"✅",tags:{"user-id":i,"app-id":e},notify:!1}).catch()}catch(e){n.program.error(`Unknow error ${(0,a.formatError)(e)}`)}p?console.log("Done ✅"):console.log(`You can use now is channel in your app with the url: ${a.host}/api/latest?appid=${e}&channel=${d}`)}))},310:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.uploadVersion=void 0;const a=n(r(844)),i=r(304),p=r(113),s=n(r(295)),d=n(r(912)),c=r(906),l=r(233);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var r,t,n,u;let{version:g,path:f,channel:v}=o;const{external:m}=o,y=o.apikey||(0,l.findSavedKey)(),h=(0,l.useLogSnag)();v=v||"dev";const _=yield(0,l.getConfig)();e=e||(null===(r=null==_?void 0:_.app)||void 0===r?void 0:r.appId),g=g||(null===(n=null===(t=null==_?void 0:_.app)||void 0===t?void 0:t.package)||void 0===n?void 0:n.version),d.default.valid(g)||i.program.error(`Your version name ${g}, is not valid it should follow semver convention : https://semver.org/`),f=f||(null===(u=null==_?void 0:_.app)||void 0===u?void 0:u.webDir),y||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&g&&f||i.program.error("Missing argument, you need to provide a appid and a version and a path, or be in a capacitor project"),console.log(`Upload ${e}@${g} started from path "${f}" to Capgo cloud`);const k=(0,l.createSupabaseClient)(y);yield(0,l.checkKey)(k,y,["write","all"]);const b=new s.default.MultiBar({clearOnComplete:!1,hideCursor:!0},s.default.Presets.shades_grey),$=b.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},s.default.Presets.shades_grey);$.start(7,0,{speed:"N/A"});const{data:w,error:x}=yield k.rpc("exist_app_versions",{apikey:y,name_version:g,appid:e});(w||x)&&(b.stop(),i.program.error(`This app version already exist or was deleted, you cannot re-upload it ${(0,l.formatError)(x)}`)),$.increment();const{data:C,error:S}=yield k.rpc("get_user_id",{apikey:y}),q=C?C.toString():"";q&&!S||(b.stop(),i.program.error(`Cannot verify user ${(0,l.formatError)(S)}`)),yield(0,l.checkPlan)(k,q,!1);const{data:A,error:P}=yield k.rpc("is_trial",{userid:q}).single();(A&&A>0||P)&&b.log(`WARNING !!\nTrial expires in ${A} days, upgrade here: ${l.hostWeb}/app/usage\n`),$.increment();const{data:I,error:j}=yield k.rpc("exist_app",{appid:e,apikey:y});I&&!j||(b.stop(),i.program.error(`Cannot find app ${e} in your account \n${(0,l.formatError)(j)}`)),$.increment();const{data:E,error:M}=yield k.rpc("exist_app_versions",{appid:e,apikey:y,name_version:g});(E||M)&&i.program.error(`Version already exists ${(0,l.formatError)(M)}`),$.increment();const O=(0,p.randomUUID)();let T="";if(m)m&&!m.startsWith("https://")&&(b.stop(),i.program.error(`External link should should start with "https://" current is "${m}"`));else{const o=new a.default;o.addLocalFolder(f);const r=o.toBuffer();T=yield(0,c.checksum)(r,"crc32");const t=Math.floor(r.byteLength/1024/1024),n=`apps/${q}/${e}/versions`;$.increment(),t>20&&(b.log(`WARNING !!\nThe app size is ${t} Mb, this may take a while to download for users\n`),h.publish({channel:"app-error",event:"App Too Large",icon:"🚛",tags:{"user-id":q,"app-id":e},notify:!1}).catch());const{error:p}=yield k.storage.from(n).upload(O,r,{contentType:"application/zip"});p&&(b.stop(),i.program.error(`Cannot upload ${(0,l.formatError)(p)}`))}$.increment();const{data:N,error:z}=yield(0,l.updateOrCreateVersion)(k,{bucket_id:m?void 0:O,user_id:q,name:g,app_id:e,external_url:m,checksum:T},y);if(z&&(b.stop(),i.program.error(`Cannot add version ${(0,l.formatError)(z)}`)),$.increment(),N&&N.length){const{error:o}=yield(0,l.updateOrCreateChannel)(k,{name:v,app_id:e,created_by:q,version:N[0].id},y);o&&b.log("Cannot set version with upload key, use key with more rights for that\n")}else b.log("Cannot set version with upload key, use key with more rights for that\n");b.stop();const U=e.replace(/\./g,"--");console.log("App uploaded to server"),console.log(`Try it in mobile app: ${l.host}/app_mobile`),console.log(`Or set the channel ${v} as public here: ${l.hostWeb}/app/package/${U}`),console.log("To use with live update in your own app"),console.log(`You can link specific device to this version to make user try it first, here: ${l.hostWeb}/app/p/${U}/devices`),h.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":q,"app-id":e},notify:!1}).catch()}))},233:function(e,o,r){var t=this&&this.__awaiter||function(e,o,r,t){return new(r||(r=Promise))((function(n,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function p(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var o;e.done?n(e.value):(o=e.value,o instanceof r?o:new r((function(e){e(o)}))).then(i,p)}s((t=t.apply(e,o||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(o,"__esModule",{value:!0}),o.useLogSnag=o.updateOrCreateChannel=o.updateOrCreateVersion=o.getConfig=o.formatError=o.findSavedKey=o.checkPlan=o.isTrial=o.isGoodPlan=o.checkKey=o.createSupabaseClient=o.supaAnon=o.hostSupa=o.hostWeb=o.host=void 0;const a=r(778),i=r(304),p=r(885),s=n(r(867)),d=n(r(147)),c=n(r(37)),l=r(133);o.host="https://capgo.app",o.hostWeb="https://web.capgo.app",o.hostSupa="https://xvwzpoazmxkqosrdewyv.supabase.co",o.supaAnon="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNzgwNTAwOSwiZXhwIjoxOTUzMzgxMDA5fQ.8tgID1d4jodPwuo_fz4KHN4o1XKB9fnqyt0_GaJSj-w",o.createSupabaseClient=e=>(0,p.createClient)(o.hostSupa,o.supaAnon,{headers:{capgkey:e}}),o.checkKey=(e,r,n)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:a}=yield e.rpc("is_allowed_capgkey",{apikey:r,keymode:n});t&&!a||i.program.error(`Invalid API key or insufficient permissions ${(0,o.formatError)(a)}`)})),o.isGoodPlan=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:r,error:t}=yield e.rpc("is_good_plan",{userid:o}).single();if(t)throw t;return r||!1})),o.isTrial=(e,o)=>t(void 0,void 0,void 0,(function*(){const{data:r,error:t}=yield e.rpc("is_trial",{userid:o}).single();if(t)throw t;return r||0})),o.checkPlan=(e,r,n=!0)=>t(void 0,void 0,void 0,(function*(){let t=yield(0,o.isGoodPlan)(e,r);const a=yield(0,o.isTrial)(e,r);a>0&&(t=!0),t||i.program.error(`You need to upgrade your plan to continue to use capgo.\n Upgrade here: ${o.hostWeb}/app/usage\n`),a>0&&n&&console.log(`WARNING !!\nTrial expires in ${a} days, upgrade here: ${o.hostWeb}/app/usage\n`)})),o.findSavedKey=()=>{let e=`${c.default.homedir()}/.capgo`;return d.default.existsSync(e)?d.default.readFileSync(e,"utf8").trim():(e=".capgo",d.default.existsSync(e)?d.default.readFileSync(e,"utf8").trim():null)},o.formatError=e=>e?`\n${s.default.render(e)}`:"",o.getConfig=()=>t(void 0,void 0,void 0,(function*(){let e;try{e=yield(0,a.loadConfig)()}catch(e){i.program.error("No capacitor config file found, run `cap init` first")}return e})),o.updateOrCreateVersion=(e,o,r)=>t(void 0,void 0,void 0,(function*(){const{data:t,error:n}=yield e.rpc("exist_app_versions",{appid:o.app_id,name_version:o.name,apikey:r});return t&&!n?(o.deleted=!1,e.from("app_versions").update(o).eq("app_id",o.app_id).eq("name",o.name)):e.from("app_versions").insert(o)})),o.updateOrCreateChannel=(e,o,r)=>t(void 0,void 0,void 0,(function*(){if(!o.app_id||!o.name||!o.created_by)return console.error("missing app_id, name, or created_by"),Promise.reject(new Error("missing app_id, name, or created_by"));const{data:t,error:n}=yield e.rpc("exist_channel",{appid:o.app_id,name_channel:o.name,apikey:r});return t&&!n?e.from("channels").update(o,{returning:"minimal"}).eq("app_id",o.app_id).eq("name",o.name).eq("created_by",o.created_by):e.from("channels").insert(o,{returning:"minimal"})})),o.useLogSnag=()=>new l.LogSnag({token:"c124f5e9d0ce5bdd14bbb48f815d5583",project:"capgo"})},778:e=>{e.exports=require("@capacitor/cli/dist/config")},885:e=>{e.exports=require("@supabase/supabase-js")},906:e=>{e.exports=require("@tomasklaen/checksum")},844:e=>{e.exports=require("adm-zip")},295:e=>{e.exports=require("cli-progress")},304:e=>{e.exports=require("commander")},470:e=>{e.exports=require("fs-extra")},133:e=>{e.exports=require("logsnag")},11:e=>{e.exports=require("mime")},867:e=>{e.exports=require("prettyjson")},912:e=>{e.exports=require("semver")},113:e=>{e.exports=require("crypto")},147:e=>{e.exports=require("fs")},37:e=>{e.exports=require("os")},598:e=>{e.exports=JSON.parse('{"name":"@capgo/cli","version":"0.16.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","semver":"^7.3.7","upath":"^2.0.1"},"devDependencies":{"@types/adm-zip":"0.5.0","@types/cli-progress":"^3.11.0","@types/fs-extra":"^9.0.13","@types/mime":"^2.0.3","@types/node":"^17.0.31","@types/prettyjson":"^0.0.30","@types/semver":"^7.3.10","@typescript-eslint/eslint-plugin":"5.22.0","@typescript-eslint/parser":"5.22.0","eslint":"8.14.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^8.5.0","eslint-import-resolver-typescript":"2.7.1","eslint-plugin-import":"2.26.0","eslint-plugin-prettier":"^4.0.0","git-format-staged":"3.0.0","husky":"^7.0.4","nodemon":"2.0.16","pkg":"5.6.0","prettier":"2.6.2","ts-loader":"^9.3.0","ts-node":"^10.7.0","tsconfig-paths":"4.0.0","typescript":"4.6.4","webpack":"5.72.0","webpack-cli":"^4.9.2","webpack-node-externals":"^3.0.0"}}')}},o={};!function r(t){var n=o[t];if(void 0!==n)return n.exports;var a=o[t]={exports:{}};return e[t].call(a.exports,a,a.exports,r),a.exports}(473)})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/cli",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "description": "A CLI to upload to capgo servers",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -44,6 +44,7 @@
44
44
  "commander": "9.2.0",
45
45
  "form-data": "^4.0.0",
46
46
  "fs-extra": "10.1.0",
47
+ "logsnag": "^0.1.2",
47
48
  "mime": "^3.0.0",
48
49
  "node-stream-zip": "^1.15.0",
49
50
  "prettyjson": "^1.2.5",
package/src/bin/add.ts CHANGED
@@ -4,7 +4,7 @@ import { readFileSync } from 'fs';
4
4
  import { existsSync } from 'fs-extra';
5
5
  import { getType } from 'mime';
6
6
  import { definitions } from './types_supabase'
7
- import { getConfig, createSupabaseClient, formatError, findSavedKey, checkPlan, checkKey } from './utils';
7
+ import { getConfig, createSupabaseClient, formatError, findSavedKey, checkPlan, checkKey, useLogSnag } from './utils';
8
8
 
9
9
  interface Options {
10
10
  apikey: string;
@@ -16,6 +16,8 @@ export const addApp = async (appid: string, options: Options) => {
16
16
  let { name, icon } = options;
17
17
  const apikey = options.apikey || findSavedKey()
18
18
  const config = await getConfig();
19
+ const snag = useLogSnag()
20
+
19
21
  appid = appid || config?.app?.appId
20
22
  name = name || config?.app?.appName || 'Unknown'
21
23
  icon = icon || "resources/icon.png" // default path for capacitor app
@@ -111,5 +113,15 @@ export const addApp = async (appid: string, options: Options) => {
111
113
  if (dbVersionError) {
112
114
  program.error(`Could not add app ${formatError(dbVersionError)}`);
113
115
  }
116
+ snag.publish({
117
+ channel: 'app',
118
+ event: 'App Added',
119
+ icon: '🎉',
120
+ tags: {
121
+ 'user-id': userId,
122
+ 'app-id': appid,
123
+ },
124
+ notify: false,
125
+ }).catch()
114
126
  console.log("App added to server, you can upload a version now")
115
127
  }
package/src/bin/delete.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { program } from 'commander';
2
- import { getConfig, createSupabaseClient, formatError, findSavedKey, checkKey } from './utils';
2
+ import { getConfig, createSupabaseClient, formatError, findSavedKey, checkKey, useLogSnag } from './utils';
3
3
  import { definitions } from './types_supabase'
4
4
 
5
5
  interface Options {
@@ -11,6 +11,8 @@ export const deleteApp = async (appid: string, options: Options) => {
11
11
  const { version } = options;
12
12
  const apikey = options.apikey || findSavedKey()
13
13
  const config = await getConfig();
14
+ const snag = useLogSnag()
15
+
14
16
  appid = appid || config?.app?.appId
15
17
  if (!apikey) {
16
18
  program.error('Missing API key, you need to provide an API key to delete your app');
@@ -132,6 +134,15 @@ export const deleteApp = async (appid: string, options: Options) => {
132
134
  if (dbAppError) {
133
135
  program.error(`Cannot delete from database ${dbAppError} `)
134
136
  }
135
-
137
+ snag.publish({
138
+ channel: 'app',
139
+ event: 'App Deleted',
140
+ icon: '😱',
141
+ tags: {
142
+ 'user-id': userId,
143
+ 'app-id': appid,
144
+ },
145
+ notify: false,
146
+ }).catch()
136
147
  console.log("App deleted from server")
137
148
  }
package/src/bin/login.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { program } from 'commander';
2
2
  import fs from 'fs'
3
3
  import os from 'os'
4
+ import { createSupabaseClient, formatError, useLogSnag } from './utils';
4
5
 
5
6
  interface Options {
6
7
  local: boolean;
@@ -8,6 +9,7 @@ interface Options {
8
9
  export const login = async (apikey: string, options: Options) => {
9
10
  // write in file .capgo the apikey in home directory
10
11
  const { local } = options;
12
+ const snag = useLogSnag()
11
13
 
12
14
  if (local) {
13
15
  if (!fs.existsSync('.git')) {
@@ -19,5 +21,21 @@ export const login = async (apikey: string, options: Options) => {
19
21
  const userHomeDir = os.homedir();
20
22
  fs.writeFileSync(`${userHomeDir}/.capgo`, `${apikey}\n`);
21
23
  }
24
+ const supabase = createSupabaseClient(apikey)
25
+ const { data: dataUser, error: userIdError } = await supabase
26
+ .rpc<string>('get_user_id', { apikey })
27
+ const userId = dataUser ? dataUser.toString() : '';
28
+ if (!userId || userIdError) {
29
+ program.error(`Cannot verify user ${formatError(userIdError)}`);
30
+ }
31
+ snag.publish({
32
+ channel: 'user-login',
33
+ event: 'User CLI login',
34
+ icon: '✅',
35
+ tags: {
36
+ 'user-id': userId,
37
+ },
38
+ notify: false,
39
+ }).catch()
22
40
  console.log(`login saved into .capgo file in ${local ? 'local' : 'home'} directory`);
23
41
  }
package/src/bin/set.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { program } from 'commander';
2
2
  import {
3
3
  getConfig, createSupabaseClient, updateOrCreateChannel,
4
- host, formatError, findSavedKey, checkPlan, checkKey
4
+ host, formatError, findSavedKey, checkPlan, checkKey, useLogSnag
5
5
  } from './utils';
6
6
  import { definitions } from './types_supabase';
7
7
 
@@ -17,6 +17,8 @@ export const setChannel = async (appid: string, options: Options) => {
17
17
  const { state, channel = 'dev' } = options;
18
18
  const apikey = options.apikey || findSavedKey()
19
19
  const config = await getConfig();
20
+ const snag = useLogSnag()
21
+
20
22
  appid = appid || config?.app?.appId
21
23
  version = version || config?.app?.package?.version
22
24
  let parsedState
@@ -75,6 +77,16 @@ export const setChannel = async (appid: string, options: Options) => {
75
77
  catch (e) {
76
78
  program.error(`Cannot set channel ${formatError(e)}`);
77
79
  }
80
+ snag.publish({
81
+ channel: 'app',
82
+ event: 'Set app',
83
+ icon: '✅',
84
+ tags: {
85
+ 'user-id': userId,
86
+ 'app-id': appid,
87
+ },
88
+ notify: false,
89
+ }).catch()
78
90
  } catch (err) {
79
91
  program.error(`Unknow error ${formatError(err)}`);
80
92
  }
package/src/bin/upload.ts CHANGED
@@ -6,7 +6,7 @@ import semver from 'semver'
6
6
  import { checksum as getChecksum } from '@tomasklaen/checksum';
7
7
  import {
8
8
  host, hostWeb, getConfig, createSupabaseClient,
9
- updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlan, checkKey
9
+ updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlan, checkKey, useLogSnag
10
10
  } from './utils';
11
11
 
12
12
  interface Options {
@@ -17,13 +17,14 @@ interface Options {
17
17
  external?: string
18
18
  }
19
19
 
20
- const maxMb = 30;
21
- const alertMb = 25;
20
+ const alertMb = 20;
22
21
 
23
22
  export const uploadVersion = async (appid: string, options: Options) => {
24
23
  let { version, path, channel } = options;
25
24
  const { external } = options;
26
25
  const apikey = options.apikey || findSavedKey()
26
+ const snag = useLogSnag()
27
+
27
28
  channel = channel || 'dev';
28
29
  const config = await getConfig();
29
30
  appid = appid || config?.app?.appId
@@ -107,12 +108,18 @@ export const uploadVersion = async (appid: string, options: Options) => {
107
108
  const mbSize = Math.floor(zipped.byteLength / 1024 / 1024);
108
109
  const filePath = `apps/${userId}/${appid}/versions`
109
110
  b1.increment();
110
- if (mbSize > maxMb) {
111
- multibar.stop()
112
- program.error(`The app is too big, the limit is ${maxMb} Mb, your is ${mbSize} Mb`);
113
- }
114
111
  if (mbSize > alertMb) {
115
- multibar.log(`WARNING !!\nThe app size is ${mbSize} Mb, the limit is ${maxMb} Mb\n`);
112
+ multibar.log(`WARNING !!\nThe app size is ${mbSize} Mb, this may take a while to download for users\n`);
113
+ snag.publish({
114
+ channel: 'app-error',
115
+ event: 'App Too Large',
116
+ icon: '🚛',
117
+ tags: {
118
+ 'user-id': userId,
119
+ 'app-id': appid,
120
+ },
121
+ notify: false,
122
+ }).catch()
116
123
  }
117
124
 
118
125
  const { error: upError } = await supabase.storage
@@ -162,4 +169,14 @@ export const uploadVersion = async (appid: string, options: Options) => {
162
169
  console.log(`Or set the channel ${channel} as public here: ${hostWeb}/app/package/${appidWeb}`)
163
170
  console.log("To use with live update in your own app")
164
171
  console.log(`You can link specific device to this version to make user try it first, here: ${hostWeb}/app/p/${appidWeb}/devices`)
172
+ snag.publish({
173
+ channel: 'app',
174
+ event: 'App Uploaded',
175
+ icon: '⏫',
176
+ tags: {
177
+ 'user-id': userId,
178
+ 'app-id': appid,
179
+ },
180
+ notify: false,
181
+ }).catch()
165
182
  }
package/src/bin/utils.ts CHANGED
@@ -4,8 +4,10 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js'
4
4
  import prettyjson from 'prettyjson';
5
5
  import fs from 'fs'
6
6
  import os from 'os'
7
+ import { LogSnag } from 'logsnag'
7
8
  import { definitions } from './types_supabase';
8
9
 
10
+
9
11
  export const host = 'https://capgo.app';
10
12
  export const hostWeb = 'https://web.capgo.app';
11
13
  export const hostSupa = process.env.SUPA_DB === 'production'
@@ -148,4 +150,12 @@ export const updateOrCreateChannel = async (supabase: SupabaseClient, update: Pa
148
150
  return supabase
149
151
  .from<definitions['channels']>('channels')
150
152
  .insert(update, { returning: "minimal" })
151
- }
153
+ }
154
+
155
+ export const useLogSnag = (): LogSnag => {
156
+ const logsnag = new LogSnag({
157
+ token: 'c124f5e9d0ce5bdd14bbb48f815d5583',
158
+ project: 'capgo',
159
+ })
160
+ return logsnag
161
+ }