@capgo/cli 4.13.2 → 4.13.4

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.
Files changed (69) hide show
  1. package/dist/index.js +103 -103
  2. package/package.json +1 -1
  3. package/.github/FUNDING.yml +0 -1
  4. package/.github/workflows/autofix.yml +0 -25
  5. package/.github/workflows/build.yml +0 -46
  6. package/.github/workflows/bump_version.yml +0 -56
  7. package/.github/workflows/check_posix_paths.yml +0 -229
  8. package/.github/workflows/test.yml +0 -30
  9. package/.prettierignore +0 -6
  10. package/.vscode/launch.json +0 -23
  11. package/.vscode/settings.json +0 -46
  12. package/.vscode/tasks.json +0 -42
  13. package/CHANGELOG.md +0 -3392
  14. package/build.mjs +0 -21
  15. package/bun.lockb +0 -0
  16. package/bunfig.toml +0 -2
  17. package/capacitor.config.ts +0 -33
  18. package/crypto_explained.png +0 -0
  19. package/eslint.config.js +0 -10
  20. package/renovate.json +0 -23
  21. package/src/api/app.ts +0 -55
  22. package/src/api/channels.ts +0 -163
  23. package/src/api/crypto.ts +0 -116
  24. package/src/api/devices_override.ts +0 -41
  25. package/src/api/update.ts +0 -13
  26. package/src/api/versions.ts +0 -101
  27. package/src/app/add.ts +0 -157
  28. package/src/app/debug.ts +0 -258
  29. package/src/app/delete.ts +0 -110
  30. package/src/app/info.ts +0 -99
  31. package/src/app/list.ts +0 -67
  32. package/src/app/set.ts +0 -96
  33. package/src/bundle/check.ts +0 -42
  34. package/src/bundle/cleanup.ts +0 -123
  35. package/src/bundle/compatibility.ts +0 -70
  36. package/src/bundle/decrypt.ts +0 -54
  37. package/src/bundle/delete.ts +0 -52
  38. package/src/bundle/encrypt.ts +0 -60
  39. package/src/bundle/list.ts +0 -42
  40. package/src/bundle/unlink.ts +0 -88
  41. package/src/bundle/upload.ts +0 -552
  42. package/src/bundle/zip.ts +0 -145
  43. package/src/channel/add.ts +0 -80
  44. package/src/channel/currentBundle.ts +0 -72
  45. package/src/channel/delete.ts +0 -57
  46. package/src/channel/list.ts +0 -49
  47. package/src/channel/set.ts +0 -179
  48. package/src/config/index.ts +0 -156
  49. package/src/index.ts +0 -310
  50. package/src/init.ts +0 -495
  51. package/src/key.ts +0 -135
  52. package/src/login.ts +0 -70
  53. package/src/types/capacitor__cli.d.ts +0 -6
  54. package/src/types/supabase.types.ts +0 -2123
  55. package/src/user/account.ts +0 -11
  56. package/src/utils.ts +0 -1076
  57. package/test/VerifyZip.java +0 -83
  58. package/test/check-posix-paths.js +0 -21
  59. package/test/chunk_convert.ts +0 -28
  60. package/test/data.ts +0 -18769
  61. package/test/test_headers_rls.ts +0 -24
  62. package/test/test_semver.ts +0 -13
  63. package/test/test_upload/app.js +0 -3
  64. package/test/test_upload/assets/check-posix-paths.js +0 -21
  65. package/test/test_upload/index.html +0 -0
  66. package/test/test_zip_swift/Package.resolved +0 -24
  67. package/test/test_zip_swift/Package.swift +0 -29
  68. package/test/test_zip_swift/Sources/main.swift +0 -80
  69. package/tsconfig.json +0 -39
package/src/init.ts DELETED
@@ -1,495 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs'
2
- import type { ExecSyncOptions } from 'node:child_process'
3
- import { execSync, spawnSync } from 'node:child_process'
4
- import { exit } from 'node:process'
5
- import { join } from 'node:path'
6
- import * as p from '@clack/prompts'
7
- import type LogSnag from 'logsnag'
8
- import semver from 'semver'
9
- import tmp from 'tmp'
10
- import { markSnag, waitLog } from './app/debug'
11
- import { createKey } from './key'
12
- import { addChannel } from './channel/add'
13
- import { uploadBundle } from './bundle/upload'
14
- import { doLoginExists, login } from './login'
15
- import { addAppInternal } from './app/add'
16
- import { checkLatest } from './api/update'
17
- import type { Options } from './api/app'
18
- import type { Organization } from './utils'
19
- import { convertAppName, createSupabaseClient, findBuildCommandForProjectType, findMainFile, findMainFileForProjectType, findProjectType, findSavedKey, getConfig, getOrganization, getPMAndCommand, readPackageJson, useLogSnag, verifyUser } from './utils'
20
-
21
- interface SuperOptions extends Options {
22
- local: boolean
23
- }
24
- const importInject = 'import { CapacitorUpdater } from \'@capgo/capacitor-updater\''
25
- const codeInject = 'CapacitorUpdater.notifyAppReady()'
26
- // create regex to find line who start by 'import ' and end by ' from '
27
- const regexImport = /import.*from.*/g
28
- const defaultChannel = 'production'
29
- const execOption = { stdio: 'pipe' }
30
-
31
- let tmpObject: tmp.FileResult['name'] | undefined
32
-
33
- function readTmpObj() {
34
- if (!tmpObject) {
35
- tmpObject = readdirSync(tmp.tmpdir)
36
- .map((name) => { return { name, full: `${tmp.tmpdir}/${name}` } })
37
- .find(obj => obj.name.startsWith('capgocli'))?.full
38
- ?? tmp.fileSync({ prefix: 'capgocli' }).name
39
- }
40
- }
41
-
42
- function markStepDone(step: number) {
43
- try {
44
- readTmpObj()
45
- writeFileSync(tmpObject!, JSON.stringify({ step_done: step }))
46
- }
47
- catch (err) {
48
- p.log.error(`Cannot mark step as done in the CLI, error:\n${err}`)
49
- p.log.warn('Onboarding will continue but please report it to the capgo team!')
50
- }
51
- }
52
-
53
- async function readStepsDone(orgId: string, snag: LogSnag): Promise<number | undefined> {
54
- try {
55
- readTmpObj()
56
- const rawData = readFileSync(tmpObject!, 'utf-8')
57
- if (!rawData || rawData.length === 0)
58
- return undefined
59
-
60
- const { step_done } = JSON.parse(rawData)
61
- p.log.info(`You have already got to the step ${step_done}/10 in the previous session`)
62
- const skipSteps = await p.confirm({ message: 'Would you like to continue from where you left off?' })
63
- await cancelCommand(skipSteps, orgId, snag)
64
- if (skipSteps)
65
- return step_done
66
- return undefined
67
- }
68
- catch (err) {
69
- p.log.error(`Cannot read which steps have been compleated, error:\n${err}`)
70
- p.log.warn('Onboarding will continue but please report it to the capgo team!')
71
- return undefined
72
- }
73
- }
74
-
75
- function cleanupStepsDone() {
76
- if (!tmpObject) {
77
- return
78
- }
79
-
80
- try {
81
- rmSync(tmpObject)
82
- }
83
- catch (err) {
84
- p.log.error(`Cannot delete the tmp steps file.\nError: ${err}`)
85
- }
86
- }
87
-
88
- async function cancelCommand(command: boolean | symbol, orgId: string, snag: LogSnag) {
89
- if (p.isCancel(command)) {
90
- await markSnag('onboarding-v2', orgId, snag, 'canceled', '🤷')
91
- exit()
92
- }
93
- }
94
-
95
- async function markStep(orgId: string, snag: LogSnag, step: number | string) {
96
- return markSnag('onboarding-v2', orgId, snag, `onboarding-step-${step}`)
97
- }
98
-
99
- async function step2(organization: Organization, snag: LogSnag, appId: string, options: SuperOptions) {
100
- const pm = getPMAndCommand()
101
- const doAdd = await p.confirm({ message: `Add ${appId} in Capgo?` })
102
- await cancelCommand(doAdd, organization.gid, snag)
103
- if (doAdd) {
104
- const s = p.spinner()
105
- s.start(`Running: ${pm.runner} @capgo/cli@latest app add ${appId}`)
106
- const addRes = await addAppInternal(appId, options, organization, false)
107
- if (!addRes)
108
- s.stop(`App already add ✅`)
109
- else
110
- s.stop(`App add Done ✅`)
111
- }
112
- else {
113
- p.log.info(`If you change your mind, run it for yourself with: "${pm.runner} @capgo/cli@latest app add ${appId}"`)
114
- }
115
- await markStep(organization.gid, snag, 2)
116
- }
117
-
118
- async function step3(orgId: string, snag: LogSnag, apikey: string, appId: string) {
119
- const pm = getPMAndCommand()
120
- const doChannel = await p.confirm({ message: `Create default channel ${defaultChannel} for ${appId} in Capgo?` })
121
- await cancelCommand(doChannel, orgId, snag)
122
- if (doChannel) {
123
- const s = p.spinner()
124
- // create production channel public
125
- s.start(`Running: ${pm.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default`)
126
- const addChannelRes = await addChannel(defaultChannel, appId, {
127
- default: true,
128
- apikey,
129
- }, false)
130
- if (!addChannelRes)
131
- s.stop(`Channel already added ✅`)
132
- else
133
- s.stop(`Channel add Done ✅`)
134
- }
135
- else {
136
- p.log.info(`If you change your mind, run it for yourself with: "${pm.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default"`)
137
- }
138
- await markStep(orgId, snag, 3)
139
- }
140
-
141
- const urlMigrateV6 = 'https://capacitorjs.com/docs/updating/6-0'
142
- const urlMigrateV5 = 'https://capacitorjs.com/docs/updating/5-0'
143
- async function step4(orgId: string, snag: LogSnag, apikey: string, appId: string) {
144
- const pm = getPMAndCommand()
145
- const doInstall = await p.confirm({ message: `Automatic Install "@capgo/capacitor-updater" dependency in ${appId}?` })
146
- await cancelCommand(doInstall, orgId, snag)
147
- if (doInstall) {
148
- const s = p.spinner()
149
- s.start(`Checking if @capgo/capacitor-updater is installed`)
150
- let versionToInstall = 'latest'
151
- const pack = await readPackageJson()
152
- let coreVersion = pack.dependencies['@capacitor/core'] || pack.devDependencies['@capacitor/core']
153
- coreVersion = coreVersion?.replace('^', '').replace('~', '')
154
- if (!coreVersion) {
155
- s.stop('Error')
156
- p.log.warn(`Cannot find @capacitor/core in package.json, please run \`capgo init\` in a capacitor project`)
157
- p.outro(`Bye 👋`)
158
- exit()
159
- }
160
- else if (semver.lt(coreVersion, '5.0.0')) {
161
- s.stop('Error')
162
- p.log.warn(`@capacitor/core version is ${coreVersion}, please update to Capacitor v5 first: ${urlMigrateV5}`)
163
- p.outro(`Bye 👋`)
164
- exit()
165
- }
166
- else if (semver.lt(coreVersion, '6.0.0')) {
167
- s.stop(`@capacitor/core version is ${coreVersion}, please update to Capacitor v6: ${urlMigrateV6} to access the best features of Capgo`)
168
- versionToInstall = '^5.0.0'
169
- }
170
- if (pm.pm === 'unknown') {
171
- s.stop('Error')
172
- p.log.warn(`Cannot reconize package manager, please run \`capgo init\` in a capacitor project with npm, pnpm, bun or yarn`)
173
- p.outro(`Bye 👋`)
174
- exit()
175
- }
176
- // // use pm to install capgo
177
- // // run command pm install @capgo/capacitor-updater@latest
178
- // check if capgo is already installed in package.json
179
- if (pack.dependencies['@capgo/capacitor-updater']) {
180
- s.stop(`Capgo already installed ✅`)
181
- }
182
- else {
183
- await execSync(`${pm.installCommand} @capgo/capacitor-updater@${versionToInstall}`, execOption as ExecSyncOptions)
184
- s.stop(`Install Done ✅`)
185
- }
186
- }
187
- else {
188
- p.log.info(`If you change your mind, run it for yourself with: "${pm.installCommand} @capgo/capacitor-updater@latest"`)
189
- }
190
- await markStep(orgId, snag, 4)
191
- }
192
-
193
- async function step5(orgId: string, snag: LogSnag, apikey: string, appId: string) {
194
- const doAddCode = await p.confirm({ message: `Automatic Add "${codeInject}" code and import in ${appId}?` })
195
- await cancelCommand(doAddCode, orgId, snag)
196
-
197
- if (doAddCode) {
198
- const s = p.spinner()
199
- s.start(`Adding @capacitor-updater to your main file`)
200
-
201
- const projectType = await findProjectType()
202
- if (projectType === 'nuxtjs-js' || projectType === 'nuxtjs-ts') {
203
- // Nuxt.js specific logic
204
- const nuxtDir = join('plugins')
205
- if (!existsSync(nuxtDir)) {
206
- mkdirSync(nuxtDir, { recursive: true })
207
- }
208
- let nuxtFilePath
209
- if (projectType === 'nuxtjs-ts') {
210
- nuxtFilePath = join(nuxtDir, 'capacitorUpdater.client.ts')
211
- }
212
- else {
213
- nuxtFilePath = join(nuxtDir, 'capacitorUpdater.client.js')
214
- }
215
- const nuxtFileContent = `
216
- import { CapacitorUpdater } from '@capgo/capacitor-updater'
217
-
218
- export default defineNuxtPlugin(() => {
219
- CapacitorUpdater.notifyAppReady()
220
- })
221
- `
222
- if (existsSync(nuxtFilePath)) {
223
- const currentContent = readFileSync(nuxtFilePath, 'utf8')
224
- if (currentContent.includes('CapacitorUpdater.notifyAppReady()')) {
225
- s.stop('Code already added to capacitorUpdater.client.ts file inside plugins directory ✅')
226
- p.log.info('Plugins directory and capacitorUpdater.client.ts file already exist with required code')
227
- }
228
- else {
229
- writeFileSync(nuxtFilePath, nuxtFileContent, 'utf8')
230
- s.stop('Code added to capacitorUpdater.client.ts file inside plugins directory ✅')
231
- p.log.info('Updated capacitorUpdater.client.ts file with required code')
232
- }
233
- }
234
- else {
235
- writeFileSync(nuxtFilePath, nuxtFileContent, 'utf8')
236
- s.stop('Code added to capacitorUpdater.client.ts file inside plugins directory ✅')
237
- p.log.info('Created plugins directory and capacitorUpdater.client.ts file')
238
- }
239
- }
240
- else {
241
- // Handle other project types
242
- let mainFilePath
243
- if (projectType === 'unknown') {
244
- mainFilePath = await findMainFile()
245
- }
246
- else {
247
- const isTypeScript = projectType.endsWith('-ts')
248
- mainFilePath = await findMainFileForProjectType(projectType, isTypeScript)
249
- }
250
-
251
- if (!mainFilePath) {
252
- s.stop('Error')
253
- if (projectType === 'nextjs-js' || projectType === 'nextjs-ts') {
254
- p.log.warn(`You might not be using app router configuration or the latest version of Next.js`)
255
- }
256
- else {
257
- p.log.warn(`Cannot find the latest version of ${projectType}, you might need to upgrade to the latest version of ${projectType}`)
258
- }
259
- p.outro(`Bye 👋`)
260
- exit()
261
- }
262
-
263
- // Open main file and inject codeInject
264
- const mainFile = readFileSync(mainFilePath, 'utf8')
265
- const mainFileContent = mainFile.toString()
266
- const matches = mainFileContent.match(regexImport)
267
- const last = matches?.pop()
268
-
269
- if (!last) {
270
- s.stop('Error')
271
- p.log.warn(`Cannot find import line in main file, use manual installation: https://capgo.app/docs/plugin/installation/`)
272
- p.outro(`Bye 👋`)
273
- exit()
274
- }
275
-
276
- if (mainFileContent.includes(codeInject)) {
277
- s.stop(`Code already added to ${mainFilePath} ✅`)
278
- }
279
- else {
280
- const newMainFileContent = mainFileContent.replace(last, `${last}\n${importInject};\n\n${codeInject};\n`)
281
- writeFileSync(mainFilePath, newMainFileContent, 'utf8')
282
- s.stop(`Code added to ${mainFilePath} ✅`)
283
- }
284
- }
285
-
286
- await markStep(orgId, snag, 5)
287
- }
288
- else {
289
- p.log.info(`Add to your main file the following code:\n\n${importInject};\n\n${codeInject};\n`)
290
- }
291
- }
292
-
293
- async function step6(orgId: string, snag: LogSnag, apikey: string, appId: string) {
294
- const pm = getPMAndCommand()
295
- const doEncrypt = await p.confirm({ message: `Automatic configure end-to-end encryption in ${appId} updates?` })
296
- await cancelCommand(doEncrypt, orgId, snag)
297
- if (doEncrypt) {
298
- const s = p.spinner()
299
- s.start(`Running: ${pm.runner} @capgo/cli@latest key create`)
300
- const keyRes = await createKey({ force: true }, false)
301
- if (!keyRes) {
302
- s.stop('Error')
303
- p.log.warn(`Cannot create key ❌`)
304
- p.outro(`Bye 👋`)
305
- exit(1)
306
- }
307
- else {
308
- s.stop(`key created 🔑`)
309
- }
310
- markSnag('onboarding-v2', orgId, snag, 'Use encryption')
311
- }
312
- await markStep(orgId, snag, 6)
313
- }
314
-
315
- async function step7(orgId: string, snag: LogSnag, apikey: string, appId: string) {
316
- const pm = getPMAndCommand()
317
- const doBuild = await p.confirm({ message: `Automatic build ${appId} with "${pm.pm} run build" ?` })
318
- await cancelCommand(doBuild, orgId, snag)
319
- if (doBuild) {
320
- const s = p.spinner()
321
- const projectType = await findProjectType()
322
- const buildCommand = await findBuildCommandForProjectType(projectType)
323
- s.start(`Running: ${pm.pm} run ${buildCommand} && ${pm.runner} cap sync`)
324
- const pack = await readPackageJson()
325
- // check in script build exist
326
- if (!pack.scripts[buildCommand]) {
327
- s.stop('Error')
328
- p.log.warn(`Cannot find ${buildCommand} script in package.json, please add it and run \`capgo init\` again`)
329
- p.outro(`Bye 👋`)
330
- exit()
331
- }
332
- execSync(`${pm.pm} run ${buildCommand} && ${pm.runner} cap sync`, execOption as ExecSyncOptions)
333
- s.stop(`Build & Sync Done ✅`)
334
- }
335
- else {
336
- p.log.info(`Build yourself with command: ${pm.pm} run build && ${pm.runner} cap sync`)
337
- }
338
- await markStep(orgId, snag, 7)
339
- }
340
-
341
- async function step8(orgId: string, snag: LogSnag, apikey: string, appId: string) {
342
- const pm = getPMAndCommand()
343
- const doBundle = await p.confirm({ message: `Automatic upload ${appId} bundle to Capgo?` })
344
- await cancelCommand(doBundle, orgId, snag)
345
- if (doBundle) {
346
- const s = p.spinner()
347
- s.start(`Running: ${pm.runner} @capgo/cli@latest bundle upload`)
348
- const uploadRes = await uploadBundle(appId, {
349
- channel: defaultChannel,
350
- apikey,
351
- }, false)
352
- if (!uploadRes) {
353
- s.stop('Error')
354
- p.log.warn(`Upload failed ❌`)
355
- p.outro(`Bye 👋`)
356
- exit()
357
- }
358
- else {
359
- s.stop(`Upload Done ✅`)
360
- }
361
- }
362
- else {
363
- p.log.info(`Upload yourself with command: ${pm.runner} @capgo/cli@latest bundle upload`)
364
- }
365
- await markStep(orgId, snag, 8)
366
- }
367
-
368
- async function step9(orgId: string, snag: LogSnag) {
369
- const pm = getPMAndCommand()
370
- const doRun = await p.confirm({ message: `Run in device now ?` })
371
- await cancelCommand(doRun, orgId, snag)
372
- if (doRun) {
373
- const plaformType = await p.select({
374
- message: 'Pick a platform to run your app',
375
- options: [
376
- { value: 'ios', label: 'IOS' },
377
- { value: 'android', label: 'Android' },
378
- ],
379
- })
380
- if (p.isCancel(plaformType)) {
381
- p.outro(`Bye 👋`)
382
- exit()
383
- }
384
-
385
- const platform = plaformType as 'ios' | 'android'
386
- const s = p.spinner()
387
- s.start(`Running: ${pm.runner} cap run ${platform}`)
388
- await spawnSync(pm.runner, ['cap', 'run', platform], { stdio: 'inherit' })
389
- s.stop(`Started Done ✅`)
390
- }
391
- else {
392
- p.log.info(`If you change your mind, run it for yourself with: ${pm.runner} cap run <ios|android>`)
393
- }
394
- await markStep(orgId, snag, 9)
395
- }
396
-
397
- async function step10(orgId: string, snag: LogSnag, apikey: string, appId: string) {
398
- const doRun = await p.confirm({ message: `Automatic check if update working in device ?` })
399
- await cancelCommand(doRun, orgId, snag)
400
- if (doRun) {
401
- p.log.info(`Wait logs sent to Capgo from ${appId} device, Please open your app 💪`)
402
- await waitLog('onboarding-v2', apikey, appId, snag, orgId)
403
- }
404
- else {
405
- const appIdUrl = convertAppName(appId)
406
- p.log.info(`Check logs in https://web.capgo.app/app/p/${appIdUrl}/logs to see if update works.`)
407
- }
408
- await markStep(orgId, snag, 10)
409
- }
410
-
411
- export async function initApp(apikeyCommand: string, appId: string, options: SuperOptions) {
412
- const pm = getPMAndCommand()
413
- p.intro(`Capgo onboarding 🛫`)
414
- await checkLatest()
415
- const snag = useLogSnag()
416
- const extConfig = await getConfig()
417
- appId = appId || extConfig?.config?.appId
418
- const apikey = apikeyCommand || findSavedKey()
419
-
420
- const log = p.spinner()
421
- if (!doLoginExists() || apikeyCommand) {
422
- log.start(`Running: ${pm.runner} @capgo/cli@latest login ***`)
423
- await login(apikey, options, false)
424
- log.stop('Login Done ✅')
425
- }
426
-
427
- const supabase = await createSupabaseClient(apikey)
428
- await verifyUser(supabase, apikey, ['upload', 'all', 'read', 'write'])
429
-
430
- const organization = await getOrganization(supabase, ['admin', 'super_admin'])
431
- const orgId = organization.gid
432
-
433
- const stepToSkip = await readStepsDone(orgId, snag) ?? 0
434
-
435
- try {
436
- if (stepToSkip < 1)
437
- await markStep(orgId, snag, 1)
438
-
439
- if (stepToSkip < 2) {
440
- await step2(organization, snag, appId, options)
441
- markStepDone(2)
442
- }
443
-
444
- if (stepToSkip < 3) {
445
- await step3(orgId, snag, apikey, appId)
446
- markStepDone(3)
447
- }
448
-
449
- if (stepToSkip < 4) {
450
- await step4(orgId, snag, apikey, appId)
451
- markStepDone(4)
452
- }
453
-
454
- if (stepToSkip < 5) {
455
- await step5(orgId, snag, apikey, appId)
456
- markStepDone(5)
457
- }
458
-
459
- if (stepToSkip < 6) {
460
- await step6(orgId, snag, apikey, appId)
461
- markStepDone(6)
462
- }
463
-
464
- if (stepToSkip < 7) {
465
- await step7(orgId, snag, apikey, appId)
466
- markStepDone(7)
467
- }
468
-
469
- if (stepToSkip < 8) {
470
- await step8(orgId, snag, apikey, appId)
471
- markStepDone(8)
472
- }
473
-
474
- if (stepToSkip < 9) {
475
- await step9(orgId, snag)
476
- markStepDone(9)
477
- }
478
-
479
- await step10(orgId, snag, apikey, appId)
480
- await markStep(orgId, snag, 0)
481
- cleanupStepsDone()
482
- }
483
- catch (e) {
484
- console.error(e)
485
- p.log.error(`Error during onboarding, please try again later`)
486
- exit(1)
487
- }
488
-
489
- p.log.info(`Welcome onboard ✈️!`)
490
- p.log.info(`Your Capgo update system is setup`)
491
- p.log.info(`Next time use \`${pm.runner} @capgo/cli@latest bundle upload\` to only upload your bundle`)
492
- p.log.info(`If you have any issue try to use the debug command \`${pm.runner} @capgo/cli@latest app debug\``)
493
- p.outro(`Bye 👋`)
494
- exit()
495
- }
package/src/key.ts DELETED
@@ -1,135 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync } from 'node:fs'
2
- import { program } from 'commander'
3
- import { intro, log, outro } from '@clack/prompts'
4
- import { writeConfig } from './config'
5
- import { createRSA } from './api/crypto'
6
- import { baseKey, baseKeyPub, getConfig } from './utils'
7
- import { checkLatest } from './api/update'
8
-
9
- interface saveOptions {
10
- key?: string
11
- keyData?: string
12
- }
13
- interface Options {
14
- force?: boolean
15
- }
16
-
17
- export async function saveKey(options: saveOptions, logg = true) {
18
- if (logg)
19
- intro(`Save keys 🔑`)
20
-
21
- const extConfig = await getConfig()
22
-
23
- const keyPath = options.key || baseKey
24
- // check if publicKey exist
25
-
26
- let privateKey = options.keyData || ''
27
-
28
- if (!existsSync(keyPath) && !privateKey) {
29
- if (logg) {
30
- log.error(`Cannot find public key ${keyPath} or as keyData option or in ${extConfig.path}`)
31
- program.error('')
32
- }
33
- else {
34
- return false
35
- }
36
- }
37
- else if (existsSync(keyPath)) {
38
- // open with fs publicKey path
39
- const keyFile = readFileSync(keyPath)
40
- privateKey = keyFile.toString()
41
- }
42
-
43
- if (extConfig?.config) {
44
- if (!extConfig.config.plugins) {
45
- extConfig.config.plugins = {
46
- extConfig: {},
47
- CapacitorUpdater: {},
48
- }
49
- }
50
- if (!extConfig.config.plugins.CapacitorUpdater)
51
- extConfig.config.plugins.CapacitorUpdater = {}
52
-
53
- extConfig.config.plugins.CapacitorUpdater.privateKey = privateKey
54
- // console.log('extConfig', extConfig)
55
- await writeConfig(extConfig)
56
- }
57
- if (log) {
58
- log.success(`private key saved into ${extConfig.path} file in local directory`)
59
- log.success(`your app will decode the zip archive with this key`)
60
- }
61
- return true
62
- }
63
- export async function saveKeyCommand(options: saveOptions) {
64
- intro(`Save keys 🔑`)
65
- await checkLatest()
66
- await saveKey(options)
67
- }
68
-
69
- export async function createKey(options: Options, logg = true) {
70
- // write in file .capgo the apikey in home directory
71
- if (logg)
72
- intro(`Create keys 🔑`)
73
-
74
- const { publicKey, privateKey } = createRSA()
75
-
76
- // check if baseName already exist
77
- if (existsSync(baseKeyPub) && !options.force) {
78
- log.error('Public Key already exists, use --force to overwrite')
79
- if (logg) {
80
- program.error('')
81
- }
82
- else {
83
- return false
84
- }
85
- }
86
- writeFileSync(baseKeyPub, publicKey)
87
- if (existsSync(baseKey) && !options.force) {
88
- log.error('Private Key already exists, use --force to overwrite')
89
- if (logg) {
90
- program.error('')
91
- }
92
- else {
93
- return false
94
- }
95
- }
96
- writeFileSync(baseKey, privateKey)
97
-
98
- const extConfig = await getConfig()
99
- if (extConfig?.config) {
100
- if (!extConfig.config.plugins) {
101
- extConfig.config.plugins = {
102
- extConfig: {},
103
- CapacitorUpdater: {},
104
- }
105
- }
106
-
107
- if (!extConfig.config.plugins.CapacitorUpdater) {
108
- extConfig.config.plugins.CapacitorUpdater = {}
109
- }
110
-
111
- const flattenPrivateKey = privateKey.replace(/\\n/g, '\\n')
112
- extConfig.config.plugins.CapacitorUpdater.privateKey = flattenPrivateKey
113
- // console.log('extConfig', extConfig)
114
- writeConfig(extConfig)
115
- }
116
-
117
- if (logg) {
118
- log.success('Your RSA key has been generated')
119
- log.success(`Public key saved in ${baseKeyPub}`)
120
- log.success('This key will be use to encrypt your bundle before sending it to Capgo')
121
- log.success('Keep it safe')
122
- log.success('Than make it unreadable by Capgo and unmodifiable by anyone')
123
- log.success(`Private key saved in ${extConfig.path}`)
124
- log.success('Your app will be the only one having it')
125
- log.success('Only your users can decrypt your update')
126
- log.success('Only you can send them an update')
127
- outro(`Done ✅`)
128
- }
129
- return true
130
- }
131
-
132
- export async function createKeyCommand(options: Options) {
133
- await checkLatest()
134
- await createKey(options)
135
- }
package/src/login.ts DELETED
@@ -1,70 +0,0 @@
1
- import { appendFileSync, existsSync, writeFileSync } from 'node:fs'
2
- import { homedir } from 'node:os'
3
- import { exit } from 'node:process'
4
- import { program } from 'commander'
5
- import { intro, log, outro } from '@clack/prompts'
6
- import { createSupabaseClient, useLogSnag, verifyUser } from './utils'
7
- import { checkLatest } from './api/update'
8
-
9
- interface Options {
10
- local: boolean
11
- }
12
- export async function doLoginExists() {
13
- const userHomeDir = homedir()
14
- return existsSync(`${userHomeDir}/.capgo`) || existsSync('.capgo')
15
- }
16
-
17
- export async function login(apikey: string, options: Options, shouldExit = true) {
18
- if (shouldExit)
19
- intro(`Login to Capgo`)
20
-
21
- if (!apikey) {
22
- if (shouldExit) {
23
- log.error('Missing API key, you need to provide a API key to upload your bundle')
24
- program.error('')
25
- }
26
- return false
27
- }
28
- await checkLatest()
29
- // write in file .capgo the apikey in home directory
30
- try {
31
- const { local } = options
32
- const snag = useLogSnag()
33
-
34
- if (local) {
35
- if (!existsSync('.git')) {
36
- log.error('To use local you should be in a git repository')
37
- program.error('')
38
- }
39
- writeFileSync('.capgo', `${apikey}\n`)
40
- appendFileSync('.gitignore', '.capgo\n')
41
- }
42
- else {
43
- const userHomeDir = homedir()
44
- writeFileSync(`${userHomeDir}/.capgo`, `${apikey}\n`)
45
- }
46
- const supabase = await createSupabaseClient(apikey)
47
- const userId = await verifyUser(supabase, apikey, ['write', 'all', 'upload'])
48
- await snag.track({
49
- channel: 'user-login',
50
- event: 'User CLI login',
51
- icon: '✅',
52
- user_id: userId,
53
- notify: false,
54
- }).catch()
55
- log.success(`login saved into .capgo file in ${local ? 'local' : 'home'} directory`)
56
- }
57
- catch (e) {
58
- log.error(`Error while saving login`)
59
- exit(1)
60
- }
61
- if (shouldExit) {
62
- outro('Done ✅')
63
- exit()
64
- }
65
- return true
66
- }
67
-
68
- export async function loginCommand(apikey: string, options: Options) {
69
- login(apikey, options, true)
70
- }
@@ -1,6 +0,0 @@
1
- // CapacitorConfig
2
-
3
- declare module '@capacitor/cli/dist/config' {
4
- export function loadConfig(): CapacitorConfig
5
- export function writeConfig(extConfig: CapacitorConfig, extConfigFilePath: string): void
6
- };