@sembix/cli 1.0.2 → 1.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.
Files changed (42) hide show
  1. package/.env.example +7 -0
  2. package/README.md +161 -8
  3. package/dist/__tests__/config.test.d.ts +2 -0
  4. package/dist/__tests__/config.test.d.ts.map +1 -0
  5. package/dist/__tests__/config.test.js +75 -0
  6. package/dist/__tests__/config.test.js.map +1 -0
  7. package/dist/__tests__/integration/configure.test.d.ts +2 -0
  8. package/dist/__tests__/integration/configure.test.d.ts.map +1 -0
  9. package/dist/__tests__/integration/configure.test.js +247 -0
  10. package/dist/__tests__/integration/configure.test.js.map +1 -0
  11. package/dist/commands/__tests__/configure.test.d.ts +2 -0
  12. package/dist/commands/__tests__/configure.test.d.ts.map +1 -0
  13. package/dist/commands/__tests__/configure.test.js +229 -0
  14. package/dist/commands/__tests__/configure.test.js.map +1 -0
  15. package/dist/commands/configure.d.ts +6 -0
  16. package/dist/commands/configure.d.ts.map +1 -0
  17. package/dist/commands/configure.js +90 -0
  18. package/dist/commands/configure.js.map +1 -0
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +19 -3
  21. package/dist/config.js.map +1 -1
  22. package/dist/index.js +25 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/prompts/__tests__/environment-setup.test.d.ts +2 -0
  25. package/dist/prompts/__tests__/environment-setup.test.d.ts.map +1 -0
  26. package/dist/prompts/__tests__/environment-setup.test.js +206 -0
  27. package/dist/prompts/__tests__/environment-setup.test.js.map +1 -0
  28. package/dist/prompts/__tests__/hub-integration.test.d.ts +2 -0
  29. package/dist/prompts/__tests__/hub-integration.test.d.ts.map +1 -0
  30. package/dist/prompts/__tests__/hub-integration.test.js +126 -0
  31. package/dist/prompts/__tests__/hub-integration.test.js.map +1 -0
  32. package/dist/sembix-cli-1.2.0.tgz +0 -0
  33. package/dist/utils/__tests__/config-file.test.d.ts +2 -0
  34. package/dist/utils/__tests__/config-file.test.d.ts.map +1 -0
  35. package/dist/utils/__tests__/config-file.test.js +218 -0
  36. package/dist/utils/__tests__/config-file.test.js.map +1 -0
  37. package/dist/utils/config-file.d.ts +23 -0
  38. package/dist/utils/config-file.d.ts.map +1 -0
  39. package/dist/utils/config-file.js +100 -0
  40. package/dist/utils/config-file.js.map +1 -0
  41. package/package.json +1 -1
  42. package/dist/sembix-cli-1.0.2.tgz +0 -0
@@ -0,0 +1,206 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { promptEnvironmentSetup } from '../environment-setup.js';
3
+ import * as prompts from '@inquirer/prompts';
4
+ // Mock @inquirer/prompts
5
+ vi.mock('@inquirer/prompts');
6
+ // Mock chalk
7
+ vi.mock('chalk', () => {
8
+ const createChalkMock = () => {
9
+ const mockFn = (str) => str;
10
+ return new Proxy(mockFn, {
11
+ get: () => createChalkMock(),
12
+ apply: (target, thisArg, args) => args[0],
13
+ });
14
+ };
15
+ return {
16
+ default: createChalkMock(),
17
+ };
18
+ });
19
+ // Mock ui utilities
20
+ vi.mock('../../utils/ui.js', () => ({
21
+ section: vi.fn(),
22
+ info: vi.fn(),
23
+ error: vi.fn(),
24
+ highlight: vi.fn((text) => text),
25
+ dim: vi.fn((text) => text),
26
+ }));
27
+ const mockInput = vi.mocked(prompts.input);
28
+ const mockSelect = vi.mocked(prompts.select);
29
+ const mockConfirm = vi.mocked(prompts.confirm);
30
+ describe('environment-setup', () => {
31
+ let mockGitHubClient;
32
+ beforeEach(() => {
33
+ vi.clearAllMocks();
34
+ // Create mock GitHub client
35
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
+ mockGitHubClient = {
37
+ listRepositories: vi.fn().mockResolvedValue([
38
+ { full_name: 'owner/repo1' },
39
+ { full_name: 'owner/repo2' },
40
+ ]),
41
+ getRepository: vi.fn().mockResolvedValue({
42
+ owner: 'owner',
43
+ name: 'repo1',
44
+ full_name: 'owner/repo1',
45
+ }),
46
+ };
47
+ // Setup default prompt responses
48
+ mockSelect.mockResolvedValue('owner/repo1');
49
+ mockInput.mockResolvedValue('test-value');
50
+ mockConfirm.mockResolvedValue(false);
51
+ });
52
+ describe('promptEnvironmentSetup', () => {
53
+ it.skip('should handle provided repository', async () => {
54
+ mockInput
55
+ .mockResolvedValueOnce('test-env') // environment name
56
+ .mockResolvedValueOnce('123456789012') // aws account id
57
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/test') // customer role
58
+ .mockResolvedValueOnce('test-bucket') // terraform bucket
59
+ .mockResolvedValueOnce('test_db') // database name
60
+ .mockResolvedValueOnce('test_user'); // database user
61
+ mockSelect
62
+ .mockResolvedValueOnce('us-east-1'); // aws region
63
+ mockConfirm
64
+ .mockResolvedValueOnce(false) // vpc endpoints
65
+ .mockResolvedValueOnce(false) // custom networking
66
+ .mockResolvedValueOnce(false) // custom security groups
67
+ .mockResolvedValueOnce(false) // custom iam roles
68
+ .mockResolvedValueOnce(false) // cloudfront custom domain
69
+ .mockResolvedValueOnce(false) // deploy memory
70
+ .mockResolvedValueOnce(false) // deploy notifications
71
+ .mockResolvedValueOnce(false) // enable waf
72
+ .mockResolvedValueOnce(false); // github app
73
+ const result = await promptEnvironmentSetup(mockGitHubClient, undefined, 'owner/repo1', {}, false);
74
+ expect(mockGitHubClient.getRepository).toHaveBeenCalledWith('owner', 'repo1');
75
+ expect(result.repository).toEqual({ owner: 'owner', repo: 'repo1' });
76
+ });
77
+ it.skip('should use provided environment name', async () => {
78
+ mockInput
79
+ .mockResolvedValueOnce('123456789012') // aws account id
80
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/test') // customer role
81
+ .mockResolvedValueOnce('test-bucket') // terraform bucket
82
+ .mockResolvedValueOnce('test_db') // database name
83
+ .mockResolvedValueOnce('test_user'); // database user
84
+ mockSelect
85
+ .mockResolvedValueOnce('us-east-1'); // aws region
86
+ mockConfirm
87
+ .mockResolvedValueOnce(false) // vpc endpoints
88
+ .mockResolvedValueOnce(false) // custom networking
89
+ .mockResolvedValueOnce(false) // custom security groups
90
+ .mockResolvedValueOnce(false) // custom iam roles
91
+ .mockResolvedValueOnce(false) // cloudfront custom domain
92
+ .mockResolvedValueOnce(false) // deploy memory
93
+ .mockResolvedValueOnce(false) // deploy notifications
94
+ .mockResolvedValueOnce(false) // enable waf
95
+ .mockResolvedValueOnce(false); // github app
96
+ const result = await promptEnvironmentSetup(mockGitHubClient, 'provided-env', 'owner/repo1', {}, false);
97
+ expect(result.environmentName).toBe('provided-env');
98
+ });
99
+ it.skip('should select repository interactively when only one repo', async () => {
100
+ mockGitHubClient.listRepositories = vi.fn().mockResolvedValue([
101
+ { full_name: 'owner/single-repo' },
102
+ ]);
103
+ mockInput
104
+ .mockResolvedValueOnce('test-env') // environment name
105
+ .mockResolvedValueOnce('123456789012') // aws account id
106
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/test') // customer role
107
+ .mockResolvedValueOnce('test-bucket') // terraform bucket
108
+ .mockResolvedValueOnce('test_db') // database name
109
+ .mockResolvedValueOnce('test_user'); // database user
110
+ mockSelect.mockResolvedValueOnce('us-east-1'); // aws region
111
+ mockConfirm
112
+ .mockResolvedValueOnce(false) // vpc endpoints
113
+ .mockResolvedValueOnce(false) // custom networking
114
+ .mockResolvedValueOnce(false) // custom security groups
115
+ .mockResolvedValueOnce(false) // custom iam roles
116
+ .mockResolvedValueOnce(false) // cloudfront custom domain
117
+ .mockResolvedValueOnce(false) // deploy memory
118
+ .mockResolvedValueOnce(false) // deploy notifications
119
+ .mockResolvedValueOnce(false) // enable waf
120
+ .mockResolvedValueOnce(false); // github app
121
+ const result = await promptEnvironmentSetup(mockGitHubClient, undefined, undefined, {}, false);
122
+ expect(result.repository).toEqual({ owner: 'owner', repo: 'single-repo' });
123
+ expect(mockSelect).not.toHaveBeenCalledWith(expect.objectContaining({ message: expect.stringContaining('repository') }));
124
+ });
125
+ it.skip('should use partial config values', async () => {
126
+ const partialConfig = {
127
+ awsAccountId: '999888777666',
128
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
+ awsRegion: 'eu-west-1',
130
+ customerRoleArn: 'arn:aws:iam::999888777666:role/PresetRole',
131
+ };
132
+ mockInput
133
+ .mockResolvedValueOnce('test-env') // environment name
134
+ .mockResolvedValueOnce('test-bucket') // terraform bucket
135
+ .mockResolvedValueOnce('test_db') // database name
136
+ .mockResolvedValueOnce('test_user'); // database user
137
+ mockConfirm
138
+ .mockResolvedValueOnce(false) // vpc endpoints
139
+ .mockResolvedValueOnce(false) // custom networking
140
+ .mockResolvedValueOnce(false) // custom security groups
141
+ .mockResolvedValueOnce(false) // custom iam roles
142
+ .mockResolvedValueOnce(false) // cloudfront custom domain
143
+ .mockResolvedValueOnce(false) // deploy memory
144
+ .mockResolvedValueOnce(false) // deploy notifications
145
+ .mockResolvedValueOnce(false) // enable waf
146
+ .mockResolvedValueOnce(false); // github app
147
+ const result = await promptEnvironmentSetup(mockGitHubClient, undefined, 'owner/repo1', partialConfig, false);
148
+ expect(result.awsAccountId).toBe('999888777666');
149
+ expect(result.awsRegion).toBe('eu-west-1');
150
+ expect(result.customerRoleArn).toBe('arn:aws:iam::999888777666:role/PresetRole');
151
+ });
152
+ it.skip('should handle custom networking enabled', async () => {
153
+ mockInput
154
+ .mockResolvedValueOnce('test-env') // environment name
155
+ .mockResolvedValueOnce('123456789012') // aws account id
156
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/test') // customer role
157
+ .mockResolvedValueOnce('test-bucket') // terraform bucket
158
+ .mockResolvedValueOnce('test_db') // database name
159
+ .mockResolvedValueOnce('test_user') // database user
160
+ .mockResolvedValueOnce('vpc-12345678') // custom vpc id
161
+ .mockResolvedValueOnce('subnet-111,subnet-222') // public subnets
162
+ .mockResolvedValueOnce('subnet-333,subnet-444'); // private subnets
163
+ mockSelect
164
+ .mockResolvedValueOnce('us-east-1'); // aws region
165
+ mockConfirm
166
+ .mockResolvedValueOnce(false) // vpc endpoints
167
+ .mockResolvedValueOnce(true) // custom networking - YES
168
+ .mockResolvedValueOnce(false) // custom security groups
169
+ .mockResolvedValueOnce(false) // custom iam roles
170
+ .mockResolvedValueOnce(false) // cloudfront custom domain
171
+ .mockResolvedValueOnce(false) // deploy memory
172
+ .mockResolvedValueOnce(false) // deploy notifications
173
+ .mockResolvedValueOnce(false) // enable waf
174
+ .mockResolvedValueOnce(false); // github app
175
+ const result = await promptEnvironmentSetup(mockGitHubClient, undefined, 'owner/repo1', {}, false);
176
+ expect(result.networking?.useCustomNetworking).toBe(true);
177
+ expect(result.networking?.customVpcId).toBe('vpc-12345678');
178
+ });
179
+ it.skip('should handle feature flags enabled', async () => {
180
+ mockInput
181
+ .mockResolvedValueOnce('test-env') // environment name
182
+ .mockResolvedValueOnce('123456789012') // aws account id
183
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/test') // customer role
184
+ .mockResolvedValueOnce('test-bucket') // terraform bucket
185
+ .mockResolvedValueOnce('test_db') // database name
186
+ .mockResolvedValueOnce('test_user'); // database user
187
+ mockSelect
188
+ .mockResolvedValueOnce('us-east-1'); // aws region
189
+ mockConfirm
190
+ .mockResolvedValueOnce(false) // vpc endpoints
191
+ .mockResolvedValueOnce(false) // custom networking
192
+ .mockResolvedValueOnce(false) // custom security groups
193
+ .mockResolvedValueOnce(false) // custom iam roles
194
+ .mockResolvedValueOnce(false) // cloudfront custom domain
195
+ .mockResolvedValueOnce(true) // deploy memory - YES
196
+ .mockResolvedValueOnce(true) // deploy notifications - YES
197
+ .mockResolvedValueOnce(true) // enable waf - YES
198
+ .mockResolvedValueOnce(false); // github app
199
+ const result = await promptEnvironmentSetup(mockGitHubClient, undefined, 'owner/repo1', {}, false);
200
+ expect(result.features?.deploySembixStudioMemory).toBe(true);
201
+ expect(result.features?.deploySembixStudioNotifications).toBe(true);
202
+ expect(result.features?.enableBffWaf).toBe(true);
203
+ });
204
+ });
205
+ });
206
+ //# sourceMappingURL=environment-setup.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-setup.test.js","sourceRoot":"","sources":["../../../src/prompts/__tests__/environment-setup.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAG7C,yBAAyB;AACzB,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAE7B,aAAa;AACb,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;IACpB,MAAM,eAAe,GAAG,GAAQ,EAAE;QAChC,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC;QACpC,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;YACvB,GAAG,EAAE,GAAG,EAAE,CAAC,eAAe,EAAE;YAC5B,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC,CAAC;IACF,OAAO;QACL,OAAO,EAAE,eAAe,EAAE;KAC3B,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,oBAAoB;AACpB,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;IAClC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;IAChB,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;IACd,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;IACxC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;CACnC,CAAC,CAAC,CAAC;AAEJ,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC3C,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7C,MAAM,WAAW,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAE/C,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAI,gBAA8B,CAAC;IAEnC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QAEnB,4BAA4B;QAC5B,8DAA8D;QAC9D,gBAAgB,GAAG;YACjB,gBAAgB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;gBAC1C,EAAE,SAAS,EAAE,aAAa,EAAE;gBAC5B,EAAE,SAAS,EAAE,aAAa,EAAE;aAC7B,CAAC;YACF,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;gBACvC,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,OAAO;gBACb,SAAS,EAAE,aAAa;aACzB,CAAC;SACI,CAAC;QAET,iCAAiC;QACjC,UAAU,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;QAC5C,SAAS,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAC1C,WAAW,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACtD,SAAS;iBACN,qBAAqB,CAAC,UAAU,CAAC,CAAC,mBAAmB;iBACrD,qBAAqB,CAAC,cAAc,CAAC,CAAC,iBAAiB;iBACvD,qBAAqB,CAAC,qCAAqC,CAAC,CAAC,gBAAgB;iBAC7E,qBAAqB,CAAC,aAAa,CAAC,CAAC,mBAAmB;iBACxD,qBAAqB,CAAC,SAAS,CAAC,CAAC,gBAAgB;iBACjD,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB;YAEvD,UAAU;iBACP,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;YAEpD,WAAW;iBACR,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,oBAAoB;iBACjD,qBAAqB,CAAC,KAAK,CAAC,CAAC,yBAAyB;iBACtD,qBAAqB,CAAC,KAAK,CAAC,CAAC,mBAAmB;iBAChD,qBAAqB,CAAC,KAAK,CAAC,CAAC,2BAA2B;iBACxD,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,uBAAuB;iBACpD,qBAAqB,CAAC,KAAK,CAAC,CAAC,aAAa;iBAC1C,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;YAE9C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CACzC,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,EAAE,EACF,KAAK,CACN,CAAC;YAEF,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9E,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,IAAI,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACzD,SAAS;iBACN,qBAAqB,CAAC,cAAc,CAAC,CAAC,iBAAiB;iBACvD,qBAAqB,CAAC,qCAAqC,CAAC,CAAC,gBAAgB;iBAC7E,qBAAqB,CAAC,aAAa,CAAC,CAAC,mBAAmB;iBACxD,qBAAqB,CAAC,SAAS,CAAC,CAAC,gBAAgB;iBACjD,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB;YAEvD,UAAU;iBACP,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;YAEpD,WAAW;iBACR,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,oBAAoB;iBACjD,qBAAqB,CAAC,KAAK,CAAC,CAAC,yBAAyB;iBACtD,qBAAqB,CAAC,KAAK,CAAC,CAAC,mBAAmB;iBAChD,qBAAqB,CAAC,KAAK,CAAC,CAAC,2BAA2B;iBACxD,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,uBAAuB;iBACpD,qBAAqB,CAAC,KAAK,CAAC,CAAC,aAAa;iBAC1C,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;YAE9C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CACzC,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,EAAE,EACF,KAAK,CACN,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YAC9E,gBAAgB,CAAC,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;gBAC5D,EAAE,SAAS,EAAE,mBAAmB,EAAE;aACnC,CAAC,CAAC;YAEH,SAAS;iBACN,qBAAqB,CAAC,UAAU,CAAC,CAAC,mBAAmB;iBACrD,qBAAqB,CAAC,cAAc,CAAC,CAAC,iBAAiB;iBACvD,qBAAqB,CAAC,qCAAqC,CAAC,CAAC,gBAAgB;iBAC7E,qBAAqB,CAAC,aAAa,CAAC,CAAC,mBAAmB;iBACxD,qBAAqB,CAAC,SAAS,CAAC,CAAC,gBAAgB;iBACjD,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB;YAEvD,UAAU,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;YAE5D,WAAW;iBACR,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,oBAAoB;iBACjD,qBAAqB,CAAC,KAAK,CAAC,CAAC,yBAAyB;iBACtD,qBAAqB,CAAC,KAAK,CAAC,CAAC,mBAAmB;iBAChD,qBAAqB,CAAC,KAAK,CAAC,CAAC,2BAA2B;iBACxD,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,uBAAuB;iBACpD,qBAAqB,CAAC,KAAK,CAAC,CAAC,aAAa;iBAC1C,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;YAE9C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CACzC,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,EAAE,EACF,KAAK,CACN,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;YAC3E,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,oBAAoB,CACzC,MAAM,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,CAAC,CAC5E,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,IAAI,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,aAAa,GAAG;gBACpB,YAAY,EAAE,cAAc;gBAC5B,8DAA8D;gBAC9D,SAAS,EAAE,WAAkB;gBAC7B,eAAe,EAAE,2CAA2C;aAC7D,CAAC;YAEF,SAAS;iBACN,qBAAqB,CAAC,UAAU,CAAC,CAAC,mBAAmB;iBACrD,qBAAqB,CAAC,aAAa,CAAC,CAAC,mBAAmB;iBACxD,qBAAqB,CAAC,SAAS,CAAC,CAAC,gBAAgB;iBACjD,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB;YAEvD,WAAW;iBACR,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,oBAAoB;iBACjD,qBAAqB,CAAC,KAAK,CAAC,CAAC,yBAAyB;iBACtD,qBAAqB,CAAC,KAAK,CAAC,CAAC,mBAAmB;iBAChD,qBAAqB,CAAC,KAAK,CAAC,CAAC,2BAA2B;iBACxD,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,uBAAuB;iBACpD,qBAAqB,CAAC,KAAK,CAAC,CAAC,aAAa;iBAC1C,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;YAE9C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CACzC,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,aAAa,EACb,KAAK,CACN,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,IAAI,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YAC5D,SAAS;iBACN,qBAAqB,CAAC,UAAU,CAAC,CAAC,mBAAmB;iBACrD,qBAAqB,CAAC,cAAc,CAAC,CAAC,iBAAiB;iBACvD,qBAAqB,CAAC,qCAAqC,CAAC,CAAC,gBAAgB;iBAC7E,qBAAqB,CAAC,aAAa,CAAC,CAAC,mBAAmB;iBACxD,qBAAqB,CAAC,SAAS,CAAC,CAAC,gBAAgB;iBACjD,qBAAqB,CAAC,WAAW,CAAC,CAAC,gBAAgB;iBACnD,qBAAqB,CAAC,cAAc,CAAC,CAAC,gBAAgB;iBACtD,qBAAqB,CAAC,uBAAuB,CAAC,CAAC,iBAAiB;iBAChE,qBAAqB,CAAC,uBAAuB,CAAC,CAAC,CAAC,kBAAkB;YAErE,UAAU;iBACP,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;YAEpD,WAAW;iBACR,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,IAAI,CAAC,CAAC,0BAA0B;iBACtD,qBAAqB,CAAC,KAAK,CAAC,CAAC,yBAAyB;iBACtD,qBAAqB,CAAC,KAAK,CAAC,CAAC,mBAAmB;iBAChD,qBAAqB,CAAC,KAAK,CAAC,CAAC,2BAA2B;iBACxD,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,uBAAuB;iBACpD,qBAAqB,CAAC,KAAK,CAAC,CAAC,aAAa;iBAC1C,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;YAE9C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CACzC,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,EAAE,EACF,KAAK,CACN,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACxD,SAAS;iBACN,qBAAqB,CAAC,UAAU,CAAC,CAAC,mBAAmB;iBACrD,qBAAqB,CAAC,cAAc,CAAC,CAAC,iBAAiB;iBACvD,qBAAqB,CAAC,qCAAqC,CAAC,CAAC,gBAAgB;iBAC7E,qBAAqB,CAAC,aAAa,CAAC,CAAC,mBAAmB;iBACxD,qBAAqB,CAAC,SAAS,CAAC,CAAC,gBAAgB;iBACjD,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB;YAEvD,UAAU;iBACP,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;YAEpD,WAAW;iBACR,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBAAgB;iBAC7C,qBAAqB,CAAC,KAAK,CAAC,CAAC,oBAAoB;iBACjD,qBAAqB,CAAC,KAAK,CAAC,CAAC,yBAAyB;iBACtD,qBAAqB,CAAC,KAAK,CAAC,CAAC,mBAAmB;iBAChD,qBAAqB,CAAC,KAAK,CAAC,CAAC,2BAA2B;iBACxD,qBAAqB,CAAC,IAAI,CAAC,CAAC,sBAAsB;iBAClD,qBAAqB,CAAC,IAAI,CAAC,CAAC,6BAA6B;iBACzD,qBAAqB,CAAC,IAAI,CAAC,CAAC,mBAAmB;iBAC/C,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;YAE9C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CACzC,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,EAAE,EACF,KAAK,CACN,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,+BAA+B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hub-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub-integration.test.d.ts","sourceRoot":"","sources":["../../../src/prompts/__tests__/hub-integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,126 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { promptHubIntegration } from '../hub-integration.js';
3
+ import * as prompts from '@inquirer/prompts';
4
+ // Mock @inquirer/prompts
5
+ vi.mock('@inquirer/prompts');
6
+ // Mock ui utilities
7
+ vi.mock('../../utils/ui.js', () => ({
8
+ section: vi.fn(),
9
+ info: vi.fn(),
10
+ error: vi.fn(),
11
+ highlight: vi.fn((text) => text),
12
+ dim: vi.fn((text) => text),
13
+ }));
14
+ const mockInput = vi.mocked(prompts.input);
15
+ const mockSelect = vi.mocked(prompts.select);
16
+ describe('hub-integration', () => {
17
+ let mockGitHubClient;
18
+ beforeEach(() => {
19
+ vi.clearAllMocks();
20
+ // Create mock GitHub client
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ mockGitHubClient = {
23
+ listRepositories: vi.fn().mockResolvedValue([
24
+ { full_name: 'owner/repo1' },
25
+ { full_name: 'owner/repo2' },
26
+ ]),
27
+ listEnvironments: vi.fn().mockResolvedValue([
28
+ { name: 'production' },
29
+ { name: 'staging' },
30
+ ]),
31
+ };
32
+ // Setup default prompt responses
33
+ mockSelect.mockResolvedValue('owner/repo1');
34
+ mockInput.mockResolvedValue('test-value');
35
+ });
36
+ describe('promptHubIntegration', () => {
37
+ it('should handle provided repository and environment', async () => {
38
+ mockInput
39
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-engine') // engine role
40
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-consumer') // consumer role
41
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-appconfig') // appconfig role
42
+ .mockResolvedValueOnce('app-12345') // app id
43
+ .mockResolvedValueOnce('env-12345') // env id
44
+ .mockResolvedValueOnce('profile-12345'); // profile id
45
+ const result = await promptHubIntegration(mockGitHubClient, 'production', 'owner/repo1', {});
46
+ expect(mockGitHubClient.listEnvironments).toHaveBeenCalledWith('owner', 'repo1');
47
+ expect(result.repository).toEqual({ owner: 'owner', repo: 'repo1' });
48
+ expect(result.environmentName).toBe('production');
49
+ expect(result.hubRoles.engineExecutionRole).toBe('arn:aws:iam::123456789012:role/hub-engine');
50
+ });
51
+ it('should select repository interactively', async () => {
52
+ mockSelect
53
+ .mockResolvedValueOnce('owner/repo2') // repo selection
54
+ .mockResolvedValueOnce('staging'); // env selection
55
+ mockInput
56
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-engine') // engine role
57
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-consumer') // consumer role
58
+ .mockResolvedValueOnce('') // appconfig role - skip
59
+ .mockResolvedValueOnce('') // app id - skip
60
+ .mockResolvedValueOnce('') // env id - skip
61
+ .mockResolvedValueOnce(''); // profile id - skip
62
+ const result = await promptHubIntegration(mockGitHubClient, undefined, undefined, {});
63
+ expect(result.repository).toEqual({ owner: 'owner', repo: 'repo2' });
64
+ expect(result.environmentName).toBe('staging');
65
+ });
66
+ it('should use CLI flags when provided', async () => {
67
+ const cliFlags = {
68
+ hubEngineExecutionRole: 'arn:aws:iam::123456789012:role/cli-engine',
69
+ hubConsumerRole: 'arn:aws:iam::123456789012:role/cli-consumer',
70
+ hubAppconfigRole: 'arn:aws:iam::123456789012:role/cli-appconfig',
71
+ hubAppconfigAppId: 'cli-app-123',
72
+ hubAppconfigEnvId: 'cli-env-123',
73
+ hubAppconfigProfileId: 'cli-profile-123',
74
+ };
75
+ // Should not prompt for values that are provided via CLI
76
+ const result = await promptHubIntegration(mockGitHubClient, 'production', 'owner/repo1', cliFlags);
77
+ expect(result.hubRoles.engineExecutionRole).toBe('arn:aws:iam::123456789012:role/cli-engine');
78
+ expect(result.hubRoles.consumerRole).toBe('arn:aws:iam::123456789012:role/cli-consumer');
79
+ expect(result.appConfig?.roleArn).toBe('arn:aws:iam::123456789012:role/cli-appconfig');
80
+ expect(result.appConfig?.appId).toBe('cli-app-123');
81
+ });
82
+ it('should handle optional AppConfig fields', async () => {
83
+ mockInput
84
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-engine') // engine role
85
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-consumer') // consumer role
86
+ .mockResolvedValueOnce('') // appconfig role - empty
87
+ .mockResolvedValueOnce('') // app id - skip
88
+ .mockResolvedValueOnce('') // env id - skip
89
+ .mockResolvedValueOnce(''); // profile id - skip
90
+ const result = await promptHubIntegration(mockGitHubClient, 'production', 'owner/repo1', {});
91
+ expect(result.hubRoles.engineExecutionRole).toBeDefined();
92
+ expect(result.hubRoles.consumerRole).toBeDefined();
93
+ expect(result.appConfig?.roleArn).toBeUndefined();
94
+ expect(result.appConfig?.appId).toBeUndefined();
95
+ });
96
+ it('should handle AppConfig with all fields', async () => {
97
+ mockInput
98
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-engine') // engine role
99
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-consumer') // consumer role
100
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/appconfig') // appconfig role
101
+ .mockResolvedValueOnce('app-abc123') // app id
102
+ .mockResolvedValueOnce('env-def456') // env id
103
+ .mockResolvedValueOnce('profile-ghi789'); // profile id
104
+ const result = await promptHubIntegration(mockGitHubClient, 'production', 'owner/repo1', {});
105
+ expect(result.appConfig?.roleArn).toBe('arn:aws:iam::123456789012:role/appconfig');
106
+ expect(result.appConfig?.appId).toBe('app-abc123');
107
+ expect(result.appConfig?.envId).toBe('env-def456');
108
+ expect(result.appConfig?.profileId).toBe('profile-ghi789');
109
+ });
110
+ it('should prompt for all AppConfig fields even when empty', async () => {
111
+ mockInput
112
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-engine') // engine role
113
+ .mockResolvedValueOnce('arn:aws:iam::123456789012:role/hub-consumer') // consumer role
114
+ .mockResolvedValueOnce('') // appconfig role - empty
115
+ .mockResolvedValueOnce('') // appconfig app id - empty
116
+ .mockResolvedValueOnce('') // appconfig env id - empty
117
+ .mockResolvedValueOnce(''); // appconfig profile id - empty
118
+ const result = await promptHubIntegration(mockGitHubClient, 'production', 'owner/repo1', {});
119
+ // All 6 inputs should be called (2 roles + 4 appconfig fields)
120
+ expect(mockInput).toHaveBeenCalledTimes(6);
121
+ expect(result.appConfig?.roleArn).toBeUndefined();
122
+ expect(result.appConfig?.appId).toBeUndefined();
123
+ });
124
+ });
125
+ });
126
+ //# sourceMappingURL=hub-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub-integration.test.js","sourceRoot":"","sources":["../../../src/prompts/__tests__/hub-integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAG7C,yBAAyB;AACzB,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAE7B,oBAAoB;AACpB,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;IAClC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;IAChB,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;IACd,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;IACxC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;CACnC,CAAC,CAAC,CAAC;AAEJ,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC3C,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAE7C,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,gBAA8B,CAAC;IAEnC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QAEnB,4BAA4B;QAC5B,8DAA8D;QAC9D,gBAAgB,GAAG;YACjB,gBAAgB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;gBAC1C,EAAE,SAAS,EAAE,aAAa,EAAE;gBAC5B,EAAE,SAAS,EAAE,aAAa,EAAE;aAC7B,CAAC;YACF,gBAAgB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;gBAC1C,EAAE,IAAI,EAAE,YAAY,EAAE;gBACtB,EAAE,IAAI,EAAE,SAAS,EAAE;aACpB,CAAC;SACI,CAAC;QAET,iCAAiC;QACjC,UAAU,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;QAC5C,SAAS,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,SAAS;iBACN,qBAAqB,CAAC,2CAA2C,CAAC,CAAC,cAAc;iBACjF,qBAAqB,CAAC,6CAA6C,CAAC,CAAC,gBAAgB;iBACrF,qBAAqB,CAAC,8CAA8C,CAAC,CAAC,iBAAiB;iBACvF,qBAAqB,CAAC,WAAW,CAAC,CAAC,SAAS;iBAC5C,qBAAqB,CAAC,WAAW,CAAC,CAAC,SAAS;iBAC5C,qBAAqB,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa;YAExD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,EAAE,CACH,CAAC;YAEF,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACjF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACrE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAChG,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACtD,UAAU;iBACP,qBAAqB,CAAC,aAAa,CAAC,CAAC,iBAAiB;iBACtD,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB;YAErD,SAAS;iBACN,qBAAqB,CAAC,2CAA2C,CAAC,CAAC,cAAc;iBACjF,qBAAqB,CAAC,6CAA6C,CAAC,CAAC,gBAAgB;iBACrF,qBAAqB,CAAC,EAAE,CAAC,CAAC,wBAAwB;iBAClD,qBAAqB,CAAC,EAAE,CAAC,CAAC,gBAAgB;iBAC1C,qBAAqB,CAAC,EAAE,CAAC,CAAC,gBAAgB;iBAC1C,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB;YAElD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,EAAE,CACH,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACrE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAClD,MAAM,QAAQ,GAAG;gBACf,sBAAsB,EAAE,2CAA2C;gBACnE,eAAe,EAAE,6CAA6C;gBAC9D,gBAAgB,EAAE,8CAA8C;gBAChE,iBAAiB,EAAE,aAAa;gBAChC,iBAAiB,EAAE,aAAa;gBAChC,qBAAqB,EAAE,iBAAiB;aACzC,CAAC;YAEF,yDAAyD;YACzD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,QAAQ,CACT,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YAC9F,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YACzF,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YACvF,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,SAAS;iBACN,qBAAqB,CAAC,2CAA2C,CAAC,CAAC,cAAc;iBACjF,qBAAqB,CAAC,6CAA6C,CAAC,CAAC,gBAAgB;iBACrF,qBAAqB,CAAC,EAAE,CAAC,CAAC,yBAAyB;iBACnD,qBAAqB,CAAC,EAAE,CAAC,CAAC,gBAAgB;iBAC1C,qBAAqB,CAAC,EAAE,CAAC,CAAC,gBAAgB;iBAC1C,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB;YAElD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,EAAE,CACH,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,SAAS;iBACN,qBAAqB,CAAC,2CAA2C,CAAC,CAAC,cAAc;iBACjF,qBAAqB,CAAC,6CAA6C,CAAC,CAAC,gBAAgB;iBACrF,qBAAqB,CAAC,0CAA0C,CAAC,CAAC,iBAAiB;iBACnF,qBAAqB,CAAC,YAAY,CAAC,CAAC,SAAS;iBAC7C,qBAAqB,CAAC,YAAY,CAAC,CAAC,SAAS;iBAC7C,qBAAqB,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa;YAEzD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,EAAE,CACH,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;YACnF,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,SAAS;iBACN,qBAAqB,CAAC,2CAA2C,CAAC,CAAC,cAAc;iBACjF,qBAAqB,CAAC,6CAA6C,CAAC,CAAC,gBAAgB;iBACrF,qBAAqB,CAAC,EAAE,CAAC,CAAC,yBAAyB;iBACnD,qBAAqB,CAAC,EAAE,CAAC,CAAC,2BAA2B;iBACrD,qBAAqB,CAAC,EAAE,CAAC,CAAC,2BAA2B;iBACrD,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,+BAA+B;YAE7D,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,EAAE,CACH,CAAC;YAEF,+DAA+D;YAC/D,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
Binary file
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config-file.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-file.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/config-file.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,218 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { promises as fs } from 'fs';
3
+ import { existsSync } from 'fs';
4
+ import { homedir } from 'os';
5
+ // Mock os module BEFORE importing the module under test
6
+ vi.mock('os', () => ({
7
+ homedir: vi.fn(() => '/home/testuser'),
8
+ }));
9
+ // Mock fs modules
10
+ vi.mock('fs', () => ({
11
+ existsSync: vi.fn(),
12
+ promises: {
13
+ readFile: vi.fn(),
14
+ writeFile: vi.fn(),
15
+ mkdir: vi.fn(),
16
+ },
17
+ }));
18
+ // NOW import the module under test
19
+ import { readConfig, writeConfig, getConfigPath, configExists, } from '../config-file.js';
20
+ const mockExistsSync = vi.mocked(existsSync);
21
+ const mockReadFile = vi.mocked(fs.readFile);
22
+ const mockWriteFile = vi.mocked(fs.writeFile);
23
+ const mockMkdir = vi.mocked(fs.mkdir);
24
+ const mockHomedir = vi.mocked(homedir);
25
+ describe('config-file', () => {
26
+ beforeEach(() => {
27
+ vi.clearAllMocks();
28
+ mockHomedir.mockReturnValue('/home/testuser');
29
+ });
30
+ describe('getConfigPath', () => {
31
+ it('should return the correct config path', () => {
32
+ const path = getConfigPath();
33
+ expect(path).toBe('/home/testuser/.sembix/config');
34
+ });
35
+ });
36
+ describe('configExists', () => {
37
+ it('should return true when config file exists', () => {
38
+ mockExistsSync.mockReturnValue(true);
39
+ expect(configExists()).toBe(true);
40
+ expect(mockExistsSync).toHaveBeenCalledWith('/home/testuser/.sembix/config');
41
+ });
42
+ it('should return false when config file does not exist', () => {
43
+ mockExistsSync.mockReturnValue(false);
44
+ expect(configExists()).toBe(false);
45
+ });
46
+ });
47
+ describe('readConfig', () => {
48
+ it('should return empty object when config file does not exist', async () => {
49
+ mockExistsSync.mockReturnValue(false);
50
+ const config = await readConfig();
51
+ expect(config).toEqual({});
52
+ });
53
+ it('should parse valid config file with github_token', async () => {
54
+ mockExistsSync.mockReturnValue(true);
55
+ mockReadFile.mockResolvedValue('github_token=ghp_test123\n');
56
+ const config = await readConfig();
57
+ expect(config).toEqual({
58
+ github_token: 'ghp_test123',
59
+ });
60
+ });
61
+ it('should parse valid config file with both fields', async () => {
62
+ mockExistsSync.mockReturnValue(true);
63
+ mockReadFile.mockResolvedValue('github_token=ghp_test123\ndefault_github_org=acme-corp\n');
64
+ const config = await readConfig();
65
+ expect(config).toEqual({
66
+ github_token: 'ghp_test123',
67
+ default_github_org: 'acme-corp',
68
+ });
69
+ });
70
+ it('should ignore comments and empty lines', async () => {
71
+ mockExistsSync.mockReturnValue(true);
72
+ mockReadFile.mockResolvedValue(`
73
+ # This is a comment
74
+ github_token=ghp_test123
75
+
76
+ ; Another comment style
77
+ default_github_org=acme-corp
78
+ `);
79
+ const config = await readConfig();
80
+ expect(config).toEqual({
81
+ github_token: 'ghp_test123',
82
+ default_github_org: 'acme-corp',
83
+ });
84
+ });
85
+ it('should handle values with equals signs', async () => {
86
+ mockExistsSync.mockReturnValue(true);
87
+ mockReadFile.mockResolvedValue('github_token=ghp_test=123=456\n');
88
+ const config = await readConfig();
89
+ expect(config).toEqual({
90
+ github_token: 'ghp_test=123=456',
91
+ });
92
+ });
93
+ it('should trim whitespace from keys and values', async () => {
94
+ mockExistsSync.mockReturnValue(true);
95
+ mockReadFile.mockResolvedValue(' github_token = ghp_test123 \n');
96
+ const config = await readConfig();
97
+ expect(config).toEqual({
98
+ github_token: 'ghp_test123',
99
+ });
100
+ });
101
+ it('should ignore unknown keys', async () => {
102
+ mockExistsSync.mockReturnValue(true);
103
+ mockReadFile.mockResolvedValue('github_token=ghp_test123\nunknown_key=value\ndefault_github_org=acme\n');
104
+ const config = await readConfig();
105
+ expect(config).toEqual({
106
+ github_token: 'ghp_test123',
107
+ default_github_org: 'acme',
108
+ });
109
+ });
110
+ it('should return empty object on read error', async () => {
111
+ mockExistsSync.mockReturnValue(true);
112
+ mockReadFile.mockRejectedValue(new Error('Permission denied'));
113
+ const config = await readConfig();
114
+ expect(config).toEqual({});
115
+ });
116
+ it('should handle invalid format gracefully', async () => {
117
+ mockExistsSync.mockReturnValue(true);
118
+ mockReadFile.mockResolvedValue('invalid line without equals\n');
119
+ const config = await readConfig();
120
+ expect(config).toEqual({});
121
+ });
122
+ });
123
+ describe('writeConfig', () => {
124
+ it('should create directory if it does not exist', async () => {
125
+ mockExistsSync.mockReturnValue(false);
126
+ mockMkdir.mockResolvedValue(undefined);
127
+ mockWriteFile.mockResolvedValue(undefined);
128
+ const config = {
129
+ github_token: 'ghp_test123',
130
+ };
131
+ await writeConfig(config);
132
+ expect(mockMkdir).toHaveBeenCalledWith('/home/testuser/.sembix', {
133
+ recursive: true,
134
+ mode: 0o700,
135
+ });
136
+ });
137
+ it('should not create directory if it already exists', async () => {
138
+ mockExistsSync.mockReturnValue(true);
139
+ mockWriteFile.mockResolvedValue(undefined);
140
+ const config = {
141
+ github_token: 'ghp_test123',
142
+ };
143
+ await writeConfig(config);
144
+ expect(mockMkdir).not.toHaveBeenCalled();
145
+ });
146
+ it('should write config with github_token only', async () => {
147
+ mockExistsSync.mockReturnValue(true);
148
+ mockWriteFile.mockResolvedValue(undefined);
149
+ const config = {
150
+ github_token: 'ghp_test123',
151
+ };
152
+ await writeConfig(config);
153
+ expect(mockWriteFile).toHaveBeenCalledWith('/home/testuser/.sembix/config', expect.stringContaining('github_token=ghp_test123'), { mode: 0o600 });
154
+ });
155
+ it('should write config with both fields', async () => {
156
+ mockExistsSync.mockReturnValue(true);
157
+ mockWriteFile.mockResolvedValue(undefined);
158
+ const config = {
159
+ github_token: 'ghp_test123',
160
+ default_github_org: 'acme-corp',
161
+ };
162
+ await writeConfig(config);
163
+ const writeCall = mockWriteFile.mock.calls[0];
164
+ const content = writeCall[1];
165
+ expect(content).toContain('github_token=ghp_test123');
166
+ expect(content).toContain('default_github_org=acme-corp');
167
+ expect(writeCall[2]).toEqual({ mode: 0o600 });
168
+ });
169
+ it('should include header comments', async () => {
170
+ mockExistsSync.mockReturnValue(true);
171
+ mockWriteFile.mockResolvedValue(undefined);
172
+ const config = {
173
+ github_token: 'ghp_test123',
174
+ };
175
+ await writeConfig(config);
176
+ const content = mockWriteFile.mock.calls[0][1];
177
+ expect(content).toContain('# Sembix CLI Configuration');
178
+ expect(content).toContain('# Generated by: sembix configure');
179
+ });
180
+ it('should end with trailing newline', async () => {
181
+ mockExistsSync.mockReturnValue(true);
182
+ mockWriteFile.mockResolvedValue(undefined);
183
+ const config = {
184
+ github_token: 'ghp_test123',
185
+ };
186
+ await writeConfig(config);
187
+ const content = mockWriteFile.mock.calls[0][1];
188
+ expect(content.endsWith('\n')).toBe(true);
189
+ });
190
+ it('should handle empty config object', async () => {
191
+ mockExistsSync.mockReturnValue(true);
192
+ mockWriteFile.mockResolvedValue(undefined);
193
+ const config = {};
194
+ await writeConfig(config);
195
+ const content = mockWriteFile.mock.calls[0][1];
196
+ expect(content).toContain('# Sembix CLI Configuration');
197
+ expect(content).not.toContain('github_token=');
198
+ expect(content).not.toContain('default_github_org=');
199
+ });
200
+ it('should propagate write errors', async () => {
201
+ mockExistsSync.mockReturnValue(true);
202
+ mockWriteFile.mockRejectedValue(new Error('Disk full'));
203
+ const config = {
204
+ github_token: 'ghp_test123',
205
+ };
206
+ await expect(writeConfig(config)).rejects.toThrow('Disk full');
207
+ });
208
+ it('should propagate mkdir errors', async () => {
209
+ mockExistsSync.mockReturnValue(false);
210
+ mockMkdir.mockRejectedValue(new Error('Permission denied'));
211
+ const config = {
212
+ github_token: 'ghp_test123',
213
+ };
214
+ await expect(writeConfig(config)).rejects.toThrow('Permission denied');
215
+ });
216
+ });
217
+ });
218
+ //# sourceMappingURL=config-file.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-file.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/config-file.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface SembixConfig {
2
+ github_token?: string;
3
+ default_github_org?: string;
4
+ }
5
+ /**
6
+ * Reads the configuration from ~/.sembix/config
7
+ * Returns an empty object if the file doesn't exist
8
+ */
9
+ export declare function readConfig(): Promise<SembixConfig>;
10
+ /**
11
+ * Writes configuration to ~/.sembix/config
12
+ * Creates the directory if it doesn't exist
13
+ */
14
+ export declare function writeConfig(config: SembixConfig): Promise<void>;
15
+ /**
16
+ * Returns the path to the config file for display purposes
17
+ */
18
+ export declare function getConfigPath(): string;
19
+ /**
20
+ * Checks if the config file exists
21
+ */
22
+ export declare function configExists(): boolean;
23
+ //# sourceMappingURL=config-file.d.ts.map