@capgo/cli 4.10.3 → 4.10.8

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 CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [4.10.8](https://github.com/Cap-go/CLI/compare/v4.10.7...v4.10.8) (2024-05-27)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * lint and updates types ([1b3313f](https://github.com/Cap-go/CLI/commit/1b3313f6b165c88b57ea64c7cb2544c05a6921df))
11
+
12
+ ### [4.10.7](https://github.com/Cap-go/CLI/compare/v4.10.6...v4.10.7) (2024-05-27)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * add snag for multipart upload ([eef8d38](https://github.com/Cap-go/CLI/commit/eef8d38d01bc7b25def9d5e9995ec3ae5acfc8cf))
18
+
19
+ ### [4.10.6](https://github.com/Cap-go/CLI/compare/v4.10.5...v4.10.6) (2024-05-24)
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * userId in logsnag ([b4f0cef](https://github.com/Cap-go/CLI/commit/b4f0cefd4e4f3366e5e8e6698f7c7b7b907eebba))
25
+
26
+ ### [4.10.5](https://github.com/Cap-go/CLI/compare/v4.10.4...v4.10.5) (2024-05-21)
27
+
28
+
29
+ ### Bug Fixes
30
+
31
+ * issue returning channel list ([aee3ed5](https://github.com/Cap-go/CLI/commit/aee3ed5cb011c10854f8a7806f69a80d10b389ac))
32
+
33
+ ### [4.10.4](https://github.com/Cap-go/CLI/compare/v4.10.3...v4.10.4) (2024-05-15)
34
+
5
35
  ### [4.10.3](https://github.com/Cap-go/CLI/compare/v4.10.2...v4.10.3) (2024-05-14)
6
36
 
7
37
 
package/dist/index.js CHANGED
@@ -109493,8 +109493,19 @@ async function finishMultipartDownload(key2, uploadId, url, parts) {
109493
109493
  });
109494
109494
  }
109495
109495
  var PART_SIZE = 10 * 1024 * 1024;
109496
- async function uploadMultipart(supabase, appId, name, data) {
109496
+ async function uploadMultipart(supabase, appId, name, data, orgId) {
109497
109497
  try {
109498
+ const snag = useLogSnag();
109499
+ await snag.track({
109500
+ channel: "app",
109501
+ event: "App Multipart Prepare",
109502
+ icon: "\u23EB",
109503
+ user_id: orgId,
109504
+ tags: {
109505
+ "app-id": appId
109506
+ },
109507
+ notify: false
109508
+ }).catch();
109498
109509
  const multipartPrep = await prepareMultipart(supabase, appId, name);
109499
109510
  if (!multipartPrep) {
109500
109511
  return false;
@@ -109504,6 +109515,16 @@ async function uploadMultipart(supabase, appId, name, data) {
109504
109515
  const uploadPromises = Array.from({ length: partCount }, (_3, index) => uploadPart(data, PART_SIZE, multipartPrep.url, multipartPrep.key, multipartPrep.uploadId, index));
109505
109516
  const parts = await Promise.all(uploadPromises);
109506
109517
  await finishMultipartDownload(multipartPrep.key, multipartPrep.uploadId, multipartPrep.url, parts);
109518
+ await snag.track({
109519
+ channel: "app",
109520
+ event: "App Multipart done",
109521
+ icon: "\u23EB",
109522
+ user_id: orgId,
109523
+ tags: {
109524
+ "app-id": appId
109525
+ },
109526
+ notify: false
109527
+ }).catch();
109507
109528
  return true;
109508
109529
  } catch (e2) {
109509
109530
  f2.error(`Could not upload via multipart ${formatError(e2)}`);
@@ -109783,7 +109804,7 @@ async function getUserId(options) {
109783
109804
  // package.json
109784
109805
  var package_default = {
109785
109806
  name: "@capgo/cli",
109786
- version: "4.10.3",
109807
+ version: "4.10.8",
109787
109808
  description: "A CLI to upload to capgo servers",
109788
109809
  author: "github.com/riderx",
109789
109810
  license: "Apache 2.0",
@@ -110449,8 +110470,8 @@ function displayChannels(data) {
110449
110470
  "Name": row.name,
110450
110471
  ...row.version ? { Version: row.version.name } : void 0,
110451
110472
  "Public": row.public ? "\u2705" : "\u274C",
110452
- "iOS": row.ios ? "\u274C" : "\u2705",
110453
- "Android": row.android ? "\u274C" : "\u2705",
110473
+ "iOS": row.ios ? "\u2705" : "\u274C",
110474
+ "Android": row.android ? "\u2705" : "\u274C",
110454
110475
  "\u2B06\uFE0F limit": row.disableAutoUpdate,
110455
110476
  "\u2B07\uFE0F under native": row.disableAutoUpdateUnderNative ? "\u274C" : "\u2705",
110456
110477
  "Self assign": row.allow_device_self_set ? "\u2705" : "\u274C",
@@ -110510,7 +110531,7 @@ async function addChannel(channelId, appId, options, shouldExit = true) {
110510
110531
  program.error("");
110511
110532
  }
110512
110533
  const supabase = await createSupabaseClient(options.apikey);
110513
- const userId = await verifyUser(supabase, options.apikey, ["write", "all"]);
110534
+ await verifyUser(supabase, options.apikey, ["write", "all"]);
110514
110535
  await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, 4 /* admin */);
110515
110536
  f2.info(`Creating channel ${appId}#${channelId} to Capgo`);
110516
110537
  try {
@@ -110531,7 +110552,7 @@ async function addChannel(channelId, appId, options, shouldExit = true) {
110531
110552
  channel: "channel",
110532
110553
  event: "Create channel",
110533
110554
  icon: "\u2705",
110534
- user_id: userId,
110555
+ user_id: orgId,
110535
110556
  tags: {
110536
110557
  "app-id": appId,
110537
110558
  "channel": channelId
@@ -110730,7 +110751,7 @@ Trial expires in ${isTrial} days`);
110730
110751
  channel: "app",
110731
110752
  event: "App encryption",
110732
110753
  icon: "\u{1F511}",
110733
- user_id: userId,
110754
+ user_id: orgId,
110734
110755
  tags: {
110735
110756
  "app-id": appid
110736
110757
  },
@@ -110762,7 +110783,7 @@ The app size is ${mbSize} Mb, this may take a while to download for users
110762
110783
  channel: "app-error",
110763
110784
  event: "App Too Large",
110764
110785
  icon: "\u{1F69B}",
110765
- user_id: userId,
110786
+ user_id: orgId,
110766
110787
  tags: {
110767
110788
  "app-id": appid
110768
110789
  },
@@ -110786,7 +110807,7 @@ The app size is ${mbSize} Mb, this may take a while to download for users
110786
110807
  channel: "app",
110787
110808
  event: "App external",
110788
110809
  icon: "\u{1F4E4}",
110789
- user_id: userId,
110810
+ user_id: orgId,
110790
110811
  tags: {
110791
110812
  "app-id": appid
110792
110813
  },
@@ -110820,7 +110841,7 @@ The app size is ${mbSize} Mb, this may take a while to download for users
110820
110841
  const startTime = import_node_perf_hooks.performance.now();
110821
110842
  try {
110822
110843
  if (options.multipart !== void 0 && options.multipart) {
110823
- await uploadMultipart(supabase, appid, bundle2, zipped);
110844
+ await uploadMultipart(supabase, appid, bundle2, zipped, orgId);
110824
110845
  } else {
110825
110846
  const url = await uploadUrl(supabase, appid, bundle2);
110826
110847
  if (!url) {
@@ -110913,7 +110934,7 @@ The app size is ${mbSize} Mb, this may take a while to download for users
110913
110934
  channel: "app",
110914
110935
  event: "App Uploaded",
110915
110936
  icon: "\u23EB",
110916
- user_id: userId,
110937
+ user_id: orgId,
110917
110938
  tags: {
110918
110939
  "app-id": appid
110919
110940
  },
@@ -111004,7 +111025,6 @@ async function loginCommand(apikey, options) {
111004
111025
  }
111005
111026
 
111006
111027
  // src/app/add.ts
111007
- var import_node_crypto4 = require("node:crypto");
111008
111028
  var import_node_fs10 = require("node:fs");
111009
111029
  var import_node_process15 = __toESM(require("node:process"));
111010
111030
 
@@ -111168,13 +111188,14 @@ async function addAppInternal(appId, options, organization, throwErr = true) {
111168
111188
  } else {
111169
111189
  f2.warn(`Cannot find app icon in any of the following locations: ${icon}, ${newIconPath}`);
111170
111190
  }
111171
- const fileName = `icon_${(0, import_node_crypto4.randomUUID)()}`;
111191
+ const fileName = `icon`;
111172
111192
  let signedURL = "https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";
111173
111193
  if (iconBuff && iconType) {
111174
- const { error } = await supabase.storage.from(`images/${userId}/${appId}`).upload(fileName, iconBuff, {
111194
+ const { error } = await supabase.storage.from(`images/org/${organizationUid}/${appId}`).upload(fileName, iconBuff, {
111175
111195
  contentType: iconType
111176
111196
  });
111177
111197
  if (error) {
111198
+ console.error(error);
111178
111199
  f2.error(`Could not add app ${formatError(error)}`);
111179
111200
  program.error("");
111180
111201
  }
@@ -111897,9 +111918,8 @@ async function setChannel(channel2, appId, options) {
111897
111918
  channel: "channel",
111898
111919
  event: "Set channel",
111899
111920
  icon: "\u2705",
111900
- user_id: userId,
111921
+ user_id: orgId,
111901
111922
  tags: {
111902
- "user-id": userId,
111903
111923
  "app-id": appId
111904
111924
  },
111905
111925
  notify: false
@@ -112103,12 +112123,13 @@ async function deleteChannel(channelId, appId, options) {
112103
112123
  f2.info(`Deleting channel ${appId}#${channelId} from Capgo`);
112104
112124
  try {
112105
112125
  await delChannel(supabase, channelId, appId, userId);
112126
+ const orgId = await getOrganizationId(supabase, appId);
112106
112127
  f2.success(`Channel deleted`);
112107
112128
  await snag.track({
112108
112129
  channel: "channel",
112109
112130
  event: "Delete channel",
112110
112131
  icon: "\u2705",
112111
- user_id: userId,
112132
+ user_id: orgId,
112112
112133
  tags: {
112113
112134
  "user-id": userId,
112114
112135
  "app-id": appId,
@@ -112159,7 +112180,7 @@ async function listChannels(appId, options) {
112159
112180
  }
112160
112181
 
112161
112182
  // src/app/set.ts
112162
- var import_node_crypto5 = require("node:crypto");
112183
+ var import_node_crypto4 = require("node:crypto");
112163
112184
  var import_node_fs15 = require("node:fs");
112164
112185
  var import_node_process29 = __toESM(require("node:process"));
112165
112186
  async function setApp(appId, options) {
@@ -112188,7 +112209,7 @@ async function setApp(appId, options) {
112188
112209
  }
112189
112210
  let iconBuff;
112190
112211
  let iconType;
112191
- const fileName = `icon_${(0, import_node_crypto5.randomUUID)()}`;
112212
+ const fileName = `icon_${(0, import_node_crypto4.randomUUID)()}`;
112192
112213
  let signedURL = "https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png";
112193
112214
  if (icon && (0, import_node_fs15.existsSync)(icon)) {
112194
112215
  iconBuff = (0, import_node_fs15.readFileSync)(icon);
@@ -112246,7 +112267,7 @@ async function deleteApp(appId, options) {
112246
112267
  const supabase = await createSupabaseClient(options.apikey);
112247
112268
  const userId = await verifyUser(supabase, options.apikey, ["write", "all"]);
112248
112269
  await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, 5 /* super_admin */);
112249
- const { data: appOwnerRaw, error: appOwnerError } = await supabase.from("apps").select(`owner_org ( created_by )`).eq("app_id", appId).single();
112270
+ const { data: appOwnerRaw, error: appOwnerError } = await supabase.from("apps").select(`owner_org ( created_by, id )`).eq("app_id", appId).single();
112250
112271
  const appOwner = appOwnerRaw;
112251
112272
  if (!appOwnerError && (appOwner?.owner_org.created_by ?? "") !== userId) {
112252
112273
  f2.warn("Deleting the app is not recomended for users that are not the organization owner");
@@ -112272,22 +112293,25 @@ async function deleteApp(appId, options) {
112272
112293
  } else if (appOwnerError) {
112273
112294
  f2.warn(`Cannot get the app owner ${formatError(appOwnerError)}`);
112274
112295
  }
112275
- const { error } = await supabase.storage.from(`images/${userId}`).remove([appId]);
112276
- if (error)
112296
+ const { error } = await supabase.storage.from(`images`).remove([`org/${appOwner?.owner_org.id}/${appId}/icon`]);
112297
+ if (error) {
112298
+ console.error(error, `images/org/${appOwner?.owner_org.id}/${appId}`);
112277
112299
  f2.error("Could not delete app logo");
112300
+ }
112278
112301
  const { error: delError } = await supabase.storage.from(`apps/${appId}/${userId}`).remove(["versions"]);
112279
112302
  if (delError)
112280
112303
  f2.error("Could not delete app version");
112281
- const { error: dbError } = await supabase.from("apps").delete().eq("app_id", appId).eq("user_id", userId);
112304
+ const { error: dbError } = await supabase.from("apps").delete().eq("app_id", appId);
112282
112305
  if (dbError) {
112283
112306
  f2.error("Could not delete app");
112284
112307
  program.error("");
112285
112308
  }
112309
+ const orgId = await getOrganizationId(supabase, appId);
112286
112310
  await snag.track({
112287
112311
  channel: "app",
112288
112312
  event: "App Deleted",
112289
112313
  icon: "\u{1F5D1}\uFE0F",
112290
- user_id: userId,
112314
+ user_id: orgId,
112291
112315
  tags: {
112292
112316
  "app-id": appId
112293
112317
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/cli",
3
- "version": "4.10.3",
3
+ "version": "4.10.8",
4
4
  "description": "A CLI to upload to capgo servers",
5
5
  "author": "github.com/riderx",
6
6
  "license": "Apache 2.0",
@@ -74,7 +74,24 @@ interface version {
74
74
  id: string
75
75
  name: string
76
76
  }
77
- export function displayChannels(data: (Database['public']['Tables']['channels']['Row'] & { version?: version, secondVersion?: version })[]) {
77
+ interface Channel {
78
+ id: number
79
+ name: string
80
+ public: boolean
81
+ ios: boolean
82
+ android: boolean
83
+ disableAutoUpdate: string
84
+ disableAutoUpdateUnderNative: boolean
85
+ allow_device_self_set: boolean
86
+ enable_progressive_deploy: boolean
87
+ secondaryVersionPercentage: number
88
+ secondVersion?: version
89
+ enableAbTesting: boolean
90
+ allow_emulator: boolean
91
+ allow_dev: boolean
92
+ version?: version
93
+ }
94
+ export function displayChannels(data: Channel[]) {
78
95
  const t = new Table({
79
96
  title: 'Channels',
80
97
  charLength: { '❌': 2, '✅': 2 },
@@ -86,8 +103,8 @@ export function displayChannels(data: (Database['public']['Tables']['channels'][
86
103
  'Name': row.name,
87
104
  ...(row.version ? { Version: row.version.name } : undefined),
88
105
  'Public': row.public ? '✅' : '❌',
89
- 'iOS': row.ios ? '' : '',
90
- 'Android': row.android ? '' : '',
106
+ 'iOS': row.ios ? '' : '',
107
+ 'Android': row.android ? '' : '',
91
108
  '⬆️ limit': row.disableAutoUpdate,
92
109
  '⬇️ under native': row.disableAutoUpdateUnderNative ? '❌' : '✅',
93
110
  'Self assign': row.allow_device_self_set ? '✅' : '❌',
@@ -136,5 +153,5 @@ export async function getActiveChannels(supabase: SupabaseClient<Database>, appi
136
153
  p.log.error(`App ${appid} not found in database`)
137
154
  program.error('')
138
155
  }
139
- return data
156
+ return data as any as Channel[]
140
157
  }
package/src/app/add.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { randomUUID } from 'node:crypto'
2
1
  import { existsSync, readFileSync } from 'node:fs'
3
2
  import process from 'node:process'
4
3
  import mime from 'mime'
@@ -95,17 +94,18 @@ export async function addAppInternal(appId: string, options: Options, organizati
95
94
  p.log.warn(`Cannot find app icon in any of the following locations: ${icon}, ${newIconPath}`)
96
95
  }
97
96
 
98
- const fileName = `icon_${randomUUID()}`
97
+ const fileName = `icon`
99
98
  let signedURL = 'https://xvwzpoazmxkqosrdewyv.supabase.co/storage/v1/object/public/images/capgo.png'
100
99
 
101
100
  // upload image if available
102
101
  if (iconBuff && iconType) {
103
102
  const { error } = await supabase.storage
104
- .from(`images/${userId}/${appId}`)
103
+ .from(`images/org/${organizationUid}/${appId}`)
105
104
  .upload(fileName, iconBuff, {
106
105
  contentType: iconType,
107
106
  })
108
107
  if (error) {
108
+ console.error(error)
109
109
  p.log.error(`Could not add app ${formatError(error)}`)
110
110
  program.error('')
111
111
  }
package/src/app/delete.ts CHANGED
@@ -3,7 +3,7 @@ import { program } from 'commander'
3
3
  import * as p from '@clack/prompts'
4
4
  import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import type { OptionsBase } from '../utils'
6
- import { OrganizationPerm, createSupabaseClient, findSavedKey, formatError, getConfig, useLogSnag, verifyUser } from '../utils'
6
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, formatError, getConfig, getOrganizationId, useLogSnag, verifyUser } from '../utils'
7
7
 
8
8
  export async function deleteApp(appId: string, options: OptionsBase) {
9
9
  p.intro(`Deleting`)
@@ -27,11 +27,11 @@ export async function deleteApp(appId: string, options: OptionsBase) {
27
27
  await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.super_admin)
28
28
 
29
29
  const { data: appOwnerRaw, error: appOwnerError } = await supabase.from('apps')
30
- .select(`owner_org ( created_by )`)
30
+ .select(`owner_org ( created_by, id )`)
31
31
  .eq('app_id', appId)
32
32
  .single()
33
33
 
34
- const appOwner = appOwnerRaw as { owner_org: { created_by: string } } | null
34
+ const appOwner = appOwnerRaw as { owner_org: { created_by: string, id: string } } | null
35
35
 
36
36
  if (!appOwnerError && (appOwner?.owner_org.created_by ?? '') !== userId) {
37
37
  // We are dealing with a member user that is not the owner
@@ -66,10 +66,12 @@ export async function deleteApp(appId: string, options: OptionsBase) {
66
66
 
67
67
  const { error } = await supabase
68
68
  .storage
69
- .from(`images/${userId}`)
70
- .remove([appId])
71
- if (error)
69
+ .from(`images`)
70
+ .remove([`org/${appOwner?.owner_org.id}/${appId}/icon`])
71
+ if (error) {
72
+ console.error(error, `images/org/${appOwner?.owner_org.id}/${appId}`)
72
73
  p.log.error('Could not delete app logo')
74
+ }
73
75
 
74
76
  const { error: delError } = await supabase
75
77
  .storage
@@ -84,17 +86,18 @@ export async function deleteApp(appId: string, options: OptionsBase) {
84
86
  .from('apps')
85
87
  .delete()
86
88
  .eq('app_id', appId)
87
- .eq('user_id', userId)
89
+ // .eq('user_id', userId)
88
90
 
89
91
  if (dbError) {
90
92
  p.log.error('Could not delete app')
91
93
  program.error('')
92
94
  }
95
+ const orgId = await getOrganizationId(supabase, appId)
93
96
  await snag.track({
94
97
  channel: 'app',
95
98
  event: 'App Deleted',
96
99
  icon: '🗑️',
97
- user_id: userId,
100
+ user_id: orgId,
98
101
  tags: {
99
102
  'app-id': appId,
100
103
  },
@@ -289,7 +289,7 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
289
289
  channel: 'app',
290
290
  event: 'App encryption',
291
291
  icon: '🔑',
292
- user_id: userId,
292
+ user_id: orgId,
293
293
  tags: {
294
294
  'app-id': appid,
295
295
  },
@@ -319,7 +319,7 @@ It will be also visible in your dashboard\n`)
319
319
  channel: 'app-error',
320
320
  event: 'App Too Large',
321
321
  icon: '🚛',
322
- user_id: userId,
322
+ user_id: orgId,
323
323
  tags: {
324
324
  'app-id': appid,
325
325
  },
@@ -345,7 +345,7 @@ It will be also visible in your dashboard\n`)
345
345
  channel: 'app',
346
346
  event: 'App external',
347
347
  icon: '📤',
348
- user_id: userId,
348
+ user_id: orgId,
349
349
  tags: {
350
350
  'app-id': appid,
351
351
  },
@@ -387,7 +387,7 @@ It will be also visible in your dashboard\n`)
387
387
 
388
388
  try {
389
389
  if (options.multipart !== undefined && options.multipart) {
390
- await uploadMultipart(supabase, appid, bundle, zipped)
390
+ await uploadMultipart(supabase, appid, bundle, zipped, orgId)
391
391
  }
392
392
  else {
393
393
  const url = await uploadUrl(supabase, appid, bundle)
@@ -496,7 +496,7 @@ It will be also visible in your dashboard\n`)
496
496
  channel: 'app',
497
497
  event: 'App Uploaded',
498
498
  icon: '⏫',
499
- user_id: userId,
499
+ user_id: orgId,
500
500
  tags: {
501
501
  'app-id': appid,
502
502
  },
@@ -27,7 +27,7 @@ export async function addChannel(channelId: string, appId: string, options: Opti
27
27
  }
28
28
  const supabase = await createSupabaseClient(options.apikey)
29
29
 
30
- const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
30
+ await verifyUser(supabase, options.apikey, ['write', 'all'])
31
31
  // Check we have app access to this appId
32
32
  await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.admin)
33
33
 
@@ -50,7 +50,7 @@ export async function addChannel(channelId: string, appId: string, options: Opti
50
50
  channel: 'channel',
51
51
  event: 'Create channel',
52
52
  icon: '✅',
53
- user_id: userId,
53
+ user_id: orgId,
54
54
  tags: {
55
55
  'app-id': appId,
56
56
  'channel': channelId,
@@ -4,7 +4,7 @@ import * as p from '@clack/prompts'
4
4
  import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
5
5
  import { delChannel } from '../api/channels'
6
6
  import type { OptionsBase } from '../utils'
7
- import { OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, useLogSnag, verifyUser } from '../utils'
7
+ import { OrganizationPerm, createSupabaseClient, findSavedKey, getConfig, getOrganizationId, useLogSnag, verifyUser } from '../utils'
8
8
 
9
9
  export async function deleteChannel(channelId: string, appId: string, options: OptionsBase) {
10
10
  p.intro(`Delete channel`)
@@ -30,12 +30,13 @@ export async function deleteChannel(channelId: string, appId: string, options: O
30
30
  p.log.info(`Deleting channel ${appId}#${channelId} from Capgo`)
31
31
  try {
32
32
  await delChannel(supabase, channelId, appId, userId)
33
+ const orgId = await getOrganizationId(supabase, appId)
33
34
  p.log.success(`Channel deleted`)
34
35
  await snag.track({
35
36
  channel: 'channel',
36
37
  event: 'Delete channel',
37
38
  icon: '✅',
38
- user_id: userId,
39
+ user_id: orgId,
39
40
  tags: {
40
41
  'user-id': userId,
41
42
  'app-id': appId,
@@ -161,9 +161,8 @@ export async function setChannel(channel: string, appId: string, options: Option
161
161
  channel: 'channel',
162
162
  event: 'Set channel',
163
163
  icon: '✅',
164
- user_id: userId,
164
+ user_id: orgId,
165
165
  tags: {
166
- 'user-id': userId,
167
166
  'app-id': appId,
168
167
  },
169
168
  notify: false,
@@ -411,129 +411,6 @@ export interface Database {
411
411
  },
412
412
  ]
413
413
  }
414
- clickhouse_app_usage_parm: {
415
- Row: {
416
- _app_list: string | null
417
- _end_date: string | null
418
- _start_date: string | null
419
- app_id: string | null
420
- bandwidth: number | null
421
- date: string | null
422
- fail: number | null
423
- get: number | null
424
- install: number | null
425
- mau: number | null
426
- storage_added: number | null
427
- storage_deleted: number | null
428
- uninstall: number | null
429
- }
430
- Insert: {
431
- _app_list?: string | null
432
- _end_date?: string | null
433
- _start_date?: string | null
434
- app_id?: string | null
435
- bandwidth?: number | null
436
- date?: string | null
437
- fail?: number | null
438
- get?: number | null
439
- install?: number | null
440
- mau?: number | null
441
- storage_added?: number | null
442
- storage_deleted?: number | null
443
- uninstall?: number | null
444
- }
445
- Update: {
446
- _app_list?: string | null
447
- _end_date?: string | null
448
- _start_date?: string | null
449
- app_id?: string | null
450
- bandwidth?: number | null
451
- date?: string | null
452
- fail?: number | null
453
- get?: number | null
454
- install?: number | null
455
- mau?: number | null
456
- storage_added?: number | null
457
- storage_deleted?: number | null
458
- uninstall?: number | null
459
- }
460
- Relationships: []
461
- }
462
- clickhouse_devices: {
463
- Row: {
464
- app_id: string | null
465
- created_at: string | null
466
- custom_id: string | null
467
- device_id: string | null
468
- is_emulator: boolean | null
469
- is_prod: boolean | null
470
- os_version: string | null
471
- platform: string | null
472
- plugin_version: string | null
473
- updated_at: string | null
474
- version: number | null
475
- version_build: string | null
476
- }
477
- Insert: {
478
- app_id?: string | null
479
- created_at?: string | null
480
- custom_id?: string | null
481
- device_id?: string | null
482
- is_emulator?: boolean | null
483
- is_prod?: boolean | null
484
- os_version?: string | null
485
- platform?: string | null
486
- plugin_version?: string | null
487
- updated_at?: string | null
488
- version?: number | null
489
- version_build?: string | null
490
- }
491
- Update: {
492
- app_id?: string | null
493
- created_at?: string | null
494
- custom_id?: string | null
495
- device_id?: string | null
496
- is_emulator?: boolean | null
497
- is_prod?: boolean | null
498
- os_version?: string | null
499
- platform?: string | null
500
- plugin_version?: string | null
501
- updated_at?: string | null
502
- version?: number | null
503
- version_build?: string | null
504
- }
505
- Relationships: []
506
- }
507
- clickhouse_logs: {
508
- Row: {
509
- action: string | null
510
- app_id: string | null
511
- created_at: string | null
512
- device_id: string | null
513
- platform: string | null
514
- version: number | null
515
- version_build: string | null
516
- }
517
- Insert: {
518
- action?: string | null
519
- app_id?: string | null
520
- created_at?: string | null
521
- device_id?: string | null
522
- platform?: string | null
523
- version?: number | null
524
- version_build?: string | null
525
- }
526
- Update: {
527
- action?: string | null
528
- app_id?: string | null
529
- created_at?: string | null
530
- device_id?: string | null
531
- platform?: string | null
532
- version?: number | null
533
- version_build?: string | null
534
- }
535
- Relationships: []
536
- }
537
414
  daily_bandwidth: {
538
415
  Row: {
539
416
  app_id: string
@@ -669,13 +546,12 @@ export interface Database {
669
546
  devices: {
670
547
  Row: {
671
548
  app_id: string
672
- created_at: string
673
549
  custom_id: string
674
550
  device_id: string
675
551
  is_emulator: boolean | null
676
552
  is_prod: boolean | null
677
553
  os_version: string | null
678
- platform: Database['public']['Enums']['platform_os'] | null
554
+ platform: Database['public']['Enums']['platform_os']
679
555
  plugin_version: string
680
556
  updated_at: string
681
557
  version: number
@@ -683,13 +559,12 @@ export interface Database {
683
559
  }
684
560
  Insert: {
685
561
  app_id: string
686
- created_at: string
687
562
  custom_id?: string
688
563
  device_id: string
689
564
  is_emulator?: boolean | null
690
565
  is_prod?: boolean | null
691
566
  os_version?: string | null
692
- platform?: Database['public']['Enums']['platform_os'] | null
567
+ platform: Database['public']['Enums']['platform_os']
693
568
  plugin_version?: string
694
569
  updated_at: string
695
570
  version: number
@@ -697,13 +572,12 @@ export interface Database {
697
572
  }
698
573
  Update: {
699
574
  app_id?: string
700
- created_at?: string
701
575
  custom_id?: string
702
576
  device_id?: string
703
577
  is_emulator?: boolean | null
704
578
  is_prod?: boolean | null
705
579
  os_version?: string | null
706
- platform?: Database['public']['Enums']['platform_os'] | null
580
+ platform?: Database['public']['Enums']['platform_os']
707
581
  plugin_version?: string
708
582
  updated_at?: string
709
583
  version?: number
@@ -1072,31 +946,25 @@ export interface Database {
1072
946
  }
1073
947
  stats: {
1074
948
  Row: {
1075
- action: string
949
+ action: Database['public']['Enums']['stats_action']
1076
950
  app_id: string
1077
951
  created_at: string
1078
952
  device_id: string
1079
- platform: Database['public']['Enums']['platform_os']
1080
953
  version: number
1081
- version_build: string
1082
954
  }
1083
955
  Insert: {
1084
- action: string
956
+ action: Database['public']['Enums']['stats_action']
1085
957
  app_id: string
1086
958
  created_at: string
1087
959
  device_id: string
1088
- platform: Database['public']['Enums']['platform_os']
1089
960
  version: number
1090
- version_build: string
1091
961
  }
1092
962
  Update: {
1093
- action?: string
963
+ action?: Database['public']['Enums']['stats_action']
1094
964
  app_id?: string
1095
965
  created_at?: string
1096
966
  device_id?: string
1097
- platform?: Database['public']['Enums']['platform_os']
1098
967
  version?: number
1099
- version_build?: string
1100
968
  }
1101
969
  Relationships: []
1102
970
  }
@@ -1266,19 +1134,19 @@ export interface Database {
1266
1134
  }
1267
1135
  version_usage: {
1268
1136
  Row: {
1269
- action: string
1137
+ action: Database['public']['Enums']['version_action']
1270
1138
  app_id: string
1271
1139
  timestamp: string
1272
1140
  version_id: number
1273
1141
  }
1274
1142
  Insert: {
1275
- action: string
1143
+ action: Database['public']['Enums']['version_action']
1276
1144
  app_id: string
1277
1145
  timestamp?: string
1278
1146
  version_id: number
1279
1147
  }
1280
1148
  Update: {
1281
- action?: string
1149
+ action?: Database['public']['Enums']['version_action']
1282
1150
  app_id?: string
1283
1151
  timestamp?: string
1284
1152
  version_id?: number
@@ -1608,6 +1476,13 @@ export interface Database {
1608
1476
  role: Database['public']['Enums']['user_min_right']
1609
1477
  }[]
1610
1478
  }
1479
+ get_org_owner_id: {
1480
+ Args: {
1481
+ apikey: string
1482
+ app_id: string
1483
+ }
1484
+ Returns: string
1485
+ }
1611
1486
  get_org_perm_for_apikey: {
1612
1487
  Args: {
1613
1488
  apikey: string
@@ -1717,16 +1592,6 @@ export interface Database {
1717
1592
  uninstall: number
1718
1593
  }[]
1719
1594
  }
1720
- get_total_stats_v5_org: {
1721
- Args: {
1722
- orgid: string
1723
- }
1724
- Returns: {
1725
- mau: number
1726
- bandwidth: number
1727
- storage: number
1728
- }[]
1729
- }
1730
1595
  get_total_storage_size:
1731
1596
  | {
1732
1597
  Args: {
@@ -1798,6 +1663,14 @@ export interface Database {
1798
1663
  }
1799
1664
  Returns: boolean
1800
1665
  }
1666
+ http_post_helper: {
1667
+ Args: {
1668
+ function_name: string
1669
+ function_type: string
1670
+ body: Json
1671
+ }
1672
+ Returns: number
1673
+ }
1801
1674
  invite_user_to_org: {
1802
1675
  Args: {
1803
1676
  email: string
@@ -1846,27 +1719,6 @@ export interface Database {
1846
1719
  }
1847
1720
  Returns: boolean
1848
1721
  }
1849
- | {
1850
- Args: {
1851
- apikey: string
1852
- keymode: Database['public']['Enums']['key_mode'][]
1853
- app_id: string
1854
- channel_id: number
1855
- right: Database['public']['Enums']['user_min_right']
1856
- user_id: string
1857
- }
1858
- Returns: boolean
1859
- }
1860
- | {
1861
- Args: {
1862
- apikey: string
1863
- keymode: Database['public']['Enums']['key_mode'][]
1864
- app_id: string
1865
- right: Database['public']['Enums']['user_min_right']
1866
- user_id: string
1867
- }
1868
- Returns: boolean
1869
- }
1870
1722
  is_app_owner:
1871
1723
  | {
1872
1724
  Args: {
@@ -2061,6 +1913,32 @@ export interface Database {
2061
1913
  pay_as_you_go_type: 'base' | 'units'
2062
1914
  platform_os: 'ios' | 'android'
2063
1915
  queue_job_status: 'inserted' | 'requested' | 'failed'
1916
+ stats_action:
1917
+ | 'delete'
1918
+ | 'reset'
1919
+ | 'set'
1920
+ | 'get'
1921
+ | 'set_fail'
1922
+ | 'update_fail'
1923
+ | 'download_fail'
1924
+ | 'windows_path_fail'
1925
+ | 'canonical_path_fail'
1926
+ | 'directory_path_fail'
1927
+ | 'unzip_fail'
1928
+ | 'low_mem_fail'
1929
+ | 'download_10'
1930
+ | 'download_20'
1931
+ | 'download_30'
1932
+ | 'download_40'
1933
+ | 'download_50'
1934
+ | 'download_60'
1935
+ | 'download_70'
1936
+ | 'download_80'
1937
+ | 'download_90'
1938
+ | 'download_complete'
1939
+ | 'decrypt_fail'
1940
+ | 'app_moved_to_foreground'
1941
+ | 'app_moved_to_background'
2064
1942
  stripe_status:
2065
1943
  | 'created'
2066
1944
  | 'succeeded'
@@ -2081,6 +1959,7 @@ export interface Database {
2081
1959
  | 'admin'
2082
1960
  | 'super_admin'
2083
1961
  user_role: 'read' | 'upload' | 'write' | 'admin'
1962
+ version_action: 'get' | 'fail' | 'install' | 'uninstall'
2084
1963
  }
2085
1964
  CompositeTypes: {
2086
1965
  match_plan: {
package/src/utils.ts CHANGED
@@ -134,13 +134,6 @@ export async function checkKey(supabase: SupabaseClient<Database>, apikey: strin
134
134
  }
135
135
  }
136
136
 
137
- export async function isGoodPlan(supabase: SupabaseClient<Database>, userId: string): Promise<boolean> {
138
- const { data } = await supabase
139
- .rpc('is_good_plan_v5', { userid: userId })
140
- .single()
141
- return data || false
142
- }
143
-
144
137
  export async function isPayingOrg(supabase: SupabaseClient<Database>, orgId: string): Promise<boolean> {
145
138
  const { data } = await supabase
146
139
  .rpc('is_paying_org', { orgid: orgId })
@@ -537,8 +530,19 @@ async function finishMultipartDownload(key: string, uploadId: string, url: strin
537
530
  }
538
531
 
539
532
  const PART_SIZE = 10 * 1024 * 1024
540
- export async function uploadMultipart(supabase: SupabaseClient<Database>, appId: string, name: string, data: Buffer): Promise<boolean> {
533
+ export async function uploadMultipart(supabase: SupabaseClient<Database>, appId: string, name: string, data: Buffer, orgId: string): Promise<boolean> {
541
534
  try {
535
+ const snag = useLogSnag()
536
+ await snag.track({
537
+ channel: 'app',
538
+ event: 'App Multipart Prepare',
539
+ icon: '⏫',
540
+ user_id: orgId,
541
+ tags: {
542
+ 'app-id': appId,
543
+ },
544
+ notify: false,
545
+ }).catch()
542
546
  const multipartPrep = await prepareMultipart(supabase, appId, name)
543
547
  if (!multipartPrep) {
544
548
  // Just pass the error
@@ -555,6 +559,16 @@ export async function uploadMultipart(supabase: SupabaseClient<Database>, appId:
555
559
 
556
560
  await finishMultipartDownload(multipartPrep.key, multipartPrep.uploadId, multipartPrep.url, parts)
557
561
 
562
+ await snag.track({
563
+ channel: 'app',
564
+ event: 'App Multipart done',
565
+ icon: '⏫',
566
+ user_id: orgId,
567
+ tags: {
568
+ 'app-id': appId,
569
+ },
570
+ notify: false,
571
+ }).catch()
558
572
  return true
559
573
  }
560
574
  catch (e) {