@capgo/cli 2.5.8 → 3.0.0-alpha.0
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 +11 -0
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/src/api/app.ts +9 -1
- package/src/api/channels.ts +57 -2
- package/src/api/devices_override.ts +1 -1
- package/src/api/storage.ts +1 -1
- package/src/api/utils.ts +4 -0
- package/src/api/versions.ts +2 -2
- package/src/{bin → app}/add.ts +33 -35
- package/src/app/delete.ts +61 -0
- package/src/{bin → app}/list.ts +12 -12
- package/src/app/set.ts +74 -0
- package/src/{bin → bundle}/cleanup.ts +5 -4
- package/src/{bin → bundle}/decrypt.ts +2 -1
- package/src/bundle/delete.ts +54 -0
- package/src/{bin → bundle}/encrypt.ts +2 -1
- package/src/{bin → bundle}/upload.ts +7 -6
- package/src/channel/add.ts +49 -0
- package/src/channel/delete.ts +45 -0
- package/src/channel/list.ts +37 -0
- package/src/{bin → channel}/set.ts +36 -38
- package/src/{bin/index.ts → index.ts} +103 -67
- package/src/{bin/key.ts → key.ts} +1 -1
- package/src/{bin/login.ts → login.ts} +0 -0
- package/src/{bin/utils.ts → utils.ts} +2 -2
- package/webpack.config.js +1 -1
- package/src/bin/channel.ts +0 -122
- package/src/bin/delete.ts +0 -99
package/src/{bin → app}/list.ts
RENAMED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import { program } from 'commander';
|
|
2
|
-
import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from './utils';
|
|
3
2
|
import { checkAppExistsAndHasPermission } from '../api/app';
|
|
4
|
-
import {
|
|
3
|
+
import { OptionsBase } from '../api/utils';
|
|
4
|
+
import { getActiveAppVersions, displayBundles } from '../api/versions';
|
|
5
|
+
import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
apikey: string;
|
|
8
|
-
version: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const listApp = async (appid: string, options: Options) => {
|
|
7
|
+
export const listApp = async (appId: string, options: OptionsBase) => {
|
|
12
8
|
const apikey = options.apikey || findSavedKey()
|
|
13
9
|
const config = await getConfig();
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
console.log('COMMAND DEPRECATED, use "app list" instead')
|
|
12
|
+
appId = appId || config?.app?.appId
|
|
16
13
|
if (!apikey) {
|
|
17
14
|
program.error('Missing API key, you need to provide an API key to delete your app');
|
|
18
15
|
}
|
|
19
|
-
if (!
|
|
16
|
+
if (!appId) {
|
|
20
17
|
program.error('Missing argument, you need to provide a appid, or be in a capacitor project');
|
|
21
18
|
}
|
|
22
19
|
console.log(`Querying available versions in Capgo`);
|
|
@@ -25,14 +22,17 @@ export const listApp = async (appid: string, options: Options) => {
|
|
|
25
22
|
|
|
26
23
|
const userId = await verifyUser(supabase, apikey);
|
|
27
24
|
|
|
25
|
+
console.log(`Querying available versions in Capgo`);
|
|
26
|
+
|
|
28
27
|
// Check we have app access to this appId
|
|
29
|
-
await checkAppExistsAndHasPermission(supabase,
|
|
28
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
30
29
|
|
|
31
30
|
// Get all active app versions we might possibly be able to cleanup
|
|
32
|
-
const allVersions = await getActiveAppVersions(supabase,
|
|
31
|
+
const allVersions = await getActiveAppVersions(supabase, appId, userId);
|
|
33
32
|
|
|
34
33
|
console.log(`Active versions in Capgo: ${allVersions?.length}`);
|
|
35
34
|
|
|
36
35
|
displayBundles(allVersions);
|
|
36
|
+
console.log(`Done ✅`);
|
|
37
37
|
process.exit()
|
|
38
38
|
}
|
package/src/app/set.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getType } from 'mime';
|
|
2
|
+
import { program } from "commander";
|
|
3
|
+
import { randomUUID } from "crypto";
|
|
4
|
+
import { existsSync, readFileSync } from "fs-extra";
|
|
5
|
+
import { checkAppExistsAndHasPermission, newIconPath, Options } from '../api/app';
|
|
6
|
+
import { createSupabaseClient, findSavedKey, formatError, getConfig, verifyUser } from "../utils";
|
|
7
|
+
|
|
8
|
+
export const setApp = async (appId: string, userId: string, options: Options) => {
|
|
9
|
+
options.apikey = options.apikey || findSavedKey() || ''
|
|
10
|
+
const config = await getConfig();
|
|
11
|
+
appId = appId || config?.app?.appId
|
|
12
|
+
|
|
13
|
+
if (!options.apikey) {
|
|
14
|
+
program.error("Missing API key, you need to provide a API key to upload your bundle");
|
|
15
|
+
}
|
|
16
|
+
if (!appId) {
|
|
17
|
+
program.error("Missing argument, you need to provide a appId, or be in a capacitor project");
|
|
18
|
+
}
|
|
19
|
+
const supabase = createSupabaseClient(options.apikey)
|
|
20
|
+
|
|
21
|
+
await verifyUser(supabase, options.apikey, ['write', 'all']);
|
|
22
|
+
// Check we have app access to this appId
|
|
23
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
24
|
+
|
|
25
|
+
const { name, icon } = options;
|
|
26
|
+
|
|
27
|
+
let iconBuff;
|
|
28
|
+
let iconType;
|
|
29
|
+
const fileName = `icon_${randomUUID()}`
|
|
30
|
+
let signedURL = 'https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png'
|
|
31
|
+
|
|
32
|
+
if (icon && existsSync(icon)) {
|
|
33
|
+
iconBuff = readFileSync(icon);
|
|
34
|
+
const contentType = getType(icon);
|
|
35
|
+
iconType = contentType || 'image/png';
|
|
36
|
+
console.warn(`Found app icon ${icon}`);
|
|
37
|
+
}
|
|
38
|
+
else if (existsSync(newIconPath)) {
|
|
39
|
+
iconBuff = readFileSync(newIconPath);
|
|
40
|
+
const contentType = getType(newIconPath);
|
|
41
|
+
iconType = contentType || 'image/png';
|
|
42
|
+
console.warn(`Found app icon ${newIconPath}`);
|
|
43
|
+
} else {
|
|
44
|
+
console.warn(`Cannot find app icon in any of the following locations: ${icon}, ${newIconPath}`);
|
|
45
|
+
}
|
|
46
|
+
if (iconBuff && iconType) {
|
|
47
|
+
const { error } = await supabase.storage
|
|
48
|
+
.from(`images/${userId}/${appId}`)
|
|
49
|
+
.upload(fileName, iconBuff, {
|
|
50
|
+
contentType: iconType,
|
|
51
|
+
})
|
|
52
|
+
if (error) {
|
|
53
|
+
program.error(`Could not add app ${formatError(error)}`);
|
|
54
|
+
}
|
|
55
|
+
const { data: signedURLData } = await supabase
|
|
56
|
+
.storage
|
|
57
|
+
.from(`images/${userId}/${appId}`)
|
|
58
|
+
.getPublicUrl(fileName)
|
|
59
|
+
signedURL = signedURLData?.publicUrl || signedURL
|
|
60
|
+
}
|
|
61
|
+
const { error: dbError } = await supabase
|
|
62
|
+
.from('apps')
|
|
63
|
+
.update({
|
|
64
|
+
icon_url: signedURL,
|
|
65
|
+
name,
|
|
66
|
+
})
|
|
67
|
+
.eq('app_id', appId)
|
|
68
|
+
.eq('user_id', userId)
|
|
69
|
+
if (dbError) {
|
|
70
|
+
program.error(`Could not add app ${formatError(dbError)}`);
|
|
71
|
+
}
|
|
72
|
+
console.log(`Done ✅`);
|
|
73
|
+
process.exit()
|
|
74
|
+
}
|
|
@@ -3,13 +3,13 @@ import semver from 'semver/preload';
|
|
|
3
3
|
import promptSync from 'prompt-sync';
|
|
4
4
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
5
5
|
import { Database } from 'types/supabase.types';
|
|
6
|
-
import {
|
|
6
|
+
import { OptionsBase } from '../api/utils';
|
|
7
|
+
import { createSupabaseClient, findSavedKey, getConfig, getHumanDate, verifyUser } from '../utils';
|
|
7
8
|
import { deleteSpecificVersion, displayBundles, getActiveAppVersions } from '../api/versions';
|
|
8
9
|
import { checkAppExistsAndHasPermission } from '../api/app';
|
|
9
10
|
// import { definitions } from '../types/types_supabase';
|
|
10
11
|
|
|
11
|
-
interface Options {
|
|
12
|
-
apikey: string;
|
|
12
|
+
interface Options extends OptionsBase {
|
|
13
13
|
version: string;
|
|
14
14
|
bundle: string;
|
|
15
15
|
keep: number;
|
|
@@ -23,7 +23,7 @@ const removeVersions = async (toRemove: Database['public']['Tables']['app_versio
|
|
|
23
23
|
|
|
24
24
|
// call deleteSpecificVersion one by one from toRemove sync
|
|
25
25
|
for await (const row of toRemove) {
|
|
26
|
-
console.log(`Removing ${row.name} created on ${(getHumanDate(row))}`);
|
|
26
|
+
console.log(`Removing ${row.name} created on ${(getHumanDate(row.created_at))}`);
|
|
27
27
|
await deleteSpecificVersion(supabase, appid, userId, row.name);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -112,5 +112,6 @@ export const cleanupApp = async (appid: string, options: Options) => {
|
|
|
112
112
|
// Yes, lets clean it up
|
|
113
113
|
console.log("You have confirmed removal, removing versions now");
|
|
114
114
|
await removeVersions(toRemove, supabase, appid, userId);
|
|
115
|
+
console.log(`Done ✅`);
|
|
115
116
|
process.exit()
|
|
116
117
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { program } from 'commander'
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
|
3
3
|
import { decryptSource } from '../api/crypto';
|
|
4
|
-
import { baseKey, getConfig } from '
|
|
4
|
+
import { baseKey, getConfig } from '../utils';
|
|
5
5
|
|
|
6
6
|
interface Options {
|
|
7
7
|
key?: string
|
|
@@ -39,5 +39,6 @@ export const decryptZip = async (zipPath: string, ivsessionKey: string, options:
|
|
|
39
39
|
const decodedZip = decryptSource(zipFile, ivsessionKey, privateKey)
|
|
40
40
|
// write decodedZip in a file
|
|
41
41
|
writeFileSync(`${zipPath}_decrypted.zip`, decodedZip)
|
|
42
|
+
console.log(`Done ✅`);
|
|
42
43
|
process.exit()
|
|
43
44
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { program } from 'commander';
|
|
2
|
+
import { checkAppExistsAndHasPermission } from '../api/app';
|
|
3
|
+
import { OptionsBase } from '../api/utils';
|
|
4
|
+
import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils';
|
|
5
|
+
import { deleteSpecificVersion } from '../api/versions';
|
|
6
|
+
|
|
7
|
+
interface Options extends OptionsBase {
|
|
8
|
+
bundle: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const deleteVersion = async (appId: string, bundleId: string, options: Options) => {
|
|
12
|
+
options.apikey = options.apikey || findSavedKey() || ''
|
|
13
|
+
const config = await getConfig();
|
|
14
|
+
appId = appId || config?.app?.appId
|
|
15
|
+
|
|
16
|
+
if (!options.apikey) {
|
|
17
|
+
program.error("Missing API key, you need to provide a API key to upload your bundle");
|
|
18
|
+
}
|
|
19
|
+
if (!appId) {
|
|
20
|
+
program.error("Missing argument, you need to provide a appId, or be in a capacitor project");
|
|
21
|
+
}
|
|
22
|
+
const supabase = createSupabaseClient(options.apikey)
|
|
23
|
+
|
|
24
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all']);
|
|
25
|
+
// Check we have app access to this appId
|
|
26
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
27
|
+
|
|
28
|
+
const apikey = options.apikey || findSavedKey()
|
|
29
|
+
|
|
30
|
+
appId = appId || config?.app?.appId
|
|
31
|
+
if (!apikey) {
|
|
32
|
+
program.error('Missing API key, you need to provide an API key to delete your app');
|
|
33
|
+
}
|
|
34
|
+
if (!bundleId) {
|
|
35
|
+
program.error('Missing argument, you need to provide a bundleId, or be in a capacitor project');
|
|
36
|
+
}
|
|
37
|
+
if (!appId) {
|
|
38
|
+
program.error('Missing argument, you need to provide a appId, or be in a capacitor project');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const { data: app, error: dbError0 } = await supabase
|
|
42
|
+
.rpc('exist_app', { appid: appId, apikey })
|
|
43
|
+
.single()
|
|
44
|
+
if (!app || dbError0) {
|
|
45
|
+
program.error('No permission to delete')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log(`Delete ${appId}@${bundleId} from Capgo`);
|
|
49
|
+
|
|
50
|
+
await deleteSpecificVersion(supabase, appId, userId, bundleId);
|
|
51
|
+
console.log(`${appId}@${bundleId} deleted from server`)
|
|
52
|
+
console.log(`Done ✅`);
|
|
53
|
+
process.exit()
|
|
54
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { program } from 'commander'
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
|
3
3
|
import { encryptSource } from '../api/crypto';
|
|
4
|
-
import { baseKeyPub } from '
|
|
4
|
+
import { baseKeyPub } from '../utils';
|
|
5
5
|
|
|
6
6
|
interface Options {
|
|
7
7
|
key?: string
|
|
@@ -33,5 +33,6 @@ export const encryptZip = async (zipPath: string, options: Options) => {
|
|
|
33
33
|
console.log('ivSessionKey', encodedZip.ivSessionKey)
|
|
34
34
|
// write decodedZip in a file
|
|
35
35
|
writeFileSync(`${zipPath}_encrypted.zip`, encodedZip.encryptedData)
|
|
36
|
+
console.log(`Done ✅`);
|
|
36
37
|
process.exit()
|
|
37
38
|
}
|
|
@@ -4,6 +4,7 @@ import { randomUUID } from 'crypto';
|
|
|
4
4
|
import cliProgress from 'cli-progress';
|
|
5
5
|
import { existsSync, readFileSync } from 'fs';
|
|
6
6
|
import { checksum as getChecksum } from '@tomasklaen/checksum';
|
|
7
|
+
import { OptionsBase } from '../api/utils';
|
|
7
8
|
import { checkAppExistsAndHasPermission } from "../api/app";
|
|
8
9
|
import { encryptSource } from '../api/crypto';
|
|
9
10
|
import {
|
|
@@ -11,20 +12,19 @@ import {
|
|
|
11
12
|
updateOrCreateChannel, updateOrCreateVersion,
|
|
12
13
|
formatError, findSavedKey, checkPlanValid,
|
|
13
14
|
useLogSnag, verifyUser, regexSemver, baseKeyPub, convertAppName
|
|
14
|
-
} from '
|
|
15
|
+
} from '../utils';
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
const alertMb = 20;
|
|
18
|
+
|
|
19
|
+
interface Options extends OptionsBase {
|
|
17
20
|
bundle: string
|
|
18
21
|
path: string
|
|
19
|
-
apikey: string
|
|
20
22
|
channel?: string
|
|
21
23
|
displayIvSession?: boolean
|
|
22
24
|
external?: string
|
|
23
25
|
key?: boolean | string
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
const alertMb = 20;
|
|
27
|
-
|
|
28
28
|
export const uploadVersion = async (appid: string, options: Options) => {
|
|
29
29
|
let { bundle, path, channel } = options;
|
|
30
30
|
const { external, key = false, displayIvSession } = options;
|
|
@@ -206,5 +206,6 @@ It will be also visible in your dashboard\n`);
|
|
|
206
206
|
},
|
|
207
207
|
notify: false,
|
|
208
208
|
}).catch()
|
|
209
|
+
console.log(`Done ✅`);
|
|
209
210
|
process.exit()
|
|
210
|
-
}
|
|
211
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { program } from "commander";
|
|
2
|
+
import { checkAppExistsAndHasPermission } from "../api/app";
|
|
3
|
+
import { createChannel, findUnknownVersion } from "../api/channels";
|
|
4
|
+
import { OptionsBase } from "../api/utils";
|
|
5
|
+
import { findSavedKey, getConfig, useLogSnag, createSupabaseClient, verifyUser } from "../utils";
|
|
6
|
+
|
|
7
|
+
export const addChannel = async (channelId: string, appId: string, options: OptionsBase) => {
|
|
8
|
+
options.apikey = options.apikey || findSavedKey() || ''
|
|
9
|
+
const config = await getConfig();
|
|
10
|
+
appId = appId || config?.app?.appId
|
|
11
|
+
const snag = useLogSnag()
|
|
12
|
+
|
|
13
|
+
if (!options.apikey) {
|
|
14
|
+
program.error("Missing API key, you need to provide a API key to upload your bundle");
|
|
15
|
+
}
|
|
16
|
+
if (!appId) {
|
|
17
|
+
program.error("Missing argument, you need to provide a appId, or be in a capacitor project");
|
|
18
|
+
}
|
|
19
|
+
const supabase = createSupabaseClient(options.apikey)
|
|
20
|
+
|
|
21
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all']);
|
|
22
|
+
// Check we have app access to this appId
|
|
23
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
24
|
+
|
|
25
|
+
console.log(`Create channel ${appId}#${channelId} to Capgo cloud`);
|
|
26
|
+
try {
|
|
27
|
+
const { data } = await findUnknownVersion(supabase, appId)
|
|
28
|
+
if (!data) {
|
|
29
|
+
program.error(`Cannot find default version for channel creation, please contact Capgo support 🤨`);
|
|
30
|
+
}
|
|
31
|
+
await createChannel(supabase, { name: channelId, app_id: appId, version: data.id, created_by: userId });
|
|
32
|
+
console.log(`Channel created ✅`);
|
|
33
|
+
await snag.publish({
|
|
34
|
+
channel: 'app',
|
|
35
|
+
event: 'Create channel',
|
|
36
|
+
icon: '✅',
|
|
37
|
+
tags: {
|
|
38
|
+
'user-id': userId,
|
|
39
|
+
'app-id': appId,
|
|
40
|
+
'channel': channelId,
|
|
41
|
+
},
|
|
42
|
+
notify: false,
|
|
43
|
+
}).catch()
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.log(`Cannot create Channel 🙀`, error);
|
|
46
|
+
}
|
|
47
|
+
console.log(`Done ✅`);
|
|
48
|
+
process.exit()
|
|
49
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { program } from "commander";
|
|
2
|
+
import { checkAppExistsAndHasPermission } from "../api/app";
|
|
3
|
+
import { delChannel } from "../api/channels";
|
|
4
|
+
import { OptionsBase } from "../api/utils";
|
|
5
|
+
import { findSavedKey, getConfig, useLogSnag, createSupabaseClient, verifyUser } from "../utils";
|
|
6
|
+
|
|
7
|
+
export const deleteChannel = async (channelId: string, appId: string, options: OptionsBase) => {
|
|
8
|
+
options.apikey = options.apikey || findSavedKey() || ''
|
|
9
|
+
const config = await getConfig();
|
|
10
|
+
appId = appId || config?.app?.appId
|
|
11
|
+
const snag = useLogSnag()
|
|
12
|
+
|
|
13
|
+
if (!options.apikey) {
|
|
14
|
+
program.error("Missing API key, you need to provide a API key to upload your bundle");
|
|
15
|
+
}
|
|
16
|
+
if (!appId) {
|
|
17
|
+
program.error("Missing argument, you need to provide a appId, or be in a capacitor project");
|
|
18
|
+
}
|
|
19
|
+
const supabase = createSupabaseClient(options.apikey)
|
|
20
|
+
|
|
21
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all']);
|
|
22
|
+
// Check we have app access to this appId
|
|
23
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
24
|
+
|
|
25
|
+
console.log(`Delete channel ${appId}#${channelId} to Capgo cloud`);
|
|
26
|
+
try {
|
|
27
|
+
await delChannel(supabase, channelId, appId, userId);
|
|
28
|
+
console.log(`Channel Delete ✅`);
|
|
29
|
+
await snag.publish({
|
|
30
|
+
channel: 'app',
|
|
31
|
+
event: 'Delete channel',
|
|
32
|
+
icon: '✅',
|
|
33
|
+
tags: {
|
|
34
|
+
'user-id': userId,
|
|
35
|
+
'app-id': appId,
|
|
36
|
+
'channel': channelId,
|
|
37
|
+
},
|
|
38
|
+
notify: false,
|
|
39
|
+
}).catch()
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.log(`Cannot delete Channel 🙀`, error);
|
|
42
|
+
}
|
|
43
|
+
console.log(`Done ✅`);
|
|
44
|
+
process.exit()
|
|
45
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { program } from 'commander';
|
|
2
|
+
import { checkAppExistsAndHasPermission } from '../api/app';
|
|
3
|
+
import { getActiveChannels, displayChannels } from '../api/channels';
|
|
4
|
+
import { OptionsBase } from '../api/utils';
|
|
5
|
+
import { findSavedKey, getConfig, createSupabaseClient, verifyUser } from '../utils';
|
|
6
|
+
|
|
7
|
+
export const listChannels = async (appId: string, options: OptionsBase) => {
|
|
8
|
+
options.apikey = options.apikey || findSavedKey() || ''
|
|
9
|
+
const config = await getConfig();
|
|
10
|
+
appId = appId || config?.app?.appId
|
|
11
|
+
|
|
12
|
+
if (!options.apikey) {
|
|
13
|
+
program.error("Missing API key, you need to provide a API key to upload your bundle");
|
|
14
|
+
}
|
|
15
|
+
if (!appId) {
|
|
16
|
+
program.error("Missing argument, you need to provide a appId, or be in a capacitor project");
|
|
17
|
+
}
|
|
18
|
+
const supabase = createSupabaseClient(options.apikey)
|
|
19
|
+
|
|
20
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all']);
|
|
21
|
+
// Check we have app access to this appId
|
|
22
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
23
|
+
|
|
24
|
+
console.log(`Querying available versions in Capgo`);
|
|
25
|
+
|
|
26
|
+
// Check we have app access to this appId
|
|
27
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
28
|
+
|
|
29
|
+
// Get all active app versions we might possibly be able to cleanup
|
|
30
|
+
const allVersions = await getActiveChannels(supabase, appId, userId);
|
|
31
|
+
|
|
32
|
+
console.log(`Active channels in Capgo: ${allVersions?.length}`);
|
|
33
|
+
|
|
34
|
+
displayChannels(allVersions);
|
|
35
|
+
console.log(`Done ✅`);
|
|
36
|
+
process.exit()
|
|
37
|
+
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { program } from 'commander';
|
|
2
|
-
import LogSnag from 'logsnag';
|
|
3
2
|
import { Database } from 'types/supabase.types';
|
|
3
|
+
import { OptionsBase } from '../api/utils';
|
|
4
4
|
import { checkAppExistsAndHasPermission } from "../api/app";
|
|
5
5
|
import {
|
|
6
6
|
getConfig, createSupabaseClient, updateOrCreateChannel,
|
|
7
7
|
formatError, findSavedKey, checkPlanValid, useLogSnag, verifyUser
|
|
8
|
-
} from '
|
|
8
|
+
} from '../utils';
|
|
9
9
|
// import { definitions } from '../types/types_supabase';
|
|
10
10
|
|
|
11
|
-
interface Options {
|
|
12
|
-
apikey: string;
|
|
11
|
+
interface Options extends OptionsBase {
|
|
13
12
|
bundle: string;
|
|
14
13
|
state?: string;
|
|
15
14
|
downgrade?: boolean;
|
|
@@ -21,7 +20,24 @@ interface Options {
|
|
|
21
20
|
channel?: string;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
export const
|
|
23
|
+
export const setChannel = async (appId: string, options: Options) => {
|
|
24
|
+
options.apikey = options.apikey || findSavedKey() || ''
|
|
25
|
+
const config = await getConfig();
|
|
26
|
+
appId = appId || config?.app?.appId
|
|
27
|
+
const snag = useLogSnag()
|
|
28
|
+
|
|
29
|
+
if (!options.apikey) {
|
|
30
|
+
program.error("Missing API key, you need to provide a API key to upload your bundle");
|
|
31
|
+
}
|
|
32
|
+
if (!appId) {
|
|
33
|
+
program.error("Missing argument, you need to provide a appId, or be in a capacitor project");
|
|
34
|
+
}
|
|
35
|
+
const supabase = createSupabaseClient(options.apikey)
|
|
36
|
+
|
|
37
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all']);
|
|
38
|
+
// Check we have app access to this appId
|
|
39
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
40
|
+
|
|
25
41
|
const { bundle, latest, downgrade, upgrade, ios, android, selfAssign, channel, state } = options;
|
|
26
42
|
if (!channel) {
|
|
27
43
|
program.error("Missing argument, you need to provide a channel");
|
|
@@ -40,61 +56,59 @@ export const setChannelInternal = async (appid: string, apikey: string, defaulVe
|
|
|
40
56
|
program.error("Missing argument, you need to provide a option to set");
|
|
41
57
|
}
|
|
42
58
|
try {
|
|
43
|
-
const supabase = createSupabaseClient(apikey)
|
|
44
|
-
const userId = await verifyUser(supabase, apikey, ['write', 'all']);
|
|
45
59
|
await checkPlanValid(supabase, userId)
|
|
46
60
|
// Check we have app access to this appId
|
|
47
|
-
await checkAppExistsAndHasPermission(supabase,
|
|
61
|
+
await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
|
|
48
62
|
const channelPayload: Database['public']['Tables']['channels']['Insert'] = {
|
|
49
63
|
created_by: userId,
|
|
50
|
-
app_id:
|
|
64
|
+
app_id: appId,
|
|
51
65
|
name: channel,
|
|
52
66
|
version: undefined as any,
|
|
53
67
|
}
|
|
54
|
-
const bundleVersion = latest ?
|
|
68
|
+
const bundleVersion = latest ? config?.app?.package?.version : bundle
|
|
55
69
|
if (bundleVersion != null) {
|
|
56
70
|
const { data, error: vError } = await supabase
|
|
57
71
|
.from('app_versions')
|
|
58
72
|
.select()
|
|
59
|
-
.eq('app_id',
|
|
73
|
+
.eq('app_id', appId)
|
|
60
74
|
.eq('name', bundleVersion)
|
|
61
75
|
.eq('user_id', userId)
|
|
62
76
|
.eq('deleted', false)
|
|
63
77
|
.single()
|
|
64
78
|
if (vError || !data)
|
|
65
79
|
program.error(`Cannot find version ${bundleVersion}`);
|
|
66
|
-
console.log(`Set ${
|
|
80
|
+
console.log(`Set ${appId} channel: ${channel} to @${bundleVersion}`);
|
|
67
81
|
channelPayload.version = data.id
|
|
68
82
|
}
|
|
69
83
|
if (state != null) {
|
|
70
84
|
if (state === 'public' || state === 'private') {
|
|
71
|
-
console.log(`Set ${
|
|
85
|
+
console.log(`Set ${appId} channel: ${channel} to public or private is deprecated, use default or normal instead`);
|
|
72
86
|
}
|
|
73
|
-
console.log(`Set ${
|
|
87
|
+
console.log(`Set ${appId} channel: ${channel} to ${state === 'public' || state === 'default' ? 'default' : 'normal'}`);
|
|
74
88
|
channelPayload.public = state === 'public' || state === 'default'
|
|
75
89
|
}
|
|
76
90
|
if (downgrade != null) {
|
|
77
|
-
console.log(`Set ${
|
|
91
|
+
console.log(`Set ${appId} channel: ${channel} to ${downgrade ? 'allow' : 'disallow'} downgrade`);
|
|
78
92
|
channelPayload.disableAutoUpdateUnderNative = !downgrade
|
|
79
93
|
}
|
|
80
94
|
if (upgrade != null) {
|
|
81
|
-
console.log(`Set ${
|
|
95
|
+
console.log(`Set ${appId} channel: ${channel} to ${upgrade ? 'allow' : 'disallow'} upgrade`);
|
|
82
96
|
channelPayload.disableAutoUpdateToMajor = !upgrade
|
|
83
97
|
}
|
|
84
98
|
if (ios != null) {
|
|
85
|
-
console.log(`Set ${
|
|
99
|
+
console.log(`Set ${appId} channel: ${channel} to ${ios ? 'allow' : 'disallow'} ios update`);
|
|
86
100
|
channelPayload.ios = !!ios
|
|
87
101
|
}
|
|
88
102
|
if (android != null) {
|
|
89
|
-
console.log(`Set ${
|
|
103
|
+
console.log(`Set ${appId} channel: ${channel} to ${android ? 'allow' : 'disallow'} android update`);
|
|
90
104
|
channelPayload.android = !!android
|
|
91
105
|
}
|
|
92
106
|
if (selfAssign != null) {
|
|
93
|
-
console.log(`Set ${
|
|
107
|
+
console.log(`Set ${appId} channel: ${channel} to ${selfAssign ? 'allow' : 'disallow'} self assign to this channel`);
|
|
94
108
|
channelPayload.allow_device_self_set = !!selfAssign
|
|
95
109
|
}
|
|
96
110
|
try {
|
|
97
|
-
const { error: dbError } = await updateOrCreateChannel(supabase, channelPayload, apikey)
|
|
111
|
+
const { error: dbError } = await updateOrCreateChannel(supabase, channelPayload, options.apikey)
|
|
98
112
|
if (dbError)
|
|
99
113
|
program.error(`Cannot set channel ${formatError(dbError)}`);
|
|
100
114
|
}
|
|
@@ -107,7 +121,7 @@ export const setChannelInternal = async (appid: string, apikey: string, defaulVe
|
|
|
107
121
|
icon: '✅',
|
|
108
122
|
tags: {
|
|
109
123
|
'user-id': userId,
|
|
110
|
-
'app-id':
|
|
124
|
+
'app-id': appId,
|
|
111
125
|
},
|
|
112
126
|
notify: false,
|
|
113
127
|
}).catch()
|
|
@@ -115,21 +129,5 @@ export const setChannelInternal = async (appid: string, apikey: string, defaulVe
|
|
|
115
129
|
program.error(`Unknow error ${formatError(err)}`);
|
|
116
130
|
}
|
|
117
131
|
console.log(`Done ✅`);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export const setChannel = async (appid: string, options: Options) => {
|
|
121
|
-
const apikey = options.apikey || findSavedKey()
|
|
122
|
-
const config = await getConfig()
|
|
123
|
-
const snag = useLogSnag()
|
|
124
|
-
|
|
125
|
-
console.log('COMMAND DEPRECATED, use "channel set" instead')
|
|
126
|
-
appid = appid || config?.app?.appId
|
|
127
|
-
if (!apikey) {
|
|
128
|
-
program.error("Missing API key, you need to provide a API key to set your app");
|
|
129
|
-
}
|
|
130
|
-
if (!appid) {
|
|
131
|
-
program.error("Missing argument, you need to provide a appid, or be in a capacitor project");
|
|
132
|
-
}
|
|
133
|
-
return setChannelInternal(appid, apikey, config?.app?.package?.version, snag, options)
|
|
134
132
|
process.exit()
|
|
135
|
-
}
|
|
133
|
+
}
|