@capgo/cli 4.0.12 → 4.0.13
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 +8 -0
- package/bun.lockb +0 -0
- package/capacitor.config.ts +2 -2
- package/dist/index.js +650 -654
- package/eslint.config.js +3 -0
- package/package.json +3 -2
- package/src/api/app.ts +29 -36
- 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/app/debug.ts
CHANGED
|
@@ -1,82 +1,83 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
import * as p from '@clack/prompts'
|
|
3
|
+
import type { SupabaseClient } from '@supabase/supabase-js'
|
|
4
|
+
import { program } from 'commander'
|
|
5
|
+
import type LogSnag from 'logsnag'
|
|
6
|
+
import type { Database } from '../types/supabase.types'
|
|
7
|
+
import { checkAppExistsAndHasPermissionErr } from '../api/app'
|
|
8
|
+
import { checkLatest } from '../api/update'
|
|
9
|
+
import { convertAppName, createSupabaseClient, findSavedKey, formatError, getConfig, getLocalConfig, useLogSnag, verifyUser } from '../utils'
|
|
10
|
+
|
|
11
|
+
function wait(ms: number) {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
setTimeout(resolve, ms)
|
|
14
|
+
})
|
|
15
|
+
}
|
|
12
16
|
|
|
13
17
|
export interface OptionsBaseDebug {
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
apikey: string
|
|
19
|
+
device?: string
|
|
16
20
|
}
|
|
17
21
|
|
|
18
|
-
export
|
|
22
|
+
export async function markSnag(channel: string, userId: string, snag: LogSnag, event: string, icon = '✅') {
|
|
19
23
|
await snag.track({
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
channel,
|
|
25
|
+
event,
|
|
26
|
+
icon,
|
|
27
|
+
user_id: userId,
|
|
28
|
+
notify: false,
|
|
25
29
|
}).catch()
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
export
|
|
32
|
+
export async function cancelCommand(channel: string, command: boolean | symbol, userId: string, snag: LogSnag) {
|
|
29
33
|
if (p.isCancel(command)) {
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
await markSnag(channel, userId, snag, 'canceled', '🤷')
|
|
35
|
+
process.exit()
|
|
32
36
|
}
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
interface Order {
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
key: string
|
|
41
|
+
sortable?: 'asc' | 'desc'
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
interface QueryStats {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
appId: string
|
|
46
|
+
devicesId?: string[]
|
|
47
|
+
search?: string
|
|
48
|
+
order?: Order[]
|
|
49
|
+
rangeStart?: number
|
|
50
|
+
rangeEnd?: number
|
|
51
|
+
after?: string
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
export async function getStats(supabase: SupabaseClient<Database>, query: QueryStats)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return null;
|
|
54
|
+
export async function getStats(supabase: SupabaseClient<Database>, query: QueryStats): Promise<Database['public']['Tables']['stats']['Row'] | null> {
|
|
55
|
+
try {
|
|
56
|
+
const pathStats = 'private/stats'
|
|
57
|
+
const res = await supabase.functions.invoke(pathStats, { body: JSON.stringify(query) })
|
|
58
|
+
const listData = res.data.data as Database['public']['Tables']['stats']['Row'][]
|
|
59
|
+
if (listData?.length > 0)
|
|
60
|
+
return listData[0]
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
p.log.error(`Cannot get stats ${formatError(error)}`)
|
|
64
|
+
}
|
|
65
|
+
return null
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
export const waitLog = async (channel: string, supabase: SupabaseClient<Database>,
|
|
67
|
-
appId: string, snag: LogSnag, userId: string, deviceId?: string) => {
|
|
68
|
+
export async function waitLog(channel: string, supabase: SupabaseClient<Database>, appId: string, snag: LogSnag, userId: string, deviceId?: string) {
|
|
68
69
|
let loop = true
|
|
69
70
|
let now = new Date().toISOString()
|
|
70
71
|
const appIdUrl = convertAppName(appId)
|
|
71
|
-
const config = await getLocalConfig()
|
|
72
|
+
const config = await getLocalConfig()
|
|
72
73
|
const baseUrl = `${config.hostWeb}/app/p/${appIdUrl}`
|
|
73
74
|
await markSnag(channel, userId, snag, 'Use waitlog')
|
|
74
75
|
const query: QueryStats = {
|
|
75
76
|
appId,
|
|
76
77
|
devicesId: deviceId ? [deviceId] : undefined,
|
|
77
78
|
order: [{
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
key: 'created_at',
|
|
80
|
+
sortable: 'desc',
|
|
80
81
|
}],
|
|
81
82
|
rangeStart: 0,
|
|
82
83
|
rangeEnd: 1,
|
|
@@ -86,133 +87,134 @@ export const waitLog = async (channel: string, supabase: SupabaseClient<Database
|
|
|
86
87
|
const data = await getStats(supabase, query)
|
|
87
88
|
// console.log('data', data)
|
|
88
89
|
if (data) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
p.log.info(`Your bundle is downloading ${action}% ...`)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
else if (data.action === 'set') {
|
|
109
|
-
p.log.info('Your bundle has been set on your device ❤️')
|
|
110
|
-
loop = false
|
|
111
|
-
await markSnag(channel, userId, snag, 'set')
|
|
112
|
-
return Promise.resolve(data)
|
|
113
|
-
}
|
|
114
|
-
else if (data.action === 'NoChannelOrOverride') {
|
|
115
|
-
p.log.error(`No default channel or override (channel/device) found, please create it here ${baseUrl}`)
|
|
116
|
-
}
|
|
117
|
-
else if (data.action === 'needPlanUpgrade') {
|
|
118
|
-
p.log.error('Your are out of quota, please upgrade your plan here https://web.capgo.app/dashboard/settings/plans')
|
|
119
|
-
}
|
|
120
|
-
else if (data.action === 'missingBundle') {
|
|
121
|
-
p.log.error('Your bundle is missing, please check how you build your app ')
|
|
122
|
-
}
|
|
123
|
-
else if (data.action === 'noNew') {
|
|
124
|
-
p.log.error(`Your version in ${data.platform} is the same as your version uploaded, change it to see the update`)
|
|
125
|
-
}
|
|
126
|
-
else if (data.action === 'disablePlatformIos') {
|
|
127
|
-
p.log.error(`iOS is disabled in the default channel and your device is an iOS device ${baseUrl}`)
|
|
128
|
-
}
|
|
129
|
-
else if (data.action === 'disablePlatformAndroid') {
|
|
130
|
-
p.log.error(`Android is disabled in the default channel and your device is an Android device ${baseUrl}`)
|
|
131
|
-
}
|
|
132
|
-
else if (data.action === 'disableAutoUpdateToMajor') {
|
|
133
|
-
p.log.error('Auto update to major version is disabled in the default channel.')
|
|
134
|
-
p.log.error('Set your app to the same major version as the default channel')
|
|
135
|
-
}
|
|
136
|
-
else if (data.action === 'disableAutoUpdateUnderNative') {
|
|
137
|
-
p.log.error('Auto update under native version is disabled in the default channel.')
|
|
138
|
-
p.log.error('Set your app to the same native version as the default channel.')
|
|
139
|
-
}
|
|
140
|
-
else if (data.action === 'disableDevBuild') {
|
|
141
|
-
p.log.error(`Dev build is disabled in the default channel. ${baseUrl}`)
|
|
142
|
-
p.log.error('Set your channel to allow it if you wanna test your app')
|
|
143
|
-
}
|
|
144
|
-
else if (data.action === 'disableEmulator') {
|
|
145
|
-
p.log.error(`Emulator is disabled in the default channel. ${baseUrl}`)
|
|
146
|
-
p.log.error('Set your channel to allow it if you wanna test your app')
|
|
147
|
-
}
|
|
148
|
-
else if (data.action === 'cannotGetBundle') {
|
|
149
|
-
p.log.error(`We cannot get your bundle from the default channel. ${baseUrl}`)
|
|
150
|
-
p.log.error('Are you sure your default channel has a bundle set?')
|
|
151
|
-
}
|
|
152
|
-
else if (data.action === 'set_fail') {
|
|
153
|
-
p.log.error(`Your bundle seems to be corrupted, try to download from ${baseUrl} to identify the issue`)
|
|
154
|
-
}
|
|
155
|
-
else if (data.action === 'reset') {
|
|
156
|
-
p.log.error('Your device has been reset to the builtin bundle, did you added notifyAppReady in your code?')
|
|
157
|
-
}
|
|
158
|
-
else if (data.action === 'update_fail') {
|
|
159
|
-
p.log.error('Your bundle has been installed but failed to call notifyAppReady')
|
|
160
|
-
p.log.error('Please check if you have network connection and try again')
|
|
161
|
-
}
|
|
162
|
-
else if (data.action === 'checksum_fail') {
|
|
163
|
-
p.log.error('Your bundle has failed to validate checksum, please check your code and send it again to Capgo')
|
|
90
|
+
p.log.info(`Log from Device: ${data.device_id}`)
|
|
91
|
+
if (data.action === 'get') {
|
|
92
|
+
p.log.info('Update Sent your your device, wait until event download complete')
|
|
93
|
+
await markSnag(channel, userId, snag, 'done')
|
|
94
|
+
}
|
|
95
|
+
else if (data.action.startsWith('download_')) {
|
|
96
|
+
const action = data.action.split('_')[1]
|
|
97
|
+
if (action === 'complete') {
|
|
98
|
+
p.log.info('Your bundle has been downloaded on your device, background the app now and open it again to see the update')
|
|
99
|
+
await markSnag(channel, userId, snag, 'downloaded')
|
|
100
|
+
}
|
|
101
|
+
else if (action === 'fail') {
|
|
102
|
+
p.log.error('Your bundle has failed to download on your device.')
|
|
103
|
+
p.log.error('Please check if you have network connection and try again')
|
|
164
104
|
}
|
|
165
105
|
else {
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
106
|
+
p.log.info(`Your bundle is downloading ${action}% ...`)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (data.action === 'set') {
|
|
110
|
+
p.log.info('Your bundle has been set on your device ❤️')
|
|
111
|
+
loop = false
|
|
112
|
+
await markSnag(channel, userId, snag, 'set')
|
|
113
|
+
return Promise.resolve(data)
|
|
114
|
+
}
|
|
115
|
+
else if (data.action === 'NoChannelOrOverride') {
|
|
116
|
+
p.log.error(`No default channel or override (channel/device) found, please create it here ${baseUrl}`)
|
|
117
|
+
}
|
|
118
|
+
else if (data.action === 'needPlanUpgrade') {
|
|
119
|
+
p.log.error('Your are out of quota, please upgrade your plan here https://web.capgo.app/dashboard/settings/plans')
|
|
120
|
+
}
|
|
121
|
+
else if (data.action === 'missingBundle') {
|
|
122
|
+
p.log.error('Your bundle is missing, please check how you build your app ')
|
|
123
|
+
}
|
|
124
|
+
else if (data.action === 'noNew') {
|
|
125
|
+
p.log.error(`Your version in ${data.platform} is the same as your version uploaded, change it to see the update`)
|
|
126
|
+
}
|
|
127
|
+
else if (data.action === 'disablePlatformIos') {
|
|
128
|
+
p.log.error(`iOS is disabled in the default channel and your device is an iOS device ${baseUrl}`)
|
|
129
|
+
}
|
|
130
|
+
else if (data.action === 'disablePlatformAndroid') {
|
|
131
|
+
p.log.error(`Android is disabled in the default channel and your device is an Android device ${baseUrl}`)
|
|
132
|
+
}
|
|
133
|
+
else if (data.action === 'disableAutoUpdateToMajor') {
|
|
134
|
+
p.log.error('Auto update to major version is disabled in the default channel.')
|
|
135
|
+
p.log.error('Set your app to the same major version as the default channel')
|
|
136
|
+
}
|
|
137
|
+
else if (data.action === 'disableAutoUpdateUnderNative') {
|
|
138
|
+
p.log.error('Auto update under native version is disabled in the default channel.')
|
|
139
|
+
p.log.error('Set your app to the same native version as the default channel.')
|
|
140
|
+
}
|
|
141
|
+
else if (data.action === 'disableDevBuild') {
|
|
142
|
+
p.log.error(`Dev build is disabled in the default channel. ${baseUrl}`)
|
|
143
|
+
p.log.error('Set your channel to allow it if you wanna test your app')
|
|
144
|
+
}
|
|
145
|
+
else if (data.action === 'disableEmulator') {
|
|
146
|
+
p.log.error(`Emulator is disabled in the default channel. ${baseUrl}`)
|
|
147
|
+
p.log.error('Set your channel to allow it if you wanna test your app')
|
|
148
|
+
}
|
|
149
|
+
else if (data.action === 'cannotGetBundle') {
|
|
150
|
+
p.log.error(`We cannot get your bundle from the default channel. ${baseUrl}`)
|
|
151
|
+
p.log.error('Are you sure your default channel has a bundle set?')
|
|
152
|
+
}
|
|
153
|
+
else if (data.action === 'set_fail') {
|
|
154
|
+
p.log.error(`Your bundle seems to be corrupted, try to download from ${baseUrl} to identify the issue`)
|
|
155
|
+
}
|
|
156
|
+
else if (data.action === 'reset') {
|
|
157
|
+
p.log.error('Your device has been reset to the builtin bundle, did you added notifyAppReady in your code?')
|
|
158
|
+
}
|
|
159
|
+
else if (data.action === 'update_fail') {
|
|
160
|
+
p.log.error('Your bundle has been installed but failed to call notifyAppReady')
|
|
161
|
+
p.log.error('Please check if you have network connection and try again')
|
|
162
|
+
}
|
|
163
|
+
else if (data.action === 'checksum_fail') {
|
|
164
|
+
p.log.error('Your bundle has failed to validate checksum, please check your code and send it again to Capgo')
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
p.log.error(`Log from Capgo ${data.action}`)
|
|
168
|
+
}
|
|
169
|
+
now = new Date().toISOString()
|
|
170
|
+
query.after = now
|
|
170
171
|
}
|
|
171
172
|
await wait(1000)
|
|
172
173
|
}
|
|
173
174
|
return Promise.resolve()
|
|
174
175
|
}
|
|
175
176
|
|
|
176
|
-
export
|
|
177
|
-
p.intro(`Debug Live update in Capgo`)
|
|
177
|
+
export async function debugApp(appId: string, options: OptionsBaseDebug) {
|
|
178
|
+
p.intro(`Debug Live update in Capgo`)
|
|
178
179
|
|
|
179
|
-
await checkLatest()
|
|
180
|
+
await checkLatest()
|
|
180
181
|
options.apikey = options.apikey || findSavedKey()
|
|
181
|
-
const config = await getConfig()
|
|
182
|
+
const config = await getConfig()
|
|
182
183
|
|
|
183
184
|
appId = appId || config?.app?.appId
|
|
184
185
|
const deviceId = options.device
|
|
185
186
|
if (!options.apikey) {
|
|
186
|
-
p.log.error(`Missing API key, you need to provide an API key to delete your app`)
|
|
187
|
-
program.error('')
|
|
187
|
+
p.log.error(`Missing API key, you need to provide an API key to delete your app`)
|
|
188
|
+
program.error('')
|
|
188
189
|
}
|
|
189
190
|
if (!appId) {
|
|
190
|
-
p.log.error(
|
|
191
|
-
program.error('')
|
|
191
|
+
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
192
|
+
program.error('')
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
const supabase = await createSupabaseClient(options.apikey)
|
|
195
196
|
const snag = useLogSnag()
|
|
196
197
|
|
|
197
|
-
const userId = await verifyUser(supabase, options.apikey)
|
|
198
|
+
const userId = await verifyUser(supabase, options.apikey)
|
|
198
199
|
|
|
199
|
-
p.log.info(`Getting active bundle in Capgo`)
|
|
200
|
+
p.log.info(`Getting active bundle in Capgo`)
|
|
200
201
|
|
|
201
202
|
// Check we have app access to this appId
|
|
202
|
-
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
203
|
+
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
203
204
|
|
|
204
|
-
const doRun = await p.confirm({ message: `Automatic check if update working in device ?` })
|
|
205
|
-
await cancelCommand('debug', doRun, userId, snag)
|
|
205
|
+
const doRun = await p.confirm({ message: `Automatic check if update working in device ?` })
|
|
206
|
+
await cancelCommand('debug', doRun, userId, snag)
|
|
206
207
|
if (doRun) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
208
|
+
p.log.info(`Wait logs sent to Capgo from ${appId} device, Put the app in background and open it again.`)
|
|
209
|
+
p.log.info('Waiting...')
|
|
210
|
+
await waitLog('debug', supabase, appId, snag, userId, deviceId)
|
|
211
|
+
p.outro(`Done ✅`)
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
// const appIdUrl = convertAppName(appId)
|
|
215
|
+
// p.log.info(`Check logs in https://web.capgo.app/app/p/${appIdUrl}/logs to see if update works.`)
|
|
216
|
+
p.outro(`Canceled ❌`)
|
|
215
217
|
}
|
|
216
|
-
p.outro(`Done ✅`)
|
|
218
|
+
p.outro(`Done ✅`)
|
|
217
219
|
process.exit()
|
|
218
220
|
}
|
package/src/app/delete.ts
CHANGED
|
@@ -1,66 +1,68 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
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 type { OptionsBase } from '../utils'
|
|
6
|
+
import { createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
|
|
5
7
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
export async function deleteApp(appId: string, options: OptionsBase) {
|
|
9
|
+
p.intro(`Deleting`)
|
|
10
|
+
options.apikey = options.apikey || findSavedKey()
|
|
11
|
+
const config = await getConfig()
|
|
12
|
+
appId = appId || config?.app?.appId
|
|
13
|
+
const snag = useLogSnag()
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
if (!options.apikey) {
|
|
16
|
+
p.log.error('Missing API key, you need to provide a API key to upload your bundle')
|
|
17
|
+
program.error('')
|
|
18
|
+
}
|
|
19
|
+
if (!appId) {
|
|
20
|
+
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
21
|
+
program.error('')
|
|
22
|
+
}
|
|
23
|
+
const supabase = await createSupabaseClient(options.apikey)
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
|
|
26
|
+
// Check we have app access to this appId
|
|
27
|
+
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
const { error: delError } = await supabase
|
|
35
|
-
.storage
|
|
36
|
-
.from(`apps/${appId}/${userId}`)
|
|
37
|
-
.remove(['versions'])
|
|
38
|
-
if (delError) {
|
|
39
|
-
p.log.error('Could not delete app version');
|
|
40
|
-
program.error('');
|
|
41
|
-
}
|
|
29
|
+
const { error } = await supabase
|
|
30
|
+
.storage
|
|
31
|
+
.from(`images/${userId}`)
|
|
32
|
+
.remove([appId])
|
|
33
|
+
if (error)
|
|
34
|
+
p.log.error('Could not delete app logo')
|
|
42
35
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
const { error: delError } = await supabase
|
|
37
|
+
.storage
|
|
38
|
+
.from(`apps/${appId}/${userId}`)
|
|
39
|
+
.remove(['versions'])
|
|
40
|
+
if (delError) {
|
|
41
|
+
p.log.error('Could not delete app version')
|
|
42
|
+
program.error('')
|
|
43
|
+
}
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
45
|
+
const { error: dbError } = await supabase
|
|
46
|
+
.from('apps')
|
|
47
|
+
.delete()
|
|
48
|
+
.eq('app_id', appId)
|
|
49
|
+
.eq('user_id', userId)
|
|
50
|
+
|
|
51
|
+
if (dbError) {
|
|
52
|
+
p.log.error('Could not delete app')
|
|
53
|
+
program.error('')
|
|
54
|
+
}
|
|
55
|
+
await snag.track({
|
|
56
|
+
channel: 'app',
|
|
57
|
+
event: 'App Deleted',
|
|
58
|
+
icon: '🗑️',
|
|
59
|
+
user_id: userId,
|
|
60
|
+
tags: {
|
|
61
|
+
'app-id': appId,
|
|
62
|
+
},
|
|
63
|
+
notify: false,
|
|
64
|
+
}).catch()
|
|
65
|
+
p.log.success(`App deleted in Capgo`)
|
|
66
|
+
p.outro('Done ✅')
|
|
67
|
+
process.exit()
|
|
66
68
|
}
|