@capgo/cli 2.2.10 → 2.3.5

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/src/bin/delete.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { program } from 'commander';
2
2
  import { createSupabaseClient, findSavedKey, formatError, getConfig, useLogSnag, verifyUser } from './utils';
3
- import { definitions } from '../types/types_supabase';
3
+ // import { definitions } from '../types/types_supabase';
4
4
  import { deleteSpecificVersion } from '../api/versions';
5
5
 
6
6
  interface Options {
@@ -27,7 +27,8 @@ export const deleteApp = async (appid: string, options: Options) => {
27
27
  const userId = await verifyUser(supabase, apikey);
28
28
 
29
29
  const { data: app, error: dbError0 } = await supabase
30
- .rpc<string>('exist_app', { appid, apikey })
30
+ .rpc('exist_app', { appid, apikey })
31
+ .single()
31
32
  if (!app || dbError0) {
32
33
  program.error('No permission to delete')
33
34
  }
@@ -42,7 +43,7 @@ export const deleteApp = async (appid: string, options: Options) => {
42
43
 
43
44
  console.log(`Delete ${appid} from Capgo`);
44
45
  const { data, error: vError } = await supabase
45
- .from<definitions['app_versions']>('app_versions')
46
+ .from('app_versions')
46
47
  .select()
47
48
  .eq('app_id', appid)
48
49
  .eq('user_id', userId)
@@ -63,7 +64,7 @@ export const deleteApp = async (appid: string, options: Options) => {
63
64
  }
64
65
 
65
66
  const { error: delAppVersionError } = await supabase
66
- .from<definitions['app_versions']>('app_versions')
67
+ .from('app_versions')
67
68
  .delete()
68
69
  .eq('app_id', appid)
69
70
  .eq('user_id', userId)
@@ -73,7 +74,7 @@ export const deleteApp = async (appid: string, options: Options) => {
73
74
  }
74
75
 
75
76
  const { error: dbAppError } = await supabase
76
- .from<definitions['apps']>('apps')
77
+ .from('apps')
77
78
  .delete()
78
79
  .eq('app_id', appid)
79
80
  .eq('user_id', userId)
package/src/bin/index.ts CHANGED
@@ -86,7 +86,7 @@ program
86
86
  .alias('c')
87
87
  .description('Cleanup versions in capgo Cloud')
88
88
  .action(cleanupApp)
89
- .requiredOption('-b, --bundle <bundle>', 'bundle version number of the app to delete')
89
+ .option('-b, --bundle <bundle>', 'bundle version number of the app to delete')
90
90
  .option('-a, --apikey <apikey>', 'apikey to link to your account')
91
91
  .option('-k, --keep <keep>', 'number of version to keep')
92
92
  .option('-f, --force', 'force removal');
package/src/bin/list.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { program } from 'commander';
2
- import { createSupabaseClient, findSavedKey, getConfig, getHumanDate, verifyUser } from './utils';
2
+ import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from './utils';
3
3
  import { checkAppExistsAndHasPermission } from '../api/app';
4
- import { getActiveAppVersions } from '../api/versions';
4
+ import { displayBundles, getActiveAppVersions } from '../api/versions';
5
5
 
6
6
  interface Options {
7
7
  apikey: string;
@@ -29,13 +29,10 @@ export const listApp = async (appid: string, options: Options) => {
29
29
  await checkAppExistsAndHasPermission(supabase, appid, apikey);
30
30
 
31
31
  // Get all active app versions we might possibly be able to cleanup
32
- const data = await getActiveAppVersions(supabase, appid, userId);
32
+ const allVersions = await getActiveAppVersions(supabase, appid, userId);
33
33
 
34
- console.log(`Active versions in Capgo: ${data?.length}`);
34
+ console.log(`Active versions in Capgo: ${allVersions?.length}`);
35
35
 
36
- data?.forEach(row => {
37
- // convert created_at to human time
38
- console.log(`${row.name} created on ${(getHumanDate(row))}`);
39
- });
36
+ displayBundles(allVersions);
40
37
 
41
38
  }
package/src/bin/set.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { program } from 'commander';
2
+ import { Database } from 'types/supabase.types';
2
3
  import {
3
4
  getConfig, createSupabaseClient, updateOrCreateChannel,
4
5
  formatError, findSavedKey, checkPlanValid, useLogSnag, verifyUser
5
6
  } from './utils';
6
- import { definitions } from '../types/types_supabase';
7
+ // import { definitions } from '../types/types_supabase';
7
8
 
8
9
  interface Options {
9
10
  apikey: string;
@@ -48,7 +49,7 @@ export const setChannel = async (appid: string, options: Options) => {
48
49
  const supabase = createSupabaseClient(apikey)
49
50
  const userId = await verifyUser(supabase, apikey, ['write', 'all']);
50
51
  await checkPlanValid(supabase, userId)
51
- const channelPayload: Partial<definitions['channels']> = {
52
+ const channelPayload: Partial<Database['public']['Tables']['channels']['Row']> = {
52
53
  created_by: userId,
53
54
  app_id: appid,
54
55
  name: channel,
@@ -56,7 +57,7 @@ export const setChannel = async (appid: string, options: Options) => {
56
57
  const bundleVersion = latest ? config?.app?.package?.version : bundle
57
58
  if (bundleVersion) {
58
59
  const { data, error: vError } = await supabase
59
- .from<definitions['app_versions']>('app_versions')
60
+ .from('app_versions')
60
61
  .select()
61
62
  .eq('app_id', appid)
62
63
  .eq('name', bundleVersion)
package/src/bin/upload.ts CHANGED
@@ -7,7 +7,9 @@ import { checksum as getChecksum } from '@tomasklaen/checksum';
7
7
  import { encryptSource } from '../api/crypto';
8
8
  import {
9
9
  host, hostWeb, getConfig, createSupabaseClient,
10
- updateOrCreateChannel, updateOrCreateVersion, formatError, findSavedKey, checkPlanValid, useLogSnag, verifyUser, regexSemver, baseKeyPub
10
+ updateOrCreateChannel, updateOrCreateVersion,
11
+ formatError, findSavedKey, checkPlanValid,
12
+ useLogSnag, verifyUser, regexSemver, baseKeyPub, convertAppName
11
13
  } from './utils';
12
14
 
13
15
  interface Options {
@@ -63,6 +65,7 @@ export const uploadVersion = async (appid: string, options: Options) => {
63
65
  // checking if user has access rights before uploading
64
66
  const { data: versionExist, error: versionExistError } = await supabase
65
67
  .rpc('exist_app_versions', { apikey, name_version: bundle, appid })
68
+ .single()
66
69
 
67
70
  if (versionExist || versionExistError) {
68
71
  multibar.stop()
@@ -70,7 +73,7 @@ export const uploadVersion = async (appid: string, options: Options) => {
70
73
  }
71
74
  b1.increment();
72
75
  const { data: isTrial, error: isTrialsError } = await supabase
73
- .rpc<number>('is_trial', { userid: userId })
76
+ .rpc('is_trial', { userid: userId })
74
77
  .single()
75
78
  if (isTrial && isTrial > 0 || isTrialsError) {
76
79
  multibar.log(`WARNING !!\nTrial expires in ${isTrial} days, upgrade here: ${hostWeb}/dashboard/settings/plans\n`);
@@ -78,7 +81,9 @@ export const uploadVersion = async (appid: string, options: Options) => {
78
81
  b1.increment();
79
82
 
80
83
  const { data: app, error: appError } = await supabase
81
- .rpc<string>('exist_app', { appid, apikey })
84
+ .rpc('exist_app', { appid, apikey })
85
+ .single()
86
+
82
87
  if (!app || appError) {
83
88
  multibar.stop()
84
89
  program.error(`Cannot find app ${appid} in your account \n${formatError(appError)}`)
@@ -86,7 +91,9 @@ export const uploadVersion = async (appid: string, options: Options) => {
86
91
  b1.increment();
87
92
  // check if app already exist
88
93
  const { data: appVersion, error: appVersionError } = await supabase
89
- .rpc<string>('exist_app_versions', { appid, apikey, name_version: bundle })
94
+ .rpc('exist_app_versions', { appid, apikey, name_version: bundle })
95
+ .single()
96
+
90
97
  if (appVersion || appVersionError) {
91
98
  program.error(`Version already exists ${formatError(appVersionError)}`)
92
99
  }
@@ -171,7 +178,7 @@ export const uploadVersion = async (appid: string, options: Options) => {
171
178
  multibar.log('Cannot set bundle with upload key, use key with more rights for that\n');
172
179
  }
173
180
  multibar.stop()
174
- const appidWeb = appid.replace(/\./g, '--')
181
+ const appidWeb = convertAppName(appid)
175
182
  console.log("App uploaded to server")
176
183
  console.log(`Try it in mobile app: ${host}/app_mobile`)
177
184
  console.log(`Or set the channel ${channel} as public here: ${hostWeb}/app/package/${appidWeb}`)
package/src/bin/utils.ts CHANGED
@@ -5,7 +5,7 @@ import prettyjson from 'prettyjson';
5
5
  import { existsSync, readFileSync } from 'fs';
6
6
  import { homedir } from 'os';
7
7
  import { LogSnag } from 'logsnag';
8
- import { definitions } from '../types/types_supabase';
8
+ import { Database } from 'types/supabase.types';
9
9
 
10
10
  export const baseKey = '.capgo_key';
11
11
  export const baseKeyPub = `${baseKey}.pub`;
@@ -23,9 +23,11 @@ export const supaAnon = process.env.SUPA_DB === 'production'
23
23
  : 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImF1Y3N5YnZuaGF2b2dkbXp3dGN3Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTQ1Mzk1MDYsImV4cCI6MTk3MDExNTUwNn0.HyuZmo_EjF5fgZQU3g37bdNardK1CLHgxXmYqtr59bo'
24
24
  /* eslint-enable */
25
25
 
26
- export const createSupabaseClient = (apikey: string) => createClient(hostSupa, supaAnon, {
27
- headers: {
28
- capgkey: apikey,
26
+ export const createSupabaseClient = (apikey: string) => createClient<Database>(hostSupa, supaAnon, {
27
+ global: {
28
+ headers: {
29
+ capgkey: apikey,
30
+ }
29
31
  }
30
32
  })
31
33
  // eslint-disable-next-line max-len
@@ -34,6 +36,7 @@ export const regexSemver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[
34
36
  export const checkKey = async (supabase: SupabaseClient, apikey: string, keymode: string[]) => {
35
37
  const { data: apiAccess, error: apiAccessError } = await supabase
36
38
  .rpc('is_allowed_capgkey', { apikey, keymode })
39
+ .single()
37
40
 
38
41
  if (!apiAccess || apiAccessError) {
39
42
  program.error(`Invalid API key or insufficient permissions ${formatError(apiAccessError)}`);
@@ -42,7 +45,7 @@ export const checkKey = async (supabase: SupabaseClient, apikey: string, keymode
42
45
 
43
46
  export const isGoodPlan = async (supabase: SupabaseClient, userId: string): Promise<boolean> => {
44
47
  const { data, error } = await supabase
45
- .rpc<boolean>('is_good_plan_v2', { userid: userId })
48
+ .rpc('is_good_plan_v2', { userid: userId })
46
49
  .single()
47
50
  if (error) {
48
51
  throw error
@@ -52,7 +55,7 @@ export const isGoodPlan = async (supabase: SupabaseClient, userId: string): Prom
52
55
 
53
56
  export const isPaying = async (supabase: SupabaseClient, userId: string): Promise<boolean> => {
54
57
  const { data, error } = await supabase
55
- .rpc<boolean>('is_paying', { userid: userId })
58
+ .rpc('is_paying', { userid: userId })
56
59
  .single()
57
60
  if (error) {
58
61
  throw error
@@ -62,7 +65,7 @@ export const isPaying = async (supabase: SupabaseClient, userId: string): Promis
62
65
 
63
66
  export const isTrial = async (supabase: SupabaseClient, userId: string): Promise<number> => {
64
67
  const { data, error } = await supabase
65
- .rpc<number>('is_trial', { userid: userId })
68
+ .rpc('is_trial', { userid: userId })
66
69
  .single()
67
70
  if (error) {
68
71
  throw error
@@ -72,7 +75,7 @@ export const isTrial = async (supabase: SupabaseClient, userId: string): Promise
72
75
 
73
76
  export const isAllowedAction = async (supabase: SupabaseClient, userId: string): Promise<boolean> => {
74
77
  const { data, error } = await supabase
75
- .rpc<boolean>('is_allowed_action_user', { userid: userId })
78
+ .rpc('is_allowed_action_user', { userid: userId })
76
79
  .single()
77
80
  if (error) {
78
81
  throw error
@@ -96,11 +99,13 @@ export const findSavedKey = () => {
96
99
  const userHomeDir = homedir();
97
100
  let keyPath = `${userHomeDir}/.capgo`;
98
101
  if (existsSync(keyPath)) {
102
+ console.log(`Use global apy key ${keyPath}`)
99
103
  const key = readFileSync(keyPath, 'utf8');
100
104
  return key.trim();
101
105
  }
102
106
  keyPath = `.capgo`;
103
107
  if (existsSync(keyPath)) {
108
+ console.log(`Use local apy key ${keyPath}`)
104
109
  const key = readFileSync(keyPath, 'utf8');
105
110
  return key.trim();
106
111
  }
@@ -131,47 +136,59 @@ export const getConfig = async () => {
131
136
  return config;
132
137
  }
133
138
 
134
- export const updateOrCreateVersion = async (supabase: SupabaseClient, update: Partial<definitions['app_versions']>, apikey: string) => {
139
+ export const updateOrCreateVersion = async (supabase: SupabaseClient,
140
+ update: Partial<Database['public']['Tables']['app_versions']['Row']>, apikey: string) => {
135
141
  // console.log('updateOrCreateVersion', update, apikey)
136
142
  const { data, error } = await supabase
137
- .rpc<string>('exist_app_versions', { appid: update.app_id, name_version: update.name, apikey })
143
+ .rpc('exist_app_versions', { appid: update.app_id, name_version: update.name, apikey })
144
+ .single()
145
+
138
146
  if (data && !error) {
139
147
  update.deleted = false
140
148
  return supabase
141
- .from<definitions['app_versions']>('app_versions')
149
+ .from('app_versions')
142
150
  .update(update)
143
151
  .eq('app_id', update.app_id)
144
152
  .eq('name', update.name)
153
+ .single()
145
154
  }
146
155
  // console.log('create Version', data, error)
147
156
 
148
157
  return supabase
149
- .from<definitions['app_versions']>('app_versions')
158
+ .from('app_versions')
150
159
  .insert(update)
151
-
160
+ .select()
161
+ .single()
152
162
  }
153
163
 
154
- export const updateOrCreateChannel = async (supabase: SupabaseClient, update: Partial<definitions['channels']>, apikey: string) => {
164
+ export const updateOrCreateChannel = async (supabase: SupabaseClient,
165
+ update: Partial<Database['public']['Tables']['channels']['Row']>, apikey: string) => {
155
166
  // console.log('updateOrCreateChannel', update)
156
167
  if (!update.app_id || !update.name || !update.created_by) {
157
168
  console.error('missing app_id, name, or created_by')
158
169
  return Promise.reject(new Error('missing app_id, name, or created_by'))
159
170
  }
160
171
  const { data, error } = await supabase
161
- .rpc<string>('exist_channel', { appid: update.app_id, name_channel: update.name, apikey })
172
+ .rpc('exist_channel', { appid: update.app_id, name_channel: update.name, apikey })
173
+ .single()
174
+
162
175
  if (data && !error) {
163
176
  return supabase
164
- .from<definitions['channels']>('channels')
165
- .update(update, { returning: "minimal" })
177
+ .from('channels')
178
+ .update(update)
166
179
  .eq('app_id', update.app_id)
167
180
  .eq('name', update.name)
168
181
  .eq('created_by', update.created_by)
182
+ .single()
183
+
169
184
  }
170
185
  // console.log('create Channel', data, error)
171
186
 
172
187
  return supabase
173
- .from<definitions['channels']>('channels')
174
- .insert(update, { returning: "minimal" })
188
+ .from('channels')
189
+ .insert(update)
190
+ .select()
191
+ .single()
175
192
  }
176
193
 
177
194
  export const useLogSnag = (): LogSnag => {
@@ -182,11 +199,13 @@ export const useLogSnag = (): LogSnag => {
182
199
  return logsnag
183
200
  }
184
201
 
202
+ export const convertAppName = (appName: string) => appName.replace(/\./g, '--')
185
203
  export const verifyUser = async (supabase: SupabaseClient, apikey: string, keymod: string[] = ['all']) => {
186
204
  await checkKey(supabase, apikey, keymod);
187
205
 
188
206
  const { data: dataUser, error: userIdError } = await supabase
189
- .rpc<string>('get_user_id', { apikey });
207
+ .rpc('get_user_id', { apikey })
208
+ .single();
190
209
 
191
210
  const userId = dataUser ? dataUser.toString() : '';
192
211
 
@@ -196,7 +215,7 @@ export const verifyUser = async (supabase: SupabaseClient, apikey: string, keymo
196
215
  return userId;
197
216
  }
198
217
 
199
- export const getHumanDate = (row: definitions["app_versions"]) => {
218
+ export const getHumanDate = (row: Database['public']['Tables']['app_versions']['Row']) => {
200
219
  const date = new Date(row.created_at || '');
201
220
  return date.toLocaleString();
202
221
  }