@capgo/cli 4.2.4 → 4.2.7

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/app/add.ts CHANGED
@@ -37,7 +37,7 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
37
37
  }
38
38
  const supabase = await createSupabaseClient(options.apikey)
39
39
 
40
- const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
40
+ let userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
41
41
 
42
42
  await checkPlanValid(supabase, userId, options.apikey, undefined, false)
43
43
 
@@ -51,6 +51,37 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
51
51
  return true
52
52
  }
53
53
 
54
+ const { error: orgError, data: allOrganizations } = await supabase
55
+ .rpc('get_orgs_v4')
56
+
57
+ if (orgError) {
58
+ p.log.error('Cannot get the list of organizations - exiting')
59
+ p.log.error(`Error ${JSON.stringify(orgError)}`)
60
+ program.error('')
61
+ }
62
+
63
+ const adminOrgs = allOrganizations.filter(org => org.role === 'admin' || org.role === 'super_admin')
64
+
65
+ const organizationUidRaw = (adminOrgs.length > 1)
66
+ ? await p.select({
67
+ message: 'Please pick the organization that you want to insert to',
68
+ options: adminOrgs.map((org) => {
69
+ return { value: org.gid, label: org.name }
70
+ }),
71
+ })
72
+ : adminOrgs[0].gid
73
+
74
+ if (p.isCancel(organizationUidRaw)) {
75
+ p.log.error('Canceled organization selection, exiting')
76
+ program.error('')
77
+ }
78
+
79
+ const organizationUid = organizationUidRaw as string
80
+ const organization = allOrganizations.find(org => org.gid === organizationUid)!
81
+ userId = organization.created_by
82
+
83
+ p.log.info(`Using the organization "${organization.name}" as the app owner`)
84
+
54
85
  let { name, icon } = options
55
86
  appId = appId || config?.app?.appId
56
87
  name = name || config?.app?.appName || 'Unknown'
@@ -106,7 +137,7 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
106
137
  .from('apps')
107
138
  .insert({
108
139
  icon_url: signedURL,
109
- user_id: userId,
140
+ owner_org: organizationUid,
110
141
  name,
111
142
  app_id: appId,
112
143
  })
@@ -117,12 +148,12 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
117
148
  const { error: dbVersionError } = await supabase
118
149
  .from('app_versions')
119
150
  .insert([{
120
- user_id: userId,
151
+ owner_org: organizationUid,
121
152
  deleted: true,
122
153
  name: 'unknown',
123
154
  app_id: appId,
124
155
  }, {
125
- user_id: userId,
156
+ owner_org: organizationUid,
126
157
  deleted: true,
127
158
  name: 'builtin',
128
159
  app_id: appId,
package/src/app/debug.ts CHANGED
@@ -4,9 +4,15 @@ import type { SupabaseClient } from '@supabase/supabase-js'
4
4
  import { program } from 'commander'
5
5
  import type LogSnag from 'logsnag'
6
6
  import type { Database } from '../types/supabase.types'
7
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
7
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
8
8
  import { checkLatest } from '../api/update'
9
- import { convertAppName, createSupabaseClient, findSavedKey, formatError, getConfig, getLocalConfig, useLogSnag, verifyUser, wait } from '../utils'
9
+ import { OrganizationPerm, convertAppName, createSupabaseClient, findSavedKey, formatError, getConfig, getLocalConfig, useLogSnag, verifyUser } from '../utils'
10
+
11
+ function wait(ms: number) {
12
+ return new Promise((resolve) => {
13
+ setTimeout(resolve, ms)
14
+ })
15
+ }
10
16
 
11
17
  export interface OptionsBaseDebug {
12
18
  apikey: string
@@ -194,7 +200,7 @@ export async function debugApp(appId: string, options: OptionsBaseDebug) {
194
200
  p.log.info(`Getting active bundle in Capgo`)
195
201
 
196
202
  // Check we have app access to this appId
197
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
203
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.admin)
198
204
 
199
205
  const doRun = await p.confirm({ message: `Automatic check if update working in device ?` })
200
206
  await cancelCommand('debug', doRun, userId, snag)
package/src/app/delete.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import process from 'node:process'
2
2
  import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
4
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import type { OptionsBase } from '../utils'
6
- import { createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
6
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, formatError, getConfig, useLogSnag, verifyUser } from '../utils'
7
7
 
8
8
  export async function deleteApp(appId: string, options: OptionsBase) {
9
9
  p.intro(`Deleting`)
@@ -24,7 +24,45 @@ export async function deleteApp(appId: string, options: OptionsBase) {
24
24
 
25
25
  const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
26
26
  // Check we have app access to this appId
27
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
27
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.super_admin)
28
+
29
+ const { data: appOwnerRaw, error: appOwnerError } = await supabase.from('apps')
30
+ .select(`owner_org ( created_by )`)
31
+ .eq('app_id', appId)
32
+ .single()
33
+
34
+ const appOwner = appOwnerRaw as { owner_org: { created_by: string } } | null
35
+
36
+ if (!appOwnerError && (appOwner?.owner_org.created_by ?? '') !== userId) {
37
+ // We are dealing with a member user that is not the owner
38
+ // Deleting the app is not recomended at this stage
39
+
40
+ p.log.warn('Deleting the app is not recomended for users that are not the organization owner')
41
+ p.log.warn('You are invited as a super_admin but your are not the owner')
42
+ p.log.warn('It\'s strongly recomended that you do not continue!')
43
+
44
+ const shouldContinue = await p.select({
45
+ message: 'Do you want to continue?',
46
+ options: [
47
+ {
48
+ label: 'Yes',
49
+ value: 'yes',
50
+ },
51
+ {
52
+ label: 'No',
53
+ value: 'no',
54
+ },
55
+ ],
56
+ })
57
+
58
+ if (p.isCancel(shouldContinue) || shouldContinue === 'no') {
59
+ p.log.error('Canceled deleting the app, exiting')
60
+ program.error('')
61
+ }
62
+ }
63
+ else if (appOwnerError) {
64
+ p.log.warn(`Cannot get the app owner ${formatError(appOwnerError)}`)
65
+ }
28
66
 
29
67
  const { error } = await supabase
30
68
  .storage
@@ -37,10 +75,10 @@ export async function deleteApp(appId: string, options: OptionsBase) {
37
75
  .storage
38
76
  .from(`apps/${appId}/${userId}`)
39
77
  .remove(['versions'])
40
- if (delError) {
78
+ if (delError)
41
79
  p.log.error('Could not delete app version')
42
- program.error('')
43
- }
80
+ // We should not care too much, most is in r2 anyways :/
81
+ // program.error('')
44
82
 
45
83
  const { error: dbError } = await supabase
46
84
  .from('apps')
package/src/app/set.ts CHANGED
@@ -5,8 +5,8 @@ import mime from 'mime'
5
5
  import { program } from 'commander'
6
6
  import * as p from '@clack/prompts'
7
7
  import type { Options } from '../api/app'
8
- import { checkAppExistsAndHasPermissionErr, newIconPath } from '../api/app'
9
- import { createSupabaseClient, findSavedKey, formatError, getConfig, verifyUser } from '../utils'
8
+ import { checkAppExistsAndHasPermissionOrgErr, newIconPath } from '../api/app'
9
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, formatError, getConfig, verifyUser } from '../utils'
10
10
 
11
11
  export async function setApp(appId: string, options: Options) {
12
12
  p.intro(`Set app`)
@@ -26,11 +26,11 @@ export async function setApp(appId: string, options: Options) {
26
26
 
27
27
  const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
28
28
  // Check we have app access to this appId
29
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
29
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.admin)
30
30
 
31
31
  const { name, icon, retention } = options
32
32
 
33
- if (retention && !Number.isNaN(Number(retention))) {
33
+ if (retention && Number.isNaN(Number(retention))) {
34
34
  p.log.error(`retention value must be a number`)
35
35
  program.error(``)
36
36
  }
@@ -6,9 +6,9 @@ import promptSync from 'prompt-sync'
6
6
  import type { SupabaseClient } from '@supabase/supabase-js'
7
7
  import type { Database } from '../types/supabase.types'
8
8
  import type { OptionsBase } from '../utils'
9
- import { createSupabaseClient, findSavedKey, getConfig, getHumanDate, verifyUser } from '../utils'
9
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, getHumanDate, verifyUser } from '../utils'
10
10
  import { deleteSpecificVersion, displayBundles, getActiveAppVersions, getChannelsVersion } from '../api/versions'
11
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
11
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
12
12
  import { checkLatest } from '../api/update'
13
13
 
14
14
  interface Options extends OptionsBase {
@@ -57,15 +57,14 @@ export async function cleanupBundle(appid: string, options: Options) {
57
57
  }
58
58
  const supabase = await createSupabaseClient(options.apikey)
59
59
 
60
- const userId = await verifyUser(supabase, options.apikey)
60
+ const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
61
61
 
62
62
  // Check we have app access to this appId
63
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appid)
63
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appid, OrganizationPerm.write)
64
64
  p.log.info(`Querying all available versions in Capgo`)
65
65
 
66
66
  // Get all active app versions we might possibly be able to cleanup
67
- let allVersions: (Database['public']['Tables']['app_versions']['Row'] & { keep?: string })[] = await
68
- getActiveAppVersions(supabase, appid, userId)
67
+ let allVersions: (Database['public']['Tables']['app_versions']['Row'] & { keep?: string })[] = await getActiveAppVersions(supabase, appid, userId)
69
68
 
70
69
  const versionInUse = await getChannelsVersion(supabase, appid)
71
70
 
@@ -2,8 +2,8 @@ import * as p from '@clack/prompts'
2
2
  import { program } from 'commander'
3
3
  import { Table } from 'console-table-printer'
4
4
  import type { OptionsBase } from '../utils'
5
- import { checkCompatibility, createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
6
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
5
+ import { OrganizationPerm, checkCompatibility, createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
6
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
7
7
 
8
8
  interface Options extends OptionsBase {
9
9
  channel?: string
@@ -36,7 +36,7 @@ export async function checkCompatibilityCommand(appId: string, options: Options)
36
36
  await verifyUser(supabase, options.apikey, ['write', 'all', 'read', 'upload'])
37
37
 
38
38
  // Check we have app access to this appId
39
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
39
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.read)
40
40
 
41
41
  // const hashedLocalDependencies = new Map(dependenciesObject
42
42
  // .filter((a) => !!a.native && a.native !== undefined)
@@ -1,9 +1,9 @@
1
1
  import process from 'node:process'
2
2
  import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
4
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import type { OptionsBase } from '../utils'
6
- import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
6
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
7
7
  import { deleteSpecificVersion } from '../api/versions'
8
8
 
9
9
  interface Options extends OptionsBase {
@@ -28,7 +28,7 @@ export async function deleteBundle(bundleId: string, appId: string, options: Opt
28
28
 
29
29
  const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
30
30
  // Check we have app access to this appId
31
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
31
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.write)
32
32
 
33
33
  appId = appId || config?.app?.appId
34
34
  if (!options.apikey) {
@@ -1,10 +1,10 @@
1
1
  import process from 'node:process'
2
2
  import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
4
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import { displayBundles, getActiveAppVersions } from '../api/versions'
6
6
  import type { OptionsBase } from '../utils'
7
- import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
7
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
8
8
  import { checkLatest } from '../api/update'
9
9
 
10
10
  export async function listBundle(appId: string, options: OptionsBase) {
@@ -30,7 +30,7 @@ export async function listBundle(appId: string, options: OptionsBase) {
30
30
  p.log.info(`Querying available versions of: ${appId} in Capgo`)
31
31
 
32
32
  // Check we have app access to this appId
33
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
33
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.read)
34
34
 
35
35
  // Get all active app versions we might possibly be able to cleanup
36
36
  const allVersions = await getActiveAppVersions(supabase, appId, userId)
@@ -4,11 +4,12 @@ import * as p from '@clack/prompts'
4
4
  import { getVersionData } from '../api/versions'
5
5
  import { checkVersionNotUsedInDeviceOverride } from '../api/devices_override'
6
6
  import { checkVersionNotUsedInChannel } from '../api/channels'
7
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
7
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
8
8
  import type {
9
9
  OptionsBase,
10
10
  } from '../utils'
11
11
  import {
12
+ OrganizationPerm,
12
13
  checkPlanValid,
13
14
  createSupabaseClient,
14
15
  findSavedKey,
@@ -23,7 +24,7 @@ interface Options extends OptionsBase {
23
24
  }
24
25
 
25
26
  export async function unlinkDevice(channel: string, appId: string, options: Options) {
26
- p.intro(`Unlink bundle`)
27
+ p.intro(`Unlink bundle ${options.apikey}`)
27
28
  options.apikey = options.apikey || findSavedKey()
28
29
  const config = await getConfig()
29
30
  appId = appId || config?.app?.appId
@@ -46,9 +47,9 @@ export async function unlinkDevice(channel: string, appId: string, options: Opti
46
47
  }
47
48
  const supabase = await createSupabaseClient(options.apikey)
48
49
 
49
- const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
50
+ const userId = await verifyUser(supabase, options.apikey, ['all', 'write'])
50
51
  // Check we have app access to this appId
51
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
52
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.write)
52
53
 
53
54
  if (!channel) {
54
55
  p.log.error('Missing argument, you need to provide a channel')
@@ -57,8 +58,8 @@ export async function unlinkDevice(channel: string, appId: string, options: Opti
57
58
  try {
58
59
  await checkPlanValid(supabase, userId, options.apikey, appId)
59
60
 
60
- const versionData = await getVersionData(supabase, appId, userId, bundle)
61
- await checkVersionNotUsedInChannel(supabase, appId, userId, versionData)
61
+ const versionData = await getVersionData(supabase, appId, bundle)
62
+ await checkVersionNotUsedInChannel(supabase, appId, versionData)
62
63
  await checkVersionNotUsedInDeviceOverride(supabase, appId, versionData)
63
64
  await snag.track({
64
65
  channel: 'bundle',
@@ -15,6 +15,7 @@ import type {
15
15
  OptionsBase,
16
16
  } from '../utils'
17
17
  import {
18
+ EMPTY_UUID,
18
19
  OrganizationPerm,
19
20
  baseKeyPub,
20
21
  checkCompatibility,
@@ -212,9 +213,6 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
212
213
  p.log.error(`Version already exists ${formatError(appVersionError)}`)
213
214
  program.error('')
214
215
  }
215
- // make bundle safe for s3 name https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html
216
- const safeBundle = bundle.replace(/[^a-zA-Z0-9-_.!*'()]/g, '__')
217
- const fileName = `${safeBundle}.zip`
218
216
 
219
217
  let sessionKey
220
218
  let checksum = ''
@@ -318,8 +316,7 @@ It will be also visible in your dashboard\n`)
318
316
  const appOwner = await getAppOwner(supabase, appid)
319
317
 
320
318
  const versionData = {
321
- bucket_id: external ? undefined : fileName,
322
- user_id: appOwner,
319
+ // bucket_id: external ? undefined : fileName,
323
320
  name: bundle,
324
321
  app_id: appid,
325
322
  session_key: sessionKey,
@@ -327,6 +324,8 @@ It will be also visible in your dashboard\n`)
327
324
  storage_provider: external ? 'external' : 'r2-direct',
328
325
  minUpdateVersion,
329
326
  native_packages: nativePackages,
327
+ owner_org: EMPTY_UUID,
328
+ user_id: userId,
330
329
  checksum,
331
330
  }
332
331
  const { error: dbError } = await updateOrCreateVersion(supabase, versionData)
@@ -338,7 +337,7 @@ It will be also visible in your dashboard\n`)
338
337
  const spinner = p.spinner()
339
338
  spinner.start(`Uploading Bundle`)
340
339
 
341
- const url = await uploadUrl(supabase, appid, fileName)
340
+ const url = await uploadUrl(supabase, appid, bundle)
342
341
  if (!url) {
343
342
  p.log.error(`Cannot get upload url`)
344
343
  program.error('')
@@ -372,6 +371,7 @@ It will be also visible in your dashboard\n`)
372
371
  app_id: appid,
373
372
  created_by: appOwner,
374
373
  version: versionId,
374
+ owner_org: EMPTY_UUID,
375
375
  })
376
376
  if (dbError3) {
377
377
  p.log.error(`Cannot set channel, the upload key is not allowed to do that, use the "all" for this. ${formatError(dbError3)}`)
package/src/bundle/zip.ts CHANGED
@@ -112,15 +112,6 @@ export async function zipBundle(appId: string, options: Options) {
112
112
  if (!json)
113
113
  s2.stop(`Saved to ${name}`)
114
114
 
115
- if (options.json) {
116
- const output = {
117
- bundle,
118
- filename: name,
119
- checksum,
120
- }
121
- p.log.info(formatError(output))
122
- }
123
-
124
115
  await snag.track({
125
116
  channel: 'app',
126
117
  event: 'App zip',
@@ -133,5 +124,16 @@ export async function zipBundle(appId: string, options: Options) {
133
124
 
134
125
  if (!json)
135
126
  p.outro(`Done ✅`)
127
+
128
+ if (json) {
129
+ const output = {
130
+ bundle,
131
+ filename: name,
132
+ checksum,
133
+ }
134
+ // Keep the console log and stringify
135
+ // eslint-disable-next-line no-console
136
+ console.log(JSON.stringify(output, null, 2))
137
+ }
136
138
  process.exit()
137
139
  }
@@ -1,10 +1,10 @@
1
1
  import process from 'node:process'
2
2
  import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
4
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import { createChannel, findUnknownVersion } from '../api/channels'
6
6
  import type { OptionsBase } from '../utils'
7
- import { createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
7
+ import { EMPTY_UUID, OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
8
8
 
9
9
  interface Options extends OptionsBase {
10
10
  default?: boolean
@@ -29,7 +29,7 @@ export async function addChannel(channelId: string, appId: string, options: Opti
29
29
 
30
30
  const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
31
31
  // Check we have app access to this appId
32
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
32
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.admin)
33
33
 
34
34
  p.log.info(`Creating channel ${appId}#${channelId} to Capgo`)
35
35
  try {
@@ -42,7 +42,7 @@ export async function addChannel(channelId: string, appId: string, options: Opti
42
42
  name: channelId,
43
43
  app_id: appId,
44
44
  version: data.id,
45
- created_by: userId,
45
+ owner_org: EMPTY_UUID,
46
46
  })
47
47
  p.log.success(`Channel created ✅`)
48
48
  await snag.track({
@@ -1,9 +1,9 @@
1
1
  import process from 'node:process'
2
2
  import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
4
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import type { OptionsBase } from '../utils'
6
- import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
6
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils'
7
7
 
8
8
  interface Options extends OptionsBase {
9
9
  channel?: string
@@ -36,9 +36,9 @@ export async function currentBundle(channel: string, appId: string, options: Opt
36
36
  }
37
37
  const supabase = await createSupabaseClient(options.apikey)
38
38
 
39
- const userId = await verifyUser(supabase, options.apikey, ['write', 'all', 'read'])
39
+ const _userId = await verifyUser(supabase, options.apikey, ['write', 'all', 'read'])
40
40
  // Check we have app access to this appId
41
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
41
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.read)
42
42
 
43
43
  if (!channel) {
44
44
  p.log.error(`Please provide a channel to get the bundle from.`)
@@ -50,7 +50,6 @@ export async function currentBundle(channel: string, appId: string, options: Opt
50
50
  .select('version ( name )')
51
51
  .eq('name', channel)
52
52
  .eq('app_id', appId)
53
- .eq('created_by', userId)
54
53
  .limit(1)
55
54
 
56
55
  if (error || supabaseChannel.length === 0) {
@@ -1,10 +1,10 @@
1
1
  import process from 'node:process'
2
2
  import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
4
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import { delChannel } from '../api/channels'
6
6
  import type { OptionsBase } from '../utils'
7
- import { createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
7
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
8
8
 
9
9
  export async function deleteChannel(channelId: string, appId: string, options: OptionsBase) {
10
10
  p.intro(`Delete channel`)
@@ -25,7 +25,7 @@ export async function deleteChannel(channelId: string, appId: string, options: O
25
25
 
26
26
  const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
27
27
  // Check we have app access to this appId
28
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
28
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.admin)
29
29
 
30
30
  p.log.info(`Deleting channel ${appId}#${channelId} from Capgo`)
31
31
  try {
@@ -1,10 +1,10 @@
1
1
  import process from 'node:process'
2
2
  import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
4
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import { displayChannels, getActiveChannels } from '../api/channels'
6
6
  import type { OptionsBase } from '../utils'
7
- import { createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
7
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
8
8
 
9
9
  export async function listChannels(appId: string, options: OptionsBase) {
10
10
  p.intro(`List channels`)
@@ -24,7 +24,7 @@ export async function listChannels(appId: string, options: OptionsBase) {
24
24
 
25
25
  const userId = await verifyUser(supabase, options.apikey, ['write', 'all', 'read', 'upload'])
26
26
  // Check we have app access to this appId
27
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
27
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.read)
28
28
 
29
29
  p.log.info(`Querying available channels in Capgo`)
30
30
 
@@ -2,11 +2,12 @@ import process from 'node:process'
2
2
  import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
4
  import type { Database } from '../types/supabase.types'
5
- import { checkAppExistsAndHasPermissionErr } from '../api/app'
5
+ import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
6
6
  import type {
7
7
  OptionsBase,
8
8
  } from '../utils'
9
9
  import {
10
+ OrganizationPerm,
10
11
  checkPlanValid,
11
12
  createSupabaseClient,
12
13
  findSavedKey,
@@ -51,7 +52,7 @@ export async function setChannel(channel: string, appId: string, options: Option
51
52
 
52
53
  const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
53
54
  // Check we have app access to this appId
54
- await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appId)
55
+ await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.admin)
55
56
 
56
57
  const { bundle, latest, downgrade, upgrade, ios, android, selfAssign, state, disableAutoUpdate } = options
57
58
  if (!channel) {
package/src/index.ts CHANGED
@@ -148,12 +148,13 @@ bundle
148
148
  .action(listBundle)
149
149
  .option('-a, --apikey <apikey>', 'apikey to link to your account')
150
150
 
151
- bundle
152
- .command('unlink [appId]')
153
- .description('Unlink a bundle in Capgo Cloud')
154
- .action(listBundle)
155
- .option('-a, --apikey <apikey>', 'apikey to link to your account')
156
- .option('-b, --bundle <bundle>', 'bundle version number of the bundle to unlink')
151
+ // TODO: Fix this command!
152
+ // bundle
153
+ // .command('unlink [appId]')
154
+ // .description('Unlink a bundle in Capgo Cloud')
155
+ // .action(listBundle)
156
+ // .option('-a, --apikey <apikey>', 'apikey to link to your account')
157
+ // .option('-b, --bundle <bundle>', 'bundle version number of the bundle to unlink')
157
158
 
158
159
  bundle
159
160
  .command('cleanup [appId]')