@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/bundle/cleanup.ts
CHANGED
|
@@ -1,131 +1,128 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
import { program } from 'commander'
|
|
3
|
+
import semver from 'semver/preload'
|
|
4
|
+
import * as p from '@clack/prompts'
|
|
5
|
+
import promptSync from 'prompt-sync'
|
|
6
|
+
import type { SupabaseClient } from '@supabase/supabase-js'
|
|
7
|
+
import type { Database } from '../types/supabase.types'
|
|
8
|
+
import type { OptionsBase } from '../utils'
|
|
9
|
+
import { createSupabaseClient, findSavedKey, getConfig, getHumanDate, verifyUser } from '../utils'
|
|
10
|
+
import { deleteSpecificVersion, displayBundles, getActiveAppVersions, getChannelsVersion } from '../api/versions'
|
|
11
|
+
import { checkAppExistsAndHasPermissionErr } from '../api/app'
|
|
12
|
+
import { checkLatest } from '../api/update'
|
|
12
13
|
|
|
13
14
|
interface Options extends OptionsBase {
|
|
14
|
-
version: string
|
|
15
|
-
bundle: string
|
|
16
|
-
keep: number
|
|
17
|
-
force: boolean
|
|
15
|
+
version: string
|
|
16
|
+
bundle: string
|
|
17
|
+
keep: number
|
|
18
|
+
force: boolean
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
const prompt = promptSync()
|
|
21
|
-
|
|
22
|
-
const removeVersions = async (toRemove: Database['public']['Tables']['app_versions']['Row'][],
|
|
23
|
-
supabase: SupabaseClient<Database>, appid: string, userId: string) => {
|
|
21
|
+
const prompt = promptSync()
|
|
24
22
|
|
|
23
|
+
async function removeVersions(toRemove: Database['public']['Tables']['app_versions']['Row'][], supabase: SupabaseClient<Database>, appid: string, userId: string) {
|
|
25
24
|
// call deleteSpecificVersion one by one from toRemove sync
|
|
26
25
|
for await (const row of toRemove) {
|
|
27
|
-
p.log.warn(`Removing ${row.name} created on ${(getHumanDate(row.created_at))}`)
|
|
28
|
-
await deleteSpecificVersion(supabase, appid, userId, row.name)
|
|
26
|
+
p.log.warn(`Removing ${row.name} created on ${(getHumanDate(row.created_at))}`)
|
|
27
|
+
await deleteSpecificVersion(supabase, appid, userId, row.name)
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const toRemove: Database['public']['Tables']['app_versions']['Row'][] = [];
|
|
31
|
+
function getRemovableVersionsInSemverRange(data: Database['public']['Tables']['app_versions']['Row'][], bundle: string, nextMajor: string) {
|
|
32
|
+
const toRemove: Database['public']['Tables']['app_versions']['Row'][] = []
|
|
35
33
|
|
|
36
|
-
data?.forEach(row => {
|
|
37
|
-
if (semver.gte(row.name, bundle) && semver.lt(row.name, `${nextMajor}`))
|
|
38
|
-
toRemove.push(row)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return toRemove;
|
|
34
|
+
data?.forEach((row) => {
|
|
35
|
+
if (semver.gte(row.name, bundle) && semver.lt(row.name, `${nextMajor}`))
|
|
36
|
+
toRemove.push(row)
|
|
37
|
+
})
|
|
38
|
+
return toRemove
|
|
42
39
|
}
|
|
43
40
|
|
|
44
|
-
export
|
|
45
|
-
p.intro(`Cleanup versions in Capgo`)
|
|
46
|
-
await checkLatest()
|
|
41
|
+
export async function cleanupBundle(appid: string, options: Options) {
|
|
42
|
+
p.intro(`Cleanup versions in Capgo`)
|
|
43
|
+
await checkLatest()
|
|
47
44
|
options.apikey = options.apikey || findSavedKey()
|
|
48
|
-
const { bundle, keep = 4 } = options
|
|
49
|
-
const force = options.force || false
|
|
45
|
+
const { bundle, keep = 4 } = options
|
|
46
|
+
const force = options.force || false
|
|
50
47
|
|
|
51
|
-
const config = await getConfig()
|
|
48
|
+
const config = await getConfig()
|
|
52
49
|
appid = appid || config?.app?.appId
|
|
53
50
|
if (!options.apikey) {
|
|
54
|
-
p.log.error('Missing API key, you need to provide an API key to delete your app')
|
|
55
|
-
program.error('')
|
|
51
|
+
p.log.error('Missing API key, you need to provide an API key to delete your app')
|
|
52
|
+
program.error('')
|
|
56
53
|
}
|
|
57
54
|
if (!appid) {
|
|
58
|
-
p.log.error('Missing argument, you need to provide a appid, or be in a capacitor project')
|
|
59
|
-
program.error('')
|
|
55
|
+
p.log.error('Missing argument, you need to provide a appid, or be in a capacitor project')
|
|
56
|
+
program.error('')
|
|
60
57
|
}
|
|
61
58
|
const supabase = await createSupabaseClient(options.apikey)
|
|
62
59
|
|
|
63
|
-
const userId = await verifyUser(supabase, options.apikey)
|
|
60
|
+
const userId = await verifyUser(supabase, options.apikey)
|
|
64
61
|
|
|
65
62
|
// Check we have app access to this appId
|
|
66
|
-
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appid)
|
|
67
|
-
p.log.info(`Querying all available versions in Capgo`)
|
|
63
|
+
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appid)
|
|
64
|
+
p.log.info(`Querying all available versions in Capgo`)
|
|
68
65
|
|
|
69
66
|
// Get all active app versions we might possibly be able to cleanup
|
|
70
67
|
let allVersions: (Database['public']['Tables']['app_versions']['Row'] & { keep?: string })[] = await
|
|
71
|
-
|
|
68
|
+
getActiveAppVersions(supabase, appid, userId)
|
|
72
69
|
|
|
73
|
-
const versionInUse = await getChannelsVersion(supabase, appid)
|
|
70
|
+
const versionInUse = await getChannelsVersion(supabase, appid)
|
|
74
71
|
|
|
75
|
-
p.log.info(`Total active versions in Capgo: ${allVersions?.length}`)
|
|
72
|
+
p.log.info(`Total active versions in Capgo: ${allVersions?.length}`)
|
|
76
73
|
if (allVersions?.length === 0) {
|
|
77
|
-
p.log.error('No versions found, aborting cleanup')
|
|
78
|
-
return
|
|
74
|
+
p.log.error('No versions found, aborting cleanup')
|
|
75
|
+
return
|
|
79
76
|
}
|
|
80
77
|
if (bundle) {
|
|
81
|
-
const nextMajor = `${semver.inc(bundle, 'major')}
|
|
82
|
-
p.log.info(`Querying available versions in Capgo between ${bundle} and ${nextMajor}`)
|
|
78
|
+
const nextMajor = `${semver.inc(bundle, 'major')}`
|
|
79
|
+
p.log.info(`Querying available versions in Capgo between ${bundle} and ${nextMajor}`)
|
|
83
80
|
|
|
84
81
|
// Get all app versions that are in the given range
|
|
85
|
-
allVersions = getRemovableVersionsInSemverRange(allVersions, bundle,
|
|
86
|
-
nextMajor) as (Database['public']['Tables']['app_versions']['Row'] & { keep: string })[];
|
|
82
|
+
allVersions = getRemovableVersionsInSemverRange(allVersions, bundle, nextMajor) as (Database['public']['Tables']['app_versions']['Row'] & { keep: string })[]
|
|
87
83
|
|
|
88
|
-
p.log.info(`Active versions in Capgo between ${bundle} and ${nextMajor}: ${allVersions?.length}`)
|
|
84
|
+
p.log.info(`Active versions in Capgo between ${bundle} and ${nextMajor}: ${allVersions?.length}`)
|
|
89
85
|
}
|
|
90
86
|
|
|
91
87
|
// Slice to keep and remove
|
|
92
88
|
|
|
93
89
|
const toRemove: (Database['public']['Tables']['app_versions']['Row'] & { keep?: string })[] = []
|
|
94
90
|
// Slice to keep and remove
|
|
95
|
-
let kept = 0
|
|
91
|
+
let kept = 0
|
|
96
92
|
allVersions.forEach((v) => {
|
|
97
|
-
const isInUse = versionInUse.find(
|
|
93
|
+
const isInUse = versionInUse.find(vi => vi === v.id)
|
|
98
94
|
if (kept < keep || isInUse) {
|
|
99
|
-
if(isInUse)
|
|
100
|
-
v.keep = '✅ (Linked to channel)'
|
|
101
|
-
|
|
102
|
-
v.keep = '✅'
|
|
103
|
-
|
|
104
|
-
kept += 1
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
95
|
+
if (isInUse)
|
|
96
|
+
v.keep = '✅ (Linked to channel)'
|
|
97
|
+
else
|
|
98
|
+
v.keep = '✅'
|
|
99
|
+
|
|
100
|
+
kept += 1
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
v.keep = '❌'
|
|
104
|
+
toRemove.push(v)
|
|
108
105
|
}
|
|
109
106
|
})
|
|
110
107
|
|
|
111
108
|
if (toRemove.length === 0) {
|
|
112
|
-
p.log.warn(
|
|
113
|
-
return
|
|
109
|
+
p.log.warn('Nothing to be removed, aborting removal...')
|
|
110
|
+
return
|
|
114
111
|
}
|
|
115
|
-
displayBundles(allVersions)
|
|
112
|
+
displayBundles(allVersions)
|
|
116
113
|
|
|
117
114
|
// Check user wants to clean that all up
|
|
118
115
|
if (!force) {
|
|
119
|
-
const result = prompt(
|
|
120
|
-
if (result !==
|
|
121
|
-
p.log.warn(
|
|
122
|
-
return
|
|
116
|
+
const result = prompt('Do you want to continue removing the versions specified? Type yes to confirm: ')
|
|
117
|
+
if (result !== 'yes') {
|
|
118
|
+
p.log.warn('Not confirmed, aborting removal...')
|
|
119
|
+
return
|
|
123
120
|
}
|
|
124
121
|
}
|
|
125
122
|
|
|
126
123
|
// Yes, lets clean it up
|
|
127
|
-
p.log.success(
|
|
128
|
-
await removeVersions(toRemove, supabase, appid, userId)
|
|
129
|
-
p.outro(`Done ✅`)
|
|
124
|
+
p.log.success('You have confirmed removal, removing versions now')
|
|
125
|
+
await removeVersions(toRemove, supabase, appid, userId)
|
|
126
|
+
p.outro(`Done ✅`)
|
|
130
127
|
process.exit()
|
|
131
128
|
}
|
|
@@ -1,73 +1,70 @@
|
|
|
1
|
-
import * as p from '@clack/prompts'
|
|
2
|
-
import { program } from 'commander'
|
|
3
|
-
import { Table } from 'console-table-printer'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import * as p from '@clack/prompts'
|
|
2
|
+
import { program } from 'commander'
|
|
3
|
+
import { Table } from 'console-table-printer'
|
|
4
|
+
import type { OptionsBase } from '../utils'
|
|
5
|
+
import { checkCompatibility, createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
|
|
6
|
+
import { checkAppExistsAndHasPermissionErr } from '../api/app'
|
|
6
7
|
|
|
7
8
|
interface Options extends OptionsBase {
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
channel?: string
|
|
10
|
+
text?: boolean
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
export async function checkCompatibilityCommand(appId: string, options: Options) {
|
|
14
|
+
p.intro(`Check compatibility`)
|
|
15
|
+
options.apikey = options.apikey || findSavedKey()
|
|
16
|
+
const config = await getConfig()
|
|
17
|
+
appId = appId || config?.app?.appId
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
const { channel } = options
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
21
|
+
if (!channel) {
|
|
22
|
+
p.log.error('Missing argument, you need to provide a channel')
|
|
23
|
+
program.error('')
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const supabase = await createSupabaseClient(options.apikey)
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
37
|
-
const _ = await verifyUser(supabase, options.apikey, ['write', 'all', 'read', 'upload']);
|
|
26
|
+
if (!options.apikey) {
|
|
27
|
+
p.log.error('Missing API key, you need to provide a API key to upload your bundle')
|
|
28
|
+
program.error('')
|
|
29
|
+
}
|
|
30
|
+
if (!appId) {
|
|
31
|
+
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
32
|
+
program.error('')
|
|
33
|
+
}
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
const supabase = await createSupabaseClient(options.apikey)
|
|
36
|
+
await verifyUser(supabase, options.apikey, ['write', 'all', 'read', 'upload'])
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// .map((a) => [a.name, a]))
|
|
38
|
+
// Check we have app access to this appId
|
|
39
|
+
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
45
40
|
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
// const hashedLocalDependencies = new Map(dependenciesObject
|
|
42
|
+
// .filter((a) => !!a.native && a.native !== undefined)
|
|
43
|
+
// .map((a) => [a.name, a]))
|
|
48
44
|
|
|
49
|
-
|
|
45
|
+
// const nativePackages = Array.from(hashedLocalDependencies, ([name, value]) => ({ name, version: value.version }))
|
|
46
|
+
// await supabase.from('app_versions').update({ native_packages: nativePackages }).eq('id', '9654')
|
|
50
47
|
|
|
48
|
+
const { finalCompatibility } = await checkCompatibility(supabase, appId, channel)
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
const t = new Table({
|
|
51
|
+
title: 'Compatibility',
|
|
52
|
+
charLength: { '❌': 2, '✅': 2 },
|
|
53
|
+
})
|
|
57
54
|
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
const yesSymbol = options.text ? 'Yes' : '✅'
|
|
56
|
+
const noSymbol = options.text ? 'No' : '❌'
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
finalCompatibility.forEach((data) => {
|
|
59
|
+
const { name, localVersion, remoteVersion } = data
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
61
|
+
t.addRow({
|
|
62
|
+
'Package': name,
|
|
63
|
+
'Local version': localVersion ?? 'None',
|
|
64
|
+
'Remote version': remoteVersion ?? 'None',
|
|
65
|
+
'Compatible': remoteVersion === localVersion ? yesSymbol : noSymbol,
|
|
70
66
|
})
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
p.log.success(t.render())
|
|
73
70
|
}
|
package/src/bundle/decrypt.ts
CHANGED
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import process from 'node:process'
|
|
2
3
|
import { program } from 'commander'
|
|
3
|
-
import * as p from '@clack/prompts'
|
|
4
|
-
import { decryptSource } from '../api/crypto'
|
|
5
|
-
import { baseKey, getConfig } from '../utils'
|
|
6
|
-
import { checkLatest } from '../api/update'
|
|
4
|
+
import * as p from '@clack/prompts'
|
|
5
|
+
import { decryptSource } from '../api/crypto'
|
|
6
|
+
import { baseKey, getConfig } from '../utils'
|
|
7
|
+
import { checkLatest } from '../api/update'
|
|
7
8
|
|
|
8
9
|
interface Options {
|
|
9
10
|
key?: string
|
|
10
11
|
keyData?: string
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
export
|
|
14
|
-
p.intro(`Decrypt zip file`)
|
|
15
|
-
await checkLatest()
|
|
14
|
+
export async function decryptZip(zipPath: string, ivsessionKey: string, options: Options) {
|
|
15
|
+
p.intro(`Decrypt zip file`)
|
|
16
|
+
await checkLatest()
|
|
16
17
|
// write in file .capgo the apikey in home directory
|
|
17
18
|
|
|
18
19
|
if (!existsSync(zipPath)) {
|
|
19
|
-
p.log.error(`Zip not found at the path ${zipPath}`)
|
|
20
|
-
program.error('')
|
|
20
|
+
p.log.error(`Zip not found at the path ${zipPath}`)
|
|
21
|
+
program.error('')
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
const config = await getConfig()
|
|
24
|
-
const { extConfig } = config.app
|
|
24
|
+
const config = await getConfig()
|
|
25
|
+
const { extConfig } = config.app
|
|
25
26
|
|
|
26
27
|
if (!options.key && !existsSync(baseKey) && !extConfig.plugins?.CapacitorUpdater?.privateKey) {
|
|
27
|
-
p.log.error(`Private Key not found at the path ${baseKey} or in ${config.app.extConfigFilePath}`)
|
|
28
|
-
program.error('')
|
|
28
|
+
p.log.error(`Private Key not found at the path ${baseKey} or in ${config.app.extConfigFilePath}`)
|
|
29
|
+
program.error('')
|
|
29
30
|
}
|
|
30
31
|
const keyPath = options.key || baseKey
|
|
31
32
|
// check if publicKey exist
|
|
@@ -33,9 +34,10 @@ export const decryptZip = async (zipPath: string, ivsessionKey: string, options:
|
|
|
33
34
|
let privateKey = extConfig?.plugins?.CapacitorUpdater?.privateKey
|
|
34
35
|
|
|
35
36
|
if (!existsSync(keyPath) && !privateKey) {
|
|
36
|
-
p.log.error(`Cannot find public key ${keyPath} or as keyData option or in ${config.app.extConfigFilePath}`)
|
|
37
|
-
program.error('')
|
|
38
|
-
}
|
|
37
|
+
p.log.error(`Cannot find public key ${keyPath} or as keyData option or in ${config.app.extConfigFilePath}`)
|
|
38
|
+
program.error('')
|
|
39
|
+
}
|
|
40
|
+
else if (existsSync(keyPath)) {
|
|
39
41
|
// open with fs publicKey path
|
|
40
42
|
const keyFile = readFileSync(keyPath)
|
|
41
43
|
privateKey = keyFile.toString()
|
|
@@ -43,10 +45,10 @@ export const decryptZip = async (zipPath: string, ivsessionKey: string, options:
|
|
|
43
45
|
// console.log('privateKey', privateKey)
|
|
44
46
|
|
|
45
47
|
const zipFile = readFileSync(zipPath)
|
|
46
|
-
|
|
47
|
-
const decodedZip = decryptSource(zipFile, ivsessionKey,
|
|
48
|
+
|
|
49
|
+
const decodedZip = decryptSource(zipFile, ivsessionKey, options.keyData ?? privateKey ?? '')
|
|
48
50
|
// write decodedZip in a file
|
|
49
51
|
writeFileSync(`${zipPath}_decrypted.zip`, decodedZip)
|
|
50
|
-
p.outro(`Decrypted zip file at ${zipPath}_decrypted.zip`)
|
|
52
|
+
p.outro(`Decrypted zip file at ${zipPath}_decrypted.zip`)
|
|
51
53
|
process.exit()
|
|
52
54
|
}
|
package/src/bundle/delete.ts
CHANGED
|
@@ -1,51 +1,53 @@
|
|
|
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 type { OptionsBase } from '../utils'
|
|
6
|
+
import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
|
|
7
|
+
import { deleteSpecificVersion } from '../api/versions'
|
|
6
8
|
|
|
7
9
|
interface Options extends OptionsBase {
|
|
8
|
-
bundle: string
|
|
10
|
+
bundle: string
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
export
|
|
12
|
-
p.intro(`Delete bundle`)
|
|
13
|
+
export async function deleteBundle(bundleId: string, appId: string, options: Options) {
|
|
14
|
+
p.intro(`Delete bundle`)
|
|
13
15
|
options.apikey = options.apikey || findSavedKey()
|
|
14
|
-
const config = await getConfig()
|
|
16
|
+
const config = await getConfig()
|
|
15
17
|
appId = appId || config?.app?.appId
|
|
16
18
|
|
|
17
19
|
if (!options.apikey) {
|
|
18
|
-
p.log.error(
|
|
19
|
-
program.error('')
|
|
20
|
+
p.log.error('Missing API key, you need to provide a API key to upload your bundle')
|
|
21
|
+
program.error('')
|
|
20
22
|
}
|
|
21
23
|
if (!appId) {
|
|
22
|
-
p.log.error(
|
|
23
|
-
program.error('')
|
|
24
|
+
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
25
|
+
program.error('')
|
|
24
26
|
}
|
|
25
27
|
const supabase = await createSupabaseClient(options.apikey)
|
|
26
28
|
|
|
27
|
-
const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
|
|
29
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
|
|
28
30
|
// Check we have app access to this appId
|
|
29
|
-
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
31
|
+
await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
|
|
30
32
|
|
|
31
33
|
appId = appId || config?.app?.appId
|
|
32
34
|
if (!options.apikey) {
|
|
33
|
-
p.log.error('Missing API key, you need to provide an API key to delete your app')
|
|
34
|
-
program.error('')
|
|
35
|
+
p.log.error('Missing API key, you need to provide an API key to delete your app')
|
|
36
|
+
program.error('')
|
|
35
37
|
}
|
|
36
38
|
if (!bundleId) {
|
|
37
|
-
p.log.error('Missing argument, you need to provide a bundleId, or be in a capacitor project')
|
|
38
|
-
program.error('')
|
|
39
|
+
p.log.error('Missing argument, you need to provide a bundleId, or be in a capacitor project')
|
|
40
|
+
program.error('')
|
|
39
41
|
}
|
|
40
42
|
if (!appId) {
|
|
41
|
-
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
42
|
-
program.error('')
|
|
43
|
+
p.log.error('Missing argument, you need to provide a appId, or be in a capacitor project')
|
|
44
|
+
program.error('')
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
p.log.info(`Deleting bundle ${appId}@${bundleId} from Capgo`)
|
|
47
|
+
p.log.info(`Deleting bundle ${appId}@${bundleId} from Capgo`)
|
|
46
48
|
|
|
47
|
-
await deleteSpecificVersion(supabase, appId, userId, bundleId)
|
|
48
|
-
p.log.success(`Bundle ${appId}@${bundleId} deleted in Capgo`)
|
|
49
|
-
p.outro(`Done`)
|
|
49
|
+
await deleteSpecificVersion(supabase, appId, userId, bundleId)
|
|
50
|
+
p.log.success(`Bundle ${appId}@${bundleId} deleted in Capgo`)
|
|
51
|
+
p.outro(`Done`)
|
|
50
52
|
process.exit()
|
|
51
53
|
}
|
package/src/bundle/encrypt.ts
CHANGED
|
@@ -1,47 +1,49 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import process from 'node:process'
|
|
2
3
|
import { program } from 'commander'
|
|
3
|
-
import ciDetect from 'ci-info'
|
|
4
|
-
import * as p from '@clack/prompts'
|
|
5
|
-
import { checkLatest } from '../api/update'
|
|
6
|
-
import { encryptSource } from '../api/crypto'
|
|
7
|
-
import { baseKeyPub, getLocalConfig } from '../utils'
|
|
4
|
+
import ciDetect from 'ci-info'
|
|
5
|
+
import * as p from '@clack/prompts'
|
|
6
|
+
import { checkLatest } from '../api/update'
|
|
7
|
+
import { encryptSource } from '../api/crypto'
|
|
8
|
+
import { baseKeyPub, getLocalConfig } from '../utils'
|
|
8
9
|
|
|
9
10
|
interface Options {
|
|
10
11
|
key?: string
|
|
11
12
|
keyData?: string
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
export
|
|
15
|
-
p.intro(`Encryption`)
|
|
15
|
+
export async function encryptZip(zipPath: string, options: Options) {
|
|
16
|
+
p.intro(`Encryption`)
|
|
16
17
|
|
|
17
|
-
await checkLatest()
|
|
18
|
+
await checkLatest()
|
|
18
19
|
const localConfig = await getLocalConfig()
|
|
19
20
|
|
|
20
21
|
// write in file .capgo the apikey in home directory
|
|
21
22
|
|
|
22
23
|
if (!existsSync(zipPath)) {
|
|
23
|
-
p.log.error(`Error: Zip not found at the path ${zipPath}`)
|
|
24
|
-
program.error('')
|
|
24
|
+
p.log.error(`Error: Zip not found at the path ${zipPath}`)
|
|
25
|
+
program.error('')
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
const keyPath = options.key || baseKeyPub
|
|
28
29
|
// check if publicKey exist
|
|
29
30
|
|
|
30
|
-
let publicKey = options.keyData ||
|
|
31
|
+
let publicKey = options.keyData || ''
|
|
31
32
|
|
|
32
33
|
if (!existsSync(keyPath) && !publicKey) {
|
|
33
|
-
p.log.warning(`Cannot find public key ${keyPath} or as keyData option`)
|
|
34
|
+
p.log.warning(`Cannot find public key ${keyPath} or as keyData option`)
|
|
34
35
|
if (ciDetect.isCI) {
|
|
35
|
-
p.log.error(`Error: Missing public key`)
|
|
36
|
-
program.error('')
|
|
36
|
+
p.log.error(`Error: Missing public key`)
|
|
37
|
+
program.error('')
|
|
37
38
|
}
|
|
38
39
|
const res = await p.confirm({ message: 'Do you want to use our public key ?' })
|
|
39
40
|
if (!res) {
|
|
40
|
-
p.log.error(`Error: Missing public key`)
|
|
41
|
-
program.error('')
|
|
41
|
+
p.log.error(`Error: Missing public key`)
|
|
42
|
+
program.error('')
|
|
42
43
|
}
|
|
43
44
|
publicKey = localConfig.signKey || ''
|
|
44
|
-
}
|
|
45
|
+
}
|
|
46
|
+
else if (existsSync(keyPath)) {
|
|
45
47
|
// open with fs publicKey path
|
|
46
48
|
const keyFile = readFileSync(keyPath)
|
|
47
49
|
publicKey = keyFile.toString()
|
|
@@ -49,10 +51,10 @@ export const encryptZip = async (zipPath: string, options: Options) => {
|
|
|
49
51
|
|
|
50
52
|
const zipFile = readFileSync(zipPath)
|
|
51
53
|
const encodedZip = encryptSource(zipFile, publicKey)
|
|
52
|
-
p.log.success(`ivSessionKey: ${encodedZip.ivSessionKey}`)
|
|
54
|
+
p.log.success(`ivSessionKey: ${encodedZip.ivSessionKey}`)
|
|
53
55
|
// write decodedZip in a file
|
|
54
56
|
writeFileSync(`${zipPath}_encrypted.zip`, encodedZip.encryptedData)
|
|
55
|
-
p.log.success(`Encrypted zip saved at ${zipPath}_encrypted.zip`)
|
|
56
|
-
p.outro(`Done ✅`)
|
|
57
|
+
p.log.success(`Encrypted zip saved at ${zipPath}_encrypted.zip`)
|
|
58
|
+
p.outro(`Done ✅`)
|
|
57
59
|
process.exit()
|
|
58
60
|
}
|