@capgo/cli 2.5.10-alpha.0 → 2.5.11

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.
@@ -1,14 +1,15 @@
1
1
  import { program } from 'commander';
2
+ import LogSnag from 'logsnag';
2
3
  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 '../utils';
8
+ } from './utils';
9
9
  // import { definitions } from '../types/types_supabase';
10
10
 
11
- interface Options extends OptionsBase {
11
+ interface Options {
12
+ apikey: string;
12
13
  bundle: string;
13
14
  state?: string;
14
15
  downgrade?: boolean;
@@ -20,24 +21,7 @@ interface Options extends OptionsBase {
20
21
  channel?: string;
21
22
  }
22
23
 
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
-
24
+ export const setChannelInternal = async (appid: string, apikey: string, defaulVersion: string, snag: LogSnag, options: Options) => {
41
25
  const { bundle, latest, downgrade, upgrade, ios, android, selfAssign, channel, state } = options;
42
26
  if (!channel) {
43
27
  program.error("Missing argument, you need to provide a channel");
@@ -56,59 +40,61 @@ export const setChannel = async (appId: string, options: Options) => {
56
40
  program.error("Missing argument, you need to provide a option to set");
57
41
  }
58
42
  try {
43
+ const supabase = createSupabaseClient(apikey)
44
+ const userId = await verifyUser(supabase, apikey, ['write', 'all']);
59
45
  await checkPlanValid(supabase, userId)
60
46
  // Check we have app access to this appId
61
- await checkAppExistsAndHasPermission(supabase, appId, options.apikey);
47
+ await checkAppExistsAndHasPermission(supabase, appid, apikey);
62
48
  const channelPayload: Database['public']['Tables']['channels']['Insert'] = {
63
49
  created_by: userId,
64
- app_id: appId,
50
+ app_id: appid,
65
51
  name: channel,
66
52
  version: undefined as any,
67
53
  }
68
- const bundleVersion = latest ? config?.app?.package?.version : bundle
54
+ const bundleVersion = latest ? defaulVersion : bundle
69
55
  if (bundleVersion != null) {
70
56
  const { data, error: vError } = await supabase
71
57
  .from('app_versions')
72
58
  .select()
73
- .eq('app_id', appId)
59
+ .eq('app_id', appid)
74
60
  .eq('name', bundleVersion)
75
61
  .eq('user_id', userId)
76
62
  .eq('deleted', false)
77
63
  .single()
78
64
  if (vError || !data)
79
65
  program.error(`Cannot find version ${bundleVersion}`);
80
- console.log(`Set ${appId} channel: ${channel} to @${bundleVersion}`);
66
+ console.log(`Set ${appid} channel: ${channel} to @${bundleVersion}`);
81
67
  channelPayload.version = data.id
82
68
  }
83
69
  if (state != null) {
84
70
  if (state === 'public' || state === 'private') {
85
- console.log(`Set ${appId} channel: ${channel} to public or private is deprecated, use default or normal instead`);
71
+ console.log(`Set ${appid} channel: ${channel} to public or private is deprecated, use default or normal instead`);
86
72
  }
87
- console.log(`Set ${appId} channel: ${channel} to ${state === 'public' || state === 'default' ? 'default' : 'normal'}`);
73
+ console.log(`Set ${appid} channel: ${channel} to ${state === 'public' || state === 'default' ? 'default' : 'normal'}`);
88
74
  channelPayload.public = state === 'public' || state === 'default'
89
75
  }
90
76
  if (downgrade != null) {
91
- console.log(`Set ${appId} channel: ${channel} to ${downgrade ? 'allow' : 'disallow'} downgrade`);
77
+ console.log(`Set ${appid} channel: ${channel} to ${downgrade ? 'allow' : 'disallow'} downgrade`);
92
78
  channelPayload.disableAutoUpdateUnderNative = !downgrade
93
79
  }
94
80
  if (upgrade != null) {
95
- console.log(`Set ${appId} channel: ${channel} to ${upgrade ? 'allow' : 'disallow'} upgrade`);
81
+ console.log(`Set ${appid} channel: ${channel} to ${upgrade ? 'allow' : 'disallow'} upgrade`);
96
82
  channelPayload.disableAutoUpdateToMajor = !upgrade
97
83
  }
98
84
  if (ios != null) {
99
- console.log(`Set ${appId} channel: ${channel} to ${ios ? 'allow' : 'disallow'} ios update`);
85
+ console.log(`Set ${appid} channel: ${channel} to ${ios ? 'allow' : 'disallow'} ios update`);
100
86
  channelPayload.ios = !!ios
101
87
  }
102
88
  if (android != null) {
103
- console.log(`Set ${appId} channel: ${channel} to ${android ? 'allow' : 'disallow'} android update`);
89
+ console.log(`Set ${appid} channel: ${channel} to ${android ? 'allow' : 'disallow'} android update`);
104
90
  channelPayload.android = !!android
105
91
  }
106
92
  if (selfAssign != null) {
107
- console.log(`Set ${appId} channel: ${channel} to ${selfAssign ? 'allow' : 'disallow'} self assign to this channel`);
93
+ console.log(`Set ${appid} channel: ${channel} to ${selfAssign ? 'allow' : 'disallow'} self assign to this channel`);
108
94
  channelPayload.allow_device_self_set = !!selfAssign
109
95
  }
110
96
  try {
111
- const { error: dbError } = await updateOrCreateChannel(supabase, channelPayload, options.apikey)
97
+ const { error: dbError } = await updateOrCreateChannel(supabase, channelPayload, apikey)
112
98
  if (dbError)
113
99
  program.error(`Cannot set channel ${formatError(dbError)}`);
114
100
  }
@@ -121,7 +107,7 @@ export const setChannel = async (appId: string, options: Options) => {
121
107
  icon: '✅',
122
108
  tags: {
123
109
  'user-id': userId,
124
- 'app-id': appId,
110
+ 'app-id': appid,
125
111
  },
126
112
  notify: false,
127
113
  }).catch()
@@ -129,5 +115,21 @@ export const setChannel = async (appId: string, options: Options) => {
129
115
  program.error(`Unknow error ${formatError(err)}`);
130
116
  }
131
117
  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)
132
134
  process.exit()
133
- }
135
+ }
@@ -4,7 +4,6 @@ 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';
8
7
  import { checkAppExistsAndHasPermission } from "../api/app";
9
8
  import { encryptSource } from '../api/crypto';
10
9
  import {
@@ -12,19 +11,20 @@ import {
12
11
  updateOrCreateChannel, updateOrCreateVersion,
13
12
  formatError, findSavedKey, checkPlanValid,
14
13
  useLogSnag, verifyUser, regexSemver, baseKeyPub, convertAppName
15
- } from '../utils';
14
+ } from './utils';
16
15
 
17
- const alertMb = 20;
18
-
19
- interface Options extends OptionsBase {
16
+ interface Options {
20
17
  bundle: string
21
18
  path: string
19
+ apikey: string
22
20
  channel?: string
23
21
  displayIvSession?: boolean
24
22
  external?: string
25
23
  key?: boolean | string
26
24
  }
27
25
 
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,6 +206,5 @@ It will be also visible in your dashboard\n`);
206
206
  },
207
207
  notify: false,
208
208
  }).catch()
209
- console.log(`Done ✅`);
210
209
  process.exit()
211
- }
210
+ }
@@ -217,7 +217,7 @@ export const verifyUser = async (supabase: SupabaseClient<Database>, apikey: str
217
217
  return userId;
218
218
  }
219
219
 
220
- export const getHumanDate = (createdA: string | null) => {
221
- const date = new Date(createdA || '');
220
+ export const getHumanDate = (row: Database['public']['Tables']['app_versions']['Row']) => {
221
+ const date = new Date(row.created_at || '');
222
222
  return date.toLocaleString();
223
223
  }
package/webpack.config.js CHANGED
@@ -6,7 +6,7 @@ module.exports = {
6
6
  mode: process.env.NODE_ENV || 'production',
7
7
  target: 'node',
8
8
  externals: [nodeExternals()],
9
- entry: './src/index.ts',
9
+ entry: './src/bin/index.ts',
10
10
  module: {
11
11
  rules: [
12
12
  {
package/src/api/utils.ts DELETED
@@ -1,4 +0,0 @@
1
-
2
- export interface OptionsBase {
3
- apikey: string;
4
- }
package/src/app/delete.ts DELETED
@@ -1,61 +0,0 @@
1
- import { program } from "commander";
2
- import { OptionsBase } from "../api/utils";
3
- import { checkAppExistsAndHasPermission } from '../api/app';
4
- import { createSupabaseClient, findSavedKey, formatError, getConfig, useLogSnag, verifyUser } from "../utils";
5
-
6
- export const deleteApp = async (appId: string, userId: string, options: OptionsBase) => {
7
- options.apikey = options.apikey || findSavedKey() || ''
8
- const config = await getConfig();
9
- appId = appId || config?.app?.appId
10
- const snag = useLogSnag()
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
- 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
- const { error } = await supabase
25
- .storage
26
- .from(`images/${userId}`)
27
- .remove([appId])
28
- if (error) {
29
- program.error(`Could not add app ${formatError(error)}`);
30
- }
31
- const { error: delError } = await supabase
32
- .storage
33
- .from(`apps/${appId}/${userId}`)
34
- .remove(['versions'])
35
- if (delError) {
36
- program.error(`Could not delete app version ${formatError(delError)}`);
37
- }
38
-
39
- const { error: dbError } = await supabase
40
- .from('apps')
41
- .delete()
42
- .eq('app_id', appId)
43
- .eq('user_id', userId)
44
-
45
- if (dbError) {
46
- program.error(`Could not delete app ${formatError(dbError)}`);
47
- }
48
- await snag.publish({
49
- channel: 'app',
50
- event: 'App Deleted',
51
- icon: '🗑️',
52
- tags: {
53
- 'user-id': userId,
54
- 'app-id': appId,
55
- },
56
- notify: false,
57
- }).catch()
58
- console.log("App deleted in Capgo")
59
- console.log(`Done ✅`);
60
- process.exit()
61
- }
package/src/app/set.ts DELETED
@@ -1,74 +0,0 @@
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
- }
@@ -1,54 +0,0 @@
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,49 +0,0 @@
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
- }
@@ -1,45 +0,0 @@
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
- }
@@ -1,37 +0,0 @@
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
- }