@capgo/cli 4.2.11 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/cli",
3
- "version": "4.2.11",
3
+ "version": "4.3.0",
4
4
  "description": "A CLI to upload to capgo servers",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -43,6 +43,7 @@
43
43
  "author": "github.com/riderx",
44
44
  "license": "Apache 2.0",
45
45
  "dependencies": {
46
+ "@aws-sdk/client-s3": "^3.540.0",
46
47
  "@capacitor/cli": "5.7.0",
47
48
  "@capgo/find-package-manager": "0.0.10",
48
49
  "@clack/prompts": "^0.7.0",
@@ -8,6 +8,10 @@ import * as p from '@clack/prompts'
8
8
  import { checksum as getChecksum } from '@tomasklaen/checksum'
9
9
  import ciDetect from 'ci-info'
10
10
  import ky from 'ky'
11
+ import {
12
+ PutObjectCommand,
13
+ S3Client,
14
+ } from '@aws-sdk/client-s3'
11
15
  import { checkLatest } from '../api/update'
12
16
  import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
13
17
  import { encryptSource } from '../api/crypto'
@@ -50,6 +54,10 @@ interface Options extends OptionsBase {
50
54
  key?: boolean | string
51
55
  keyData?: string
52
56
  ivSessionKey?: string
57
+ s3Region?: string
58
+ s3Apikey?: string
59
+ s3Apisecret?: string
60
+ s3BucketName?: string
53
61
  bundleUrl?: boolean
54
62
  codeCheck?: boolean
55
63
  minUpdateVersion?: string
@@ -63,6 +71,21 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
63
71
  let { bundle, path, channel } = options
64
72
  const { external, key, displayIvSession, autoMinUpdateVersion, ignoreMetadataCheck } = options
65
73
  let { minUpdateVersion } = options
74
+ const { s3Region, s3Apikey, s3Apisecret, s3BucketName } = options
75
+ let useS3 = false
76
+ let s3Client
77
+ if (s3Region && s3Apikey && s3Apisecret && s3BucketName) {
78
+ p.log.info('Uploading to S3')
79
+ useS3 = true
80
+ s3Client = new S3Client({
81
+ region: s3Region,
82
+ credentials: {
83
+ accessKeyId: s3Apikey,
84
+ secretAccessKey: s3Apisecret,
85
+ },
86
+ })
87
+ }
88
+
66
89
  options.apikey = options.apikey || findSavedKey()
67
90
  const snag = useLogSnag()
68
91
 
@@ -91,6 +114,13 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
91
114
  p.log.error('Missing argument, you need to provide a appid and a bundle and a path, or be in a capacitor project')
92
115
  program.error('')
93
116
  }
117
+ // if one S3 variable is set, check that all are set
118
+ if (s3BucketName || s3Region || s3Apikey || s3Apisecret) {
119
+ if (!s3BucketName || !s3Region || !s3Apikey || !s3Apisecret) {
120
+ p.log.error('Missing argument, for S3 upload you need to provide a bucket name, region, API key, and API secret')
121
+ program.error('')
122
+ }
123
+ }
94
124
  // check if path exist
95
125
  if (!existsSync(path)) {
96
126
  p.log.error(`Path ${path} does not exist, build your app first, or provide a valid path`)
@@ -217,7 +247,7 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
217
247
  let sessionKey
218
248
  let checksum = ''
219
249
  let zipped: Buffer | null = null
220
- if (!external) {
250
+ if (!external && useS3 === false) {
221
251
  const zip = new AdmZip()
222
252
  zip.addLocalFolder(path)
223
253
  zipped = zip.toBuffer()
@@ -292,6 +322,15 @@ It will be also visible in your dashboard\n`)
292
322
  program.error('')
293
323
  }
294
324
  else {
325
+ if (useS3) {
326
+ const zip = new AdmZip()
327
+ zip.addLocalFolder(path)
328
+ zipped = zip.toBuffer()
329
+ const s = p.spinner()
330
+ s.start(`Calculating checksum`)
331
+ checksum = await getChecksum(zipped, 'crc32')
332
+ s.stop(`Checksum: ${checksum}`)
333
+ }
295
334
  await snag.track({
296
335
  channel: 'app',
297
336
  event: 'App external',
@@ -361,6 +400,33 @@ It will be also visible in your dashboard\n`)
361
400
  }
362
401
  spinner.stop('Bundle Uploaded 💪')
363
402
  }
403
+ else if (useS3 && zipped) {
404
+ const spinner = p.spinner()
405
+ spinner.start(`Uploading Bundle`)
406
+
407
+ const fileName = `${appid}-${bundle}`
408
+ const encodeFileName = encodeURIComponent(fileName)
409
+ const command: PutObjectCommand = new PutObjectCommand({
410
+ Bucket: s3BucketName,
411
+ Key: fileName,
412
+ Body: zipped,
413
+ })
414
+
415
+ const response = await s3Client.send(command)
416
+ if (response.$metadata.httpStatusCode !== 200) {
417
+ p.log.error(`Cannot upload to S3`)
418
+ program.error('')
419
+ }
420
+
421
+ versionData.storage_provider = 'external'
422
+ versionData.external_url = `https://${s3BucketName}.s3.amazonaws.com/${encodeFileName}`
423
+ const { error: dbError2 } = await updateOrCreateVersion(supabase, versionData)
424
+ if (dbError2) {
425
+ p.log.error(`Cannot update bundle ${formatError(dbError2)}`)
426
+ program.error('')
427
+ }
428
+ spinner.stop('Bundle Uploaded 💪')
429
+ }
364
430
  const { data: versionId } = await supabase
365
431
  .rpc('get_app_versions', { apikey: options.apikey, name_version: bundle, appid })
366
432
  .single()
package/src/index.ts CHANGED
@@ -113,6 +113,10 @@ bundle
113
113
  .option('-c, --channel <channel>', 'channel to link to')
114
114
  .option('-e, --external <url>', 'link to external url intead of upload to Capgo Cloud')
115
115
  .option('--iv-session-key <key>', 'Set the iv and session key for bundle url external')
116
+ .option('--s3-region <region>', 'Region for your AWS S3 bucket')
117
+ .option('--s3-apikey <apikey>', 'apikey for your AWS S3 account')
118
+ .option('--s3-apisecret <apisecret>', 'api secret for your AWS S3 account')
119
+ .option('--s3-bucket-name <bucketName>', 'Name for your AWS S3 bucket')
116
120
  .option('--key <key>', 'custom path for public signing key')
117
121
  .option('--key-data <keyData>', 'base64 public signing key')
118
122
  .option('--bundle-url', 'prints bundle url into stdout')