@capawesome/cli 4.1.0-dev.f5ef8ba.1771047437 → 4.2.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 +14 -0
- package/dist/commands/apps/builds/cancel.js +6 -41
- package/dist/commands/apps/builds/create.js +10 -55
- package/dist/commands/apps/builds/download.js +6 -41
- package/dist/commands/apps/builds/logs.js +6 -41
- package/dist/commands/apps/channels/create.js +6 -36
- package/dist/commands/apps/channels/create.test.js +5 -15
- package/dist/commands/apps/channels/delete.js +6 -36
- package/dist/commands/apps/channels/delete.test.js +6 -18
- package/dist/commands/apps/channels/get.js +3 -7
- package/dist/commands/apps/channels/list.js +6 -36
- package/dist/commands/apps/channels/list.test.js +4 -1
- package/dist/commands/apps/channels/pause.js +6 -40
- package/dist/commands/apps/channels/resume.js +6 -40
- package/dist/commands/apps/channels/update.js +6 -36
- package/dist/commands/apps/channels/update.test.js +14 -31
- package/dist/commands/apps/create.js +5 -23
- package/dist/commands/apps/create.test.js +13 -31
- package/dist/commands/apps/delete.js +6 -35
- package/dist/commands/apps/delete.test.js +11 -35
- package/dist/commands/apps/deployments/cancel.js +6 -41
- package/dist/commands/apps/deployments/create.js +6 -41
- package/dist/commands/apps/deployments/logs.js +6 -41
- package/dist/commands/apps/devices/delete.js +6 -36
- package/dist/commands/apps/devices/delete.test.js +14 -36
- package/dist/commands/apps/environments/create.js +6 -36
- package/dist/commands/apps/environments/delete.js +6 -36
- package/dist/commands/apps/environments/list.js +6 -36
- package/dist/commands/apps/environments/set.js +6 -36
- package/dist/commands/apps/environments/unset.js +6 -36
- package/dist/commands/apps/liveupdates/register.js +6 -40
- package/dist/commands/apps/liveupdates/register.test.js +2 -1
- package/dist/commands/apps/liveupdates/rollback.js +6 -41
- package/dist/commands/apps/liveupdates/rollout.js +6 -41
- package/dist/commands/apps/liveupdates/set-native-versions.js +3 -7
- package/dist/commands/apps/liveupdates/upload.js +6 -40
- package/dist/commands/apps/liveupdates/upload.test.js +2 -1
- package/dist/commands/organizations/create.js +3 -7
- package/dist/commands/organizations/create.test.js +3 -1
- package/dist/utils/auth.js +27 -0
- package/dist/utils/prompt.js +56 -11
- package/dist/utils/signature.js +2 -1
- package/package.json +6 -2
|
@@ -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 { prompt } from '../../utils/prompt.js';
|
|
3
|
+
import { prompt, promptAppSelection, promptOrganizationSelection } from '../../utils/prompt.js';
|
|
4
4
|
import userConfig from '../../utils/user-config.js';
|
|
5
5
|
import consola from 'consola';
|
|
6
6
|
import nock from 'nock';
|
|
@@ -17,6 +17,8 @@ vi.mock('@/utils/environment.js', () => ({
|
|
|
17
17
|
describe('apps-delete', () => {
|
|
18
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
19
19
|
const mockPrompt = vi.mocked(prompt);
|
|
20
|
+
const mockPromptOrganizationSelection = vi.mocked(promptOrganizationSelection);
|
|
21
|
+
const mockPromptAppSelection = vi.mocked(promptAppSelection);
|
|
20
22
|
const mockConsola = vi.mocked(consola);
|
|
21
23
|
const mockAuthorizationService = vi.mocked(authorizationService);
|
|
22
24
|
beforeEach(() => {
|
|
@@ -62,51 +64,25 @@ describe('apps-delete', () => {
|
|
|
62
64
|
const orgId = 'org-1';
|
|
63
65
|
const appId = 'app-1';
|
|
64
66
|
const testToken = 'test-token';
|
|
65
|
-
const organization = { id: orgId, name: 'Org 1' };
|
|
66
|
-
const app = { id: appId, name: 'App 1' };
|
|
67
67
|
const options = {};
|
|
68
|
-
const orgsScope = nock(DEFAULT_API_BASE_URL)
|
|
69
|
-
.get('/v1/organizations')
|
|
70
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
71
|
-
.reply(200, [organization]);
|
|
72
|
-
const appsScope = nock(DEFAULT_API_BASE_URL)
|
|
73
|
-
.get('/v1/apps')
|
|
74
|
-
.query({ organizationId: orgId })
|
|
75
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
76
|
-
.reply(200, [app]);
|
|
77
68
|
const deleteScope = nock(DEFAULT_API_BASE_URL)
|
|
78
69
|
.delete(`/v1/apps/${appId}`)
|
|
79
70
|
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
80
71
|
.reply(200);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.mockResolvedValueOnce(true); // confirmation
|
|
72
|
+
mockPromptOrganizationSelection.mockResolvedValueOnce(orgId);
|
|
73
|
+
mockPromptAppSelection.mockResolvedValueOnce(appId);
|
|
74
|
+
mockPrompt.mockResolvedValueOnce(true); // confirmation
|
|
85
75
|
await deleteAppCommand.action(options, undefined);
|
|
86
|
-
expect(orgsScope.isDone()).toBe(true);
|
|
87
|
-
expect(appsScope.isDone()).toBe(true);
|
|
88
76
|
expect(deleteScope.isDone()).toBe(true);
|
|
89
77
|
expect(mockConsola.success).toHaveBeenCalledWith('App deleted successfully.');
|
|
90
78
|
});
|
|
91
|
-
it('should
|
|
92
|
-
const testToken = 'test-token';
|
|
79
|
+
it('should exit when promptOrganizationSelection exits', async () => {
|
|
93
80
|
const options = {};
|
|
94
|
-
|
|
95
|
-
.
|
|
96
|
-
.
|
|
97
|
-
.reply(200, []);
|
|
98
|
-
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
99
|
-
throw new Error(`process.exit called with code ${code}`);
|
|
81
|
+
mockPromptOrganizationSelection.mockImplementation(() => {
|
|
82
|
+
process.exit(1);
|
|
83
|
+
return Promise.resolve('');
|
|
100
84
|
});
|
|
101
|
-
|
|
102
|
-
await deleteAppCommand.action(options, undefined);
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
expect(error.message).toBe('process.exit called with code 1');
|
|
106
|
-
}
|
|
107
|
-
expect(scope.isDone()).toBe(true);
|
|
108
|
-
expect(mockConsola.error).toHaveBeenCalledWith('You must create an organization before deleting an app.');
|
|
109
|
-
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
85
|
+
await expect(deleteAppCommand.action(options, undefined)).rejects.toThrow('Process exited with code 1');
|
|
110
86
|
});
|
|
111
87
|
it('should handle API error during deletion', async () => {
|
|
112
88
|
const appId = 'app-123';
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import appDeploymentsService from '../../../services/app-deployments.js';
|
|
2
|
-
import appsService from '../../../services/apps.js';
|
|
3
|
-
import authorizationService from '../../../services/authorization-service.js';
|
|
4
2
|
import jobsService from '../../../services/jobs.js';
|
|
5
|
-
import
|
|
3
|
+
import { withAuth } from '../../../utils/auth.js';
|
|
6
4
|
import { isInteractive } from '../../../utils/environment.js';
|
|
7
|
-
import { prompt } from '../../../utils/prompt.js';
|
|
5
|
+
import { prompt, promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
|
|
8
6
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
9
7
|
import consola from 'consola';
|
|
10
8
|
import { z } from 'zod';
|
|
@@ -24,49 +22,16 @@ export default defineCommand({
|
|
|
24
22
|
.optional()
|
|
25
23
|
.describe('Deployment ID to cancel.'),
|
|
26
24
|
})),
|
|
27
|
-
action: async (options) => {
|
|
25
|
+
action: withAuth(async (options) => {
|
|
28
26
|
let { appId, deploymentId } = options;
|
|
29
|
-
// Check if the user is logged in
|
|
30
|
-
if (!authorizationService.hasAuthorizationToken()) {
|
|
31
|
-
consola.error('You must be logged in to run this command. Please run the `login` command first.');
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
27
|
// Prompt for app ID if not provided
|
|
35
28
|
if (!appId) {
|
|
36
29
|
if (!isInteractive()) {
|
|
37
30
|
consola.error('You must provide an app ID when running in non-interactive environment.');
|
|
38
31
|
process.exit(1);
|
|
39
32
|
}
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
consola.error('You must create an organization before canceling a deployment.');
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
46
|
-
const organizationId = await prompt('Select the organization of the app for which you want to cancel a deployment.', {
|
|
47
|
-
type: 'select',
|
|
48
|
-
options: organizations.map((organization) => ({ label: organization.name, value: organization.id })),
|
|
49
|
-
});
|
|
50
|
-
if (!organizationId) {
|
|
51
|
-
consola.error('You must select the organization of an app for which you want to cancel a deployment.');
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
|
-
const apps = await appsService.findAll({
|
|
55
|
-
organizationId,
|
|
56
|
-
});
|
|
57
|
-
if (apps.length === 0) {
|
|
58
|
-
consola.error('You must create an app before canceling a deployment.');
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
62
|
-
appId = await prompt('Which app do you want to cancel a deployment for:', {
|
|
63
|
-
type: 'select',
|
|
64
|
-
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
65
|
-
});
|
|
66
|
-
if (!appId) {
|
|
67
|
-
consola.error('You must select an app to cancel a deployment for.');
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
33
|
+
const organizationId = await promptOrganizationSelection();
|
|
34
|
+
appId = await promptAppSelection(organizationId);
|
|
70
35
|
}
|
|
71
36
|
// Prompt for deployment ID if not provided
|
|
72
37
|
if (!deploymentId) {
|
|
@@ -107,5 +72,5 @@ export default defineCommand({
|
|
|
107
72
|
},
|
|
108
73
|
});
|
|
109
74
|
consola.success('Deployment successfully canceled.');
|
|
110
|
-
},
|
|
75
|
+
}),
|
|
111
76
|
});
|
|
@@ -2,12 +2,10 @@ import { DEFAULT_CONSOLE_BASE_URL } from '../../../config/consts.js';
|
|
|
2
2
|
import appBuildsService from '../../../services/app-builds.js';
|
|
3
3
|
import appDeploymentsService from '../../../services/app-deployments.js';
|
|
4
4
|
import appDestinationsService from '../../../services/app-destinations.js';
|
|
5
|
-
import appsService from '../../../services/apps.js';
|
|
6
|
-
import authorizationService from '../../../services/authorization-service.js';
|
|
7
|
-
import organizationsService from '../../../services/organizations.js';
|
|
8
5
|
import { unescapeAnsi } from '../../../utils/ansi.js';
|
|
6
|
+
import { withAuth } from '../../../utils/auth.js';
|
|
9
7
|
import { isInteractive } from '../../../utils/environment.js';
|
|
10
|
-
import { prompt } from '../../../utils/prompt.js';
|
|
8
|
+
import { prompt, promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
|
|
11
9
|
import { wait } from '../../../utils/wait.js';
|
|
12
10
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
13
11
|
import consola from 'consola';
|
|
@@ -35,49 +33,16 @@ export default defineCommand({
|
|
|
35
33
|
.optional()
|
|
36
34
|
.describe('Exit immediately after creating the deployment without waiting for completion.'),
|
|
37
35
|
})),
|
|
38
|
-
action: async (options) => {
|
|
36
|
+
action: withAuth(async (options) => {
|
|
39
37
|
let { appId, buildId, buildNumber, channel, destination } = options;
|
|
40
|
-
// Check if the user is logged in
|
|
41
|
-
if (!authorizationService.hasAuthorizationToken()) {
|
|
42
|
-
consola.error('You must be logged in to run this command. Please run the `login` command first.');
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
38
|
// Prompt for app ID if not provided
|
|
46
39
|
if (!appId) {
|
|
47
40
|
if (!isInteractive()) {
|
|
48
41
|
consola.error('You must provide an app ID when running in non-interactive environment.');
|
|
49
42
|
process.exit(1);
|
|
50
43
|
}
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
consola.error('You must create an organization before creating a deployment.');
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
57
|
-
const organizationId = await prompt('Select the organization of the app for which you want to create a deployment.', {
|
|
58
|
-
type: 'select',
|
|
59
|
-
options: organizations.map((organization) => ({ label: organization.name, value: organization.id })),
|
|
60
|
-
});
|
|
61
|
-
if (!organizationId) {
|
|
62
|
-
consola.error('You must select the organization of an app for which you want to create a deployment.');
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
const apps = await appsService.findAll({
|
|
66
|
-
organizationId,
|
|
67
|
-
});
|
|
68
|
-
if (apps.length === 0) {
|
|
69
|
-
consola.error('You must create an app before creating a deployment.');
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
73
|
-
appId = await prompt('Which app do you want to create a deployment for:', {
|
|
74
|
-
type: 'select',
|
|
75
|
-
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
76
|
-
});
|
|
77
|
-
if (!appId) {
|
|
78
|
-
consola.error('You must select an app to create a deployment for.');
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
44
|
+
const organizationId = await promptOrganizationSelection({ allowCreate: true });
|
|
45
|
+
appId = await promptAppSelection(organizationId, { allowCreate: true });
|
|
81
46
|
}
|
|
82
47
|
// Convert build number to build ID if provided
|
|
83
48
|
if (!buildId && buildNumber) {
|
|
@@ -269,5 +234,5 @@ export default defineCommand({
|
|
|
269
234
|
}
|
|
270
235
|
}
|
|
271
236
|
}
|
|
272
|
-
},
|
|
237
|
+
}),
|
|
273
238
|
});
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import appDeploymentsService from '../../../services/app-deployments.js';
|
|
2
|
-
import appsService from '../../../services/apps.js';
|
|
3
|
-
import authorizationService from '../../../services/authorization-service.js';
|
|
4
|
-
import organizationsService from '../../../services/organizations.js';
|
|
5
2
|
import { unescapeAnsi } from '../../../utils/ansi.js';
|
|
6
|
-
import {
|
|
3
|
+
import { withAuth } from '../../../utils/auth.js';
|
|
4
|
+
import { prompt, promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
|
|
7
5
|
import { wait } from '../../../utils/wait.js';
|
|
8
6
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
9
7
|
import consola from 'consola';
|
|
@@ -25,49 +23,16 @@ export default defineCommand({
|
|
|
25
23
|
.optional()
|
|
26
24
|
.describe('Deployment ID to view logs.'),
|
|
27
25
|
})),
|
|
28
|
-
action: async (options) => {
|
|
26
|
+
action: withAuth(async (options) => {
|
|
29
27
|
let { appId, deploymentId } = options;
|
|
30
|
-
// Check if the user is logged in
|
|
31
|
-
if (!authorizationService.hasAuthorizationToken()) {
|
|
32
|
-
consola.error('You must be logged in to run this command. Please run the `login` command first.');
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
35
28
|
// Prompt for app ID if not provided
|
|
36
29
|
if (!appId) {
|
|
37
30
|
if (!isInteractive()) {
|
|
38
31
|
consola.error('You must provide an app ID when running in non-interactive environment.');
|
|
39
32
|
process.exit(1);
|
|
40
33
|
}
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
consola.error('You must create an organization before viewing deployment logs.');
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
47
|
-
const organizationId = await prompt('Select the organization that contains the app whose deployment logs you want to view?', {
|
|
48
|
-
type: 'select',
|
|
49
|
-
options: organizations.map((organization) => ({ label: organization.name, value: organization.id })),
|
|
50
|
-
});
|
|
51
|
-
if (!organizationId) {
|
|
52
|
-
consola.error('You must select the organization containing the app whose deployment logs you want to view.');
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
const apps = await appsService.findAll({
|
|
56
|
-
organizationId,
|
|
57
|
-
});
|
|
58
|
-
if (apps.length === 0) {
|
|
59
|
-
consola.error('You must create an app before viewing deployment logs.');
|
|
60
|
-
process.exit(1);
|
|
61
|
-
}
|
|
62
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
63
|
-
appId = await prompt('Which app do you want to view deployment logs for?', {
|
|
64
|
-
type: 'select',
|
|
65
|
-
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
66
|
-
});
|
|
67
|
-
if (!appId) {
|
|
68
|
-
consola.error('You must select an app to view its deployment logs.');
|
|
69
|
-
process.exit(1);
|
|
70
|
-
}
|
|
34
|
+
const organizationId = await promptOrganizationSelection();
|
|
35
|
+
appId = await promptAppSelection(organizationId);
|
|
71
36
|
}
|
|
72
37
|
// Prompt for deployment ID if not provided
|
|
73
38
|
if (!deploymentId) {
|
|
@@ -125,5 +90,5 @@ export default defineCommand({
|
|
|
125
90
|
}
|
|
126
91
|
}
|
|
127
92
|
}
|
|
128
|
-
},
|
|
93
|
+
}),
|
|
129
94
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import appDevicesService from '../../../services/app-devices.js';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import organizationsService from '../../../services/organizations.js';
|
|
5
|
-
import { prompt } from '../../../utils/prompt.js';
|
|
2
|
+
import { withAuth } from '../../../utils/auth.js';
|
|
3
|
+
import { prompt, promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
|
|
6
4
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
7
5
|
import consola from 'consola';
|
|
8
6
|
import { isInteractive } from '../../../utils/environment.js';
|
|
@@ -14,44 +12,16 @@ export default defineCommand({
|
|
|
14
12
|
deviceId: z.string().optional().describe('ID of the device.'),
|
|
15
13
|
yes: z.boolean().optional().describe('Skip confirmation prompt.'),
|
|
16
14
|
}), { y: 'yes' }),
|
|
17
|
-
action: async (options, args) => {
|
|
15
|
+
action: withAuth(async (options, args) => {
|
|
18
16
|
let { appId, deviceId } = options;
|
|
19
|
-
if (!authorizationService.hasAuthorizationToken()) {
|
|
20
|
-
consola.error('You must be logged in to run this command. Please run the `login` command first.');
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
17
|
// Prompt for app ID if not provided
|
|
24
18
|
if (!appId) {
|
|
25
19
|
if (!isInteractive()) {
|
|
26
20
|
consola.error('You must provide an app ID when running in non-interactive environment.');
|
|
27
21
|
process.exit(1);
|
|
28
22
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
consola.error('You must create an organization before deleting a device.');
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
35
|
-
const organizationId = await prompt('Select the organization of the app from which you want to delete a device.', {
|
|
36
|
-
type: 'select',
|
|
37
|
-
options: organizations.map((organization) => ({ label: organization.name, value: organization.id })),
|
|
38
|
-
});
|
|
39
|
-
if (!organizationId) {
|
|
40
|
-
consola.error('You must select the organization of an app from which you want to delete a device.');
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
const apps = await appsService.findAll({
|
|
44
|
-
organizationId,
|
|
45
|
-
});
|
|
46
|
-
if (!apps.length) {
|
|
47
|
-
consola.error('You must create an app before deleting a device.');
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
51
|
-
appId = await prompt('Which app do you want to delete the device from?', {
|
|
52
|
-
type: 'select',
|
|
53
|
-
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
54
|
-
});
|
|
23
|
+
const organizationId = await promptOrganizationSelection();
|
|
24
|
+
appId = await promptAppSelection(organizationId);
|
|
55
25
|
}
|
|
56
26
|
// Prompt for device ID if not provided
|
|
57
27
|
if (!deviceId) {
|
|
@@ -78,5 +48,5 @@ export default defineCommand({
|
|
|
78
48
|
deviceId,
|
|
79
49
|
});
|
|
80
50
|
consola.success('Device deleted successfully.');
|
|
81
|
-
},
|
|
51
|
+
}),
|
|
82
52
|
});
|
|
@@ -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 { prompt } from '../../../utils/prompt.js';
|
|
3
|
+
import { prompt, promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
|
|
4
4
|
import userConfig from '../../../utils/user-config.js';
|
|
5
5
|
import consola from 'consola';
|
|
6
6
|
import nock from 'nock';
|
|
@@ -17,6 +17,8 @@ vi.mock('@/utils/environment.js', () => ({
|
|
|
17
17
|
describe('apps-devices-delete', () => {
|
|
18
18
|
const mockUserConfig = vi.mocked(userConfig);
|
|
19
19
|
const mockPrompt = vi.mocked(prompt);
|
|
20
|
+
const mockPromptOrganizationSelection = vi.mocked(promptOrganizationSelection);
|
|
21
|
+
const mockPromptAppSelection = vi.mocked(promptAppSelection);
|
|
20
22
|
const mockConsola = vi.mocked(consola);
|
|
21
23
|
const mockAuthorizationService = vi.mocked(authorizationService);
|
|
22
24
|
beforeEach(() => {
|
|
@@ -24,7 +26,9 @@ describe('apps-devices-delete', () => {
|
|
|
24
26
|
mockUserConfig.read.mockReturnValue({ token: 'test-token' });
|
|
25
27
|
mockAuthorizationService.getCurrentAuthorizationToken.mockReturnValue('test-token');
|
|
26
28
|
mockAuthorizationService.hasAuthorizationToken.mockReturnValue(true);
|
|
27
|
-
vi.spyOn(process, 'exit').mockImplementation(() =>
|
|
29
|
+
vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
30
|
+
throw new Error(`Process exited with code ${code}`);
|
|
31
|
+
});
|
|
28
32
|
});
|
|
29
33
|
afterEach(() => {
|
|
30
34
|
nock.cleanAll();
|
|
@@ -63,29 +67,15 @@ describe('apps-devices-delete', () => {
|
|
|
63
67
|
const appId = 'app-1';
|
|
64
68
|
const deviceId = 'device-456';
|
|
65
69
|
const testToken = 'test-token';
|
|
66
|
-
const organization = { id: orgId, name: 'Org 1' };
|
|
67
|
-
const app = { id: appId, name: 'App 1' };
|
|
68
70
|
const options = { deviceId };
|
|
69
|
-
const orgsScope = nock(DEFAULT_API_BASE_URL)
|
|
70
|
-
.get('/v1/organizations')
|
|
71
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
72
|
-
.reply(200, [organization]);
|
|
73
|
-
const appsScope = nock(DEFAULT_API_BASE_URL)
|
|
74
|
-
.get('/v1/apps')
|
|
75
|
-
.query({ organizationId: orgId })
|
|
76
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
77
|
-
.reply(200, [app]);
|
|
78
71
|
const deleteScope = nock(DEFAULT_API_BASE_URL)
|
|
79
72
|
.delete(`/v1/apps/${appId}/devices/${deviceId}`)
|
|
80
73
|
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
81
74
|
.reply(200);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
.mockResolvedValueOnce(true); // confirmation
|
|
75
|
+
mockPromptOrganizationSelection.mockResolvedValueOnce(orgId);
|
|
76
|
+
mockPromptAppSelection.mockResolvedValueOnce(appId);
|
|
77
|
+
mockPrompt.mockResolvedValueOnce(true); // confirmation
|
|
86
78
|
await deleteDeviceCommand.action(options, undefined);
|
|
87
|
-
expect(orgsScope.isDone()).toBe(true);
|
|
88
|
-
expect(appsScope.isDone()).toBe(true);
|
|
89
79
|
expect(deleteScope.isDone()).toBe(true);
|
|
90
80
|
expect(mockConsola.success).toHaveBeenCalledWith('Device deleted successfully.');
|
|
91
81
|
});
|
|
@@ -106,25 +96,13 @@ describe('apps-devices-delete', () => {
|
|
|
106
96
|
expect(mockPrompt).toHaveBeenCalledWith('Enter the device ID:', { type: 'text' });
|
|
107
97
|
expect(mockConsola.success).toHaveBeenCalledWith('Device deleted successfully.');
|
|
108
98
|
});
|
|
109
|
-
it('should
|
|
110
|
-
const testToken = 'test-token';
|
|
99
|
+
it('should exit when promptOrganizationSelection exits', async () => {
|
|
111
100
|
const options = {};
|
|
112
|
-
|
|
113
|
-
.
|
|
114
|
-
.
|
|
115
|
-
.reply(200, []);
|
|
116
|
-
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
117
|
-
throw new Error(`process.exit called with code ${code}`);
|
|
101
|
+
mockPromptOrganizationSelection.mockImplementation(() => {
|
|
102
|
+
process.exit(1);
|
|
103
|
+
return Promise.resolve('');
|
|
118
104
|
});
|
|
119
|
-
|
|
120
|
-
await deleteDeviceCommand.action(options, undefined);
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
expect(error.message).toBe('process.exit called with code 1');
|
|
124
|
-
}
|
|
125
|
-
expect(scope.isDone()).toBe(true);
|
|
126
|
-
expect(mockConsola.error).toHaveBeenCalledWith('You must create an organization before deleting a device.');
|
|
127
|
-
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
105
|
+
await expect(deleteDeviceCommand.action(options, undefined)).rejects.toThrow('Process exited with code 1');
|
|
128
106
|
});
|
|
129
107
|
it('should handle API error during deletion', async () => {
|
|
130
108
|
const appId = 'app-123';
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import appEnvironmentsService from '../../../services/app-environments.js';
|
|
2
|
-
import
|
|
3
|
-
import authorizationService from '../../../services/authorization-service.js';
|
|
4
|
-
import organizationsService from '../../../services/organizations.js';
|
|
2
|
+
import { withAuth } from '../../../utils/auth.js';
|
|
5
3
|
import { isInteractive } from '../../../utils/environment.js';
|
|
6
|
-
import { prompt } from '../../../utils/prompt.js';
|
|
4
|
+
import { prompt, promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
|
|
7
5
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
8
6
|
import consola from 'consola';
|
|
9
7
|
import { z } from 'zod';
|
|
@@ -13,43 +11,15 @@ export default defineCommand({
|
|
|
13
11
|
appId: z.string().optional().describe('ID of the app.'),
|
|
14
12
|
name: z.string().optional().describe('Name of the environment.'),
|
|
15
13
|
})),
|
|
16
|
-
action: async (options, args) => {
|
|
14
|
+
action: withAuth(async (options, args) => {
|
|
17
15
|
let { appId, name } = options;
|
|
18
|
-
if (!authorizationService.hasAuthorizationToken()) {
|
|
19
|
-
consola.error('You must be logged in to run this command. Please run the `login` command first.');
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
16
|
if (!appId) {
|
|
23
17
|
if (!isInteractive()) {
|
|
24
18
|
consola.error('You must provide an app ID when running in non-interactive environment.');
|
|
25
19
|
process.exit(1);
|
|
26
20
|
}
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
consola.error('You must create an organization before creating an environment.');
|
|
30
|
-
process.exit(1);
|
|
31
|
-
}
|
|
32
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
33
|
-
const organizationId = await prompt('Select the organization of the app for which you want to create an environment.', {
|
|
34
|
-
type: 'select',
|
|
35
|
-
options: organizations.map((organization) => ({ label: organization.name, value: organization.id })),
|
|
36
|
-
});
|
|
37
|
-
if (!organizationId) {
|
|
38
|
-
consola.error('You must select the organization of an app for which you want to create an environment.');
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
const apps = await appsService.findAll({
|
|
42
|
-
organizationId,
|
|
43
|
-
});
|
|
44
|
-
if (!apps.length) {
|
|
45
|
-
consola.error('You must create an app before creating an environment.');
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
49
|
-
appId = await prompt('Which app do you want to create the environment for?', {
|
|
50
|
-
type: 'select',
|
|
51
|
-
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
52
|
-
});
|
|
21
|
+
const organizationId = await promptOrganizationSelection({ allowCreate: true });
|
|
22
|
+
appId = await promptAppSelection(organizationId, { allowCreate: true });
|
|
53
23
|
}
|
|
54
24
|
if (!name) {
|
|
55
25
|
if (!isInteractive()) {
|
|
@@ -64,5 +34,5 @@ export default defineCommand({
|
|
|
64
34
|
});
|
|
65
35
|
consola.info(`Environment ID: ${response.id}`);
|
|
66
36
|
consola.success('Environment created successfully.');
|
|
67
|
-
},
|
|
37
|
+
}),
|
|
68
38
|
});
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import appEnvironmentsService from '../../../services/app-environments.js';
|
|
2
|
-
import
|
|
3
|
-
import authorizationService from '../../../services/authorization-service.js';
|
|
4
|
-
import organizationsService from '../../../services/organizations.js';
|
|
2
|
+
import { withAuth } from '../../../utils/auth.js';
|
|
5
3
|
import { isInteractive } from '../../../utils/environment.js';
|
|
6
|
-
import { prompt } from '../../../utils/prompt.js';
|
|
4
|
+
import { prompt, promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
|
|
7
5
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
8
6
|
import consola from 'consola';
|
|
9
7
|
import { z } from 'zod';
|
|
@@ -15,43 +13,15 @@ export default defineCommand({
|
|
|
15
13
|
name: z.string().optional().describe('Name of the environment. Either the ID or name must be provided.'),
|
|
16
14
|
yes: z.boolean().optional().describe('Skip confirmation prompt.'),
|
|
17
15
|
}), { y: 'yes' }),
|
|
18
|
-
action: async (options, args) => {
|
|
16
|
+
action: withAuth(async (options, args) => {
|
|
19
17
|
let { appId, environmentId, name } = options;
|
|
20
|
-
if (!authorizationService.hasAuthorizationToken()) {
|
|
21
|
-
consola.error('You must be logged in to run this command. Please run the `login` command first.');
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
24
18
|
if (!appId) {
|
|
25
19
|
if (!isInteractive()) {
|
|
26
20
|
consola.error('You must provide an app ID when running in non-interactive environment.');
|
|
27
21
|
process.exit(1);
|
|
28
22
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
consola.error('You must create an organization before deleting an environment.');
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
35
|
-
const organizationId = await prompt('Select the organization of the app from which you want to delete an environment.', {
|
|
36
|
-
type: 'select',
|
|
37
|
-
options: organizations.map((organization) => ({ label: organization.name, value: organization.id })),
|
|
38
|
-
});
|
|
39
|
-
if (!organizationId) {
|
|
40
|
-
consola.error('You must select the organization of an app from which you want to delete an environment.');
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
const apps = await appsService.findAll({
|
|
44
|
-
organizationId,
|
|
45
|
-
});
|
|
46
|
-
if (!apps.length) {
|
|
47
|
-
consola.error('You must create an app before deleting an environment.');
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
51
|
-
appId = await prompt('Which app do you want to delete the environment from?', {
|
|
52
|
-
type: 'select',
|
|
53
|
-
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
54
|
-
});
|
|
23
|
+
const organizationId = await promptOrganizationSelection();
|
|
24
|
+
appId = await promptAppSelection(organizationId);
|
|
55
25
|
}
|
|
56
26
|
if (!environmentId && !name) {
|
|
57
27
|
if (!isInteractive()) {
|
|
@@ -84,5 +54,5 @@ export default defineCommand({
|
|
|
84
54
|
name,
|
|
85
55
|
});
|
|
86
56
|
consola.success('Environment deleted successfully.');
|
|
87
|
-
},
|
|
57
|
+
}),
|
|
88
58
|
});
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import appEnvironmentsService from '../../../services/app-environments.js';
|
|
2
|
-
import
|
|
3
|
-
import authorizationService from '../../../services/authorization-service.js';
|
|
4
|
-
import organizationsService from '../../../services/organizations.js';
|
|
2
|
+
import { withAuth } from '../../../utils/auth.js';
|
|
5
3
|
import { isInteractive } from '../../../utils/environment.js';
|
|
6
|
-
import {
|
|
4
|
+
import { promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
|
|
7
5
|
import { defineCommand, defineOptions } from '@robingenz/zli';
|
|
8
6
|
import consola from 'consola';
|
|
9
7
|
import { z } from 'zod';
|
|
@@ -15,43 +13,15 @@ export default defineCommand({
|
|
|
15
13
|
limit: z.coerce.number().optional().describe('Limit for pagination.'),
|
|
16
14
|
offset: z.coerce.number().optional().describe('Offset for pagination.'),
|
|
17
15
|
})),
|
|
18
|
-
action: async (options, args) => {
|
|
16
|
+
action: withAuth(async (options, args) => {
|
|
19
17
|
let { appId, json, limit, offset } = options;
|
|
20
|
-
if (!authorizationService.hasAuthorizationToken()) {
|
|
21
|
-
consola.error('You must be logged in to run this command. Please run the `login` command first.');
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
24
18
|
if (!appId) {
|
|
25
19
|
if (!isInteractive()) {
|
|
26
20
|
consola.error('You must provide an app ID when running in non-interactive environment.');
|
|
27
21
|
process.exit(1);
|
|
28
22
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
consola.error('You must create an organization before listing environments.');
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
35
|
-
const organizationId = await prompt('Select the organization of the app for which you want to list environments.', {
|
|
36
|
-
type: 'select',
|
|
37
|
-
options: organizations.map((organization) => ({ label: organization.name, value: organization.id })),
|
|
38
|
-
});
|
|
39
|
-
if (!organizationId) {
|
|
40
|
-
consola.error('You must select the organization of an app for which you want to list environments.');
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
const apps = await appsService.findAll({
|
|
44
|
-
organizationId,
|
|
45
|
-
});
|
|
46
|
-
if (!apps.length) {
|
|
47
|
-
consola.error('You must create an app before listing environments.');
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
// @ts-ignore wait till https://github.com/unjs/consola/pull/280 is merged
|
|
51
|
-
appId = await prompt('Which app do you want to list the environments for?', {
|
|
52
|
-
type: 'select',
|
|
53
|
-
options: apps.map((app) => ({ label: app.name, value: app.id })),
|
|
54
|
-
});
|
|
23
|
+
const organizationId = await promptOrganizationSelection();
|
|
24
|
+
appId = await promptAppSelection(organizationId);
|
|
55
25
|
}
|
|
56
26
|
const environments = await appEnvironmentsService.findAll({
|
|
57
27
|
appId,
|
|
@@ -65,5 +35,5 @@ export default defineCommand({
|
|
|
65
35
|
console.table(environments);
|
|
66
36
|
consola.success('Environments retrieved successfully.');
|
|
67
37
|
}
|
|
68
|
-
},
|
|
38
|
+
}),
|
|
69
39
|
});
|