@capawesome/cli 0.0.10 → 0.0.12
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,25 @@
|
|
|
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
|
+
## [0.0.12](https://github.com/capawesome-team/cli/compare/v0.0.11...v0.0.12) (2024-07-25)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **apps:** typo ([2376f13](https://github.com/capawesome-team/cli/commit/2376f1397e4b8e71aeea58fff3b2338d59ab41e7))
|
|
11
|
+
|
|
12
|
+
## [0.0.11](https://github.com/capawesome-team/cli/compare/v0.0.10...v0.0.11) (2024-07-12)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* add support for signature verification ([#6](https://github.com/capawesome-team/cli/issues/6)) ([b82a190](https://github.com/capawesome-team/cli/commit/b82a1901f9cbca856d493e0c778fefb8205f6742))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* **apps:** throw error if empty path is provided ([e5de25c](https://github.com/capawesome-team/cli/commit/e5de25c68dbceb412d53790349f977c71ce33683))
|
|
23
|
+
|
|
5
24
|
## [0.0.10](https://github.com/capawesome-team/cli/compare/v0.0.9...v0.0.10) (2024-07-10)
|
|
6
25
|
|
|
7
26
|
|
|
@@ -24,6 +24,8 @@ const app_bundles_1 = __importDefault(require("../../../services/app-bundles"));
|
|
|
24
24
|
const error_1 = require("../../../utils/error");
|
|
25
25
|
const hash_1 = require("../../../utils/hash");
|
|
26
26
|
const buffer_1 = require("../../../utils/buffer");
|
|
27
|
+
const signature_1 = require("../../../utils/signature");
|
|
28
|
+
const file_1 = require("../../../utils/file");
|
|
27
29
|
exports.default = (0, citty_1.defineCommand)({
|
|
28
30
|
meta: {
|
|
29
31
|
description: 'Create a new app bundle.',
|
|
@@ -57,6 +59,10 @@ exports.default = (0, citty_1.defineCommand)({
|
|
|
57
59
|
type: 'string',
|
|
58
60
|
description: 'Path to the bundle to upload. Must be a folder (e.g. `www` or `dist`) or a zip file.',
|
|
59
61
|
},
|
|
62
|
+
privateKey: {
|
|
63
|
+
type: 'string',
|
|
64
|
+
description: 'The path to the private key file to sign the bundle with.',
|
|
65
|
+
},
|
|
60
66
|
rollout: {
|
|
61
67
|
type: 'string',
|
|
62
68
|
description: 'The percentage of devices to deploy the bundle to. Must be a number between 0 and 1 (e.g. 0.5).',
|
|
@@ -71,7 +77,7 @@ exports.default = (0, citty_1.defineCommand)({
|
|
|
71
77
|
consola_1.default.error('You must be logged in to run this command.');
|
|
72
78
|
return;
|
|
73
79
|
}
|
|
74
|
-
const { androidMax, androidMin, rollout, iosMax, iosMin } = ctx.args;
|
|
80
|
+
const { androidMax, androidMin, privateKey, rollout, iosMax, iosMin } = ctx.args;
|
|
75
81
|
let appId = ctx.args.appId;
|
|
76
82
|
let channelName = ctx.args.channel;
|
|
77
83
|
let path = ctx.args.path;
|
|
@@ -80,6 +86,10 @@ exports.default = (0, citty_1.defineCommand)({
|
|
|
80
86
|
path = yield (0, prompt_1.prompt)('Enter the path to the app bundle:', {
|
|
81
87
|
type: 'text',
|
|
82
88
|
});
|
|
89
|
+
if (!path) {
|
|
90
|
+
consola_1.default.error('You must provide a path to the app bundle.');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
83
93
|
}
|
|
84
94
|
if (!appId) {
|
|
85
95
|
const apps = yield apps_1.default.findAll();
|
|
@@ -104,22 +114,43 @@ exports.default = (0, citty_1.defineCommand)({
|
|
|
104
114
|
}
|
|
105
115
|
}
|
|
106
116
|
}
|
|
117
|
+
let privateKeyBuffer;
|
|
118
|
+
if (privateKey) {
|
|
119
|
+
if (privateKey.endsWith('.pem')) {
|
|
120
|
+
const fileExists = yield (0, file_1.fileExistsAtPath)(privateKey);
|
|
121
|
+
if (fileExists) {
|
|
122
|
+
privateKeyBuffer = yield (0, buffer_1.createBufferFromPath)(privateKey);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
consola_1.default.error('Private key file not found.');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
consola_1.default.error('Private key must be a path to a .pem file.');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
107
134
|
// Create form data
|
|
108
135
|
const formData = new form_data_1.default();
|
|
109
136
|
if (path) {
|
|
137
|
+
let fileBuffer;
|
|
110
138
|
if (zip_1.default.isZipped(path)) {
|
|
111
139
|
const readStream = (0, node_fs_1.createReadStream)(path);
|
|
112
|
-
|
|
113
|
-
const hash = yield (0, hash_1.createHash)(buffer);
|
|
114
|
-
formData.append('file', buffer, { filename: 'bundle.zip' });
|
|
115
|
-
formData.append('checksum', hash);
|
|
140
|
+
fileBuffer = yield (0, buffer_1.createBuffer)(readStream);
|
|
116
141
|
}
|
|
117
142
|
else {
|
|
118
143
|
consola_1.default.start('Zipping folder...');
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
144
|
+
fileBuffer = yield zip_1.default.zipFolder(path);
|
|
145
|
+
}
|
|
146
|
+
consola_1.default.start('Generating checksum...');
|
|
147
|
+
const hash = yield (0, hash_1.createHash)(fileBuffer);
|
|
148
|
+
formData.append('file', fileBuffer, { filename: 'bundle.zip' });
|
|
149
|
+
formData.append('checksum', hash);
|
|
150
|
+
if (privateKeyBuffer) {
|
|
151
|
+
consola_1.default.start('Signing bundle...');
|
|
152
|
+
const signature = yield (0, signature_1.createSignature)(privateKeyBuffer, fileBuffer);
|
|
153
|
+
formData.append('signature', signature);
|
|
123
154
|
}
|
|
124
155
|
}
|
|
125
156
|
if (url) {
|
|
@@ -41,7 +41,7 @@ exports.default = (0, citty_1.defineCommand)({
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
44
|
-
appId = yield (0, prompt_1.prompt)('Which app do you want to
|
|
44
|
+
appId = yield (0, prompt_1.prompt)('Which app do you want to create the channel for?', {
|
|
45
45
|
type: 'select',
|
|
46
46
|
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
47
47
|
});
|
package/dist/utils/buffer.js
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -9,7 +32,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
32
|
});
|
|
10
33
|
};
|
|
11
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.createBuffer = void 0;
|
|
35
|
+
exports.createBufferFromPath = exports.createBuffer = void 0;
|
|
13
36
|
const createBuffer = (data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
37
|
const chunks = [];
|
|
15
38
|
return new Promise((resolve, reject) => {
|
|
@@ -26,3 +49,9 @@ const createBuffer = (data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
26
49
|
});
|
|
27
50
|
});
|
|
28
51
|
exports.createBuffer = createBuffer;
|
|
52
|
+
const createBufferFromPath = (path) => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
const fs = yield Promise.resolve().then(() => __importStar(require('fs')));
|
|
54
|
+
const stream = fs.createReadStream(path);
|
|
55
|
+
return (0, exports.createBuffer)(stream);
|
|
56
|
+
});
|
|
57
|
+
exports.createBufferFromPath = createBufferFromPath;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.fileExistsAtPath = void 0;
|
|
36
|
+
const fileExistsAtPath = (path) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
const fs = yield Promise.resolve().then(() => __importStar(require('fs')));
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
fs.access(path, fs.constants.F_OK, (err) => {
|
|
40
|
+
resolve(!err);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
exports.fileExistsAtPath = fileExistsAtPath;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.createSignature = void 0;
|
|
36
|
+
const createSignature = (privateKey, data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
const crypto = yield Promise.resolve().then(() => __importStar(require('crypto')));
|
|
38
|
+
const sign = crypto.createSign('sha256');
|
|
39
|
+
sign.update(data);
|
|
40
|
+
sign.end();
|
|
41
|
+
return sign.sign(privateKey).toString('base64');
|
|
42
|
+
});
|
|
43
|
+
exports.createSignature = createSignature;
|