@capawesome/cli 4.18.1 → 4.18.3

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,20 @@
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
+ ## [4.18.3](https://github.com/capawesome-team/cli/compare/v4.18.2...v4.18.3) (2026-08-18)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * write the manifest file before uploading a bundle ([#206](https://github.com/capawesome-team/cli/issues/206)) ([631e99b](https://github.com/capawesome-team/cli/commit/631e99bff0b9426260e1f997d00c3fd36e840e78))
11
+
12
+ ## [4.18.2](https://github.com/capawesome-team/cli/compare/v4.18.1...v4.18.2) (2026-08-10)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **uploads:** lower multipart upload threshold to 10 MB ([#204](https://github.com/capawesome-team/cli/issues/204)) ([1fc97c7](https://github.com/capawesome-team/cli/commit/1fc97c78879755196f4cce5bd3791ed62fd2c4bc))
18
+
5
19
  ## [4.18.1](https://github.com/capawesome-team/cli/compare/v4.18.0...v4.18.1) (2026-08-07)
6
20
 
7
21
 
@@ -3,3 +3,5 @@ export const DEFAULT_CONSOLE_BASE_URL = 'https://console.cloud.capawesome.io';
3
3
  export const MANIFEST_JSON_FILE_NAME = 'capawesome-live-update-manifest.json'; // Do NOT change this!
4
4
  export const MAX_CONCURRENT_FILE_UPLOADS = 20;
5
5
  export const MAX_CONCURRENT_PART_UPLOADS = 4;
6
+ export const MULTIPART_UPLOAD_THRESHOLD_IN_BYTES = 10 * 1024 * 1024; // 10 MB
7
+ export const UPLOAD_PART_SIZE_IN_BYTES = 10 * 1024 * 1024; // 10 MB. 5 MB is the minimum part size except for the last part.
@@ -1,4 +1,4 @@
1
- import { MAX_CONCURRENT_PART_UPLOADS } from '../config/index.js';
1
+ import { MAX_CONCURRENT_PART_UPLOADS, UPLOAD_PART_SIZE_IN_BYTES } from '../config/index.js';
2
2
  import authorizationService from '../services/authorization-service.js';
3
3
  import httpClient from '../utils/http-client.js';
4
4
  import FormData from 'form-data';
@@ -63,8 +63,7 @@ class AppBuildSourcesServiceImpl {
63
63
  }
64
64
  async createUploadParts(dto, onProgress) {
65
65
  const uploadedParts = [];
66
- const partSize = 10 * 1024 * 1024; // 10 MB
67
- const totalParts = Math.ceil(dto.buffer.byteLength / partSize);
66
+ const totalParts = Math.ceil(dto.buffer.byteLength / UPLOAD_PART_SIZE_IN_BYTES);
68
67
  let partNumber = 0;
69
68
  const uploadNextPart = async () => {
70
69
  if (partNumber >= totalParts) {
@@ -72,8 +71,8 @@ class AppBuildSourcesServiceImpl {
72
71
  }
73
72
  partNumber++;
74
73
  onProgress?.(partNumber, totalParts);
75
- const start = (partNumber - 1) * partSize;
76
- const end = Math.min(start + partSize, dto.buffer.byteLength);
74
+ const start = (partNumber - 1) * UPLOAD_PART_SIZE_IN_BYTES;
75
+ const end = Math.min(start + UPLOAD_PART_SIZE_IN_BYTES, dto.buffer.byteLength);
77
76
  const partBuffer = dto.buffer.subarray(start, end);
78
77
  const uploadedPart = await this.createUploadPart({
79
78
  appBuildSourceId: dto.appBuildSourceId,
@@ -1,4 +1,4 @@
1
- import { MAX_CONCURRENT_PART_UPLOADS } from '../config/index.js';
1
+ import { MAX_CONCURRENT_PART_UPLOADS, MULTIPART_UPLOAD_THRESHOLD_IN_BYTES, UPLOAD_PART_SIZE_IN_BYTES, } from '../config/index.js';
2
2
  import authorizationService from '../services/authorization-service.js';
3
3
  import httpClient from '../utils/http-client.js';
4
4
  import FormData from 'form-data';
@@ -9,7 +9,7 @@ class AppBundleFilesServiceImpl {
9
9
  }
10
10
  async create(dto, onProgress) {
11
11
  const sizeInBytes = dto.buffer.byteLength;
12
- const useMultipartUpload = sizeInBytes >= 50 * 1024 * 1024; // 50 MB
12
+ const useMultipartUpload = sizeInBytes >= MULTIPART_UPLOAD_THRESHOLD_IN_BYTES;
13
13
  const formData = new FormData();
14
14
  formData.append('checksum', dto.checksum);
15
15
  if (!useMultipartUpload) {
@@ -76,8 +76,7 @@ class AppBundleFilesServiceImpl {
76
76
  }
77
77
  async createUploadParts(dto, onProgress) {
78
78
  const uploadedParts = [];
79
- const partSize = 10 * 1024 * 1024; // 10 MB. 5 MB is the minimum part size except for the last part.
80
- const totalParts = Math.ceil(dto.buffer.byteLength / partSize);
79
+ const totalParts = Math.ceil(dto.buffer.byteLength / UPLOAD_PART_SIZE_IN_BYTES);
81
80
  let partNumber = 0;
82
81
  const uploadNextPart = async () => {
83
82
  if (partNumber >= totalParts) {
@@ -85,8 +84,8 @@ class AppBundleFilesServiceImpl {
85
84
  }
86
85
  partNumber++;
87
86
  onProgress?.(partNumber, totalParts);
88
- const start = (partNumber - 1) * partSize;
89
- const end = Math.min(start + partSize, dto.buffer.byteLength);
87
+ const start = (partNumber - 1) * UPLOAD_PART_SIZE_IN_BYTES;
88
+ const end = Math.min(start + UPLOAD_PART_SIZE_IN_BYTES, dto.buffer.byteLength);
90
89
  const partBuffer = dto.buffer.subarray(start, end);
91
90
  const uploadedPart = await this.createUploadPart({
92
91
  appBundleFileId: dto.appBundleFileId,
@@ -23,5 +23,5 @@ export const generateManifestJson = async (path) => {
23
23
  });
24
24
  }
25
25
  // Write the manifest file
26
- writeFile(`${path}/${MANIFEST_JSON_FILE_NAME}`, JSON.stringify(manifestItems, null, 2));
26
+ await writeFile(`${path}/${MANIFEST_JSON_FILE_NAME}`, JSON.stringify(manifestItems, null, 2));
27
27
  };
@@ -0,0 +1,27 @@
1
+ import fs from 'fs';
2
+ import os from 'os';
3
+ import pathModule from 'path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { MANIFEST_JSON_FILE_NAME } from '../config/index.js';
6
+ import { generateManifestJson } from './manifest.js';
7
+ describe('generateManifestJson', () => {
8
+ let directory;
9
+ beforeEach(() => {
10
+ directory = fs.mkdtempSync(pathModule.join(os.tmpdir(), 'manifest-'));
11
+ fs.mkdirSync(pathModule.join(directory, 'assets'));
12
+ fs.writeFileSync(pathModule.join(directory, 'index.html'), '<html></html>');
13
+ fs.writeFileSync(pathModule.join(directory, 'assets', 'main.js'), 'console.log(1);');
14
+ });
15
+ afterEach(() => {
16
+ fs.rmSync(directory, { force: true, recursive: true });
17
+ });
18
+ it('should write the manifest file before resolving', async () => {
19
+ await generateManifestJson(directory);
20
+ expect(fs.existsSync(pathModule.join(directory, MANIFEST_JSON_FILE_NAME))).toBe(true);
21
+ });
22
+ it('should list all files except the manifest file itself', async () => {
23
+ await generateManifestJson(directory);
24
+ const manifestItems = JSON.parse(fs.readFileSync(pathModule.join(directory, MANIFEST_JSON_FILE_NAME), 'utf8'));
25
+ expect(manifestItems.map((item) => item.href).sort()).toEqual(['assets/main.js', 'index.html']);
26
+ });
27
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capawesome/cli",
3
- "version": "4.18.1",
3
+ "version": "4.18.3",
4
4
  "description": "The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.",
5
5
  "type": "module",
6
6
  "scripts": {