-
-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathdelete.ts
More file actions
133 lines (112 loc) · 3.75 KB
/
delete.ts
File metadata and controls
133 lines (112 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import type { OptionsBase } from '../schemas/base'
import { intro, isCancel, log, outro, select } from '@clack/prompts'
import { checkAppExistsAndHasPermissionOrgErr, getAppIconStoragePath } from '../api/app'
import {
createSupabaseClient,
findSavedKey,
formatError,
getAppId,
getConfig,
getOrganizationId,
OrganizationPerm,
resolveUserIdFromApiKey,
sendEvent,
} from '../utils'
export async function deleteAppInternal(
initialAppId: string,
options: OptionsBase,
silent = false,
skipConfirmation = false,
) {
if (!silent)
intro('Deleting')
options.apikey = options.apikey || findSavedKey()
const extConfig = await getConfig()
const appId = getAppId(initialAppId, extConfig?.config)
if (!options.apikey) {
if (!silent)
log.error('Missing API key, you need to provide an API key to upload your bundle')
throw new Error('Missing API key')
}
if (!appId) {
if (!silent)
log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
throw new Error('Missing appId')
}
const supabase = await createSupabaseClient(options.apikey, options.supaHost, options.supaAnon)
const userId = await resolveUserIdFromApiKey(supabase, options.apikey)
await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.super_admin, silent)
const { data: appOwnerRaw, error: appOwnerError } = await supabase.from('apps')
.select('owner_org ( created_by, id )')
.eq('app_id', appId)
.single()
const appOwner = appOwnerRaw as { owner_org: { created_by: string, id: string } } | null
if (!skipConfirmation && !appOwnerError && (appOwner?.owner_org.created_by ?? '') !== userId) {
if (!silent) {
log.warn('Deleting the app is not recommended for users that are not the organization owner')
log.warn('You are invited as a super_admin but your are not the owner')
log.warn('It\'s strongly recommended that you do not continue!')
const shouldContinue = await select({
message: 'Do you want to continue?',
options: [
{ label: 'Yes', value: 'yes' },
{ label: 'No', value: 'no' },
],
})
if (isCancel(shouldContinue) || shouldContinue === 'no') {
log.error('Canceled deleting the app, exiting')
throw new Error('App deletion cancelled')
}
}
else {
throw new Error('Cannot delete app: you are not the organization owner')
}
}
else if (appOwnerError && !silent) {
log.warn(`Cannot get the app owner ${formatError(appOwnerError)}`)
}
const { error: storageError } = appOwner?.owner_org.id
? await supabase
.storage
.from('images')
.remove([getAppIconStoragePath(appOwner.owner_org.id, appId)])
: { error: null }
if (storageError && !silent) {
log.error('Could not delete app logo')
}
const { error: delError } = await supabase
.storage
.from(`apps/${appId}/${userId}`)
.remove(['versions'])
if (delError && !silent)
log.error('Could not delete app version')
const { error: dbError } = await supabase
.from('apps')
.delete()
.eq('app_id', appId)
if (dbError) {
if (!silent)
log.error('Could not delete app')
throw new Error(`Could not delete app: ${formatError(dbError)}`)
}
const orgId = await getOrganizationId(supabase, appId)
await sendEvent(options.apikey, {
channel: 'app',
event: 'App Deleted',
icon: '🗑️',
user_id: orgId,
tags: { 'app-id': appId },
notify: false,
}).catch(() => {})
if (!silent) {
log.success('App deleted in Capgo')
outro('Done ✅')
}
return true
}
export async function deleteApp(
initialAppId: string,
options: OptionsBase,
) {
return deleteAppInternal(initialAppId, options, false, false)
}