@capawesome/cli 3.1.0 → 3.2.1
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 +21 -0
- package/dist/commands/apps/bundles/create.js +26 -8
- package/dist/commands/apps/bundles/create.test.js +12 -1
- package/dist/commands/apps/bundles/delete.js +16 -5
- package/dist/commands/apps/bundles/delete.test.js +3 -0
- package/dist/commands/apps/bundles/update.js +9 -0
- package/dist/commands/apps/bundles/update.test.js +3 -0
- package/dist/commands/apps/channels/create.js +27 -1
- package/dist/commands/apps/channels/create.test.js +31 -0
- package/dist/commands/apps/channels/delete.js +11 -0
- package/dist/commands/apps/channels/update.js +11 -0
- package/dist/commands/apps/channels/update.test.js +3 -0
- package/dist/commands/apps/create.js +9 -0
- package/dist/commands/apps/create.test.js +3 -0
- package/dist/commands/apps/delete.js +12 -5
- package/dist/commands/apps/delete.test.js +3 -0
- package/dist/commands/apps/devices/delete.js +20 -5
- package/dist/commands/apps/devices/delete.test.js +3 -0
- package/dist/commands/login.test.js +3 -0
- package/dist/commands/manifests/generate.js +8 -3
- package/dist/commands/manifests/generate.test.js +3 -0
- package/dist/commands/organizations/create.js +5 -0
- package/dist/commands/organizations/create.test.js +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
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
|
+
## [3.2.1](https://github.com/capawesome-team/cli/compare/v3.2.0...v3.2.1) (2025-09-26)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* add missing CI checks ([#84](https://github.com/capawesome-team/cli/issues/84)) ([617e89c](https://github.com/capawesome-team/cli/commit/617e89c6b69c907573b61b5e685a2f05cdab2d62))
|
|
11
|
+
* **apps:bundles:create:** add CI check for channel prompt ([5d89cff](https://github.com/capawesome-team/cli/commit/5d89cffad756b6d5b9017c8797dc8c2e8cd2d5f8))
|
|
12
|
+
* **apps:bundles:create:** add CI checks for path and app ID prompts ([e96f567](https://github.com/capawesome-team/cli/commit/e96f5674293a01a8d87eb293dffdf06b4a59f43f))
|
|
13
|
+
|
|
14
|
+
## [3.2.0](https://github.com/capawesome-team/cli/compare/v3.1.0...v3.2.0) (2025-09-21)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **apps:channels:create:** add `--expires-in-days` option ([#69](https://github.com/capawesome-team/cli/issues/69)) ([ef2dd36](https://github.com/capawesome-team/cli/commit/ef2dd3638653e35a3ee3390ad336f39d368cd7ca))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* **apps:bundles:create:** add error handling for invalid path types ([1fae8c6](https://github.com/capawesome-team/cli/commit/1fae8c6a831bdc0f5bb1e80f2dea4fa3a981e625))
|
|
25
|
+
|
|
5
26
|
## [3.1.0](https://github.com/capawesome-team/cli/compare/v3.0.0...v3.1.0) (2025-09-17)
|
|
6
27
|
|
|
7
28
|
|
|
@@ -5,16 +5,17 @@ import appsService from '../../../services/apps.js';
|
|
|
5
5
|
import authorizationService from '../../../services/authorization-service.js';
|
|
6
6
|
import organizationsService from '../../../services/organizations.js';
|
|
7
7
|
import { createBufferFromPath, createBufferFromReadStream, createBufferFromString, isPrivateKeyContent, } from '../../../utils/buffer.js';
|
|
8
|
-
import { formatPrivateKey } from '../../../utils/private-key.js';
|
|
9
8
|
import { fileExistsAtPath, getFilesInDirectoryAndSubdirectories, isDirectory } from '../../../utils/file.js';
|
|
10
9
|
import { createHash } from '../../../utils/hash.js';
|
|
11
10
|
import { generateManifestJson } from '../../../utils/manifest.js';
|
|
11
|
+
import { formatPrivateKey } from '../../../utils/private-key.js';
|
|
12
12
|
import { prompt } from '../../../utils/prompt.js';
|
|
13
13
|
import { createSignature } from '../../../utils/signature.js';
|
|
14
14
|
import zip from '../../../utils/zip.js';
|
|
15
15
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
16
16
|
import consola from 'consola';
|
|
17
17
|
import { createReadStream } from 'fs';
|
|
18
|
+
import { isCI } from 'std-env';
|
|
18
19
|
import { z } from 'zod';
|
|
19
20
|
export default defineCommand({
|
|
20
21
|
description: 'Create a new app bundle.',
|
|
@@ -94,7 +95,7 @@ export default defineCommand({
|
|
|
94
95
|
consola.error('You must be logged in to run this command.');
|
|
95
96
|
process.exit(1);
|
|
96
97
|
}
|
|
97
|
-
//
|
|
98
|
+
// Calculate the expiration date
|
|
98
99
|
let expiresAt;
|
|
99
100
|
if (expiresInDays) {
|
|
100
101
|
const expiresAtDate = new Date();
|
|
@@ -103,13 +104,19 @@ export default defineCommand({
|
|
|
103
104
|
}
|
|
104
105
|
// Check that either a path or a url is provided
|
|
105
106
|
if (!path && !url) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
109
|
-
if (!path) {
|
|
110
|
-
consola.error('You must provide a path to the app bundle.');
|
|
107
|
+
if (isCI) {
|
|
108
|
+
consola.error('You must provide either a path or a url when running in CI mode.');
|
|
111
109
|
process.exit(1);
|
|
112
110
|
}
|
|
111
|
+
else {
|
|
112
|
+
path = await prompt('Enter the path to the app bundle:', {
|
|
113
|
+
type: 'text',
|
|
114
|
+
});
|
|
115
|
+
if (!path) {
|
|
116
|
+
consola.error('You must provide a path to the app bundle.');
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
113
120
|
}
|
|
114
121
|
if (path) {
|
|
115
122
|
// Check if the path exists when a path is provided
|
|
@@ -128,6 +135,13 @@ export default defineCommand({
|
|
|
128
135
|
process.exit(1);
|
|
129
136
|
}
|
|
130
137
|
}
|
|
138
|
+
else if (zip.isZipped(path)) {
|
|
139
|
+
// No-op
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
consola.error('The path must be either a folder or a zip file.');
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
131
145
|
}
|
|
132
146
|
// Check that the path is a directory when creating a bundle with an artifact type
|
|
133
147
|
if (artifactType === 'manifest' && path) {
|
|
@@ -143,6 +157,10 @@ export default defineCommand({
|
|
|
143
157
|
process.exit(1);
|
|
144
158
|
}
|
|
145
159
|
if (!appId) {
|
|
160
|
+
if (isCI) {
|
|
161
|
+
consola.error('You must provide an app ID when running in CI mode.');
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
146
164
|
const organizations = await organizationsService.findAll();
|
|
147
165
|
if (organizations.length === 0) {
|
|
148
166
|
consola.error('You must create an organization before creating a bundle.');
|
|
@@ -174,7 +192,7 @@ export default defineCommand({
|
|
|
174
192
|
process.exit(1);
|
|
175
193
|
}
|
|
176
194
|
}
|
|
177
|
-
if (!channel) {
|
|
195
|
+
if (!channel && !isCI) {
|
|
178
196
|
const promptChannel = await prompt('Do you want to deploy to a specific channel?', {
|
|
179
197
|
type: 'select',
|
|
180
198
|
options: ['Yes', 'No'],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_API_BASE_URL } from '../../../config/consts.js';
|
|
2
2
|
import authorizationService from '../../../services/authorization-service.js';
|
|
3
|
-
import { fileExistsAtPath, isDirectory } from '../../../utils/file.js';
|
|
3
|
+
import { fileExistsAtPath, getFilesInDirectoryAndSubdirectories, isDirectory } from '../../../utils/file.js';
|
|
4
4
|
import userConfig from '../../../utils/user-config.js';
|
|
5
5
|
import consola from 'consola';
|
|
6
6
|
import nock from 'nock';
|
|
@@ -20,6 +20,7 @@ describe('apps-bundles-create', () => {
|
|
|
20
20
|
const mockUserConfig = vi.mocked(userConfig);
|
|
21
21
|
const mockAuthorizationService = vi.mocked(authorizationService);
|
|
22
22
|
const mockFileExistsAtPath = vi.mocked(fileExistsAtPath);
|
|
23
|
+
const mockGetFilesInDirectoryAndSubdirectories = vi.mocked(getFilesInDirectoryAndSubdirectories);
|
|
23
24
|
const mockIsDirectory = vi.mocked(isDirectory);
|
|
24
25
|
const mockConsola = vi.mocked(consola);
|
|
25
26
|
beforeEach(() => {
|
|
@@ -100,6 +101,9 @@ describe('apps-bundles-create', () => {
|
|
|
100
101
|
};
|
|
101
102
|
mockFileExistsAtPath.mockResolvedValue(true);
|
|
102
103
|
mockIsDirectory.mockResolvedValue(false);
|
|
104
|
+
// Mock zip utility to return true so path validation passes
|
|
105
|
+
const mockZip = await import('../../../utils/zip.js');
|
|
106
|
+
vi.mocked(mockZip.default.isZipped).mockReturnValue(true);
|
|
103
107
|
await expect(createBundleCommand.action(options, undefined)).rejects.toThrow('Process exited with code 1');
|
|
104
108
|
expect(mockConsola.error).toHaveBeenCalledWith('The path must be a folder when creating a bundle with an artifact type of `manifest`.');
|
|
105
109
|
});
|
|
@@ -249,6 +253,10 @@ describe('apps-bundles-create', () => {
|
|
|
249
253
|
return Promise.resolve(false);
|
|
250
254
|
return Promise.resolve(true);
|
|
251
255
|
});
|
|
256
|
+
mockIsDirectory.mockResolvedValue(true);
|
|
257
|
+
mockGetFilesInDirectoryAndSubdirectories.mockResolvedValue([
|
|
258
|
+
{ href: 'index.html', mimeType: 'text/html', name: 'index.html', path: 'index.html' },
|
|
259
|
+
]);
|
|
252
260
|
// Mock utility functions
|
|
253
261
|
const mockBuffer = await import('../../../utils/buffer.js');
|
|
254
262
|
vi.mocked(mockBuffer.isPrivateKeyContent).mockReturnValue(false);
|
|
@@ -267,6 +275,9 @@ describe('apps-bundles-create', () => {
|
|
|
267
275
|
};
|
|
268
276
|
mockFileExistsAtPath.mockResolvedValue(true);
|
|
269
277
|
mockIsDirectory.mockResolvedValue(false);
|
|
278
|
+
// Mock zip utility to pass path validation
|
|
279
|
+
const mockZip = await import('../../../utils/zip.js');
|
|
280
|
+
vi.mocked(mockZip.default.isZipped).mockReturnValue(true);
|
|
270
281
|
// Mock utility functions
|
|
271
282
|
const mockBuffer = await import('../../../utils/buffer.js');
|
|
272
283
|
vi.mocked(mockBuffer.isPrivateKeyContent).mockReturnValue(false);
|
|
@@ -5,6 +5,7 @@ import organizationsService from '../../../services/organizations.js';
|
|
|
5
5
|
import { prompt } from '../../../utils/prompt.js';
|
|
6
6
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
7
7
|
import consola from 'consola';
|
|
8
|
+
import { isCI } from 'std-env';
|
|
8
9
|
import { z } from 'zod';
|
|
9
10
|
export default defineCommand({
|
|
10
11
|
description: 'Delete an app bundle.',
|
|
@@ -20,6 +21,10 @@ export default defineCommand({
|
|
|
20
21
|
}
|
|
21
22
|
// Prompt for missing arguments
|
|
22
23
|
if (!appId) {
|
|
24
|
+
if (isCI) {
|
|
25
|
+
consola.error('You must provide an app ID when running in CI mode.');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
23
28
|
const organizations = await organizationsService.findAll();
|
|
24
29
|
if (organizations.length === 0) {
|
|
25
30
|
consola.error('You must create an organization before deleting a bundle.');
|
|
@@ -48,16 +53,22 @@ export default defineCommand({
|
|
|
48
53
|
});
|
|
49
54
|
}
|
|
50
55
|
if (!bundleId) {
|
|
56
|
+
if (isCI) {
|
|
57
|
+
consola.error('You must provide the bundle ID when running in CI mode.');
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
51
60
|
bundleId = await prompt('Enter the bundle ID:', {
|
|
52
61
|
type: 'text',
|
|
53
62
|
});
|
|
54
63
|
}
|
|
55
64
|
// Confirm deletion
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
if (!isCI) {
|
|
66
|
+
const confirmed = await prompt('Are you sure you want to delete this bundle?', {
|
|
67
|
+
type: 'confirm',
|
|
68
|
+
});
|
|
69
|
+
if (!confirmed) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
61
72
|
}
|
|
62
73
|
// Delete bundle
|
|
63
74
|
await appBundlesService.delete({
|
|
@@ -11,6 +11,9 @@ vi.mock('@/utils/user-config.js');
|
|
|
11
11
|
vi.mock('@/utils/prompt.js');
|
|
12
12
|
vi.mock('@/services/authorization-service.js');
|
|
13
13
|
vi.mock('consola');
|
|
14
|
+
vi.mock('std-env', () => ({
|
|
15
|
+
isCI: false,
|
|
16
|
+
}));
|
|
14
17
|
describe('apps-bundles-delete', () => {
|
|
15
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
16
19
|
const mockPrompt = vi.mocked(prompt);
|
|
@@ -5,6 +5,7 @@ import organizationsService from '../../../services/organizations.js';
|
|
|
5
5
|
import { prompt } from '../../../utils/prompt.js';
|
|
6
6
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
7
7
|
import consola from 'consola';
|
|
8
|
+
import { isCI } from 'std-env';
|
|
8
9
|
import { z } from 'zod';
|
|
9
10
|
export default defineCommand({
|
|
10
11
|
description: 'Update an app bundle.',
|
|
@@ -44,6 +45,10 @@ export default defineCommand({
|
|
|
44
45
|
}
|
|
45
46
|
// Prompt for missing arguments
|
|
46
47
|
if (!appId) {
|
|
48
|
+
if (isCI) {
|
|
49
|
+
consola.error('You must provide an app ID when running in CI mode.');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
47
52
|
const organizations = await organizationsService.findAll();
|
|
48
53
|
if (organizations.length === 0) {
|
|
49
54
|
consola.error('You must create an organization before updating a bundle.');
|
|
@@ -72,6 +77,10 @@ export default defineCommand({
|
|
|
72
77
|
});
|
|
73
78
|
}
|
|
74
79
|
if (!bundleId) {
|
|
80
|
+
if (isCI) {
|
|
81
|
+
consola.error('You must provide the bundle ID when running in CI mode.');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
75
84
|
bundleId = await prompt('Enter the bundle ID:', {
|
|
76
85
|
type: 'text',
|
|
77
86
|
});
|
|
@@ -11,6 +11,9 @@ vi.mock('@/utils/user-config.js');
|
|
|
11
11
|
vi.mock('@/utils/prompt.js');
|
|
12
12
|
vi.mock('@/services/authorization-service.js');
|
|
13
13
|
vi.mock('consola');
|
|
14
|
+
vi.mock('std-env', () => ({
|
|
15
|
+
isCI: false,
|
|
16
|
+
}));
|
|
14
17
|
describe('apps-bundles-update', () => {
|
|
15
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
16
19
|
const mockPrompt = vi.mocked(prompt);
|
|
@@ -6,6 +6,7 @@ import { getMessageFromUnknownError } from '../../../utils/error.js';
|
|
|
6
6
|
import { prompt } from '../../../utils/prompt.js';
|
|
7
7
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
8
8
|
import consola from 'consola';
|
|
9
|
+
import { isCI } from 'std-env';
|
|
9
10
|
import { z } from 'zod';
|
|
10
11
|
export default defineCommand({
|
|
11
12
|
description: 'Create a new app channel.',
|
|
@@ -15,17 +16,37 @@ export default defineCommand({
|
|
|
15
16
|
.number()
|
|
16
17
|
.optional()
|
|
17
18
|
.describe('Maximum number of bundles that can be assigned to the channel. If more bundles are assigned, the oldest bundles will be automatically deleted.'),
|
|
19
|
+
expiresInDays: z.coerce
|
|
20
|
+
.number({
|
|
21
|
+
message: 'Expiration days must be an integer.',
|
|
22
|
+
})
|
|
23
|
+
.int({
|
|
24
|
+
message: 'Expiration days must be an integer.',
|
|
25
|
+
})
|
|
26
|
+
.optional()
|
|
27
|
+
.describe('The number of days until the channel is automatically deleted.'),
|
|
18
28
|
ignoreErrors: z.boolean().optional().describe('Whether to ignore errors or not.'),
|
|
19
29
|
name: z.string().optional().describe('Name of the channel.'),
|
|
20
30
|
})),
|
|
21
31
|
action: async (options, args) => {
|
|
22
|
-
let { appId, bundleLimit, ignoreErrors, name } = options;
|
|
32
|
+
let { appId, bundleLimit, expiresInDays, ignoreErrors, name } = options;
|
|
23
33
|
if (!authorizationService.hasAuthorizationToken()) {
|
|
24
34
|
consola.error('You must be logged in to run this command.');
|
|
25
35
|
process.exit(1);
|
|
26
36
|
}
|
|
37
|
+
// Calculate the expiration date
|
|
38
|
+
let expiresAt;
|
|
39
|
+
if (expiresInDays) {
|
|
40
|
+
const expiresAtDate = new Date();
|
|
41
|
+
expiresAtDate.setDate(expiresAtDate.getDate() + expiresInDays);
|
|
42
|
+
expiresAt = expiresAtDate.toISOString();
|
|
43
|
+
}
|
|
27
44
|
// Validate the app ID
|
|
28
45
|
if (!appId) {
|
|
46
|
+
if (isCI) {
|
|
47
|
+
consola.error('You must provide an app ID when running in CI mode.');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
29
50
|
const organizations = await organizationsService.findAll();
|
|
30
51
|
if (organizations.length === 0) {
|
|
31
52
|
consola.error('You must create an organization before creating a channel.');
|
|
@@ -55,6 +76,10 @@ export default defineCommand({
|
|
|
55
76
|
}
|
|
56
77
|
// Validate the channel name
|
|
57
78
|
if (!name) {
|
|
79
|
+
if (isCI) {
|
|
80
|
+
consola.error('You must provide the channel name when running in CI mode.');
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
58
83
|
name = await prompt('Enter the name of the channel:', { type: 'text' });
|
|
59
84
|
}
|
|
60
85
|
try {
|
|
@@ -62,6 +87,7 @@ export default defineCommand({
|
|
|
62
87
|
appId,
|
|
63
88
|
name,
|
|
64
89
|
totalAppBundleLimit: bundleLimit,
|
|
90
|
+
expiresAt,
|
|
65
91
|
});
|
|
66
92
|
consola.success('Channel created successfully.');
|
|
67
93
|
consola.info(`Channel ID: ${response.id}`);
|
|
@@ -11,6 +11,9 @@ vi.mock('@/utils/user-config.js');
|
|
|
11
11
|
vi.mock('@/utils/prompt.js');
|
|
12
12
|
vi.mock('@/services/authorization-service.js');
|
|
13
13
|
vi.mock('consola');
|
|
14
|
+
vi.mock('std-env', () => ({
|
|
15
|
+
isCI: false,
|
|
16
|
+
}));
|
|
14
17
|
describe('apps-channels-create', () => {
|
|
15
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
16
19
|
const mockPrompt = vi.mocked(prompt);
|
|
@@ -116,4 +119,32 @@ describe('apps-channels-create', () => {
|
|
|
116
119
|
await expect(createChannelCommand.action(options, undefined)).rejects.toThrow();
|
|
117
120
|
expect(scope.isDone()).toBe(true);
|
|
118
121
|
});
|
|
122
|
+
it('should create channel with expiresInDays option', async () => {
|
|
123
|
+
const appId = 'app-123';
|
|
124
|
+
const channelName = 'production';
|
|
125
|
+
const expiresInDays = 30;
|
|
126
|
+
const channelId = 'channel-456';
|
|
127
|
+
const testToken = 'test-token';
|
|
128
|
+
const options = { appId, name: channelName, expiresInDays };
|
|
129
|
+
// Calculate expected expiration date
|
|
130
|
+
const expectedExpiresAt = new Date();
|
|
131
|
+
expectedExpiresAt.setDate(expectedExpiresAt.getDate() + expiresInDays);
|
|
132
|
+
const scope = nock(DEFAULT_API_BASE_URL)
|
|
133
|
+
.post(`/v1/apps/${appId}/channels`, (body) => {
|
|
134
|
+
// Verify the request includes expiresAt and it's approximately correct (within 1 minute)
|
|
135
|
+
const actualExpiresAt = new Date(body.expiresAt);
|
|
136
|
+
const timeDiff = Math.abs(actualExpiresAt.getTime() - expectedExpiresAt.getTime());
|
|
137
|
+
const oneMinute = 60 * 1000;
|
|
138
|
+
return (body.appId === appId &&
|
|
139
|
+
body.name === channelName &&
|
|
140
|
+
body.totalAppBundleLimit === undefined &&
|
|
141
|
+
timeDiff < oneMinute);
|
|
142
|
+
})
|
|
143
|
+
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
144
|
+
.reply(201, { id: channelId, name: channelName });
|
|
145
|
+
await createChannelCommand.action(options, undefined);
|
|
146
|
+
expect(scope.isDone()).toBe(true);
|
|
147
|
+
expect(mockConsola.success).toHaveBeenCalledWith('Channel created successfully.');
|
|
148
|
+
expect(mockConsola.info).toHaveBeenCalledWith(`Channel ID: ${channelId}`);
|
|
149
|
+
});
|
|
119
150
|
});
|
|
@@ -27,6 +27,10 @@ export default defineCommand({
|
|
|
27
27
|
process.exit(1);
|
|
28
28
|
}
|
|
29
29
|
if (!appId) {
|
|
30
|
+
if (isCI) {
|
|
31
|
+
consola.error('You must provide an app ID when running in CI mode.');
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
30
34
|
const organizations = await organizationsService.findAll();
|
|
31
35
|
if (organizations.length === 0) {
|
|
32
36
|
consola.error('You must create an organization before deleting a channel.');
|
|
@@ -54,11 +58,17 @@ export default defineCommand({
|
|
|
54
58
|
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
55
59
|
});
|
|
56
60
|
}
|
|
61
|
+
// Prompt for channel ID or name if neither is provided
|
|
57
62
|
if (!channelId && !name) {
|
|
63
|
+
if (isCI) {
|
|
64
|
+
consola.error('You must provide either the channel ID or name when running in CI mode.');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
58
67
|
name = await prompt('Enter the channel name:', {
|
|
59
68
|
type: 'text',
|
|
60
69
|
});
|
|
61
70
|
}
|
|
71
|
+
// Confirm deletion
|
|
62
72
|
if (!isCI) {
|
|
63
73
|
const confirmed = await prompt('Are you sure you want to delete this channel?', {
|
|
64
74
|
type: 'confirm',
|
|
@@ -67,6 +77,7 @@ export default defineCommand({
|
|
|
67
77
|
return;
|
|
68
78
|
}
|
|
69
79
|
}
|
|
80
|
+
// Delete channel
|
|
70
81
|
await appChannelsService.delete({
|
|
71
82
|
appId,
|
|
72
83
|
id: channelId,
|
|
@@ -5,6 +5,7 @@ import organizationsService from '../../../services/organizations.js';
|
|
|
5
5
|
import { prompt } from '../../../utils/prompt.js';
|
|
6
6
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
7
7
|
import consola from 'consola';
|
|
8
|
+
import { isCI } from 'std-env';
|
|
8
9
|
import { z } from 'zod';
|
|
9
10
|
export default defineCommand({
|
|
10
11
|
description: 'Update an existing app channel.',
|
|
@@ -23,7 +24,12 @@ export default defineCommand({
|
|
|
23
24
|
consola.error('You must be logged in to run this command.');
|
|
24
25
|
process.exit(1);
|
|
25
26
|
}
|
|
27
|
+
// Prompt app ID if not provided
|
|
26
28
|
if (!appId) {
|
|
29
|
+
if (isCI) {
|
|
30
|
+
consola.error('You must provide an app ID when running in CI mode.');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
27
33
|
const organizations = await organizationsService.findAll();
|
|
28
34
|
if (organizations.length === 0) {
|
|
29
35
|
consola.error('You must create an organization before updating a channel.');
|
|
@@ -51,7 +57,12 @@ export default defineCommand({
|
|
|
51
57
|
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
52
58
|
});
|
|
53
59
|
}
|
|
60
|
+
// Prompt for channel ID if not provided
|
|
54
61
|
if (!channelId) {
|
|
62
|
+
if (isCI) {
|
|
63
|
+
consola.error('You must provide the channel ID when running in CI mode.');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
55
66
|
channelId = await prompt('Enter the channel ID:', {
|
|
56
67
|
type: 'text',
|
|
57
68
|
});
|
|
@@ -11,6 +11,9 @@ vi.mock('@/utils/user-config.js');
|
|
|
11
11
|
vi.mock('@/utils/prompt.js');
|
|
12
12
|
vi.mock('@/services/authorization-service.js');
|
|
13
13
|
vi.mock('consola');
|
|
14
|
+
vi.mock('std-env', () => ({
|
|
15
|
+
isCI: false,
|
|
16
|
+
}));
|
|
14
17
|
describe('apps-channels-update', () => {
|
|
15
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
16
19
|
const mockPrompt = vi.mocked(prompt);
|
|
@@ -4,6 +4,7 @@ import organizationsService from '../../services/organizations.js';
|
|
|
4
4
|
import { prompt } from '../../utils/prompt.js';
|
|
5
5
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
6
6
|
import consola from 'consola';
|
|
7
|
+
import { isCI } from 'std-env';
|
|
7
8
|
import { z } from 'zod';
|
|
8
9
|
export default defineCommand({
|
|
9
10
|
description: 'Create a new app.',
|
|
@@ -18,6 +19,10 @@ export default defineCommand({
|
|
|
18
19
|
process.exit(1);
|
|
19
20
|
}
|
|
20
21
|
if (!organizationId) {
|
|
22
|
+
if (isCI) {
|
|
23
|
+
consola.error('You must provide the organization ID when running in CI mode.');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
21
26
|
const organizations = await organizationsService.findAll();
|
|
22
27
|
if (organizations.length === 0) {
|
|
23
28
|
consola.error('You must create an organization before creating an app.');
|
|
@@ -34,6 +39,10 @@ export default defineCommand({
|
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
41
|
if (!name) {
|
|
42
|
+
if (isCI) {
|
|
43
|
+
consola.error('You must provide the app name when running in CI mode.');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
37
46
|
name = await prompt('Enter the name of the app:', { type: 'text' });
|
|
38
47
|
}
|
|
39
48
|
const response = await appsService.create({ name, organizationId });
|
|
@@ -11,6 +11,9 @@ vi.mock('@/utils/user-config.js');
|
|
|
11
11
|
vi.mock('@/utils/prompt.js');
|
|
12
12
|
vi.mock('@/services/authorization-service.js');
|
|
13
13
|
vi.mock('consola');
|
|
14
|
+
vi.mock('std-env', () => ({
|
|
15
|
+
isCI: false,
|
|
16
|
+
}));
|
|
14
17
|
describe('apps-create', () => {
|
|
15
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
16
19
|
const mockPrompt = vi.mocked(prompt);
|
|
@@ -4,6 +4,7 @@ import organizationsService from '../../services/organizations.js';
|
|
|
4
4
|
import { prompt } from '../../utils/prompt.js';
|
|
5
5
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
6
6
|
import consola from 'consola';
|
|
7
|
+
import { isCI } from 'std-env';
|
|
7
8
|
import { z } from 'zod';
|
|
8
9
|
export default defineCommand({
|
|
9
10
|
description: 'Delete an app.',
|
|
@@ -17,6 +18,10 @@ export default defineCommand({
|
|
|
17
18
|
process.exit(1);
|
|
18
19
|
}
|
|
19
20
|
if (!appId) {
|
|
21
|
+
if (isCI) {
|
|
22
|
+
consola.error('You must provide the app ID when running in CI mode.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
20
25
|
const organizations = await organizationsService.findAll();
|
|
21
26
|
if (organizations.length === 0) {
|
|
22
27
|
consola.error('You must create an organization before deleting an app.');
|
|
@@ -44,11 +49,13 @@ export default defineCommand({
|
|
|
44
49
|
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
45
50
|
});
|
|
46
51
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
if (!isCI) {
|
|
53
|
+
const confirmed = await prompt('Are you sure you want to delete this app?', {
|
|
54
|
+
type: 'confirm',
|
|
55
|
+
});
|
|
56
|
+
if (!confirmed) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
52
59
|
}
|
|
53
60
|
await appsService.delete({ id: appId });
|
|
54
61
|
consola.success('App deleted successfully.');
|
|
@@ -11,6 +11,9 @@ vi.mock('@/utils/user-config.js');
|
|
|
11
11
|
vi.mock('@/utils/prompt.js');
|
|
12
12
|
vi.mock('@/services/authorization-service.js');
|
|
13
13
|
vi.mock('consola');
|
|
14
|
+
vi.mock('std-env', () => ({
|
|
15
|
+
isCI: false,
|
|
16
|
+
}));
|
|
14
17
|
describe('apps-delete', () => {
|
|
15
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
16
19
|
const mockPrompt = vi.mocked(prompt);
|
|
@@ -5,6 +5,7 @@ import organizationsService from '../../../services/organizations.js';
|
|
|
5
5
|
import { prompt } from '../../../utils/prompt.js';
|
|
6
6
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
7
7
|
import consola from 'consola';
|
|
8
|
+
import { isCI } from 'std-env';
|
|
8
9
|
import { z } from 'zod';
|
|
9
10
|
export default defineCommand({
|
|
10
11
|
description: 'Delete an app device.',
|
|
@@ -18,7 +19,12 @@ export default defineCommand({
|
|
|
18
19
|
consola.error('You must be logged in to run this command.');
|
|
19
20
|
process.exit(1);
|
|
20
21
|
}
|
|
22
|
+
// Prompt for app ID if not provided
|
|
21
23
|
if (!appId) {
|
|
24
|
+
if (isCI) {
|
|
25
|
+
consola.error('You must provide an app ID when running in CI mode.');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
22
28
|
const organizations = await organizationsService.findAll();
|
|
23
29
|
if (organizations.length === 0) {
|
|
24
30
|
consola.error('You must create an organization before deleting a device.');
|
|
@@ -46,17 +52,26 @@ export default defineCommand({
|
|
|
46
52
|
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
47
53
|
});
|
|
48
54
|
}
|
|
55
|
+
// Prompt for device ID if not provided
|
|
49
56
|
if (!deviceId) {
|
|
57
|
+
if (isCI) {
|
|
58
|
+
consola.error('You must provide the device ID when running in CI mode.');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
50
61
|
deviceId = await prompt('Enter the device ID:', {
|
|
51
62
|
type: 'text',
|
|
52
63
|
});
|
|
53
64
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
65
|
+
// Confirm deletion
|
|
66
|
+
if (!isCI) {
|
|
67
|
+
const confirmed = await prompt('Are you sure you want to delete this device?', {
|
|
68
|
+
type: 'confirm',
|
|
69
|
+
});
|
|
70
|
+
if (!confirmed) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
59
73
|
}
|
|
74
|
+
// Delete device
|
|
60
75
|
await appDevicesService.delete({
|
|
61
76
|
appId,
|
|
62
77
|
deviceId,
|
|
@@ -11,6 +11,9 @@ vi.mock('@/utils/user-config.js');
|
|
|
11
11
|
vi.mock('@/utils/prompt.js');
|
|
12
12
|
vi.mock('@/services/authorization-service.js');
|
|
13
13
|
vi.mock('consola');
|
|
14
|
+
vi.mock('std-env', () => ({
|
|
15
|
+
isCI: false,
|
|
16
|
+
}));
|
|
14
17
|
describe('apps-devices-delete', () => {
|
|
15
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
16
19
|
const mockPrompt = vi.mocked(prompt);
|
|
@@ -20,6 +20,9 @@ vi.mock('@/utils/prompt.js');
|
|
|
20
20
|
vi.mock('std-env', () => ({
|
|
21
21
|
isCI: false,
|
|
22
22
|
}));
|
|
23
|
+
vi.mock('std-env', () => ({
|
|
24
|
+
isCI: false,
|
|
25
|
+
}));
|
|
23
26
|
describe('login', () => {
|
|
24
27
|
const mockUserConfig = vi.mocked(userConfig);
|
|
25
28
|
const mockSessionCodesService = vi.mocked(sessionCodesService);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
2
|
-
import consola from 'consola';
|
|
3
|
-
import { z } from 'zod';
|
|
4
1
|
import { fileExistsAtPath } from '../../utils/file.js';
|
|
5
2
|
import { generateManifestJson } from '../../utils/manifest.js';
|
|
6
3
|
import { prompt } from '../../utils/prompt.js';
|
|
4
|
+
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
5
|
+
import consola from 'consola';
|
|
6
|
+
import { isCI } from 'std-env';
|
|
7
|
+
import { z } from 'zod';
|
|
7
8
|
export default defineCommand({
|
|
8
9
|
description: 'Generate a manifest file.',
|
|
9
10
|
options: defineOptions(z.object({
|
|
@@ -12,6 +13,10 @@ export default defineCommand({
|
|
|
12
13
|
action: async (options, args) => {
|
|
13
14
|
let path = options.path;
|
|
14
15
|
if (!path) {
|
|
16
|
+
if (isCI) {
|
|
17
|
+
consola.error('You must provide the path to the web assets folder when running in CI mode.');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
15
20
|
path = await prompt('Enter the path to the web assets folder:', {
|
|
16
21
|
type: 'text',
|
|
17
22
|
});
|
|
@@ -9,6 +9,9 @@ vi.mock('@/utils/file.js');
|
|
|
9
9
|
vi.mock('@/utils/manifest.js');
|
|
10
10
|
vi.mock('@/utils/prompt.js');
|
|
11
11
|
vi.mock('consola');
|
|
12
|
+
vi.mock('std-env', () => ({
|
|
13
|
+
isCI: false,
|
|
14
|
+
}));
|
|
12
15
|
describe('manifests-generate', () => {
|
|
13
16
|
const mockFileExistsAtPath = vi.mocked(fileExistsAtPath);
|
|
14
17
|
const mockGenerateManifestJson = vi.mocked(generateManifestJson);
|
|
@@ -3,6 +3,7 @@ import organizationsService from '../../services/organizations.js';
|
|
|
3
3
|
import { prompt } from '../../utils/prompt.js';
|
|
4
4
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
5
5
|
import consola from 'consola';
|
|
6
|
+
import { isCI } from 'std-env';
|
|
6
7
|
import { z } from 'zod';
|
|
7
8
|
export default defineCommand({
|
|
8
9
|
description: 'Create a new organization.',
|
|
@@ -16,6 +17,10 @@ export default defineCommand({
|
|
|
16
17
|
process.exit(1);
|
|
17
18
|
}
|
|
18
19
|
if (!name) {
|
|
20
|
+
if (isCI) {
|
|
21
|
+
consola.error('You must provide the organization name when running in CI mode.');
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
19
24
|
name = await prompt('Enter the name of the organization:', { type: 'text' });
|
|
20
25
|
}
|
|
21
26
|
const response = await organizationsService.create({ name });
|
|
@@ -11,6 +11,9 @@ vi.mock('@/utils/user-config.js');
|
|
|
11
11
|
vi.mock('@/utils/prompt.js');
|
|
12
12
|
vi.mock('@/services/authorization-service.js');
|
|
13
13
|
vi.mock('consola');
|
|
14
|
+
vi.mock('std-env', () => ({
|
|
15
|
+
isCI: false,
|
|
16
|
+
}));
|
|
14
17
|
describe('organizations-create', () => {
|
|
15
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
16
19
|
const mockPrompt = vi.mocked(prompt);
|