@capgo/cli 2.1.12 → 2.2.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/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [2.2.1](https://github.com/Cap-go/capgo-cli/compare/v2.2.0...v2.2.1) (2022-12-03)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * documentation ([77231bd](https://github.com/Cap-go/capgo-cli/commit/77231bd33cb6b7ed00465837f641a7f35670a7ee))
11
+
12
+ ## [2.2.0](https://github.com/Cap-go/capgo-cli/compare/v2.1.12...v2.2.0) (2022-12-03)
13
+
14
+
15
+ ### Features
16
+
17
+ * add key save command for CLI and document ([7fc5fd2](https://github.com/Cap-go/capgo-cli/commit/7fc5fd2c578aa658691b9d27bc1cd34da2792d36))
18
+
5
19
  ### [2.1.12](https://github.com/Cap-go/capgo-cli/compare/v2.1.11...v2.1.12) (2022-12-02)
6
20
 
7
21
 
package/README.md CHANGED
@@ -9,74 +9,158 @@ A CLI to upload and download files from the Capgo Cloud.
9
9
 
10
10
  ## Usage
11
11
 
12
- Before use the CLI you should register here : https://capgo.app/
12
+ Before use the CLI, you should register here : https://capgo.app/
13
13
 
14
14
  Then go to your account in `apikey` section and click in the `all` key to copy it.
15
15
 
16
16
  ## Login to Cloud
17
- `npx @capgo/cli login API_KEY`
18
- `API_KEY` your `apikey` copied in the previous step
17
+ `npx @capgo/cli login [apikey]`
18
+ `[apikey]` your `apikey` coming from your account.
19
+
20
+ Optionally, you can give:
21
+ - `--local` to save the API key in the local folder.
19
22
 
20
23
  ## Add new app to Cloud
21
24
  `npx @capgo/cli add [appId]`
22
25
  `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/init)
26
+ > 💡 All option will be guessed in your config if not provided.
23
27
 
24
28
  Optionally, you can give:
25
- - icon with `--icon /path/to/my/icon` to have a custom icon in the list
26
- - name with `--name test` to have a custom name in the list
27
-
28
-
29
+ - `--icon [/path/to/my/icon]` to have a custom icon in the list.
30
+ - `--name [test]` to have a custom name in the list.
31
+ - `--apikey [key]` API key to link to your account.
32
+
33
+ Example of capacitor.config.json for appId and AppName, the icon is guess in the resources folder
34
+ ```json
35
+ {
36
+ "appId": "ee.forgr.capacitor_go",
37
+ "appName": "Capgo",
38
+ "webDir": "dist",
39
+ }
40
+ ```
29
41
  ### Send version to Cloud
30
42
  `npx @capgo/cli upload [appId]`
31
- `[appId]` is your app ID the format is explained [here](https://capacitorjs.com/docs/cli/init)
43
+ `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/init)
44
+ Optionally, you can give:
45
+ - `--apikey [key]` API key to link to your account.
46
+ - `--path [/path/to/my/app]` to upload a specific folder.
47
+ - `--channel [test]` to upload to a specific channel.
48
+ - `--external [https://mydomain.com/myapp.zip]` to link to an external URL instead of upload to Capgo cloud, it should be a zip URL in HTTPS.
49
+ - `--key [/path/to/my/private_key]` the path of your private key.
50
+ - `--key-data [privateKey]` the private key data, if you want to use inline.
51
+ - `--no-key` to ignore signing key and send clear update.
52
+ - `--bundle [1.0.0]` to set the bundle version number of the file to upload.
53
+ - `--iv-session-key [key]` to send a custom session key to the cloud.
54
+
55
+ > ⭐️ External option help to unlock 2 cases: corporate with privacy concern, don't send the code to a third part and app bigger than 30 MB. With this setting, Capgo store only the link to the zip and send the link to all app
56
+
57
+ > 👀 Capgo cloud never look of what is in the link (for external option), or in the code when stored.
58
+
59
+ > 🔑 You can add a second layer of security by using encryption, then Capgo will not be able to look or modify anything, it become zero-trust.
60
+
61
+ Example of `package.json` for version
62
+ ```json
63
+ {
64
+ "version": "1.0.2"
65
+ }
66
+ ```
67
+ > ⛔ Version should be greater than “0.0.0”.
68
+
69
+ >💡 Don't forget to update the version number each time you send one, or device will don't see the update.
70
+ ### Configure channel
71
+ `npx @capgo/cli set [appId] --channel dev`
72
+ `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/init)
32
73
 
33
74
  Optionally, you can give:
34
- - icon with `--path /path/to/my/dist/folder` to send your code to the cloud
35
- - name with `--name test` to have a custom name in the list
36
- - channel with `--channel prod` to link this version to channel
75
+ `--bundle [1.2.3]` your app bundle already sent to the cloud, to link it to a channel.
76
+ `--latest` get the bundle version from `package.json:version`, cannot be used with `--bundle`.
77
+ `--state [ normal | default ]` set the channel state, can be `normal` or `default`. One channel need to be `default`.
78
+ `--downgrade` allow the channel to send downgrade version to devices.
79
+ `--no-downgrade` disallow the channel to send downgrade version to devices.
80
+ `--upgrade` allow the channel to send upgrade (major) version to devices.
81
+ `--no-upgrade` disallow the channel to send upgrade (major) version to devices.
82
+ `--ios` allow the channel to send version to iOS devices.
83
+ `--no-ios` disallow the channel to send version to iOS devices.
84
+ `--android` allow the channel to send version to android devices.
85
+ `--no-android` disallow the channel to send version to android devices.
86
+ `--self-assign` allow devices to self assign to this channel.
87
+ `--no-self-assign` disallow devices to self assign to this channel.
88
+ - `--apikey [key]` API key to link to your account.
37
89
 
38
- ### Send version to Cloud channel
39
- `npx @capgo/cli set [appId] [version] [channel]`
40
- `[appId]` your app ID the format is explained [here](https://capacitorjs.com/docs/cli/init)
41
- `[version]` your app version already sent to the cloud
42
- `[channel]` the channel you want to link the version
90
+ Optionally, you can give:
91
+ - `--apikey [key]` API key to link to your account.
92
+
93
+ ### List versions
94
+ `npx @capgo/cli list [appId] `
95
+ `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/init)
43
96
 
44
97
  ### Delete package to Cloud
45
98
  `npx @capgo/cli delete [appId]`
46
- `[appId]` your app ID present in the Cloud
99
+ `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/init)
47
100
 
101
+ Optionally, you can give:
102
+ - `--apikey [key]` API key to link to your account.
103
+ - `--bundle [bundleVersion]` with the version number will only delete this version
48
104
  ### Delete older packages in a SemVer range for a major version to Cloud
49
105
  `npx @capgo/cli cleanup [appId] --bundle=[majorVersion] --keep=[numberToKeep]`
50
- `[appId]` your app ID present in the Cloud
51
- `[majorVersion]` a version you wish to remove previous packages for, it will keep the last one + numberToKeep
52
- `[numberToKeep]` the number of packages you wish to keep
106
+ `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/init)
107
+
108
+ Optionally, you can give:
109
+ - `--apikey [key]` API key to link to your account.
110
+ - `--bundle [majorVersion]` a version you wish to remove previous packages for, it will keep the last one + numberToKeep.
111
+ - `--keep [numberToKeep]` the number of packages you wish to keep (default 4).
53
112
 
54
113
  For example:
55
114
  If you have 10 versions, from 10.0.1 to 10.0.11, and you use
56
115
  `npx @capgo/cli cleanup [appId] --bundle=10.0.0`
57
116
  it will remove 10.0.1 to 10.0.6.
58
- 10.0.7 untill 10.0.11 will be kept
117
+ 10.0.7 until 10.0.11 will be kept.
59
118
 
60
- This command will show a list of what it will be removing and ask for confirmation
119
+ This command will show a list of what it will be removing and ask for confirmation.
120
+
121
+ ## End-to-End encryption (Zero trust)
122
+
123
+ Capgo support end-to-end encryption, this mean that your code is encrypted before send to the cloud and decrypted on the device.
124
+ For that, you need to generate an RSA key pair, you can use the following command to generate it.
125
+
126
+ The encryption system is a combination of RSA and AES, the RSA key is used to encrypt the AES key, and the AES key is used to encrypt the file.
127
+
128
+ See below for more information about the encryption system.
129
+
130
+ ![crypto_explained](/crypto_explained.png)
131
+
132
+ ### Create key for your app
133
+ `npx @capgo/cli key create`
134
+
135
+ Optionally, you can give:
136
+ `--force` to overwrite the existing key.
137
+ This command will create for you a key pair in your app, and will ask you to save the private key in a safe place.
138
+ It's recommended to not git commit the private and public key, and to not share it with anyone.
139
+
140
+ ### Save key in your app config
141
+ `npx @capgo/cli key save`
142
+
143
+ Optionally, you can give:
144
+ `--key [/path/to/my/private_key]` the path of your private key.
145
+ `--key-data [privateKey]` the private key data, if you want to use inline.
146
+ This command is useful if you followed the recommendation and didn't commit the key in your app, and in the config.
147
+
148
+ ### Encrypt zip with your key
149
+ `npx @capgo/cli encrypt [path/to/zip]`
150
+ Optionally, you can give:
151
+ `--key [/path/to/my/private_key]` the path of your private key.
152
+ `--key-data [privateKey]` the private key data, if you want to use inline.
153
+ This command is use when you use external source to store your code or for test purpose.
154
+ The command will print your ivSessionKey and the encrypted zip, you can use it with the `--iv-session-key` and `--external` option of the `upload` command, or for decrypting the zip.
155
+
156
+
157
+ ### Decrypt zip with your key
158
+ `npx @capgo/cli encrypt [path/to/zip] [ivSessionKey]`
61
159
 
62
- ### Configure channel
63
- `npx @capgo/cli set [appId] --channel dev
64
- `
65
160
  Optionally, you can give:
66
- [appId] your app ID the format is explained here
67
- --bundle your app bundle already sent to the cloud, to link it to a channel
68
- --latest get the bundle version from `package.json:version`, cannot be use with --bundle
69
- --state set the channel state, can be normal or default. To use in your app, one channel need to be "default".
70
- --downgrade allow the channel to send downgrade version to devices.
71
- --no-downgrade disallow the channel to send downgrade version to devices.
72
- --upgrade allow the channel to send upgrade (major) version to devices.
73
- --no-upgrade disallow the channel to send upgrade (major) version to devices.
74
- --ios allow the channel to send version to iOS devices.
75
- --no-ios disallow the channel to send version to iOS devices.
76
- --android allow the channel to send version to android devices.
77
- --no-android disallow the channel to send version to android devices.
78
- --self-assign allow devices to self assign to this channel.
79
- --no-self-assign disallow devices to self assign to this channel.
161
+ `--key [/path/to/my/private_key]` the path of your private key.
162
+ `--key-data [privateKey]` the private key data, if you want to use inline.
163
+ This command is mainly used for test purpose, it will decrypt the zip and print the base64 decrypted session key in the console.
80
164
 
81
165
  ## Dev contribution
82
166
 
Binary file
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- (()=>{"use strict";var e={577: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 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")}))},978: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880);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)&&i.program.error(`Version ${o}@${s} is used in a channel, unlink it first ${(0,r.formatError)(p)}`)}))},113:(e,o,n)=>{Object.defineProperty(o,"__esModule",{value:!0}),o.createRSA=o.encryptSource=o.decryptSource=void 0;const t=n(663),i="aes-128-cbc",r="sha256",a="base64",s=t.constants.RSA_PKCS1_OAEP_PADDING;o.decryptSource=(e,o,n)=>{const[p,d]=o.split(":"),c=(0,t.privateDecrypt)({key:n,padding:s,oaepHash:r},Buffer.from(d,a)),l=Buffer.from(p,a),u=c.toString(a);console.log("\nsessionB64",u);const y=(0,t.createDecipheriv)(i,c,l);return y.setAutoPadding(!0),Buffer.concat([y.update(e),y.final()])},o.encryptSource=(e,o)=>{const n=(0,t.randomBytes)(16),p=(0,t.randomBytes)(16),d=(0,t.createCipheriv)(i,p,n);d.setAutoPadding(!0);const c=`${n.toString(a)}:${(0,t.publicEncrypt)({key:o,padding:s,oaepHash:r},p).toString(a)}`;return{encryptedData:Buffer.concat([d.update(e),d.final()]),ivSessionKey:c}},o.createRSA=()=>{const{publicKey:e,privateKey:o}=(0,t.generateKeyPairSync)("rsa",{modulusLength:2048});return{publicKey:e.export({type:"pkcs1",format:"pem"}),privateKey:o.export({type:"pkcs1",format:"pem"})}}},386: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880);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)}`)}))},191: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880);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&&i.program.error(`Something went wrong when trying to delete ${n} @${s} ${(0,r.formatError)(t)} `)}))},340: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880),a=n(978),s=n(386),p=n(191);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&&i.program.error(`App ${o}@${a} not found in database '${(0,r.formatError)(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,p.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:a}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("deleted",!1).order("id");return a&&i.program.error(`App ${o} not found in database ${(0,r.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||i.program.error(`Version ${o}@${a} doesn't exist ${(0,r.formatError)(s)}`),t}))},870: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(663),a=n(147),s=n(470),p=n(11),d=n(880),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 y=o.apikey||(0,d.findSavedKey)(),v=yield(0,d.getConfig)(),g=(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",y||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&l||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 f=(0,d.createSupabaseClient)(y),m=yield(0,d.verifyUser)(f,y,["write","all"]);let h,b;yield(0,d.checkPlanValid)(f,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:k}=yield f.rpc("exist_app",{appid:e,apikey:y});(_||k)&&i.program.error(`App already exists ${(0,d.formatError)(k)}`);const w=`icon_${(0,r.randomUUID)()}`;let $="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(h&&b){const{error:o}=yield f.storage.from(`images/${m}/${e}`).upload(w,h,{contentType:b});o&&i.program.error(`Could not add app ${(0,d.formatError)(o)}`);const{data:n}=yield f.storage.from(`images/${m}/${e}`).getPublicUrl(w);$=(null==n?void 0:n.publicURL)||$}const{error:x}=yield f.from("apps").insert({icon_url:$,user_id:m,name:l,app_id:e},{returning:"minimal"});x&&i.program.error(`Could not add app ${(0,d.formatError)(x)}`);const{error:S}=yield f.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"});S&&i.program.error(`Could not add app ${(0,d.formatError)(S)}`),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")}))},600: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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())}))},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)),p=n(880),d=n(340),c=n(577),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:i,keep:s=4}=o,u=o.force||!1,y=yield(0,p.getConfig)();e=e||(null===(n=null==y?void 0:y.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 v=`${a.default.inc(i,"major")}`;console.log(`Querying available versions in Capgo between ${i} and ${v}`);const g=(0,p.createSupabaseClient)(t),f=yield(0,p.verifyUser)(g,t);yield(0,c.checkAppExistsAndHasPermission)(g,e,t);const m=yield(0,d.getActiveAppVersions)(g,e,f);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,v).reverse();console.log(`Active versions in Capgo between ${i} 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)}))})(_,g,e,f)}else console.log("Nothing to be removed, aborting removal...")}))},692: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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.decryptZip=void 0;const i=n(304),r=n(147),a=n(113),s=n(880);o.decryptZip=(e,o,n)=>t(void 0,void 0,void 0,(function*(){var t,p,d;(0,r.existsSync)(e)||i.program.error(`Zip not found at the path ${e}`);const c=yield(0,s.getConfig)(),{extConfig:l}=c.app;n.key||(0,r.existsSync)(s.baseKey)||(null===(p=null===(t=l.plugins)||void 0===t?void 0:t.CapacitorUpdater)||void 0===p?void 0:p.privateKey)||i.program.error(`Private Key not found at the path ${s.baseKey} or in ${c.app.extConfigFilePath}`);const u="string"==typeof n.key?n.key:s.baseKey;let{privateKey:y}=(null===(d=null==l?void 0:l.plugins)||void 0===d?void 0:d.CapacitorUpdater)||"";(0,r.existsSync)(u)||y?(0,r.existsSync)(u)&&(y=(0,r.readFileSync)(u).toString()):i.program.error(`Cannot find public key ${u}`);const v=(0,r.readFileSync)(e),g=(0,a.decryptSource)(v,o,y);(0,r.writeFileSync)(`${e}_decrypted.zip`,g)}))},0: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880),a=n(340);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const{bundle:t}=o,s=o.apikey||(0,r.findSavedKey)(),p=yield(0,r.getConfig)(),d=(0,r.useLogSnag)();e=e||(null===(n=null==p?void 0:p.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 c=(0,r.createSupabaseClient)(s),l=yield(0,r.verifyUser)(c,s),{data:u,error:y}=yield c.rpc("exist_app",{appid:e,apikey:s});if(u&&!y||i.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:g}=yield c.from("app_versions").select().eq("app_id",e).eq("user_id",l);if(g&&i.program.error(`App ${e} not found in database ${(0,r.formatError)(g)} `),v&&v.length){const o=v.map((o=>`${l}/${e}/versions/${o.bucket_id} `)),{error:n}=yield c.storage.from("apps").remove(o);n&&i.program.error(`Cannot delete stored version for app ${e} from storage ${(0,r.formatError)(n)} `)}const{error:f}=yield c.from("app_versions").delete().eq("app_id",e).eq("user_id",l);f&&i.program.error(`Cannot delete version for app ${e} from database ${(0,r.formatError)(f)} `);const{error:m}=yield c.from("apps").delete().eq("app_id",e).eq("user_id",l);m&&i.program.error(`Cannot delete from database ${(0,r.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`)}))},128: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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.encryptZip=void 0;const i=n(304),r=n(147),a=n(113),s=n(880);o.encryptZip=e=>t(void 0,void 0,void 0,(function*(){(0,r.existsSync)(e)||i.program.error(`Zip not found at the path ${e}`),(0,r.existsSync)(s.baseKeyPub)||i.program.error(`Public Key not found at the path ${s.baseKeyPub}`);const o=(0,r.readFileSync)(s.baseKeyPub).toString(),n=(0,r.readFileSync)(e),t=(0,a.encryptSource)(n,o);console.log("ivSessionKey",t.ivSessionKey),(0,r.writeFileSync)(`${e}_encrypted.zip`,t.encryptedData)}))},731: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(692),a=n(128),s=n(870),p=n(218),d=n(0),c=n(331),l=n(510),u=t(n(598)),y=n(621),v=n(272),g=n(600);i.program.description("Manage packages and bundle versions in capgo Cloud").version(u.default.version),i.program.command("add [appid]").alias("a").description("Add a new app to capgo Cloud").action(s.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(y.login).option("--local","Only save in local folder"),i.program.command("upload [appid]").alias("u").description("Upload a new bundle to capgo Cloud").action(l.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 public signing key").option("--keyData <keyData>","base64 public signing key").option("--no-key","ignore signing key and send clear update").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(c.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(d.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(v.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(g.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.command("key [option]").description("Save base64 signing key in capacitor config, usefull for CI").action(p.manageKey).option("-f, --force","force generate a new one"),i.program.command("decrypt [zipPath] [sessionKey]").description("Decrypt a signed zip update").action(r.decryptZip).option("--key <key>","custom path for private signing key").option("--keyData <keyData>","base64 private signing key"),i.program.command("encrypt [zipPath]").description("Encrypt a zip update").action(a.encryptZip).option("--key <key>","custom path for private signing key").option("--keyData <keyData>","base64 private signing key"),i.program.parse(process.argv)},218: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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.manageKey=void 0;const i=n(304),r=n(147),a=n(778),s=n(113),p=n(880);o.manageKey=(e,o)=>t(void 0,void 0,void 0,(function*(){"create"===e?(e=>{t(void 0,void 0,void 0,(function*(){(0,r.existsSync)(".git")||i.program.error("To use local you should be in a git repository");const{publicKey:o,privateKey:n}=(0,s.createRSA)();(0,r.existsSync)(p.baseKeyPub)&&!e.force&&i.program.error("Public Key already exists, use --force to overwrite"),(0,r.writeFileSync)(p.baseKeyPub,o),(0,r.existsSync)(p.baseKey)&&!e.force&&i.program.error("Private Key already exists, use --force to overwrite"),(0,r.writeFileSync)(p.baseKey,n);const t=yield(0,p.getConfig)(),{extConfig:d}=t.app;d&&(d.plugins||(d.plugins={}),d.plugins.CapacitorUpdater||(d.plugins.CapacitorUpdater={}),d.plugins.CapacitorUpdater.privateKey=n,(0,a.writeConfig)(d,t.app.extConfigFilePath)),console.log("Your RSA key has been generated using node-rsa with this settings:\n\n- encryptionScheme — 'pkcs1_oaep'.\n- signingScheme — 'pkcs8-sha256'.\n- bits — 2048.\n- exp — 65537.\n"),console.log(`public key saved into ${p.baseKeyPub} file in local directory\n`),console.log("This key will be use to encode your zipped bundle before sending it to Capgo,\nthan make them unreadable by Capgo and unmodifiable by anyone\n"),console.log(`Private key saved into ${t.app.extConfigFilePath} file in local directory`),console.log("Your app will decode with this key the zipped bundle\n")}))})(o):i.program.error("You should provide a valid option (create or save)")}))},272: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880),a=n(577),s=n(340);o.listApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,r.findSavedKey)(),p=yield(0,r.getConfig)();e=e||(null===(n=null==p?void 0:p.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 d=(0,r.createSupabaseClient)(t),c=yield(0,r.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,r.getHumanDate)(e)}`)}))}))},621: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(147),a=n(37),s=n(880);o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:n}=o,t=(0,s.useLogSnag)();if(n)(0,r.existsSync)(".git")||i.program.error("To use local you should be in a git repository"),(0,r.writeFileSync)(".capgo",`${e}\n`),(0,r.appendFileSync)(".gitignore",".capgo\n");else{const o=(0,a.homedir)();(0,r.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`)}))},331: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880);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:y,channel:v,state:g}=o,f=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),f||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"),p&&s&&i.program.error("Cannot set latest and bundle at the same time"),void 0===s&&void 0===g&&void 0===p&&void 0===d&&void 0===c&&void 0===l&&void 0===u&&void 0===y&&i.program.error("Missing argument, you need to provide a option to set");try{const o=(0,r.createSupabaseClient)(f),n=yield(0,r.verifyUser)(o,f,["write","all"]);yield(0,r.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:r}=yield o.from("app_versions").select().eq("app_id",e).eq("name",_).eq("user_id",n).eq("deleted",!1);!r&&t&&t.length||i.program.error(`Cannot find version ${_}`),console.log(`Set ${e} channel: ${v} to @${s}`),b.version=t[0].id}void 0!==g&&("public"!==g&&"private"!==g||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"===g||"default"===g?"default":"normal"}`),b.public="public"===g||"default"===g),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!==y&&(console.log(`Set ${e} channel: ${v} to ${y?"allow":"disallow"} self assign to this channel`),b.allow_device_self_set=!!y);try{const{error:e}=yield(0,r.updateOrCreateChannel)(o,b,f);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 ✅")}))},510: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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())}))},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(663),p=i(n(295)),d=n(147),c=n(906),l=n(113),u=n(880);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,i,y;let{bundle:v,path:g,channel:f}=o;const{external:m,key:h=!1}=o,b=o.apikey||(0,u.findSavedKey)(),_=(0,u.useLogSnag)();f=f||"dev";const k=yield(0,u.getConfig)();e=e||(null===(n=null==k?void 0:k.app)||void 0===n?void 0:n.appId),v=v||(null===(i=null===(t=null==k?void 0:k.app)||void 0===t?void 0:t.package)||void 0===i?void 0:i.version),u.regexSemver.test(v)||a.program.error(`Your bundle name ${v}, is not valid it should follow semver convention : https://semver.org/`),g=g||(null===(y=null==k?void 0:k.app)||void 0===y?void 0:y.webDir),b||a.program.error("Missing API key, you need to provide a API key to add your app"),e&&v&&g||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 "${g}" to Capgo cloud`);const w=(0,u.createSupabaseClient)(b),$=yield(0,u.verifyUser)(w,b,["write","all","upload"]);yield(0,u.checkPlanValid)(w,$,!1);const x=new p.default.MultiBar({clearOnComplete:!1,hideCursor:!0},p.default.Presets.shades_grey),S=x.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},p.default.Presets.shades_grey);S.start(7,0,{speed:"N/A"});const{data:C,error:A}=yield w.rpc("exist_app_versions",{apikey:b,name_version:v,appid:e});(C||A)&&(x.stop(),a.program.error(`This app bundle already exist or was deleted, you cannot re-upload it ${(0,u.formatError)(A)}`)),S.increment();const{data:P,error:K}=yield w.rpc("is_trial",{userid:$}).single();(P&&P>0||K)&&x.log(`WARNING !!\nTrial expires in ${P} days, upgrade here: ${u.hostWeb}/dashboard/settings/plans\n`),S.increment();const{data:q,error:D}=yield w.rpc("exist_app",{appid:e,apikey:b});q&&!D||(x.stop(),a.program.error(`Cannot find app ${e} in your account \n${(0,u.formatError)(D)}`)),S.increment();const{data:I,error:j}=yield w.rpc("exist_app_versions",{appid:e,apikey:b,name_version:v});(I||j)&&a.program.error(`Version already exists ${(0,u.formatError)(j)}`),S.increment();const M=(0,s.randomUUID)();let E,U="";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 r.default;o.addLocalFolder(g);let n=o.toBuffer();if(U=yield(0,c.checksum)(n,"crc32"),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),t=(0,l.encryptSource)(n,o.toString());E=t.ivSessionKey,n=t.encryptedData}const t=Math.floor(n.byteLength/1024/1024),i=`apps/${$}/${e}/versions`;S.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 w.storage.from(i).upload(M,n,{contentType:"application/zip"});s&&(x.stop(),a.program.error(`Cannot upload ${(0,u.formatError)(s)}`))}S.increment();const{data:O,error:V}=yield(0,u.updateOrCreateVersion)(w,{bucket_id:m?void 0:M,user_id:$,name:v,app_id:e,session_key:E,external_url:m,checksum:U},b);if(V&&(x.stop(),a.program.error(`Cannot add bundle ${(0,u.formatError)(V)}`)),S.increment(),O&&O.length){const{error:o}=yield(0,u.updateOrCreateChannel)(w,{name:f,app_id:e,created_by:$,version:O[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 z=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 ${f} as public here: ${u.hostWeb}/app/package/${z}`),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/${z}/devices`),_.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":$,"app-id":e},notify:!1}).catch()}))},880: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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())}))},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=o.baseKeyPub=o.baseKey=void 0;const r=n(778),a=n(304),s=n(885),p=i(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,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=`${(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,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 l.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")},663: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":"2.1.12","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","test":"npx ts-node -T src/bin/index.ts","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.5.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":"11.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.45.0","@typescript-eslint/parser":"5.45.0","eslint":"8.28.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.8.0","ts-loader":"^9.4.1","ts-node":"^10.9.1","tsconfig-paths":"4.1.1","typescript":"4.9.3","webpack":"5.75.0","webpack-cli":"^5.0.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}(731)})();
2
+ (()=>{"use strict";var e={577: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 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")}))},978: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880);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)&&i.program.error(`Version ${o}@${s} is used in a channel, unlink it first ${(0,r.formatError)(p)}`)}))},113:(e,o,n)=>{Object.defineProperty(o,"__esModule",{value:!0}),o.createRSA=o.encryptSource=o.decryptSource=void 0;const t=n(663),i="aes-128-cbc",r="sha256",a="base64",s=t.constants.RSA_PKCS1_OAEP_PADDING;o.decryptSource=(e,o,n)=>{const[p,d]=o.split(":"),c=(0,t.privateDecrypt)({key:n,padding:s,oaepHash:r},Buffer.from(d,a)),l=Buffer.from(p,a),u=c.toString(a);console.log("\nsessionB64",u);const y=(0,t.createDecipheriv)(i,c,l);return y.setAutoPadding(!0),Buffer.concat([y.update(e),y.final()])},o.encryptSource=(e,o)=>{const n=(0,t.randomBytes)(16),p=(0,t.randomBytes)(16),d=(0,t.createCipheriv)(i,p,n);d.setAutoPadding(!0);const c=`${n.toString(a)}:${(0,t.publicEncrypt)({key:o,padding:s,oaepHash:r},p).toString(a)}`;return{encryptedData:Buffer.concat([d.update(e),d.final()]),ivSessionKey:c}},o.createRSA=()=>{const{publicKey:e,privateKey:o}=(0,t.generateKeyPairSync)("rsa",{modulusLength:2048});return{publicKey:e.export({type:"pkcs1",format:"pem"}),privateKey:o.export({type:"pkcs1",format:"pem"})}}},386: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880);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)}`)}))},191: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880);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&&i.program.error(`Something went wrong when trying to delete ${n} @${s} ${(0,r.formatError)(t)} `)}))},340: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880),a=n(978),s=n(386),p=n(191);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&&i.program.error(`App ${o}@${a} not found in database '${(0,r.formatError)(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,p.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:a}=yield e.from("app_versions").select().eq("app_id",o).eq("user_id",n).eq("deleted",!1).order("id");return a&&i.program.error(`App ${o} not found in database ${(0,r.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||i.program.error(`Version ${o}@${a} doesn't exist ${(0,r.formatError)(s)}`),t}))},870: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(663),a=n(147),s=n(470),p=n(11),d=n(880),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 y=o.apikey||(0,d.findSavedKey)(),g=yield(0,d.getConfig)(),v=(0,d.useLogSnag)();e=e||(null===(n=null==g?void 0:g.app)||void 0===n?void 0:n.appId),l=l||(null===(t=null==g?void 0:g.app)||void 0===t?void 0:t.appName)||"Unknown",u=u||"resources/icon.png",y||i.program.error("Missing API key, you need to provide a API key to add your app"),e&&l||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 f=(0,d.createSupabaseClient)(y),m=yield(0,d.verifyUser)(f,y,["write","all"]);let h,b;yield(0,d.checkPlanValid)(f,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:k}=yield f.rpc("exist_app",{appid:e,apikey:y});(_||k)&&i.program.error(`App already exists ${(0,d.formatError)(k)}`);const w=`icon_${(0,r.randomUUID)()}`;let $="https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";if(h&&b){const{error:o}=yield f.storage.from(`images/${m}/${e}`).upload(w,h,{contentType:b});o&&i.program.error(`Could not add app ${(0,d.formatError)(o)}`);const{data:n}=yield f.storage.from(`images/${m}/${e}`).getPublicUrl(w);$=(null==n?void 0:n.publicURL)||$}const{error:x}=yield f.from("apps").insert({icon_url:$,user_id:m,name:l,app_id:e},{returning:"minimal"});x&&i.program.error(`Could not add app ${(0,d.formatError)(x)}`);const{error:S}=yield f.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"});S&&i.program.error(`Could not add app ${(0,d.formatError)(S)}`),v.publish({channel:"app",event:"App Added",icon:"🎉",tags:{"user-id":m,"app-id":e},notify:!1}).catch(),console.log("App added to server, you can upload a bundle now")}))},600: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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())}))},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)),p=n(880),d=n(340),c=n(577),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:i,keep:s=4}=o,u=o.force||!1,y=yield(0,p.getConfig)();e=e||(null===(n=null==y?void 0:y.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 g=`${a.default.inc(i,"major")}`;console.log(`Querying available versions in Capgo between ${i} and ${g}`);const v=(0,p.createSupabaseClient)(t),f=yield(0,p.verifyUser)(v,t);yield(0,c.checkAppExistsAndHasPermission)(v,e,t);const m=yield(0,d.getActiveAppVersions)(v,e,f);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,g).reverse();console.log(`Active versions in Capgo between ${i} and ${g}: ${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)}))})(_,v,e,f)}else console.log("Nothing to be removed, aborting removal...")}))},692: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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.decryptZip=void 0;const i=n(304),r=n(147),a=n(113),s=n(880);o.decryptZip=(e,o,n)=>t(void 0,void 0,void 0,(function*(){var t,p,d;(0,r.existsSync)(e)||i.program.error(`Zip not found at the path ${e}`);const c=yield(0,s.getConfig)(),{extConfig:l}=c.app;n.key||(0,r.existsSync)(s.baseKey)||(null===(p=null===(t=l.plugins)||void 0===t?void 0:t.CapacitorUpdater)||void 0===p?void 0:p.privateKey)||i.program.error(`Private Key not found at the path ${s.baseKey} or in ${c.app.extConfigFilePath}`);const u=n.key||s.baseKey;let{privateKey:y}=n.keyData||(null===(d=null==l?void 0:l.plugins)||void 0===d?void 0:d.CapacitorUpdater)||"";(0,r.existsSync)(u)||y?(0,r.existsSync)(u)&&(y=(0,r.readFileSync)(u).toString()):i.program.error(`Cannot find public key ${u} or as keyData option or in ${c.app.extConfigFilePath}`);const g=(0,r.readFileSync)(e),v=(0,a.decryptSource)(g,o,y);(0,r.writeFileSync)(`${e}_decrypted.zip`,v)}))},0: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880),a=n(340);o.deleteApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const{bundle:t}=o,s=o.apikey||(0,r.findSavedKey)(),p=yield(0,r.getConfig)(),d=(0,r.useLogSnag)();e=e||(null===(n=null==p?void 0:p.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 c=(0,r.createSupabaseClient)(s),l=yield(0,r.verifyUser)(c,s),{data:u,error:y}=yield c.rpc("exist_app",{appid:e,apikey:s});if(u&&!y||i.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:g,error:v}=yield c.from("app_versions").select().eq("app_id",e).eq("user_id",l);if(v&&i.program.error(`App ${e} not found in database ${(0,r.formatError)(v)} `),g&&g.length){const o=g.map((o=>`${l}/${e}/versions/${o.bucket_id} `)),{error:n}=yield c.storage.from("apps").remove(o);n&&i.program.error(`Cannot delete stored version for app ${e} from storage ${(0,r.formatError)(n)} `)}const{error:f}=yield c.from("app_versions").delete().eq("app_id",e).eq("user_id",l);f&&i.program.error(`Cannot delete version for app ${e} from database ${(0,r.formatError)(f)} `);const{error:m}=yield c.from("apps").delete().eq("app_id",e).eq("user_id",l);m&&i.program.error(`Cannot delete from database ${(0,r.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`)}))},128: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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.encryptZip=void 0;const i=n(304),r=n(147),a=n(113),s=n(880);o.encryptZip=(e,o)=>t(void 0,void 0,void 0,(function*(){(0,r.existsSync)(e)||i.program.error(`Zip not found at the path ${e}`);const n=o.key||s.baseKeyPub;let t=o.keyData||"";(0,r.existsSync)(n)||t?(0,r.existsSync)(n)&&(t=(0,r.readFileSync)(n).toString()):i.program.error(`Cannot find public key ${n} or as keyData option`);const p=(0,r.readFileSync)(e),d=(0,a.encryptSource)(p,t);console.log("ivSessionKey",d.ivSessionKey),(0,r.writeFileSync)(`${e}_encrypted.zip`,d.encryptedData)}))},731: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(692),a=n(128),s=n(870),p=n(218),d=n(0),c=n(331),l=n(510),u=t(n(598)),y=n(621),g=n(272),v=n(600);i.program.description("Manage packages and bundle versions in capgo Cloud").version(u.default.version),i.program.command("add [appid]").alias("a").description("Add a new app to capgo Cloud").action(s.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(y.login).option("--local","Only save in local folder"),i.program.command("upload [appid]").alias("u").description("Upload a new bundle to capgo Cloud").action(l.uploadVersion).option("-a, --apikey <apikey>","apikey to link to your account").option("-p, --path <path>","path of the folder 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("--key <key>","custom path for public signing key").option("--keyData <keyData>","base64 public signing key").option("--no-key","ignore signing key and send clear update").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(c.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(d.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(g.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(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"),i.program.command("key [option]").description("Save base64 signing key in capacitor config, usefull for CI").action(p.manageKey).option("-f, --force","force generate a new one"),i.program.command("decrypt [zipPath] [sessionKey]").description("Decrypt a signed zip update").action(r.decryptZip).option("--key <key>","custom path for private signing key").option("--keyData <keyData>","base64 private signing key"),i.program.command("encrypt [zipPath]").description("Encrypt a zip update").action(a.encryptZip).option("--key <key>","custom path for private signing key").option("--keyData <keyData>","base64 private signing key"),i.program.parse(process.argv)},218: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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.manageKey=void 0;const i=n(304),r=n(147),a=n(778),s=n(113),p=n(880);o.manageKey=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,d;"save"===e?(n=o.key,d=o.keyData,t(void 0,void 0,void 0,(function*(){var e;(0,r.existsSync)(".git")||i.program.error("To use local you should be in a git repository");const o=yield(0,p.getConfig)(),{extConfig:t}=o.app,s=n||p.baseKey;let{privateKey:c}=d||(null===(e=null==t?void 0:t.plugins)||void 0===e?void 0:e.CapacitorUpdater)||"";(0,r.existsSync)(s)||c?(0,r.existsSync)(s)&&(c=(0,r.readFileSync)(s).toString()):i.program.error(`Cannot find public key ${s} or as keyData option or in ${o.app.extConfigFilePath}`),t&&(t.plugins||(t.plugins={}),t.plugins.CapacitorUpdater||(t.plugins.CapacitorUpdater={}),t.plugins.CapacitorUpdater.privateKey=d,(0,a.writeConfig)(t,o.app.extConfigFilePath)),console.log(`private key saved into ${o.app.extConfigFilePath} file in local directory`),console.log("your app will decode the zip archive with this key\n")}))):"create"===e?(e=>{t(void 0,void 0,void 0,(function*(){(0,r.existsSync)(".git")||i.program.error("To use local you should be in a git repository");const{publicKey:o,privateKey:n}=(0,s.createRSA)();(0,r.existsSync)(p.baseKeyPub)&&!e.force&&i.program.error("Public Key already exists, use --force to overwrite"),(0,r.writeFileSync)(p.baseKeyPub,o),(0,r.existsSync)(p.baseKey)&&!e.force&&i.program.error("Private Key already exists, use --force to overwrite"),(0,r.writeFileSync)(p.baseKey,n);const t=yield(0,p.getConfig)(),{extConfig:d}=t.app;d&&(d.plugins||(d.plugins={}),d.plugins.CapacitorUpdater||(d.plugins.CapacitorUpdater={}),d.plugins.CapacitorUpdater.privateKey=n,(0,a.writeConfig)(d,t.app.extConfigFilePath)),console.log("Your RSA key has been generated using node-rsa with this settings:\n\n- encryptionScheme — 'pkcs1_oaep'.\n- signingScheme — 'pkcs8-sha256'.\n- bits — 2048.\n- exp — 65537.\n"),console.log(`public key saved into ${p.baseKeyPub} file in local directory\n`),console.log("This key will be use to encode your zipped bundle before sending it to Capgo,\nthan make them unreadable by Capgo and unmodifiable by anyone\n"),console.log(`Private key saved into ${t.app.extConfigFilePath} file in local directory`),console.log("Your app will decode with this key the zipped bundle\n")}))})(o):i.program.error("You should provide a valid option (create or save)")}))},272: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880),a=n(577),s=n(340);o.listApp=(e,o)=>t(void 0,void 0,void 0,(function*(){var n;const t=o.apikey||(0,r.findSavedKey)(),p=yield(0,r.getConfig)();e=e||(null===(n=null==p?void 0:p.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 d=(0,r.createSupabaseClient)(t),c=yield(0,r.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,r.getHumanDate)(e)}`)}))}))},621: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(147),a=n(37),s=n(880);o.login=(e,o)=>t(void 0,void 0,void 0,(function*(){const{local:n}=o,t=(0,s.useLogSnag)();if(n)(0,r.existsSync)(".git")||i.program.error("To use local you should be in a git repository"),(0,r.writeFileSync)(".capgo",`${e}\n`),(0,r.appendFileSync)(".gitignore",".capgo\n");else{const o=(0,a.homedir)();(0,r.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`)}))},331: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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 i=n(304),r=n(880);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:y,channel:g,state:v}=o,f=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),f||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"),p&&s&&i.program.error("Cannot set latest and bundle at the same time"),void 0===s&&void 0===v&&void 0===p&&void 0===d&&void 0===c&&void 0===l&&void 0===u&&void 0===y&&i.program.error("Missing argument, you need to provide a option to set");try{const o=(0,r.createSupabaseClient)(f),n=yield(0,r.verifyUser)(o,f,["write","all"]);yield(0,r.checkPlanValid)(o,n);const b={created_by:n,app_id:e,name:g},_=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:r}=yield o.from("app_versions").select().eq("app_id",e).eq("name",_).eq("user_id",n).eq("deleted",!1);!r&&t&&t.length||i.program.error(`Cannot find version ${_}`),console.log(`Set ${e} channel: ${g} to @${s}`),b.version=t[0].id}void 0!==v&&("public"!==v&&"private"!==v||console.log(`Set ${e} channel: ${g} to public or private is deprecated, use default or normal instead`),console.log(`Set ${e} channel: ${g} to ${"public"===v||"default"===v?"default":"normal"}`),b.public="public"===v||"default"===v),void 0!==d&&(console.log(`Set ${e} channel: ${g} to ${d?"allow":"disallow"} downgrade`),b.disableAutoUpdateUnderNative=!d),void 0!==c&&(console.log(`Set ${e} channel: ${g} to ${c?"allow":"disallow"} upgrade`),b.disableAutoUpdateToMajor=!c),void 0!==l&&(console.log(`Set ${e} channel: ${g} to ${l?"allow":"disallow"} ios update`),b.ios=!!l),void 0!==u&&(console.log(`Set ${e} channel: ${g} to ${u?"allow":"disallow"} android update`),b.android=!!u),void 0!==y&&(console.log(`Set ${e} channel: ${g} to ${y?"allow":"disallow"} self assign to this channel`),b.allow_device_self_set=!!y);try{const{error:e}=yield(0,r.updateOrCreateChannel)(o,b,f);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 ✅")}))},510: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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())}))},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(663),p=i(n(295)),d=n(147),c=n(906),l=n(113),u=n(880);o.uploadVersion=(e,o)=>t(void 0,void 0,void 0,(function*(){var n,t,i,y;let{bundle:g,path:v,channel:f}=o;const{external:m,key:h=!1}=o,b=o.apikey||(0,u.findSavedKey)(),_=(0,u.useLogSnag)();f=f||"dev";const k=yield(0,u.getConfig)();e=e||(null===(n=null==k?void 0:k.app)||void 0===n?void 0:n.appId),g=g||(null===(i=null===(t=null==k?void 0:k.app)||void 0===t?void 0:t.package)||void 0===i?void 0:i.version),u.regexSemver.test(g)||a.program.error(`Your bundle name ${g}, is not valid it should follow semver convention : https://semver.org/`),v=v||(null===(y=null==k?void 0:k.app)||void 0===y?void 0:y.webDir),b||a.program.error("Missing API key, you need to provide a API key to add your app"),e&&g&&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}@${g} started from path "${v}" to Capgo cloud`);const w=(0,u.createSupabaseClient)(b),$=yield(0,u.verifyUser)(w,b,["write","all","upload"]);yield(0,u.checkPlanValid)(w,$,!1);const x=new p.default.MultiBar({clearOnComplete:!1,hideCursor:!0},p.default.Presets.shades_grey),S=x.create(7,0,{format:"Uploading: [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} Part"},p.default.Presets.shades_grey);S.start(7,0,{speed:"N/A"});const{data:C,error:A}=yield w.rpc("exist_app_versions",{apikey:b,name_version:g,appid:e});(C||A)&&(x.stop(),a.program.error(`This app bundle already exist or was deleted, you cannot re-upload it ${(0,u.formatError)(A)}`)),S.increment();const{data:P,error:D}=yield w.rpc("is_trial",{userid:$}).single();(P&&P>0||D)&&x.log(`WARNING !!\nTrial expires in ${P} days, upgrade here: ${u.hostWeb}/dashboard/settings/plans\n`),S.increment();const{data:K,error:q}=yield w.rpc("exist_app",{appid:e,apikey:b});K&&!q||(x.stop(),a.program.error(`Cannot find app ${e} in your account \n${(0,u.formatError)(q)}`)),S.increment();const{data:I,error:j}=yield w.rpc("exist_app_versions",{appid:e,apikey:b,name_version:g});(I||j)&&a.program.error(`Version already exists ${(0,u.formatError)(j)}`),S.increment();const M=(0,s.randomUUID)();let U,E="";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 r.default;o.addLocalFolder(v);let n=o.toBuffer();if(E=yield(0,c.checksum)(n,"crc32"),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),t=(0,l.encryptSource)(n,o.toString());U=t.ivSessionKey,n=t.encryptedData}const t=Math.floor(n.byteLength/1024/1024),i=`apps/${$}/${e}/versions`;S.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 w.storage.from(i).upload(M,n,{contentType:"application/zip"});s&&(x.stop(),a.program.error(`Cannot upload ${(0,u.formatError)(s)}`))}S.increment();const{data:O,error:V}=yield(0,u.updateOrCreateVersion)(w,{bucket_id:m?void 0:M,user_id:$,name:g,app_id:e,session_key:U,external_url:m,checksum:E},b);if(V&&(x.stop(),a.program.error(`Cannot add bundle ${(0,u.formatError)(V)}`)),S.increment(),O&&O.length){const{error:o}=yield(0,u.updateOrCreateChannel)(w,{name:f,app_id:e,created_by:$,version:O[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 z=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 ${f} as public here: ${u.hostWeb}/app/package/${z}`),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/${z}/devices`),_.publish({channel:"app",event:"App Uploaded",icon:"⏫",tags:{"user-id":$,"app-id":e},notify:!1}).catch()}))},880: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{p(t.next(e))}catch(e){r(e)}}function s(e){try{p(t.throw(e))}catch(e){r(e)}}function p(e){var o;e.done?i(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())}))},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=o.baseKeyPub=o.baseKey=void 0;const r=n(778),a=n(304),s=n(885),p=i(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,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=`${(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,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 l.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")},663: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":"2.2.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","test":"npx ts-node -T src/bin/index.ts","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.5.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":"11.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.45.0","@typescript-eslint/parser":"5.45.0","eslint":"8.28.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.8.0","ts-loader":"^9.4.1","ts-node":"^10.9.1","tsconfig-paths":"4.1.1","typescript":"4.9.3","webpack":"5.75.0","webpack-cli":"^5.0.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}(731)})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/cli",
3
- "version": "2.1.12",
3
+ "version": "2.2.1",
4
4
  "description": "A CLI to upload to capgo servers",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -4,7 +4,8 @@ import { decryptSource } from '../api/crypto';
4
4
  import { baseKey, getConfig } from './utils';
5
5
 
6
6
  interface Options {
7
- key?: boolean | string
7
+ key?: string
8
+ keyData?: string
8
9
  }
9
10
 
10
11
  export const decryptZip = async (zipPath: string, ivsessionKey: string, options: Options) => {
@@ -20,16 +21,16 @@ export const decryptZip = async (zipPath: string, ivsessionKey: string, options:
20
21
  if (!options.key && !existsSync(baseKey) && !extConfig.plugins?.CapacitorUpdater?.privateKey) {
21
22
  program.error(`Private Key not found at the path ${baseKey} or in ${config.app.extConfigFilePath}`);
22
23
  }
23
- const keyString = typeof options.key === 'string' ? options.key : baseKey
24
+ const keyPath = options.key || baseKey
24
25
  // check if publicKey exist
25
26
 
26
- let { privateKey } = extConfig?.plugins?.CapacitorUpdater || "";
27
+ let { privateKey } = options.keyData || extConfig?.plugins?.CapacitorUpdater || "";
27
28
 
28
- if (!existsSync(keyString) && !privateKey) {
29
- program.error(`Cannot find public key ${keyString}`)
30
- } else if (existsSync(keyString)) {
29
+ if (!existsSync(keyPath) && !privateKey) {
30
+ program.error(`Cannot find public key ${keyPath} or as keyData option or in ${config.app.extConfigFilePath}`)
31
+ } else if (existsSync(keyPath)) {
31
32
  // open with fs publicKey path
32
- const keyFile = readFileSync(keyString)
33
+ const keyFile = readFileSync(keyPath)
33
34
  privateKey = keyFile.toString()
34
35
  }
35
36
  // console.log('privateKey', privateKey)
@@ -3,22 +3,33 @@ import { existsSync, readFileSync, writeFileSync } from 'fs'
3
3
  import { encryptSource } from '../api/crypto';
4
4
  import { baseKeyPub } from './utils';
5
5
 
6
- export const encryptZip = async (zipPath: string) => {
6
+ interface Options {
7
+ key?: string
8
+ keyData?: string
9
+ }
10
+
11
+ export const encryptZip = async (zipPath: string, options: Options) => {
7
12
  // write in file .capgo the apikey in home directory
8
13
 
9
14
  if (!existsSync(zipPath)) {
10
15
  program.error(`Zip not found at the path ${zipPath}`);
11
16
  }
12
17
 
13
- if (!existsSync(baseKeyPub)) {
14
- program.error(`Public Key not found at the path ${baseKeyPub}`);
18
+ const keyPath = options.key || baseKeyPub
19
+ // check if publicKey exist
20
+
21
+ let publicKey = options.keyData || "";
22
+
23
+ if (!existsSync(keyPath) && !publicKey) {
24
+ program.error(`Cannot find public key ${keyPath} or as keyData option`)
25
+ } else if (existsSync(keyPath)) {
26
+ // open with fs publicKey path
27
+ const keyFile = readFileSync(keyPath)
28
+ publicKey = keyFile.toString()
15
29
  }
16
- // open with fs publicKey path
17
- const keyFile = readFileSync(baseKeyPub)
18
- const keyString = keyFile.toString()
19
30
 
20
31
  const zipFile = readFileSync(zipPath)
21
- const encodedZip = encryptSource(zipFile, keyString)
32
+ const encodedZip = encryptSource(zipFile, publicKey)
22
33
  console.log('ivSessionKey', encodedZip.ivSessionKey)
23
34
  // write decodedZip in a file
24
35
  writeFileSync(`${zipPath}_encrypted.zip`, encodedZip.encryptedData)
package/src/bin/index.ts CHANGED
@@ -37,10 +37,9 @@ program
37
37
  .description('Upload a new bundle to capgo Cloud')
38
38
  .action(uploadVersion)
39
39
  .option('-a, --apikey <apikey>', 'apikey to link to your account')
40
- .option('-p, --path <path>', 'path of the file to upload')
40
+ .option('-p, --path <path>', 'path of the folder to upload')
41
41
  .option('-c, --channel <channel>', 'channel to link to')
42
42
  .option('-e, --external <url>', 'link to external url intead of upload to capgo cloud')
43
- .option('-f, --format <base64|hex|binary|utf8>', 'choose the upload format default base64')
44
43
  .option('--key <key>', 'custom path for public signing key')
45
44
  .option('--keyData <keyData>', 'base64 public signing key')
46
45
  .option('--no-key', 'ignore signing key and send clear update')
package/src/bin/key.ts CHANGED
@@ -1,38 +1,52 @@
1
1
  import { program } from 'commander'
2
- import { existsSync, writeFileSync } from 'fs'
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs'
3
3
  import { writeConfig } from '@capacitor/cli/dist/config';
4
4
  import { createRSA } from '../api/crypto';
5
5
  import { baseKey, baseKeyPub, getConfig } from './utils';
6
6
 
7
7
  interface Options {
8
8
  force?: boolean;
9
- private?: string;
10
- public?: string;
9
+ key?: string
10
+ keyData?: string
11
11
  }
12
12
 
13
- // const saveKey = async (privateKeyBase64: string) => {
14
- // if (!existsSync('.git')) {
15
- // program.error('To use local you should be in a git repository');
16
- // }
17
-
18
- // const config = await getConfig();
19
- // const { extConfig } = config.app;
20
- // if (extConfig) {
21
- // if (!extConfig.plugins) {
22
- // extConfig.plugins = {};
23
- // }
24
- // if (!extConfig.plugins.CapacitorUpdater) {
25
- // extConfig.plugins.CapacitorUpdater = {};
26
- // }
27
- // extConfig.plugins.CapacitorUpdater.privateKey = privateKeyBase64;
28
- // // console.log('extConfig', extConfig)
29
- // writeConfig(extConfig, config.app.extConfigFilePath)
30
- // }
31
-
32
- // console.log(`private key saved into ${config.app.extConfigFilePath} file in local directory`);
33
- // console.log(`your app will decode the zip archive with this key\n`);
34
-
35
- // }
13
+ const saveKey = async (privateKeyPath: string | undefined, privateKeyBase64: string | undefined) => {
14
+ if (!existsSync('.git')) {
15
+ program.error('To use local you should be in a git repository');
16
+ }
17
+
18
+ const config = await getConfig();
19
+ const { extConfig } = config.app;
20
+
21
+ const keyPath = privateKeyPath || baseKey
22
+ // check if publicKey exist
23
+
24
+ let { privateKey } = privateKeyBase64 || extConfig?.plugins?.CapacitorUpdater || "";
25
+
26
+ if (!existsSync(keyPath) && !privateKey) {
27
+ program.error(`Cannot find public key ${keyPath} or as keyData option or in ${config.app.extConfigFilePath}`)
28
+ } else if (existsSync(keyPath)) {
29
+ // open with fs publicKey path
30
+ const keyFile = readFileSync(keyPath)
31
+ privateKey = keyFile.toString()
32
+ }
33
+
34
+ if (extConfig) {
35
+ if (!extConfig.plugins) {
36
+ extConfig.plugins = {};
37
+ }
38
+ if (!extConfig.plugins.CapacitorUpdater) {
39
+ extConfig.plugins.CapacitorUpdater = {};
40
+ }
41
+ extConfig.plugins.CapacitorUpdater.privateKey = privateKeyBase64;
42
+ // console.log('extConfig', extConfig)
43
+ writeConfig(extConfig, config.app.extConfigFilePath)
44
+ }
45
+
46
+ console.log(`private key saved into ${config.app.extConfigFilePath} file in local directory`);
47
+ console.log(`your app will decode the zip archive with this key\n`);
48
+
49
+ }
36
50
 
37
51
  const createKey = async (options: Options) => {
38
52
  // write in file .capgo the apikey in home directory
@@ -80,15 +94,12 @@ than make them unreadable by Capgo and unmodifiable by anyone\n`);
80
94
 
81
95
  export const manageKey = async (option: string, options: Options) => {
82
96
 
83
- // if (option === 'save') {
84
- // if (!options.private) {
85
- // program.error('You should provide a private key to save');
86
- // }
87
- // saveKey(options.private);
88
- // } else
89
- if (option === 'create') {
90
- createKey(options);
91
- } else {
92
- program.error('You should provide a valid option (create or save)');
93
- }
97
+ if (option === 'save') {
98
+ saveKey(options.key, options.keyData);
99
+ } else
100
+ if (option === 'create') {
101
+ createKey(options);
102
+ } else {
103
+ program.error('You should provide a valid option (create or save)');
104
+ }
94
105
  }