@nexical/cli 0.1.6 → 0.10.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/.github/workflows/deploy.yml +3 -3
- package/README.md +317 -104
- package/dist/chunk-JYASTIIW.js +42 -0
- package/dist/chunk-JYASTIIW.js.map +1 -0
- package/dist/chunk-LZ3YQWAR.js +2204 -0
- package/dist/chunk-LZ3YQWAR.js.map +1 -0
- package/dist/chunk-OKXOCNXP.js +105 -0
- package/dist/chunk-OKXOCNXP.js.map +1 -0
- package/dist/chunk-OYFWMYPG.js +52 -0
- package/dist/chunk-OYFWMYPG.js.map +1 -0
- package/dist/chunk-WKERTCM6.js +74 -0
- package/dist/chunk-WKERTCM6.js.map +1 -0
- package/dist/index.js +33 -6
- package/dist/index.js.map +1 -1
- package/dist/src/commands/init.d.ts +11 -0
- package/dist/src/commands/init.js +88 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/module/add.d.ts +14 -0
- package/dist/src/commands/module/add.js +136 -0
- package/dist/src/commands/module/add.js.map +1 -0
- package/dist/src/commands/module/list.d.ts +10 -0
- package/dist/src/commands/module/list.js +73 -0
- package/dist/src/commands/module/list.js.map +1 -0
- package/dist/src/commands/module/remove.d.ts +12 -0
- package/dist/src/commands/module/remove.js +71 -0
- package/dist/src/commands/module/remove.js.map +1 -0
- package/dist/src/commands/module/update.d.ts +11 -0
- package/dist/src/commands/module/update.js +52 -0
- package/dist/src/commands/module/update.js.map +1 -0
- package/dist/src/commands/run.d.ts +11 -0
- package/dist/src/commands/run.js +93 -0
- package/dist/src/commands/run.js.map +1 -0
- package/dist/src/utils/discovery.d.ts +13 -0
- package/dist/src/utils/discovery.js +9 -0
- package/dist/src/utils/git.d.ts +16 -0
- package/dist/src/utils/git.js +29 -0
- package/dist/src/utils/git.js.map +1 -0
- package/dist/src/utils/url-resolver.d.ts +15 -0
- package/dist/src/utils/url-resolver.js +9 -0
- package/dist/src/utils/url-resolver.js.map +1 -0
- package/index.ts +29 -5
- package/package.json +32 -30
- package/src/commands/init.ts +85 -0
- package/src/commands/module/add.ts +169 -0
- package/src/commands/module/list.ts +69 -0
- package/src/commands/module/remove.ts +74 -0
- package/src/commands/module/update.ts +50 -0
- package/src/commands/run.ts +98 -0
- package/src/utils/discovery.ts +134 -0
- package/src/utils/git.ts +65 -0
- package/src/utils/url-resolver.ts +57 -0
- package/test/e2e/lifecycle.e2e.test.ts +152 -0
- package/test/integration/commands/init.integration.test.ts +82 -0
- package/test/integration/commands/module.integration.test.ts +144 -0
- package/test/integration/commands/run.integration.test.ts +90 -0
- package/test/integration/utils/command-loading.integration.test.ts +80 -0
- package/test/unit/commands/init.test.ts +153 -0
- package/test/unit/commands/module/add.test.ts +262 -0
- package/test/unit/commands/module/list.test.ts +115 -0
- package/test/unit/commands/module/remove.test.ts +89 -0
- package/test/unit/commands/module/update.test.ts +91 -0
- package/test/unit/commands/run.test.ts +252 -0
- package/test/unit/utils/command-discovery.test.ts +176 -0
- package/test/unit/utils/git.test.ts +152 -0
- package/test/unit/utils/integration-helpers.test.ts +72 -0
- package/test/unit/utils/url-resolver.test.ts +39 -0
- package/test/utils/integration-helpers.ts +66 -0
- package/vitest.e2e.config.ts +0 -1
- package/dist/chunk-JDRAVUKK.js +0 -48
- package/dist/chunk-JDRAVUKK.js.map +0 -1
- package/dist/src/commands/admin/create-user.d.ts +0 -15
- package/dist/src/commands/admin/create-user.js +0 -49
- package/dist/src/commands/admin/create-user.js.map +0 -1
- package/dist/src/commands/branch/create.d.ts +0 -19
- package/dist/src/commands/branch/create.js +0 -59
- package/dist/src/commands/branch/create.js.map +0 -1
- package/dist/src/commands/branch/delete.d.ts +0 -15
- package/dist/src/commands/branch/delete.js +0 -50
- package/dist/src/commands/branch/delete.js.map +0 -1
- package/dist/src/commands/branch/get.d.ts +0 -15
- package/dist/src/commands/branch/get.js +0 -53
- package/dist/src/commands/branch/get.js.map +0 -1
- package/dist/src/commands/branch/list.d.ts +0 -15
- package/dist/src/commands/branch/list.js +0 -51
- package/dist/src/commands/branch/list.js.map +0 -1
- package/dist/src/commands/job/get.d.ts +0 -15
- package/dist/src/commands/job/get.js +0 -62
- package/dist/src/commands/job/get.js.map +0 -1
- package/dist/src/commands/job/list.d.ts +0 -15
- package/dist/src/commands/job/list.js +0 -57
- package/dist/src/commands/job/list.js.map +0 -1
- package/dist/src/commands/job/logs.d.ts +0 -15
- package/dist/src/commands/job/logs.js +0 -67
- package/dist/src/commands/job/logs.js.map +0 -1
- package/dist/src/commands/job/trigger.d.ts +0 -19
- package/dist/src/commands/job/trigger.js +0 -74
- package/dist/src/commands/job/trigger.js.map +0 -1
- package/dist/src/commands/login.d.ts +0 -8
- package/dist/src/commands/login.js +0 -31
- package/dist/src/commands/login.js.map +0 -1
- package/dist/src/commands/project/create.d.ts +0 -24
- package/dist/src/commands/project/create.js +0 -63
- package/dist/src/commands/project/create.js.map +0 -1
- package/dist/src/commands/project/delete.d.ts +0 -20
- package/dist/src/commands/project/delete.js +0 -58
- package/dist/src/commands/project/delete.js.map +0 -1
- package/dist/src/commands/project/get.d.ts +0 -15
- package/dist/src/commands/project/get.js +0 -49
- package/dist/src/commands/project/get.js.map +0 -1
- package/dist/src/commands/project/list.d.ts +0 -15
- package/dist/src/commands/project/list.js +0 -45
- package/dist/src/commands/project/list.js.map +0 -1
- package/dist/src/commands/project/update.d.ts +0 -19
- package/dist/src/commands/project/update.js +0 -66
- package/dist/src/commands/project/update.js.map +0 -1
- package/dist/src/commands/team/create.d.ts +0 -19
- package/dist/src/commands/team/create.js +0 -45
- package/dist/src/commands/team/create.js.map +0 -1
- package/dist/src/commands/team/delete.d.ts +0 -20
- package/dist/src/commands/team/delete.js +0 -52
- package/dist/src/commands/team/delete.js.map +0 -1
- package/dist/src/commands/team/get.d.ts +0 -15
- package/dist/src/commands/team/get.js +0 -42
- package/dist/src/commands/team/get.js.map +0 -1
- package/dist/src/commands/team/list.d.ts +0 -8
- package/dist/src/commands/team/list.js +0 -30
- package/dist/src/commands/team/list.js.map +0 -1
- package/dist/src/commands/team/member/invite.d.ts +0 -20
- package/dist/src/commands/team/member/invite.js +0 -54
- package/dist/src/commands/team/member/invite.js.map +0 -1
- package/dist/src/commands/team/member/remove.d.ts +0 -15
- package/dist/src/commands/team/member/remove.js +0 -43
- package/dist/src/commands/team/member/remove.js.map +0 -1
- package/dist/src/commands/team/update.d.ts +0 -19
- package/dist/src/commands/team/update.js +0 -55
- package/dist/src/commands/team/update.js.map +0 -1
- package/dist/src/commands/token/generate.d.ts +0 -19
- package/dist/src/commands/token/generate.js +0 -48
- package/dist/src/commands/token/generate.js.map +0 -1
- package/dist/src/commands/token/list.d.ts +0 -8
- package/dist/src/commands/token/list.js +0 -31
- package/dist/src/commands/token/list.js.map +0 -1
- package/dist/src/commands/token/revoke.d.ts +0 -15
- package/dist/src/commands/token/revoke.js +0 -38
- package/dist/src/commands/token/revoke.js.map +0 -1
- package/dist/src/commands/whoami.d.ts +0 -8
- package/dist/src/commands/whoami.js +0 -26
- package/dist/src/commands/whoami.js.map +0 -1
- package/dist/src/utils/nexical-client.d.ts +0 -10
- package/dist/src/utils/nexical-client.js +0 -12
- package/src/commands/admin/create-user.ts +0 -46
- package/src/commands/branch/create.ts +0 -57
- package/src/commands/branch/delete.ts +0 -47
- package/src/commands/branch/get.ts +0 -50
- package/src/commands/branch/list.ts +0 -50
- package/src/commands/job/get.ts +0 -59
- package/src/commands/job/list.ts +0 -56
- package/src/commands/job/logs.ts +0 -67
- package/src/commands/job/trigger.ts +0 -73
- package/src/commands/login.ts +0 -31
- package/src/commands/project/create.ts +0 -61
- package/src/commands/project/delete.ts +0 -56
- package/src/commands/project/get.ts +0 -46
- package/src/commands/project/list.ts +0 -44
- package/src/commands/project/update.ts +0 -63
- package/src/commands/team/create.ts +0 -43
- package/src/commands/team/delete.ts +0 -50
- package/src/commands/team/get.ts +0 -39
- package/src/commands/team/list.ts +0 -26
- package/src/commands/team/member/invite.ts +0 -56
- package/src/commands/team/member/remove.ts +0 -40
- package/src/commands/team/update.ts +0 -53
- package/src/commands/token/generate.ts +0 -45
- package/src/commands/token/list.ts +0 -27
- package/src/commands/token/revoke.ts +0 -35
- package/src/commands/whoami.ts +0 -21
- package/src/utils/nexical-client.ts +0 -47
- package/test/e2e/auth.e2e.test.ts +0 -46
- package/test/e2e/job-workflow.e2e.test.ts +0 -33
- package/test/e2e/project-lifecycle.e2e.test.ts +0 -48
- package/test/e2e/setup.ts +0 -237
- package/test/e2e/utils.ts +0 -33
- package/test/integration/commands/admin/create-user.test.ts +0 -51
- package/test/integration/commands/branch/create.test.ts +0 -51
- package/test/integration/commands/branch/delete.test.ts +0 -43
- package/test/integration/commands/branch/get.test.ts +0 -49
- package/test/integration/commands/branch/list.test.ts +0 -47
- package/test/integration/commands/job/get.test.ts +0 -54
- package/test/integration/commands/job/list.test.ts +0 -47
- package/test/integration/commands/job/logs.test.ts +0 -47
- package/test/integration/commands/job/trigger.test.ts +0 -57
- package/test/integration/commands/login.test.ts +0 -62
- package/test/integration/commands/project/create.test.ts +0 -53
- package/test/integration/commands/project/delete.test.ts +0 -43
- package/test/integration/commands/project/get.test.ts +0 -51
- package/test/integration/commands/project/list.test.ts +0 -47
- package/test/integration/commands/project/update.test.ts +0 -53
- package/test/integration/commands/team/create.test.ts +0 -53
- package/test/integration/commands/team/delete.test.ts +0 -43
- package/test/integration/commands/team/get.test.ts +0 -50
- package/test/integration/commands/team/list.test.ts +0 -47
- package/test/integration/commands/team/member/invite.test.ts +0 -46
- package/test/integration/commands/team/member/remove.test.ts +0 -43
- package/test/integration/commands/team/update.test.ts +0 -50
- package/test/integration/commands/token/generate.test.ts +0 -51
- package/test/integration/commands/token/list.test.ts +0 -47
- package/test/integration/commands/token/revoke.test.ts +0 -43
- package/test/integration/commands/whoami.test.ts +0 -49
- package/test/unit/commands/admin/create-user.test.ts +0 -51
- package/test/unit/commands/branch/create.test.ts +0 -57
- package/test/unit/commands/branch/delete.test.ts +0 -49
- package/test/unit/commands/branch/get.test.ts +0 -67
- package/test/unit/commands/branch/list.test.ts +0 -62
- package/test/unit/commands/job/get.test.ts +0 -76
- package/test/unit/commands/job/list.test.ts +0 -62
- package/test/unit/commands/job/logs.test.ts +0 -60
- package/test/unit/commands/job/trigger.test.ts +0 -75
- package/test/unit/commands/login.test.ts +0 -64
- package/test/unit/commands/project/create.test.ts +0 -64
- package/test/unit/commands/project/delete.test.ts +0 -72
- package/test/unit/commands/project/get.test.ts +0 -73
- package/test/unit/commands/project/list.test.ts +0 -62
- package/test/unit/commands/project/update.test.ts +0 -58
- package/test/unit/commands/team/create.test.ts +0 -68
- package/test/unit/commands/team/delete.test.ts +0 -71
- package/test/unit/commands/team/get.test.ts +0 -70
- package/test/unit/commands/team/list.test.ts +0 -56
- package/test/unit/commands/team/member/invite.test.ts +0 -52
- package/test/unit/commands/team/member/remove.test.ts +0 -49
- package/test/unit/commands/team/update.test.ts +0 -63
- package/test/unit/commands/token/generate.test.ts +0 -65
- package/test/unit/commands/token/list.test.ts +0 -58
- package/test/unit/commands/token/revoke.test.ts +0 -49
- package/test/unit/commands/whoami.test.ts +0 -49
- package/test/unit/utils/nexical-client.test.ts +0 -113
- /package/dist/src/utils/{nexical-client.js.map → discovery.js.map} +0 -0
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
-
import TeamsMembersRemoveCommand from '../../../../../src/commands/team/member/remove.js';
|
|
4
|
-
import { getClient } from '../../../../../src/utils/nexical-client.js';
|
|
5
|
-
|
|
6
|
-
vi.mock('../../../../../src/utils/nexical-client.js');
|
|
7
|
-
|
|
8
|
-
describe('TeamsMembersRemoveCommand', () => {
|
|
9
|
-
let command: TeamsMembersRemoveCommand;
|
|
10
|
-
let mockClient: any;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.resetAllMocks();
|
|
14
|
-
|
|
15
|
-
mockClient = {
|
|
16
|
-
teams: {
|
|
17
|
-
removeMember: vi.fn(),
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
vi.mocked(getClient).mockReturnValue(mockClient);
|
|
21
|
-
|
|
22
|
-
command = new TeamsMembersRemoveCommand([], {} as any);
|
|
23
|
-
vi.spyOn(command, 'success').mockImplementation(() => { });
|
|
24
|
-
vi.spyOn(command, 'error').mockImplementation(() => { });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should remove member successfully', async () => {
|
|
28
|
-
mockClient.teams.removeMember.mockResolvedValue({});
|
|
29
|
-
|
|
30
|
-
await command.run({ teamId: '1', userId: 'user-123' });
|
|
31
|
-
|
|
32
|
-
expect(mockClient.teams.removeMember).toHaveBeenCalledWith(1, 'user-123');
|
|
33
|
-
expect(command.success).toHaveBeenCalledWith('User user-123 removed from team 1.');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should validate Team ID', async () => {
|
|
37
|
-
await command.run({ teamId: 'invalid', userId: 'user-123' });
|
|
38
|
-
expect(command.error).toHaveBeenCalledWith('Team ID must be a number.');
|
|
39
|
-
expect(mockClient.teams.removeMember).not.toHaveBeenCalled();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should handle removal failure', async () => {
|
|
43
|
-
mockClient.teams.removeMember.mockRejectedValue(new Error('User not found'));
|
|
44
|
-
|
|
45
|
-
await command.run({ teamId: '1', userId: 'user-123' });
|
|
46
|
-
|
|
47
|
-
expect(command.error).toHaveBeenCalledWith('Failed to remove member: User not found');
|
|
48
|
-
});
|
|
49
|
-
});
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
-
import TeamsUpdateCommand from '../../../../src/commands/team/update.js';
|
|
4
|
-
import { getClient } from '../../../../src/utils/nexical-client.js';
|
|
5
|
-
|
|
6
|
-
vi.mock('../../../../src/utils/nexical-client.js');
|
|
7
|
-
|
|
8
|
-
describe('TeamsUpdateCommand', () => {
|
|
9
|
-
let command: TeamsUpdateCommand;
|
|
10
|
-
let mockClient: any;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.resetAllMocks();
|
|
14
|
-
|
|
15
|
-
mockClient = {
|
|
16
|
-
teams: {
|
|
17
|
-
update: vi.fn(),
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
vi.mocked(getClient).mockReturnValue(mockClient);
|
|
21
|
-
|
|
22
|
-
command = new TeamsUpdateCommand([], {} as any);
|
|
23
|
-
vi.spyOn(command, 'info').mockImplementation(() => { });
|
|
24
|
-
vi.spyOn(command, 'success').mockImplementation(() => { });
|
|
25
|
-
vi.spyOn(command, 'warn').mockImplementation(() => { });
|
|
26
|
-
vi.spyOn(command, 'error').mockImplementation(() => { });
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should update team successfully', async () => {
|
|
30
|
-
mockClient.teams.update.mockResolvedValue({
|
|
31
|
-
id: '1',
|
|
32
|
-
name: 'New Name'
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
await command.run({ teamId: '1', name: 'New Name' });
|
|
36
|
-
|
|
37
|
-
expect(mockClient.teams.update).toHaveBeenCalledWith(1, {
|
|
38
|
-
name: 'New Name',
|
|
39
|
-
});
|
|
40
|
-
expect(command.success).toHaveBeenCalledWith('Team 1 updated!');
|
|
41
|
-
expect(command.info).toHaveBeenCalledWith('Name: New Name');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should warn if no updates provided', async () => {
|
|
45
|
-
await command.run({ teamId: '1' });
|
|
46
|
-
expect(command.warn).toHaveBeenCalledWith('No updates provided. Use --name or --slug.');
|
|
47
|
-
expect(mockClient.teams.update).not.toHaveBeenCalled();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should validate Team ID', async () => {
|
|
51
|
-
await command.run({ teamId: 'invalid' });
|
|
52
|
-
expect(command.error).toHaveBeenCalledWith('Team ID must be a number.');
|
|
53
|
-
expect(mockClient.teams.update).not.toHaveBeenCalled();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('should handle update failure', async () => {
|
|
57
|
-
mockClient.teams.update.mockRejectedValue(new Error('Update failed'));
|
|
58
|
-
|
|
59
|
-
await command.run({ teamId: '1', name: 'N' });
|
|
60
|
-
|
|
61
|
-
expect(command.error).toHaveBeenCalledWith('Failed to update team: Update failed');
|
|
62
|
-
});
|
|
63
|
-
});
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
-
import AuthTokensGenerateCommand from '../../../../src/commands/token/generate.js';
|
|
4
|
-
import { getClient } from '../../../../src/utils/nexical-client.js';
|
|
5
|
-
|
|
6
|
-
vi.mock('../../../../src/utils/nexical-client.js');
|
|
7
|
-
|
|
8
|
-
describe('AuthTokensGenerateCommand', () => {
|
|
9
|
-
let command: AuthTokensGenerateCommand;
|
|
10
|
-
let mockClient: any;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.resetAllMocks();
|
|
14
|
-
|
|
15
|
-
mockClient = {
|
|
16
|
-
auth: {
|
|
17
|
-
generateToken: vi.fn(),
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
vi.mocked(getClient).mockReturnValue(mockClient);
|
|
21
|
-
|
|
22
|
-
command = new AuthTokensGenerateCommand([], {} as any);
|
|
23
|
-
vi.spyOn(command, 'success').mockImplementation(() => { });
|
|
24
|
-
vi.spyOn(command, 'warn').mockImplementation(() => { });
|
|
25
|
-
vi.spyOn(command, 'error').mockImplementation(() => { });
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should generate token successfully', async () => {
|
|
29
|
-
mockClient.auth.generateToken.mockResolvedValue({
|
|
30
|
-
name: 'My Token',
|
|
31
|
-
token: 'secret-token-value'
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
await command.run({ name: 'My Token', scopes: 'read,write' });
|
|
35
|
-
|
|
36
|
-
expect(mockClient.auth.generateToken).toHaveBeenCalledWith({
|
|
37
|
-
name: 'My Token',
|
|
38
|
-
scopes: ['read', 'write'],
|
|
39
|
-
});
|
|
40
|
-
expect(command.success).toHaveBeenCalledWith('Token "My Token" generated!');
|
|
41
|
-
expect(command.warn).toHaveBeenCalledWith('Token: secret-token-value');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should generate token without scopes', async () => {
|
|
45
|
-
mockClient.auth.generateToken.mockResolvedValue({
|
|
46
|
-
name: 'My Token',
|
|
47
|
-
token: 'secret-token-value'
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
await command.run({ name: 'My Token' });
|
|
51
|
-
|
|
52
|
-
expect(mockClient.auth.generateToken).toHaveBeenCalledWith({
|
|
53
|
-
name: 'My Token',
|
|
54
|
-
scopes: undefined,
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('should handle generation failure', async () => {
|
|
59
|
-
mockClient.auth.generateToken.mockRejectedValue(new Error('Limit reached'));
|
|
60
|
-
|
|
61
|
-
await command.run({ name: 'My Token' });
|
|
62
|
-
|
|
63
|
-
expect(command.error).toHaveBeenCalledWith('Failed to generate token: Limit reached');
|
|
64
|
-
});
|
|
65
|
-
});
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
-
import AuthTokensListCommand from '../../../../src/commands/token/list.js';
|
|
4
|
-
import { getClient } from '../../../../src/utils/nexical-client.js';
|
|
5
|
-
|
|
6
|
-
vi.mock('../../../../src/utils/nexical-client.js');
|
|
7
|
-
|
|
8
|
-
describe('AuthTokensListCommand', () => {
|
|
9
|
-
let command: AuthTokensListCommand;
|
|
10
|
-
let mockClient: any;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.resetAllMocks();
|
|
14
|
-
|
|
15
|
-
mockClient = {
|
|
16
|
-
auth: {
|
|
17
|
-
listTokens: vi.fn(),
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
vi.mocked(getClient).mockReturnValue(mockClient);
|
|
21
|
-
|
|
22
|
-
command = new AuthTokensListCommand([], {} as any);
|
|
23
|
-
vi.spyOn(command, 'info').mockImplementation(() => { });
|
|
24
|
-
vi.spyOn(command, 'error').mockImplementation(() => { });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should list tokens successfully', async () => {
|
|
28
|
-
mockClient.auth.listTokens.mockResolvedValue({
|
|
29
|
-
tokens: [
|
|
30
|
-
{ name: 'Token 1', tokenPrefix: 'abc', expiresAt: '2023-01-01' },
|
|
31
|
-
{ name: 'Token 2', tokenPrefix: 'def' }
|
|
32
|
-
]
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
await command.run();
|
|
36
|
-
|
|
37
|
-
expect(mockClient.auth.listTokens).toHaveBeenCalled();
|
|
38
|
-
expect(command.info).toHaveBeenCalledWith('Your API Tokens:');
|
|
39
|
-
expect(command.info).toHaveBeenCalledWith('- Token 1 (abc...) [Expires: 2023-01-01]');
|
|
40
|
-
expect(command.info).toHaveBeenCalledWith('- Token 2 (def...) [Expires: Never]');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should handle empty list', async () => {
|
|
44
|
-
mockClient.auth.listTokens.mockResolvedValue({ tokens: [] });
|
|
45
|
-
|
|
46
|
-
await command.run();
|
|
47
|
-
|
|
48
|
-
expect(command.info).toHaveBeenCalledWith('No API tokens found.');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should handle list failure', async () => {
|
|
52
|
-
mockClient.auth.listTokens.mockRejectedValue(new Error('Network error'));
|
|
53
|
-
|
|
54
|
-
await command.run();
|
|
55
|
-
|
|
56
|
-
expect(command.error).toHaveBeenCalledWith('Failed to list tokens: Network error');
|
|
57
|
-
});
|
|
58
|
-
});
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
-
import AuthTokensRevokeCommand from '../../../../src/commands/token/revoke.js';
|
|
4
|
-
import { getClient } from '../../../../src/utils/nexical-client.js';
|
|
5
|
-
|
|
6
|
-
vi.mock('../../../../src/utils/nexical-client.js');
|
|
7
|
-
|
|
8
|
-
describe('AuthTokensRevokeCommand', () => {
|
|
9
|
-
let command: AuthTokensRevokeCommand;
|
|
10
|
-
let mockClient: any;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.resetAllMocks();
|
|
14
|
-
|
|
15
|
-
mockClient = {
|
|
16
|
-
auth: {
|
|
17
|
-
revokeToken: vi.fn(),
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
vi.mocked(getClient).mockReturnValue(mockClient);
|
|
21
|
-
|
|
22
|
-
command = new AuthTokensRevokeCommand([], {} as any);
|
|
23
|
-
vi.spyOn(command, 'success').mockImplementation(() => { });
|
|
24
|
-
vi.spyOn(command, 'error').mockImplementation(() => { });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should revoke token successfully', async () => {
|
|
28
|
-
mockClient.auth.revokeToken.mockResolvedValue({});
|
|
29
|
-
|
|
30
|
-
await command.run({ id: '123' });
|
|
31
|
-
|
|
32
|
-
expect(mockClient.auth.revokeToken).toHaveBeenCalledWith(123);
|
|
33
|
-
expect(command.success).toHaveBeenCalledWith('Token 123 revoked.');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should validate ID', async () => {
|
|
37
|
-
await command.run({ id: 'invalid' });
|
|
38
|
-
expect(command.error).toHaveBeenCalledWith('Token ID must be a number.');
|
|
39
|
-
expect(mockClient.auth.revokeToken).not.toHaveBeenCalled();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should handle revocation failure', async () => {
|
|
43
|
-
mockClient.auth.revokeToken.mockRejectedValue(new Error('Token not found'));
|
|
44
|
-
|
|
45
|
-
await command.run({ id: '123' });
|
|
46
|
-
|
|
47
|
-
expect(command.error).toHaveBeenCalledWith('Failed to revoke token: Token not found');
|
|
48
|
-
});
|
|
49
|
-
});
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
-
import WhoamiCommand from '../../../src/commands/whoami.js';
|
|
4
|
-
import { getClient } from '../../../src/utils/nexical-client.js';
|
|
5
|
-
|
|
6
|
-
vi.mock('../../../src/utils/nexical-client.js');
|
|
7
|
-
|
|
8
|
-
describe('WhoamiCommand', () => {
|
|
9
|
-
let command: WhoamiCommand;
|
|
10
|
-
let mockClient: any;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.resetAllMocks();
|
|
14
|
-
|
|
15
|
-
mockClient = {
|
|
16
|
-
users: {
|
|
17
|
-
me: vi.fn(),
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
vi.mocked(getClient).mockReturnValue(mockClient);
|
|
21
|
-
|
|
22
|
-
command = new WhoamiCommand([], {} as any);
|
|
23
|
-
vi.spyOn(command, 'info').mockImplementation(() => { });
|
|
24
|
-
vi.spyOn(command, 'error').mockImplementation(() => { });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should display user info when logged in', async () => {
|
|
28
|
-
mockClient.users.me.mockResolvedValue({
|
|
29
|
-
fullName: 'Test User',
|
|
30
|
-
email: 'test@example.com',
|
|
31
|
-
id: 'user-123'
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
await command.run();
|
|
35
|
-
|
|
36
|
-
expect(command.info).toHaveBeenCalledWith('Logged in as:');
|
|
37
|
-
expect(command.info).toHaveBeenCalledWith(' Name: Test User');
|
|
38
|
-
expect(command.info).toHaveBeenCalledWith(' Email: test@example.com');
|
|
39
|
-
expect(command.info).toHaveBeenCalledWith(' ID: user-123');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should display error when not logged in', async () => {
|
|
43
|
-
mockClient.users.me.mockRejectedValue(new Error('Unauthorized'));
|
|
44
|
-
|
|
45
|
-
await command.run();
|
|
46
|
-
|
|
47
|
-
expect(command.error).toHaveBeenCalledWith('Not logged in or token expired. Run `astrical login`.');
|
|
48
|
-
});
|
|
49
|
-
});
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
3
|
-
import { getConfig, saveToken, getClient } from '../../../src/utils/nexical-client.js';
|
|
4
|
-
import fs from 'node:fs';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
import os from 'node:os';
|
|
7
|
-
import { NexicalClient } from '@nexical/sdk';
|
|
8
|
-
|
|
9
|
-
vi.mock('node:fs');
|
|
10
|
-
vi.mock('node:fs');
|
|
11
|
-
vi.mock('node:os', () => ({
|
|
12
|
-
default: {
|
|
13
|
-
homedir: vi.fn(() => '/home/user')
|
|
14
|
-
}
|
|
15
|
-
}));
|
|
16
|
-
vi.mock('@nexical/sdk');
|
|
17
|
-
|
|
18
|
-
describe('nexical-client', () => {
|
|
19
|
-
const mockHomeDir = '/home/user';
|
|
20
|
-
const configDir = path.join(mockHomeDir, '.nexical');
|
|
21
|
-
const configFile = path.join(configDir, 'config.json');
|
|
22
|
-
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
vi.resetAllMocks();
|
|
25
|
-
vi.stubEnv('HOME', '/home/user');
|
|
26
|
-
// os.homedir is already mocked by factory
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
afterEach(() => {
|
|
30
|
-
vi.unstubAllEnvs();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should use os.homedir() if HOME env var is not set', () => {
|
|
34
|
-
vi.unstubAllEnvs();
|
|
35
|
-
vi.stubEnv('HOME', '');
|
|
36
|
-
|
|
37
|
-
// Trigger path resolution
|
|
38
|
-
getConfig();
|
|
39
|
-
|
|
40
|
-
expect(os.homedir).toHaveBeenCalled();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
describe('getConfig', () => {
|
|
44
|
-
it('should return empty object if config file does not exist', () => {
|
|
45
|
-
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
46
|
-
expect(getConfig()).toEqual({});
|
|
47
|
-
expect(fs.existsSync).toHaveBeenCalledWith(configFile);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should return parsed config if file exists', () => {
|
|
51
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
52
|
-
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify({ token: 'test-token' }));
|
|
53
|
-
expect(getConfig()).toEqual({ token: 'test-token' });
|
|
54
|
-
expect(fs.readFileSync).toHaveBeenCalledWith(configFile, 'utf-8');
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should return empty object on JSON parse error', () => {
|
|
58
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
59
|
-
vi.mocked(fs.readFileSync).mockReturnValue('invalid-json');
|
|
60
|
-
expect(getConfig()).toEqual({});
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
describe('saveToken', () => {
|
|
65
|
-
it('should create directory if it does not exist', () => {
|
|
66
|
-
vi.mocked(fs.existsSync)
|
|
67
|
-
.mockReturnValueOnce(false) // config dir check
|
|
68
|
-
.mockReturnValueOnce(false); // config file check (inside getConfig)
|
|
69
|
-
|
|
70
|
-
saveToken('new-token');
|
|
71
|
-
|
|
72
|
-
expect(fs.mkdirSync).toHaveBeenCalledWith(configDir, { recursive: true });
|
|
73
|
-
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
|
74
|
-
configFile,
|
|
75
|
-
JSON.stringify({ token: 'new-token' }, null, 2)
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should update existing config', () => {
|
|
80
|
-
vi.mocked(fs.existsSync)
|
|
81
|
-
.mockReturnValueOnce(true) // config dir check
|
|
82
|
-
.mockReturnValueOnce(true); // config file check (inside getConfig)
|
|
83
|
-
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify({ other: 'value' }));
|
|
84
|
-
|
|
85
|
-
saveToken('new-token');
|
|
86
|
-
|
|
87
|
-
expect(fs.mkdirSync).not.toHaveBeenCalled();
|
|
88
|
-
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
|
89
|
-
configFile,
|
|
90
|
-
JSON.stringify({ other: 'value', token: 'new-token' }, null, 2)
|
|
91
|
-
);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('getClient', () => {
|
|
96
|
-
it('should return NexicalClient instance with token from config', () => {
|
|
97
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
98
|
-
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify({ token: 'saved-token' }));
|
|
99
|
-
|
|
100
|
-
getClient();
|
|
101
|
-
|
|
102
|
-
expect(NexicalClient).toHaveBeenCalledWith({ token: 'saved-token' });
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should return NexicalClient instance without token if config missing', () => {
|
|
106
|
-
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
107
|
-
|
|
108
|
-
getClient();
|
|
109
|
-
|
|
110
|
-
expect(NexicalClient).toHaveBeenCalledWith({ token: undefined });
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
});
|
|
File without changes
|