@capgo/cli 4.0.12 → 4.0.14
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 +10 -0
- package/bun.lockb +0 -0
- package/capacitor.config.ts +2 -2
- package/dist/index.js +654 -658
- package/eslint.config.js +3 -0
- package/package.json +3 -2
- package/src/api/app.ts +32 -39
- package/src/api/channels.ts +53 -49
- package/src/api/crypto.ts +83 -80
- package/src/api/devices_override.ts +12 -13
- package/src/api/update.ts +10 -10
- package/src/api/versions.ts +43 -42
- package/src/app/add.ts +61 -53
- package/src/app/debug.ts +153 -151
- package/src/app/delete.ts +61 -59
- package/src/app/info.ts +74 -77
- package/src/app/list.ts +33 -31
- package/src/app/set.ts +85 -82
- package/src/bundle/check.ts +30 -32
- package/src/bundle/cleanup.ts +71 -74
- package/src/bundle/compatibility.ts +52 -55
- package/src/bundle/decrypt.ts +21 -19
- package/src/bundle/delete.ts +27 -25
- package/src/bundle/encrypt.ts +23 -21
- package/src/bundle/list.ts +42 -40
- package/src/bundle/unlink.ts +69 -60
- package/src/bundle/upload.ts +170 -149
- package/src/bundle/zip.ts +122 -118
- package/src/channel/add.ts +62 -60
- package/src/channel/currentBundle.ts +56 -56
- package/src/channel/delete.ts +46 -43
- package/src/channel/list.ts +23 -21
- package/src/channel/set.ts +76 -68
- package/src/index.ts +55 -57
- package/src/init.ts +254 -252
- package/src/key.ts +56 -52
- package/src/login.ts +30 -28
- package/src/types/capacitor__cli.d.ts +2 -3
- package/src/types/supabase.types.ts +505 -505
- package/src/utils.ts +560 -571
- package/.eslintrc +0 -71
package/src/bundle/zip.ts
CHANGED
|
@@ -1,133 +1,137 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto'
|
|
2
|
-
import { writeFileSync } from 'node:fs'
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
1
|
+
import { randomUUID } from 'node:crypto'
|
|
2
|
+
import { writeFileSync } from 'node:fs'
|
|
3
|
+
import process from 'node:process'
|
|
4
|
+
import AdmZip from 'adm-zip'
|
|
5
|
+
import { program } from 'commander'
|
|
6
|
+
import * as p from '@clack/prompts'
|
|
7
|
+
import { checksum as getChecksum } from '@tomasklaen/checksum'
|
|
8
|
+
import { checkLatest } from '../api/update'
|
|
9
|
+
import type {
|
|
10
|
+
OptionsBase,
|
|
11
|
+
} from '../utils'
|
|
8
12
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from '../utils'
|
|
14
|
-
import { checkIndexPosition, searchInDirectory } from './check'
|
|
13
|
+
formatError,
|
|
14
|
+
getConfig,
|
|
15
|
+
regexSemver,
|
|
16
|
+
useLogSnag,
|
|
17
|
+
} from '../utils'
|
|
18
|
+
import { checkIndexPosition, searchInDirectory } from './check'
|
|
15
19
|
|
|
16
|
-
const alertMb = 20
|
|
20
|
+
const alertMb = 20
|
|
17
21
|
|
|
18
22
|
interface Options extends OptionsBase {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
bundle?: string
|
|
24
|
+
path?: string
|
|
25
|
+
codeCheck?: boolean
|
|
26
|
+
name?: string
|
|
27
|
+
json?: boolean
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
export async function zipBundle(appId: string, options: Options) {
|
|
31
|
+
let { bundle, path } = options
|
|
32
|
+
const { json } = options
|
|
33
|
+
const snag = useLogSnag()
|
|
34
|
+
if (!json)
|
|
35
|
+
await checkLatest()
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// check if bundle is valid
|
|
41
|
-
|
|
42
|
-
if (!json)
|
|
43
|
-
p.log.error(`Your bundle name ${bundle}, is not valid it should follow semver convention : https://semver.org/`);
|
|
44
|
-
else
|
|
45
|
-
console.error(JSON.stringify({ error: 'invalid_semver' }))
|
|
46
|
-
program.error('');
|
|
47
|
-
}
|
|
48
|
-
path = path || config?.app?.webDir
|
|
49
|
-
if (!appId || !bundle || !path) {
|
|
50
|
-
if (!json)
|
|
51
|
-
p.log.error("Missing argument, you need to provide a appId and a bundle and a path, or be in a capacitor project");
|
|
52
|
-
else
|
|
53
|
-
console.error(JSON.stringify({ error: 'missing_argument' }))
|
|
54
|
-
program.error('');
|
|
55
|
-
}
|
|
56
|
-
if (!json)
|
|
57
|
-
p.log.info(`Started from path "${path}"`);
|
|
58
|
-
const checkNotifyAppReady = options.codeCheck
|
|
59
|
-
if (typeof checkNotifyAppReady === 'undefined' || checkNotifyAppReady) {
|
|
60
|
-
const isPluginConfigured = searchInDirectory(path, 'notifyAppReady')
|
|
61
|
-
if (!isPluginConfigured) {
|
|
62
|
-
if (!json)
|
|
63
|
-
p.log.error(`notifyAppReady() is missing in the source code. see: https://capgo.app/docs/plugin/api/#notifyappready`);
|
|
64
|
-
else
|
|
65
|
-
console.error(JSON.stringify({ error: 'notifyAppReady_not_in_source_code' }))
|
|
66
|
-
program.error('');
|
|
67
|
-
}
|
|
68
|
-
const foundIndex = checkIndexPosition(path);
|
|
69
|
-
if (!foundIndex) {
|
|
70
|
-
if (!json)
|
|
71
|
-
p.log.error(`index.html is missing in the root folder or in the only folder in the root folder`);
|
|
72
|
-
else
|
|
73
|
-
console.error(JSON.stringify({ error: 'index_html_not_found' }))
|
|
74
|
-
program.error('');
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
const zip = new AdmZip();
|
|
78
|
-
zip.addLocalFolder(path);
|
|
79
|
-
const zipped = zip.toBuffer();
|
|
80
|
-
if (!json)
|
|
81
|
-
p.log.info(`Zipped ${zipped.byteLength} bytes`);
|
|
82
|
-
const s = p.spinner()
|
|
37
|
+
const config = await getConfig()
|
|
38
|
+
appId = appId || config?.app?.appId
|
|
39
|
+
// create bundle name format : 1.0.0-beta.x where x is a uuid
|
|
40
|
+
const uuid = randomUUID().split('-')[0]
|
|
41
|
+
bundle = bundle || config?.app?.package?.version || `0.0.1-beta.${uuid}`
|
|
42
|
+
if (!json)
|
|
43
|
+
p.intro(`Zipping ${appId}@${bundle}`)
|
|
44
|
+
// check if bundle is valid
|
|
45
|
+
if (!regexSemver.test(bundle)) {
|
|
83
46
|
if (!json)
|
|
84
|
-
|
|
85
|
-
|
|
47
|
+
p.log.error(`Your bundle name ${bundle}, is not valid it should follow semver convention : https://semver.org/`)
|
|
48
|
+
else
|
|
49
|
+
console.error(formatError({ error: 'invalid_semver' }))
|
|
50
|
+
program.error('')
|
|
51
|
+
}
|
|
52
|
+
path = path || config?.app?.webDir
|
|
53
|
+
if (!appId || !bundle || !path) {
|
|
86
54
|
if (!json)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
55
|
+
p.log.error('Missing argument, you need to provide a appId and a bundle and a path, or be in a capacitor project')
|
|
56
|
+
else
|
|
57
|
+
console.error(formatError({ error: 'missing_argument' }))
|
|
58
|
+
program.error('')
|
|
59
|
+
}
|
|
60
|
+
if (!json)
|
|
61
|
+
p.log.info(`Started from path "${path}"`)
|
|
62
|
+
const checkNotifyAppReady = options.codeCheck
|
|
63
|
+
if (typeof checkNotifyAppReady === 'undefined' || checkNotifyAppReady) {
|
|
64
|
+
const isPluginConfigured = searchInDirectory(path, 'notifyAppReady')
|
|
65
|
+
if (!isPluginConfigured) {
|
|
66
|
+
if (!json)
|
|
67
|
+
p.log.error(`notifyAppReady() is missing in the source code. see: https://capgo.app/docs/plugin/api/#notifyappready`)
|
|
68
|
+
else
|
|
69
|
+
console.error(formatError({ error: 'notifyAppReady_not_in_source_code' }))
|
|
70
|
+
program.error('')
|
|
102
71
|
}
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (options.json) {
|
|
112
|
-
const output = {
|
|
113
|
-
bundle,
|
|
114
|
-
filename: name,
|
|
115
|
-
checksum,
|
|
116
|
-
};
|
|
117
|
-
console.log(JSON.stringify(output));
|
|
72
|
+
const foundIndex = checkIndexPosition(path)
|
|
73
|
+
if (!foundIndex) {
|
|
74
|
+
if (!json)
|
|
75
|
+
p.log.error(`index.html is missing in the root folder or in the only folder in the root folder`)
|
|
76
|
+
else
|
|
77
|
+
console.error(formatError({ error: 'index_html_not_found' }))
|
|
78
|
+
program.error('')
|
|
118
79
|
}
|
|
119
|
-
|
|
80
|
+
}
|
|
81
|
+
const zip = new AdmZip()
|
|
82
|
+
zip.addLocalFolder(path)
|
|
83
|
+
const zipped = zip.toBuffer()
|
|
84
|
+
if (!json)
|
|
85
|
+
p.log.info(`Zipped ${zipped.byteLength} bytes`)
|
|
86
|
+
const s = p.spinner()
|
|
87
|
+
if (!json)
|
|
88
|
+
s.start(`Calculating checksum`)
|
|
89
|
+
const checksum = await getChecksum(zipped, 'crc32')
|
|
90
|
+
if (!json)
|
|
91
|
+
s.stop(`Checksum: ${checksum}`)
|
|
92
|
+
const mbSize = Math.floor(zipped.byteLength / 1024 / 1024)
|
|
93
|
+
// We do not issue this warning for json
|
|
94
|
+
if (mbSize > alertMb && !json) {
|
|
95
|
+
p.log.warn(`WARNING !!\nThe app size is ${mbSize} Mb, this may take a while to download for users\n`)
|
|
96
|
+
p.log.warn(`Learn how to optimize your assets https://capgo.app/blog/optimise-your-images-for-updates/\n`)
|
|
120
97
|
await snag.track({
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
98
|
+
channel: 'app-error',
|
|
99
|
+
event: 'App Too Large',
|
|
100
|
+
icon: '🚛',
|
|
101
|
+
tags: {
|
|
102
|
+
'app-id': appId,
|
|
103
|
+
},
|
|
104
|
+
notify: false,
|
|
128
105
|
}).catch()
|
|
106
|
+
}
|
|
107
|
+
const s2 = p.spinner()
|
|
108
|
+
const name = options.name || `${appId}_${bundle}.zip`
|
|
109
|
+
if (!json)
|
|
110
|
+
s2.start(`Saving to ${name}`)
|
|
111
|
+
writeFileSync(name, zipped)
|
|
112
|
+
if (!json)
|
|
113
|
+
s2.stop(`Saved to ${name}`)
|
|
129
114
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
115
|
+
if (options.json) {
|
|
116
|
+
const output = {
|
|
117
|
+
bundle,
|
|
118
|
+
filename: name,
|
|
119
|
+
checksum,
|
|
120
|
+
}
|
|
121
|
+
p.log.info(formatError(output))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
await snag.track({
|
|
125
|
+
channel: 'app',
|
|
126
|
+
event: 'App zip',
|
|
127
|
+
icon: '⏫',
|
|
128
|
+
tags: {
|
|
129
|
+
'app-id': appId,
|
|
130
|
+
},
|
|
131
|
+
notify: false,
|
|
132
|
+
}).catch()
|
|
133
|
+
|
|
134
|
+
if (!json)
|
|
135
|
+
p.outro(`Done ✅`)
|
|
136
|
+
process.exit()
|
|
133
137
|
}
|
package/src/channel/add.ts
CHANGED
|
@@ -1,71 +1,73 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
import { program } from 'commander'
|
|
3
|
+
import * as p from '@clack/prompts'
|
|
4
|
+
import { checkAppExistsAndHasPermissionErr } from '../api/app'
|
|
5
|
+
import { createChannel, findUnknownVersion } from '../api/channels'
|
|
6
|
+
import type { OptionsBase } from '../utils'
|
|
7
|
+
import { createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
|
|
6
8
|
|
|
7
9
|
interface Options extends OptionsBase {
|
|
8
|
-
|
|
10
|
+
default?: boolean
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
export async function addChannel(channelId: string, appId: string, options: Options, shouldExit = true) {
|
|
14
|
+
p.intro(`Create channel`)
|
|
15
|
+
options.apikey = options.apikey || findSavedKey()
|
|
16
|
+
const config = await getConfig()
|
|
17
|
+
appId = appId || config?.app?.appId
|
|
18
|
+
const snag = useLogSnag()
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
if (!options.apikey) {
|
|
21
|
+
p.log.error('Missing API key, you need to provide a API key to upload your bundle')
|
|
22
|
+
program.error('')
|
|
23
|
+
}
|
|
24
|
+
if (!appId) {
|
|
25
|
+
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
26
|
+
program.error('')
|
|
27
|
+
}
|
|
28
|
+
const supabase = await createSupabaseClient(options.apikey)
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
|
|
31
|
+
// Check we have app access to this appId
|
|
32
|
+
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
await createChannel(supabase, {
|
|
40
|
-
name: channelId,
|
|
41
|
-
app_id: appId,
|
|
42
|
-
version: data.id,
|
|
43
|
-
created_by: userId
|
|
44
|
-
});
|
|
45
|
-
p.log.success(`Channel created ✅`);
|
|
46
|
-
await snag.track({
|
|
47
|
-
channel: 'channel',
|
|
48
|
-
event: 'Create channel',
|
|
49
|
-
icon: '✅',
|
|
50
|
-
user_id: userId,
|
|
51
|
-
tags: {
|
|
52
|
-
'app-id': appId,
|
|
53
|
-
'channel': channelId,
|
|
54
|
-
},
|
|
55
|
-
notify: false,
|
|
56
|
-
}).catch()
|
|
57
|
-
} catch (error) {
|
|
58
|
-
p.log.error(`Cannot create Channel 🙀`);
|
|
59
|
-
return false
|
|
34
|
+
p.log.info(`Creating channel ${appId}#${channelId} to Capgo`)
|
|
35
|
+
try {
|
|
36
|
+
const data = await findUnknownVersion(supabase, appId)
|
|
37
|
+
if (!data) {
|
|
38
|
+
p.log.error(`Cannot find default version for channel creation, please contact Capgo support 🤨`)
|
|
39
|
+
program.error('')
|
|
60
40
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
41
|
+
await createChannel(supabase, {
|
|
42
|
+
name: channelId,
|
|
43
|
+
app_id: appId,
|
|
44
|
+
version: data.id,
|
|
45
|
+
created_by: userId,
|
|
46
|
+
})
|
|
47
|
+
p.log.success(`Channel created ✅`)
|
|
48
|
+
await snag.track({
|
|
49
|
+
channel: 'channel',
|
|
50
|
+
event: 'Create channel',
|
|
51
|
+
icon: '✅',
|
|
52
|
+
user_id: userId,
|
|
53
|
+
tags: {
|
|
54
|
+
'app-id': appId,
|
|
55
|
+
'channel': channelId,
|
|
56
|
+
},
|
|
57
|
+
notify: false,
|
|
58
|
+
}).catch()
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
p.log.error(`Cannot create Channel 🙀`)
|
|
62
|
+
return false
|
|
63
|
+
}
|
|
64
|
+
if (shouldExit) {
|
|
65
|
+
p.outro(`Done ✅`)
|
|
66
|
+
process.exit()
|
|
67
|
+
}
|
|
68
|
+
return true
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
addChannel(apikey, appId, options, true)
|
|
71
|
+
export async function addChannelCommand(apikey: string, appId: string, options: Options) {
|
|
72
|
+
addChannel(apikey, appId, options, true)
|
|
71
73
|
}
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
import { program } from 'commander'
|
|
3
|
+
import * as p from '@clack/prompts'
|
|
4
|
+
import { checkAppExistsAndHasPermissionErr } from '../api/app'
|
|
5
|
+
import type { OptionsBase } from '../utils'
|
|
6
|
+
import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
|
|
6
7
|
|
|
7
8
|
interface Options extends OptionsBase {
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
channel?: string
|
|
10
|
+
quiet?: boolean
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
interface Channel {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
version: {
|
|
15
|
+
name: string
|
|
16
|
+
}
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
export
|
|
19
|
-
|
|
19
|
+
export async function currentBundle(channel: string, appId: string, options: Options) {
|
|
20
|
+
const { quiet } = options
|
|
21
|
+
|
|
22
|
+
if (!quiet)
|
|
23
|
+
p.intro(`List current bundle`)
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
options.apikey = options.apikey || findSavedKey(quiet)
|
|
26
|
+
const config = await getConfig()
|
|
27
|
+
appId = appId || config?.app?.appId
|
|
23
28
|
|
|
29
|
+
if (!options.apikey) {
|
|
30
|
+
p.log.error('Missing API key, you need to provide a API key to upload your bundle')
|
|
31
|
+
program.error('')
|
|
32
|
+
}
|
|
33
|
+
if (!appId) {
|
|
34
|
+
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
35
|
+
program.error('')
|
|
36
|
+
}
|
|
37
|
+
const supabase = await createSupabaseClient(options.apikey)
|
|
24
38
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (!options.apikey) {
|
|
30
|
-
p.log.error("Missing API key, you need to provide a API key to upload your bundle");
|
|
31
|
-
program.error('');
|
|
32
|
-
}
|
|
33
|
-
if (!appId) {
|
|
34
|
-
p.log.error("Missing argument, you need to provide a appId, or be in a capacitor project");
|
|
35
|
-
program.error('');
|
|
36
|
-
}
|
|
37
|
-
const supabase = await createSupabaseClient(options.apikey)
|
|
38
|
-
|
|
39
|
-
const userId = await verifyUser(supabase, options.apikey, ['write', 'all', 'read']);
|
|
40
|
-
// Check we have app access to this appId
|
|
41
|
-
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId);
|
|
39
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all', 'read'])
|
|
40
|
+
// Check we have app access to this appId
|
|
41
|
+
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
if (!channel) {
|
|
44
|
+
p.log.error(`Please provide a channel to get the bundle from.`)
|
|
45
|
+
program.error('')
|
|
46
|
+
}
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
const { data: supabaseChannel, error } = await supabase
|
|
49
|
+
.from('channels')
|
|
50
|
+
.select('version ( name )')
|
|
51
|
+
.eq('name', channel)
|
|
52
|
+
.eq('app_id', appId)
|
|
53
|
+
.eq('created_by', userId)
|
|
54
|
+
.limit(1)
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
if (error || supabaseChannel.length === 0) {
|
|
57
|
+
p.log.error(`Error retrieving channel ${channel} for app ${appId}. Perhaps the channel does not exists?`)
|
|
58
|
+
program.error('')
|
|
59
|
+
}
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
const { version } = supabaseChannel[0] as any as Channel
|
|
62
|
+
if (!version) {
|
|
63
|
+
p.log.error(`Error retrieving channel ${channel} for app ${appId}. Perhaps the channel does not exists?`)
|
|
64
|
+
program.error('')
|
|
65
|
+
}
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
if (!quiet)
|
|
68
|
+
p.log.info(`Current bundle for channel ${channel} is ${version.name}`)
|
|
69
|
+
else
|
|
70
|
+
p.log.info(version.name)
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
process.exit()
|
|
73
73
|
}
|
package/src/channel/delete.ts
CHANGED
|
@@ -1,48 +1,51 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
import { program } from 'commander'
|
|
3
|
+
import * as p from '@clack/prompts'
|
|
4
|
+
import { checkAppExistsAndHasPermissionErr } from '../api/app'
|
|
5
|
+
import { delChannel } from '../api/channels'
|
|
6
|
+
import type { OptionsBase } from '../utils'
|
|
7
|
+
import { createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
|
|
6
8
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
export async function deleteChannel(channelId: string, appId: string, options: OptionsBase) {
|
|
10
|
+
p.intro(`Delete channel`)
|
|
11
|
+
options.apikey = options.apikey || findSavedKey()
|
|
12
|
+
const config = await getConfig()
|
|
13
|
+
appId = appId || config?.app?.appId
|
|
14
|
+
const snag = useLogSnag()
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
if (!options.apikey) {
|
|
17
|
+
p.log.error('Missing API key, you need to provide a API key to upload your bundle')
|
|
18
|
+
program.error('')
|
|
19
|
+
}
|
|
20
|
+
if (!appId) {
|
|
21
|
+
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
22
|
+
program.error('')
|
|
23
|
+
}
|
|
24
|
+
const supabase = await createSupabaseClient(options.apikey)
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
|
|
27
|
+
// Check we have app access to this appId
|
|
28
|
+
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
p.log.info(`Deleting channel ${appId}#${channelId} from Capgo`)
|
|
31
|
+
try {
|
|
32
|
+
await delChannel(supabase, channelId, appId, userId)
|
|
33
|
+
p.log.success(`Channel deleted`)
|
|
34
|
+
await snag.track({
|
|
35
|
+
channel: 'channel',
|
|
36
|
+
event: 'Delete channel',
|
|
37
|
+
icon: '✅',
|
|
38
|
+
tags: {
|
|
39
|
+
'user-id': userId,
|
|
40
|
+
'app-id': appId,
|
|
41
|
+
'channel': channelId,
|
|
42
|
+
},
|
|
43
|
+
notify: false,
|
|
44
|
+
}).catch()
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
p.log.error(`Cannot delete Channel 🙀`)
|
|
48
|
+
}
|
|
49
|
+
p.outro(`Done ✅`)
|
|
50
|
+
process.exit()
|
|
48
51
|
}
|