@capawesome/cli 1.4.1 → 1.5.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/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [1.5.0](https://github.com/capawesome-team/cli/compare/v1.4.1...v1.5.0) (2025-02-21)
6
+
7
+
8
+ ### Features
9
+
10
+ * **apps:bundles:create:** support code signing for self-hosted bundles ([ebc84ec](https://github.com/capawesome-team/cli/commit/ebc84ecdf3006e9b68491d3082991d0bcf8f9423))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **apps:bundles:create:** provide a url without path to support self-hosted bundles ([1dcf020](https://github.com/capawesome-team/cli/commit/1dcf020ff006445e3ff211ed66a1cec1afdd012d))
16
+
5
17
  ## [1.4.1](https://github.com/capawesome-team/cli/compare/v1.4.0...v1.4.1) (2025-02-16)
6
18
 
7
19
 
@@ -127,6 +127,7 @@ exports.default = (0, citty_1.defineCommand)({
127
127
  }
128
128
  rolloutPercentage = rolloutAsNumber;
129
129
  }
130
+ // Check that either a path or a url is provided
130
131
  if (!path && !url) {
131
132
  path = yield (0, prompt_1.prompt)('Enter the path to the app bundle:', {
132
133
  type: 'text',
@@ -136,6 +137,7 @@ exports.default = (0, citty_1.defineCommand)({
136
137
  process.exit(1);
137
138
  }
138
139
  }
140
+ // Check that the path is a directory when creating a bundle with an artifact type
139
141
  if (artifactType === 'manifest' && path) {
140
142
  const pathIsDirectory = (0, file_1.isDirectory)(path);
141
143
  if (!pathIsDirectory) {
@@ -143,12 +145,20 @@ exports.default = (0, citty_1.defineCommand)({
143
145
  process.exit(1);
144
146
  }
145
147
  }
146
- // Check if the path exists
147
- const pathExists = yield (0, file_1.fileExistsAtPath)(path);
148
- if (!pathExists) {
149
- consola_1.default.error(`The path does not exist.`);
148
+ // Check that a URL is not provided when creating a bundle with an artifact type of manifest
149
+ if (artifactType === 'manifest' && url) {
150
+ consola_1.default.error('It is not yet possible to provide a URL when creating a bundle with an artifact type of `manifest`.');
150
151
  process.exit(1);
151
152
  }
153
+ // Check if the path exists when a path is provided
154
+ if (path) {
155
+ const pathExists = yield (0, file_1.fileExistsAtPath)(path);
156
+ if (!pathExists) {
157
+ consola_1.default.error(`The path does not exist.`);
158
+ process.exit(1);
159
+ }
160
+ }
161
+ // Let the user select an app and channel if not provided
152
162
  if (!appId) {
153
163
  const apps = yield apps_1.default.findAll();
154
164
  if (apps.length === 0) {
@@ -180,6 +190,7 @@ exports.default = (0, citty_1.defineCommand)({
180
190
  }
181
191
  }
182
192
  }
193
+ // Create the private key buffer
183
194
  let privateKeyBuffer;
184
195
  if (privateKey) {
185
196
  if (privateKey.endsWith('.pem')) {
@@ -201,10 +212,22 @@ exports.default = (0, citty_1.defineCommand)({
201
212
  try {
202
213
  // Create the app bundle
203
214
  consola_1.default.start('Creating bundle...');
215
+ let checksum;
216
+ let signature;
217
+ if (path && url) {
218
+ const fileBuffer = yield (0, buffer_1.createBufferFromPath)(path);
219
+ // Generate checksum
220
+ checksum = yield (0, hash_1.createHash)(fileBuffer);
221
+ // Sign the bundle
222
+ if (privateKeyBuffer) {
223
+ signature = yield (0, signature_1.createSignature)(privateKeyBuffer, fileBuffer);
224
+ }
225
+ }
204
226
  const response = yield app_bundles_1.default.create({
205
227
  appId,
206
228
  artifactType,
207
229
  channelName,
230
+ checksum,
208
231
  customProperties: parseCustomProperties(customProperty),
209
232
  expiresAt: expiresAt,
210
233
  url,
@@ -213,21 +236,28 @@ exports.default = (0, citty_1.defineCommand)({
213
236
  minAndroidAppVersionCode: androidMin,
214
237
  minIosAppVersionCode: iosMin,
215
238
  rolloutPercentage,
239
+ signature,
216
240
  });
217
241
  appBundleId = response.id;
218
242
  if (path) {
219
- let appBundleFileId;
220
- // Upload the app bundle files
221
- if (artifactType === 'manifest') {
222
- yield uploadFiles({ appId, appBundleId: response.id, path, privateKeyBuffer });
243
+ if (url) {
244
+ // Important: Do NOT upload files if the URL is provided.
245
+ // The user wants to self-host the bundle. The path is only needed for code signing.
223
246
  }
224
247
  else {
225
- const result = yield uploadZip({ appId, appBundleId: response.id, path, privateKeyBuffer });
226
- appBundleFileId = result.appBundleFileId;
248
+ let appBundleFileId;
249
+ // Upload the app bundle files
250
+ if (artifactType === 'manifest') {
251
+ yield uploadFiles({ appId, appBundleId: response.id, path, privateKeyBuffer });
252
+ }
253
+ else {
254
+ const result = yield uploadZip({ appId, appBundleId: response.id, path, privateKeyBuffer });
255
+ appBundleFileId = result.appBundleFileId;
256
+ }
257
+ // Update the app bundle
258
+ consola_1.default.start('Updating bundle...');
259
+ yield app_bundles_1.default.update({ appBundleFileId, appId, artifactStatus: 'ready', appBundleId: response.id });
227
260
  }
228
- // Update the app bundle
229
- consola_1.default.start('Updating bundle...');
230
- yield app_bundles_1.default.update({ appBundleFileId, appId, artifactStatus: 'ready', appBundleId: response.id });
231
261
  }
232
262
  consola_1.default.success('Bundle successfully created.');
233
263
  consola_1.default.info(`Bundle ID: ${response.id}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capawesome/cli",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.",
5
5
  "scripts": {
6
6
  "build": "patch-package && rimraf ./dist && tsc",