@capawesome/cli 1.13.2 → 1.14.0-dev.3b0fc7e.1755934102

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 (76) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +7 -3
  3. package/dist/commands/apps/bundles/create.js +218 -234
  4. package/dist/commands/apps/bundles/create.test.js +276 -0
  5. package/dist/commands/apps/bundles/delete.js +47 -55
  6. package/dist/commands/apps/bundles/delete.test.js +139 -0
  7. package/dist/commands/apps/bundles/update.js +73 -84
  8. package/dist/commands/apps/bundles/update.test.js +141 -0
  9. package/dist/commands/apps/channels/create.js +57 -70
  10. package/dist/commands/apps/channels/create.test.js +119 -0
  11. package/dist/commands/apps/channels/delete.js +58 -64
  12. package/dist/commands/apps/channels/delete.test.js +141 -0
  13. package/dist/commands/apps/channels/get.js +52 -94
  14. package/dist/commands/apps/channels/get.test.js +135 -0
  15. package/dist/commands/apps/channels/list.js +37 -82
  16. package/dist/commands/apps/channels/list.test.js +121 -0
  17. package/dist/commands/apps/channels/update.js +50 -77
  18. package/dist/commands/apps/channels/update.test.js +138 -0
  19. package/dist/commands/apps/create.js +39 -42
  20. package/dist/commands/apps/create.test.js +117 -0
  21. package/dist/commands/apps/delete.js +41 -45
  22. package/dist/commands/apps/delete.test.js +120 -0
  23. package/dist/commands/apps/devices/delete.js +47 -55
  24. package/dist/commands/apps/devices/delete.test.js +139 -0
  25. package/dist/commands/doctor.js +12 -29
  26. package/dist/commands/doctor.test.js +52 -0
  27. package/dist/commands/login.js +50 -71
  28. package/dist/commands/login.test.js +116 -0
  29. package/dist/commands/logout.js +13 -31
  30. package/dist/commands/logout.test.js +47 -0
  31. package/dist/commands/manifests/generate.js +20 -38
  32. package/dist/commands/manifests/generate.test.js +60 -0
  33. package/dist/commands/organizations/create.js +25 -0
  34. package/dist/commands/organizations/create.test.js +80 -0
  35. package/dist/commands/whoami.js +20 -31
  36. package/dist/commands/whoami.test.js +30 -0
  37. package/dist/config/consts.js +4 -5
  38. package/dist/config/index.js +1 -17
  39. package/dist/index.js +54 -80
  40. package/dist/services/app-bundle-files.js +117 -136
  41. package/dist/services/app-bundles.js +22 -41
  42. package/dist/services/app-channels.js +54 -77
  43. package/dist/services/app-devices.js +10 -25
  44. package/dist/services/apps.js +25 -41
  45. package/dist/services/authorization-service.js +4 -8
  46. package/dist/services/config.js +15 -28
  47. package/dist/services/organizations.js +26 -0
  48. package/dist/services/session-code.js +7 -22
  49. package/dist/services/sessions.js +13 -30
  50. package/dist/services/update.js +17 -55
  51. package/dist/services/users.js +11 -26
  52. package/dist/types/app-bundle-file.js +1 -2
  53. package/dist/types/app-bundle.js +1 -2
  54. package/dist/types/app-channel.js +1 -2
  55. package/dist/types/app-device.js +1 -2
  56. package/dist/types/app.js +1 -2
  57. package/dist/types/index.js +8 -23
  58. package/dist/types/npm-package.js +1 -2
  59. package/dist/types/organization.js +1 -0
  60. package/dist/types/session-code.js +1 -2
  61. package/dist/types/session.js +1 -2
  62. package/dist/types/user.js +1 -2
  63. package/dist/utils/buffer.js +12 -43
  64. package/dist/utils/error.js +24 -14
  65. package/dist/utils/file.js +22 -41
  66. package/dist/utils/hash.js +3 -39
  67. package/dist/utils/http-client.js +27 -53
  68. package/dist/utils/manifest.js +11 -24
  69. package/dist/utils/private-key.js +23 -0
  70. package/dist/utils/prompt.js +9 -26
  71. package/dist/utils/signature.js +3 -39
  72. package/dist/utils/user-config.js +12 -0
  73. package/dist/utils/zip.js +11 -27
  74. package/package.json +22 -9
  75. package/dist/utils/ci.js +0 -7
  76. package/dist/utils/userConfig.js +0 -16
@@ -1,216 +1,190 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- const citty_1 = require("citty");
16
- const consola_1 = __importDefault(require("consola"));
17
- const fs_1 = require("fs");
18
- const config_1 = require("../../../config");
19
- const app_bundle_files_1 = __importDefault(require("../../../services/app-bundle-files"));
20
- const app_bundles_1 = __importDefault(require("../../../services/app-bundles"));
21
- const apps_1 = __importDefault(require("../../../services/apps"));
22
- const authorization_service_1 = __importDefault(require("../../../services/authorization-service"));
23
- const buffer_1 = require("../../../utils/buffer");
24
- const error_1 = require("../../../utils/error");
25
- const file_1 = require("../../../utils/file");
26
- const hash_1 = require("../../../utils/hash");
27
- const manifest_1 = require("../../../utils/manifest");
28
- const prompt_1 = require("../../../utils/prompt");
29
- const signature_1 = require("../../../utils/signature");
30
- const zip_1 = __importDefault(require("../../../utils/zip"));
31
- exports.default = (0, citty_1.defineCommand)({
32
- meta: {
33
- description: 'Create a new app bundle.',
34
- },
35
- args: {
36
- androidMax: {
37
- type: 'string',
38
- description: 'The maximum Android version code (`versionCode`) that the bundle supports.',
39
- },
40
- androidMin: {
41
- type: 'string',
42
- description: 'The minimum Android version code (`versionCode`) that the bundle supports.',
43
- },
44
- appId: {
45
- type: 'string',
46
- description: 'App ID to deploy to.',
47
- },
48
- artifactType: {
49
- type: 'string',
50
- description: 'The type of artifact to deploy. Must be either `manifest` or `zip`. The default is `zip`.',
51
- },
52
- channel: {
53
- type: 'string',
54
- description: 'Channel to associate the bundle with.',
55
- },
56
- commitMessage: {
57
- type: 'string',
58
- description: 'The commit message related to the bundle.',
59
- },
60
- commitRef: {
61
- type: 'string',
62
- description: 'The commit ref related to the bundle.',
63
- },
64
- commitSha: {
65
- type: 'string',
66
- description: 'The commit sha related to the bundle.',
67
- },
68
- customProperty: {
69
- type: 'string',
70
- description: 'A custom property to assign to the bundle. Must be in the format `key=value`. Can be specified multiple times.',
71
- },
72
- expiresInDays: {
73
- type: 'string',
74
- description: 'The number of days until the bundle is automatically deleted.',
75
- },
76
- iosMax: {
77
- type: 'string',
78
- description: 'The maximum iOS bundle version (`CFBundleVersion`) that the bundle supports.',
79
- },
80
- iosMin: {
81
- type: 'string',
82
- description: 'The minimum iOS bundle version (`CFBundleVersion`) that the bundle supports.',
83
- },
84
- path: {
85
- type: 'string',
86
- description: 'Path to the bundle to upload. Must be a folder (e.g. `www` or `dist`) or a zip file.',
87
- },
88
- privateKey: {
89
- type: 'string',
90
- description: 'The path to the private key file to sign the bundle with.',
91
- },
92
- rollout: {
93
- type: 'string',
94
- description: 'The percentage of devices to deploy the bundle to. Must be a number between 0 and 1 (e.g. 0.5).',
95
- },
96
- url: {
97
- type: 'string',
98
- description: 'The url to the self-hosted bundle file.',
99
- },
100
- },
101
- run: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
102
- if (!authorization_service_1.default.hasAuthorizationToken()) {
103
- consola_1.default.error('You must be logged in to run this command.');
1
+ import { MAX_CONCURRENT_UPLOADS } from '../../../config/index.js';
2
+ import appBundleFilesService from '../../../services/app-bundle-files.js';
3
+ import appBundlesService from '../../../services/app-bundles.js';
4
+ import appsService from '../../../services/apps.js';
5
+ import authorizationService from '../../../services/authorization-service.js';
6
+ import organizationsService from '../../../services/organizations.js';
7
+ import { createBufferFromPath, createBufferFromReadStream, createBufferFromString, isPrivateKeyContent, } from '../../../utils/buffer.js';
8
+ import { formatPrivateKey } from '../../../utils/private-key.js';
9
+ import { fileExistsAtPath, getFilesInDirectoryAndSubdirectories, isDirectory } from '../../../utils/file.js';
10
+ import { createHash } from '../../../utils/hash.js';
11
+ import { generateManifestJson } from '../../../utils/manifest.js';
12
+ import { prompt } from '../../../utils/prompt.js';
13
+ import { createSignature } from '../../../utils/signature.js';
14
+ import zip from '../../../utils/zip.js';
15
+ import { defineCommand, defineOptions } from '@robingenz/zli';
16
+ import consola from 'consola';
17
+ import { createReadStream } from 'fs';
18
+ import { z } from 'zod';
19
+ export default defineCommand({
20
+ description: 'Create a new app bundle.',
21
+ options: defineOptions(z.object({
22
+ androidMax: z.coerce
23
+ .string()
24
+ .optional()
25
+ .describe('The maximum Android version code (`versionCode`) that the bundle supports.'),
26
+ androidMin: z.coerce
27
+ .string()
28
+ .optional()
29
+ .describe('The minimum Android version code (`versionCode`) that the bundle supports.'),
30
+ appId: z
31
+ .string({
32
+ message: 'App ID must be a UUID.',
33
+ })
34
+ .uuid({
35
+ message: 'App ID must be a UUID.',
36
+ })
37
+ .optional()
38
+ .describe('App ID to deploy to.'),
39
+ artifactType: z
40
+ .enum(['manifest', 'zip'], {
41
+ message: 'Invalid artifact type. Must be either `manifest` or `zip`.',
42
+ })
43
+ .optional()
44
+ .describe('The type of artifact to deploy. Must be either `manifest` or `zip`. The default is `zip`.')
45
+ .default('zip'),
46
+ channel: z.string().optional().describe('Channel to associate the bundle with.'),
47
+ commitMessage: z.string().optional().describe('The commit message related to the bundle.'),
48
+ commitRef: z.string().optional().describe('The commit ref related to the bundle.'),
49
+ commitSha: z.string().optional().describe('The commit sha related to the bundle.'),
50
+ customProperty: z
51
+ .array(z.string().min(1).max(100))
52
+ .optional()
53
+ .describe('A custom property to assign to the bundle. Must be in the format `key=value`. Can be specified multiple times.'),
54
+ expiresInDays: z.coerce
55
+ .number({
56
+ message: 'Expiration days must be an integer.',
57
+ })
58
+ .int({
59
+ message: 'Expiration days must be an integer.',
60
+ })
61
+ .optional()
62
+ .describe('The number of days until the bundle is automatically deleted.'),
63
+ iosMax: z
64
+ .string()
65
+ .optional()
66
+ .describe('The maximum iOS bundle version (`CFBundleVersion`) that the bundle supports.'),
67
+ iosMin: z
68
+ .string()
69
+ .optional()
70
+ .describe('The minimum iOS bundle version (`CFBundleVersion`) that the bundle supports.'),
71
+ path: z
72
+ .string()
73
+ .optional()
74
+ .describe('Path to the bundle to upload. Must be a folder (e.g. `www` or `dist`) or a zip file.'),
75
+ privateKey: z
76
+ .string()
77
+ .optional()
78
+ .describe('The private key to sign the bundle with. Can be a file path to a .pem file or the private key content as plain text.'),
79
+ rollout: z.coerce
80
+ .number()
81
+ .min(0)
82
+ .max(1, {
83
+ message: 'Rollout percentage must be a number between 0 and 1 (e.g. 0.5).',
84
+ })
85
+ .optional()
86
+ .default(1)
87
+ .describe('The percentage of devices to deploy the bundle to. Must be a number between 0 and 1 (e.g. 0.5).'),
88
+ url: z.string().optional().describe('The url to the self-hosted bundle file.'),
89
+ })),
90
+ action: async (options, args) => {
91
+ let { androidMax, androidMin, appId, artifactType, channel, commitMessage, commitRef, commitSha, customProperty, expiresInDays, iosMax, iosMin, path, privateKey, rollout, url, } = options;
92
+ // Check if the user is logged in
93
+ if (!authorizationService.hasAuthorizationToken()) {
94
+ consola.error('You must be logged in to run this command.');
104
95
  process.exit(1);
105
96
  }
106
- let androidMax = ctx.args.androidMax === undefined ? undefined : ctx.args.androidMax + ''; // Convert to string
107
- let androidMin = ctx.args.androidMin === undefined ? undefined : ctx.args.androidMin + ''; // Convert to string
108
- let appId = ctx.args.appId;
109
- let artifactType = ctx.args.artifactType === 'manifest' || ctx.args.artifactType === 'zip'
110
- ? ctx.args.artifactType
111
- : 'zip';
112
- let channelName = ctx.args.channel;
113
- let customProperty = ctx.args.customProperty;
114
- let expiresInDays = ctx.args.expiresInDays === undefined ? undefined : ctx.args.expiresInDays + ''; // Convert to string
115
- let iosMax = ctx.args.iosMax === undefined ? undefined : ctx.args.iosMax + ''; // Convert to string
116
- let iosMin = ctx.args.iosMin === undefined ? undefined : ctx.args.iosMin + ''; // Convert to string
117
- let path = ctx.args.path;
118
- let privateKey = ctx.args.privateKey;
119
- let rolloutAsString = ctx.args.rollout === undefined ? undefined : ctx.args.rollout + ''; // Convert to string
120
- let url = ctx.args.url;
121
- let commitMessage = ctx.args.commitMessage;
122
- let commitRef = ctx.args.commitRef;
123
- let commitSha = ctx.args.commitSha;
124
97
  // Validate the expiration days
125
98
  let expiresAt;
126
99
  if (expiresInDays) {
127
- const expiresInDaysAsNumber = parseInt(expiresInDays, 10);
128
- if (isNaN(expiresInDaysAsNumber) || expiresInDaysAsNumber < 1) {
129
- consola_1.default.error('Expires in days must be a number greater than 0.');
130
- process.exit(1);
131
- }
132
100
  const expiresAtDate = new Date();
133
- expiresAtDate.setDate(expiresAtDate.getDate() + expiresInDaysAsNumber);
101
+ expiresAtDate.setDate(expiresAtDate.getDate() + expiresInDays);
134
102
  expiresAt = expiresAtDate.toISOString();
135
103
  }
136
- // Validate the rollout percentage
137
- let rolloutPercentage = 1;
138
- if (rolloutAsString) {
139
- const rolloutAsNumber = parseFloat(rolloutAsString);
140
- if (isNaN(rolloutAsNumber) || rolloutAsNumber < 0 || rolloutAsNumber > 1) {
141
- consola_1.default.error('Rollout percentage must be a number between 0 and 1.');
142
- process.exit(1);
143
- }
144
- rolloutPercentage = rolloutAsNumber;
145
- }
146
104
  // Check that either a path or a url is provided
147
105
  if (!path && !url) {
148
- path = yield (0, prompt_1.prompt)('Enter the path to the app bundle:', {
106
+ path = await prompt('Enter the path to the app bundle:', {
149
107
  type: 'text',
150
108
  });
151
109
  if (!path) {
152
- consola_1.default.error('You must provide a path to the app bundle.');
110
+ consola.error('You must provide a path to the app bundle.');
153
111
  process.exit(1);
154
112
  }
155
113
  }
156
114
  if (path) {
157
115
  // Check if the path exists when a path is provided
158
- const pathExists = yield (0, file_1.fileExistsAtPath)(path);
116
+ const pathExists = await fileExistsAtPath(path);
159
117
  if (!pathExists) {
160
- consola_1.default.error(`The path does not exist.`);
118
+ consola.error(`The path does not exist.`);
161
119
  process.exit(1);
162
120
  }
163
121
  // Check if the directory contains an index.html file
164
- const pathIsDirectory = yield (0, file_1.isDirectory)(path);
122
+ const pathIsDirectory = await isDirectory(path);
165
123
  if (pathIsDirectory) {
166
- const files = yield (0, file_1.getFilesInDirectoryAndSubdirectories)(path);
124
+ const files = await getFilesInDirectoryAndSubdirectories(path);
167
125
  const indexHtml = files.find((file) => file.href === 'index.html');
168
126
  if (!indexHtml) {
169
- consola_1.default.error('The directory must contain an `index.html` file.');
127
+ consola.error('The directory must contain an `index.html` file.');
170
128
  process.exit(1);
171
129
  }
172
130
  }
173
131
  }
174
132
  // Check that the path is a directory when creating a bundle with an artifact type
175
133
  if (artifactType === 'manifest' && path) {
176
- const pathIsDirectory = yield (0, file_1.isDirectory)(path);
134
+ const pathIsDirectory = await isDirectory(path);
177
135
  if (!pathIsDirectory) {
178
- consola_1.default.error('The path must be a folder when creating a bundle with an artifact type of `manifest`.');
136
+ consola.error('The path must be a folder when creating a bundle with an artifact type of `manifest`.');
179
137
  process.exit(1);
180
138
  }
181
139
  }
182
140
  // Check that a URL is not provided when creating a bundle with an artifact type of manifest
183
141
  if (artifactType === 'manifest' && url) {
184
- consola_1.default.error('It is not yet possible to provide a URL when creating a bundle with an artifact type of `manifest`.');
142
+ consola.error('It is not yet possible to provide a URL when creating a bundle with an artifact type of `manifest`.');
185
143
  process.exit(1);
186
144
  }
187
145
  if (!appId) {
188
- const apps = yield apps_1.default.findAll();
146
+ const organizations = await organizationsService.findAll();
147
+ if (organizations.length === 0) {
148
+ consola.error('You must create an organization before creating a bundle.');
149
+ process.exit(1);
150
+ }
151
+ // @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
152
+ const organizationId = await prompt('Select the organization of the app for which you want to create a bundle.', {
153
+ type: 'select',
154
+ options: organizations.map((organization) => ({ label: organization.name, value: organization.id })),
155
+ });
156
+ if (!organizationId) {
157
+ consola.error('You must select the organization of an app for which you want to create a bundle.');
158
+ process.exit(1);
159
+ }
160
+ const apps = await appsService.findAll({
161
+ organizationId,
162
+ });
189
163
  if (apps.length === 0) {
190
- consola_1.default.error('You must create an app before creating a bundle.');
164
+ consola.error('You must create an app before creating a bundle.');
191
165
  process.exit(1);
192
166
  }
193
167
  // @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
194
- appId = yield (0, prompt_1.prompt)('Which app do you want to deploy to:', {
168
+ appId = await prompt('Which app do you want to deploy to:', {
195
169
  type: 'select',
196
170
  options: apps.map((app) => ({ label: app.name, value: app.id })),
197
171
  });
198
172
  if (!appId) {
199
- consola_1.default.error('You must select an app to deploy to.');
173
+ consola.error('You must select an app to deploy to.');
200
174
  process.exit(1);
201
175
  }
202
176
  }
203
- if (!channelName) {
204
- const promptChannel = yield (0, prompt_1.prompt)('Do you want to deploy to a specific channel?', {
177
+ if (!channel) {
178
+ const promptChannel = await prompt('Do you want to deploy to a specific channel?', {
205
179
  type: 'select',
206
180
  options: ['Yes', 'No'],
207
181
  });
208
182
  if (promptChannel === 'Yes') {
209
- channelName = yield (0, prompt_1.prompt)('Enter the channel name:', {
183
+ channel = await prompt('Enter the channel name:', {
210
184
  type: 'text',
211
185
  });
212
- if (!channelName) {
213
- consola_1.default.error('The channel name must be at least one character long.');
186
+ if (!channel) {
187
+ consola.error('The channel name must be at least one character long.');
214
188
  process.exit(1);
215
189
  }
216
190
  }
@@ -218,57 +192,66 @@ exports.default = (0, citty_1.defineCommand)({
218
192
  // Create the private key buffer
219
193
  let privateKeyBuffer;
220
194
  if (privateKey) {
221
- if (privateKey.endsWith('.pem')) {
222
- const fileExists = yield (0, file_1.fileExistsAtPath)(privateKey);
195
+ if (isPrivateKeyContent(privateKey)) {
196
+ // Handle plain text private key content
197
+ const formattedPrivateKey = formatPrivateKey(privateKey);
198
+ privateKeyBuffer = createBufferFromString(formattedPrivateKey);
199
+ }
200
+ else if (privateKey.endsWith('.pem')) {
201
+ // Handle file path
202
+ const fileExists = await fileExistsAtPath(privateKey);
223
203
  if (fileExists) {
224
- privateKeyBuffer = yield (0, buffer_1.createBufferFromPath)(privateKey);
204
+ const keyBuffer = await createBufferFromPath(privateKey);
205
+ const keyContent = keyBuffer.toString('utf8');
206
+ const formattedPrivateKey = formatPrivateKey(keyContent);
207
+ privateKeyBuffer = createBufferFromString(formattedPrivateKey);
225
208
  }
226
209
  else {
227
- consola_1.default.error('Private key file not found.');
210
+ consola.error('Private key file not found.');
228
211
  process.exit(1);
229
212
  }
230
213
  }
231
214
  else {
232
- consola_1.default.error('Private key must be a path to a .pem file.');
215
+ consola.error('Private key must be either a path to a .pem file or the private key content as plain text.');
233
216
  process.exit(1);
234
217
  }
235
218
  }
236
219
  let appBundleId;
237
220
  try {
238
221
  // Create the app bundle
239
- consola_1.default.start('Creating bundle...');
222
+ consola.start('Creating bundle...');
240
223
  let checksum;
241
224
  let signature;
242
225
  if (path && url) {
243
226
  // Create the file buffer
244
- if (!zip_1.default.isZipped(path)) {
245
- consola_1.default.error('The path must be a zip file when providing a URL.');
227
+ if (!zip.isZipped(path)) {
228
+ consola.error('The path must be a zip file when providing a URL.');
246
229
  process.exit(1);
247
230
  }
248
- const fileBuffer = yield (0, buffer_1.createBufferFromPath)(path);
231
+ const fileBuffer = await createBufferFromPath(path);
249
232
  // Generate checksum
250
- checksum = yield (0, hash_1.createHash)(fileBuffer);
233
+ checksum = await createHash(fileBuffer);
251
234
  // Sign the bundle
252
235
  if (privateKeyBuffer) {
253
- signature = yield (0, signature_1.createSignature)(privateKeyBuffer, fileBuffer);
236
+ signature = await createSignature(privateKeyBuffer, fileBuffer);
254
237
  }
255
238
  }
256
- const response = yield app_bundles_1.default.create({
239
+ const response = await appBundlesService.create({
257
240
  appId,
258
241
  artifactType,
259
- channelName,
242
+ channelName: channel,
260
243
  checksum,
261
244
  gitCommitMessage: commitMessage,
262
245
  gitCommitRef: commitRef,
263
246
  gitCommitSha: commitSha,
264
247
  customProperties: parseCustomProperties(customProperty),
265
- expiresAt: expiresAt,
248
+ expiresAt,
266
249
  url,
267
250
  maxAndroidAppVersionCode: androidMax,
268
251
  maxIosAppVersionCode: iosMax,
269
252
  minAndroidAppVersionCode: androidMin,
270
253
  minIosAppVersionCode: iosMin,
271
- rolloutPercentage,
254
+ rolloutPercentage: rollout,
272
255
  signature,
273
256
  });
274
257
  appBundleId = response.id;
@@ -281,132 +264,133 @@ exports.default = (0, citty_1.defineCommand)({
281
264
  let appBundleFileId;
282
265
  // Upload the app bundle files
283
266
  if (artifactType === 'manifest') {
284
- yield uploadFiles({ appId, appBundleId: response.id, path, privateKeyBuffer });
267
+ await uploadFiles({ appId, appBundleId: response.id, path, privateKeyBuffer });
285
268
  }
286
269
  else {
287
- const result = yield uploadZip({ appId, appBundleId: response.id, path, privateKeyBuffer });
270
+ const result = await uploadZip({ appId, appBundleId: response.id, path, privateKeyBuffer });
288
271
  appBundleFileId = result.appBundleFileId;
289
272
  }
290
273
  // Update the app bundle
291
- consola_1.default.start('Updating bundle...');
292
- yield app_bundles_1.default.update({ appBundleFileId, appId, artifactStatus: 'ready', appBundleId: response.id });
274
+ consola.start('Updating bundle...');
275
+ await appBundlesService.update({
276
+ appBundleFileId,
277
+ appId,
278
+ artifactStatus: 'ready',
279
+ appBundleId: response.id,
280
+ });
293
281
  }
294
282
  }
295
- consola_1.default.success('Bundle successfully created.');
296
- consola_1.default.info(`Bundle ID: ${response.id}`);
283
+ consola.success('Bundle successfully created.');
284
+ consola.info(`Bundle ID: ${response.id}`);
297
285
  }
298
286
  catch (error) {
299
287
  if (appBundleId) {
300
- yield app_bundles_1.default.delete({ appId, appBundleId }).catch(() => {
288
+ await appBundlesService.delete({ appId, appBundleId }).catch(() => {
301
289
  // No-op
302
290
  });
303
291
  }
304
- const message = (0, error_1.getMessageFromUnknownError)(error);
305
- consola_1.default.error(message);
306
- process.exit(1);
292
+ throw error;
307
293
  }
308
- }),
294
+ },
309
295
  });
310
- const uploadFile = (options) => __awaiter(void 0, void 0, void 0, function* () {
296
+ const uploadFile = async (options) => {
297
+ let { appId, appBundleId, buffer, href, mimeType, name, privateKeyBuffer, retryOnFailure } = options;
311
298
  try {
312
299
  // Generate checksum
313
- const hash = yield (0, hash_1.createHash)(options.buffer);
300
+ const hash = await createHash(buffer);
314
301
  // Sign the bundle
315
302
  let signature;
316
- if (options.privateKeyBuffer) {
317
- signature = yield (0, signature_1.createSignature)(options.privateKeyBuffer, options.buffer);
303
+ if (privateKeyBuffer) {
304
+ signature = await createSignature(privateKeyBuffer, buffer);
318
305
  }
319
306
  // Create the multipart upload
320
- return yield app_bundle_files_1.default.create({
321
- appId: options.appId,
322
- appBundleId: options.appBundleId,
323
- buffer: options.buffer,
307
+ return await appBundleFilesService.create({
308
+ appId,
309
+ appBundleId,
310
+ buffer,
324
311
  checksum: hash,
325
- href: options.href,
326
- mimeType: options.mimeType,
327
- name: options.name,
312
+ href,
313
+ mimeType,
314
+ name,
328
315
  signature,
329
316
  });
330
317
  }
331
318
  catch (error) {
332
- if (options.retryOnFailure) {
333
- return uploadFile(Object.assign(Object.assign({}, options), { retryOnFailure: false }));
319
+ if (retryOnFailure) {
320
+ return uploadFile({
321
+ ...options,
322
+ retryOnFailure: false,
323
+ });
334
324
  }
335
325
  throw error;
336
326
  }
337
- });
338
- const uploadFiles = (options) => __awaiter(void 0, void 0, void 0, function* () {
327
+ };
328
+ const uploadFiles = async (options) => {
329
+ let { appId, appBundleId, path, privateKeyBuffer } = options;
339
330
  // Generate the manifest file
340
- yield (0, manifest_1.generateManifestJson)(options.path);
331
+ await generateManifestJson(path);
341
332
  // Get all files in the directory
342
- const files = yield (0, file_1.getFilesInDirectoryAndSubdirectories)(options.path);
333
+ const files = await getFilesInDirectoryAndSubdirectories(path);
343
334
  // Iterate over each file
344
335
  let fileIndex = 0;
345
- const uploadNextFile = () => __awaiter(void 0, void 0, void 0, function* () {
336
+ const uploadNextFile = async () => {
346
337
  if (fileIndex >= files.length) {
347
338
  return;
348
339
  }
349
340
  const file = files[fileIndex];
350
341
  fileIndex++;
351
- consola_1.default.start(`Uploading file (${fileIndex}/${files.length})...`);
352
- const buffer = yield (0, buffer_1.createBufferFromPath)(file.path);
353
- yield uploadFile({
354
- appId: options.appId,
355
- appBundleId: options.appBundleId,
342
+ consola.start(`Uploading file (${fileIndex}/${files.length})...`);
343
+ const buffer = await createBufferFromPath(file.path);
344
+ await uploadFile({
345
+ appId,
346
+ appBundleId: appBundleId,
356
347
  buffer,
357
348
  href: file.href,
358
349
  mimeType: file.mimeType,
359
350
  name: file.name,
360
- privateKeyBuffer: options.privateKeyBuffer,
351
+ privateKeyBuffer: privateKeyBuffer,
361
352
  retryOnFailure: true,
362
353
  });
363
- yield uploadNextFile();
364
- });
365
- const uploadPromises = Array.from({ length: config_1.MAX_CONCURRENT_UPLOADS });
366
- for (let i = 0; i < config_1.MAX_CONCURRENT_UPLOADS; i++) {
354
+ await uploadNextFile();
355
+ };
356
+ const uploadPromises = Array.from({ length: MAX_CONCURRENT_UPLOADS });
357
+ for (let i = 0; i < MAX_CONCURRENT_UPLOADS; i++) {
367
358
  uploadPromises[i] = uploadNextFile();
368
359
  }
369
- yield Promise.all(uploadPromises);
370
- });
371
- const uploadZip = (options) => __awaiter(void 0, void 0, void 0, function* () {
360
+ await Promise.all(uploadPromises);
361
+ };
362
+ const uploadZip = async (options) => {
363
+ let { appId, appBundleId, path, privateKeyBuffer } = options;
372
364
  // Read the zip file
373
365
  let fileBuffer;
374
- if (zip_1.default.isZipped(options.path)) {
375
- const readStream = (0, fs_1.createReadStream)(options.path);
376
- fileBuffer = yield (0, buffer_1.createBufferFromReadStream)(readStream);
366
+ if (zip.isZipped(path)) {
367
+ const readStream = createReadStream(path);
368
+ fileBuffer = await createBufferFromReadStream(readStream);
377
369
  }
378
370
  else {
379
- consola_1.default.start('Zipping folder...');
380
- fileBuffer = yield zip_1.default.zipFolder(options.path);
371
+ consola.start('Zipping folder...');
372
+ fileBuffer = await zip.zipFolder(path);
381
373
  }
382
374
  // Upload the zip file
383
- consola_1.default.start('Uploading file...');
384
- const result = yield uploadFile({
385
- appId: options.appId,
386
- appBundleId: options.appBundleId,
375
+ consola.start('Uploading file...');
376
+ const result = await uploadFile({
377
+ appId,
378
+ appBundleId: appBundleId,
387
379
  buffer: fileBuffer,
388
380
  mimeType: 'application/zip',
389
381
  name: 'bundle.zip',
390
- privateKeyBuffer: options.privateKeyBuffer,
382
+ privateKeyBuffer: privateKeyBuffer,
391
383
  });
392
384
  return {
393
385
  appBundleFileId: result.id,
394
386
  };
395
- });
387
+ };
396
388
  const parseCustomProperties = (customProperty) => {
397
389
  let customProperties;
398
390
  if (customProperty) {
399
391
  customProperties = {};
400
- if (Array.isArray(customProperty)) {
401
- for (const property of customProperty) {
402
- const [key, value] = property.split('=');
403
- if (key && value) {
404
- customProperties[key] = value;
405
- }
406
- }
407
- }
408
- else {
409
- const [key, value] = customProperty.split('=');
392
+ for (const property of customProperty) {
393
+ const [key, value] = property.split('=');
410
394
  if (key && value) {
411
395
  customProperties[key] = value;
412
396
  }