@sembix/cli 0.1.0 → 1.1.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 (45) hide show
  1. package/README.md +135 -18
  2. package/dist/__tests__/config-schema.test.d.ts +2 -0
  3. package/dist/__tests__/config-schema.test.d.ts.map +1 -0
  4. package/dist/__tests__/config-schema.test.js +471 -0
  5. package/dist/__tests__/config-schema.test.js.map +1 -0
  6. package/dist/__tests__/integration/fixtures/configs.d.ts +477 -0
  7. package/dist/__tests__/integration/fixtures/configs.d.ts.map +1 -0
  8. package/dist/__tests__/integration/fixtures/configs.js +175 -0
  9. package/dist/__tests__/integration/fixtures/configs.js.map +1 -0
  10. package/dist/__tests__/integration/helpers/cli-runner.d.ts +63 -0
  11. package/dist/__tests__/integration/helpers/cli-runner.d.ts.map +1 -0
  12. package/dist/__tests__/integration/helpers/cli-runner.js +152 -0
  13. package/dist/__tests__/integration/helpers/cli-runner.js.map +1 -0
  14. package/dist/__tests__/integration/helpers/command-runner.d.ts +53 -0
  15. package/dist/__tests__/integration/helpers/command-runner.d.ts.map +1 -0
  16. package/dist/__tests__/integration/helpers/command-runner.js +117 -0
  17. package/dist/__tests__/integration/helpers/command-runner.js.map +1 -0
  18. package/dist/__tests__/integration/studio-create.test.d.ts +2 -0
  19. package/dist/__tests__/integration/studio-create.test.d.ts.map +1 -0
  20. package/dist/__tests__/integration/studio-create.test.js +209 -0
  21. package/dist/__tests__/integration/studio-create.test.js.map +1 -0
  22. package/dist/__tests__/integration/studio-update.test.d.ts +2 -0
  23. package/dist/__tests__/integration/studio-update.test.d.ts.map +1 -0
  24. package/dist/__tests__/integration/studio-update.test.js +166 -0
  25. package/dist/__tests__/integration/studio-update.test.js.map +1 -0
  26. package/dist/index.js +8 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/prompts/__tests__/prompt-helpers.test.d.ts +2 -0
  29. package/dist/prompts/__tests__/prompt-helpers.test.d.ts.map +1 -0
  30. package/dist/prompts/__tests__/prompt-helpers.test.js +235 -0
  31. package/dist/prompts/__tests__/prompt-helpers.test.js.map +1 -0
  32. package/dist/sembix-cli-1.1.0.tgz +0 -0
  33. package/dist/utils/__tests__/config-loader.test.d.ts +2 -0
  34. package/dist/utils/__tests__/config-loader.test.d.ts.map +1 -0
  35. package/dist/utils/__tests__/config-loader.test.js +325 -0
  36. package/dist/utils/__tests__/config-loader.test.js.map +1 -0
  37. package/dist/utils/__tests__/github.test.d.ts +2 -0
  38. package/dist/utils/__tests__/github.test.d.ts.map +1 -0
  39. package/dist/utils/__tests__/github.test.js +282 -0
  40. package/dist/utils/__tests__/github.test.js.map +1 -0
  41. package/dist/utils/__tests__/ui.test.d.ts +2 -0
  42. package/dist/utils/__tests__/ui.test.d.ts.map +1 -0
  43. package/dist/utils/__tests__/ui.test.js +256 -0
  44. package/dist/utils/__tests__/ui.test.js.map +1 -0
  45. package/package.json +20 -9
@@ -0,0 +1,325 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import * as yaml from 'js-yaml';
3
+ import { loadConfigFile, mergeConfig, displayConfigErrors, getConfigFilePath, } from '../config-loader.js';
4
+ vi.mock('fs/promises', () => ({
5
+ readFile: vi.fn(),
6
+ }));
7
+ import { readFile as mockReadFile } from 'fs/promises';
8
+ vi.mock('../ui.js', () => ({
9
+ error: vi.fn(),
10
+ dim: vi.fn((text) => text),
11
+ info: vi.fn(),
12
+ highlight: vi.fn((text) => text),
13
+ }));
14
+ describe('config-loader', () => {
15
+ describe('loadConfigFile', () => {
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ });
19
+ it('should load and parse valid YAML config file', async () => {
20
+ const validConfig = {
21
+ environmentName: 'production',
22
+ awsAccountId: '123456789012',
23
+ awsRegion: 'us-east-1',
24
+ repository: { owner: 'test-owner', repo: 'test-repo' },
25
+ };
26
+ vi.mocked(mockReadFile).mockResolvedValue(yaml.dump(validConfig));
27
+ const result = await loadConfigFile('config.yaml');
28
+ expect(result.success).toBe(true);
29
+ expect(result.data).toEqual(validConfig);
30
+ expect(result.errors).toBeUndefined();
31
+ });
32
+ it('should return error for non-existent file', async () => {
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ const error = new Error('File not found');
35
+ error.code = 'ENOENT';
36
+ vi.mocked(mockReadFile).mockRejectedValue(error);
37
+ const result = await loadConfigFile('missing.yaml');
38
+ expect(result.success).toBe(false);
39
+ expect(result.errors).toContain('Config file not found: missing.yaml');
40
+ });
41
+ // Note: YAML parsing errors are handled but difficult to test reliably
42
+ // since js-yaml is permissive. The error handling path exists in the code.
43
+ it('should return validation errors for invalid field values', async () => {
44
+ const invalidConfig = {
45
+ environmentName: 'INVALID_NAME', // uppercase not allowed
46
+ awsAccountId: '12345', // not 12 digits
47
+ };
48
+ vi.mocked(mockReadFile).mockResolvedValue(yaml.dump(invalidConfig));
49
+ const result = await loadConfigFile('invalid-fields.yaml');
50
+ expect(result.success).toBe(false);
51
+ expect(result.errors).toBeDefined();
52
+ expect(result.errors.length).toBeGreaterThan(0);
53
+ });
54
+ it('should validate AWS account ID format', async () => {
55
+ const configWithInvalidAccountId = {
56
+ awsAccountId: 'abc123456789', // contains letters
57
+ };
58
+ vi.mocked(mockReadFile).mockResolvedValue(yaml.dump(configWithInvalidAccountId));
59
+ const result = await loadConfigFile('test.yaml');
60
+ expect(result.success).toBe(false);
61
+ expect(result.errors?.some(e => e.includes('awsAccountId'))).toBe(true);
62
+ });
63
+ it('should validate IAM role ARN format', async () => {
64
+ const configWithInvalidArn = {
65
+ customerRoleArn: 'invalid-arn',
66
+ };
67
+ vi.mocked(mockReadFile).mockResolvedValue(yaml.dump(configWithInvalidArn));
68
+ const result = await loadConfigFile('test.yaml');
69
+ expect(result.success).toBe(false);
70
+ expect(result.errors?.some(e => e.includes('customerRoleArn'))).toBe(true);
71
+ });
72
+ it('should accept partial config with only some fields', async () => {
73
+ const partialConfig = {
74
+ environmentName: 'dev',
75
+ awsRegion: 'us-west-2',
76
+ };
77
+ vi.mocked(mockReadFile).mockResolvedValue(yaml.dump(partialConfig));
78
+ const result = await loadConfigFile('partial.yaml');
79
+ expect(result.success).toBe(true);
80
+ expect(result.data).toEqual(partialConfig);
81
+ });
82
+ });
83
+ describe('mergeConfig', () => {
84
+ it('should return empty config when no inputs provided', () => {
85
+ const result = mergeConfig(undefined, {});
86
+ expect(result).toEqual({});
87
+ });
88
+ it('should use config file values when no CLI flags provided', () => {
89
+ const configFile = {
90
+ environmentName: 'staging',
91
+ awsAccountId: '123456789012',
92
+ awsRegion: 'us-east-1',
93
+ };
94
+ const result = mergeConfig(configFile, {});
95
+ expect(result.environmentName).toBe('staging');
96
+ expect(result.awsAccountId).toBe('123456789012');
97
+ expect(result.awsRegion).toBe('us-east-1');
98
+ });
99
+ it('should override config file with CLI flags', () => {
100
+ const configFile = {
101
+ environmentName: 'staging',
102
+ awsRegion: 'us-east-1',
103
+ };
104
+ const cliFlags = {
105
+ environmentName: 'production',
106
+ awsAccountId: '987654321098',
107
+ };
108
+ const result = mergeConfig(configFile, cliFlags);
109
+ expect(result.environmentName).toBe('production'); // CLI flag wins
110
+ expect(result.awsRegion).toBe('us-east-1'); // from config file
111
+ expect(result.awsAccountId).toBe('987654321098'); // from CLI flag
112
+ });
113
+ it('should parse repository from CLI repo flag', () => {
114
+ const cliFlags = {
115
+ repo: 'owner/repo-name',
116
+ };
117
+ const result = mergeConfig(undefined, cliFlags);
118
+ expect(result.repository).toEqual({
119
+ owner: 'owner',
120
+ repo: 'repo-name',
121
+ });
122
+ });
123
+ it('should merge database configuration', () => {
124
+ const configFile = {
125
+ database: {
126
+ name: 'mydb',
127
+ },
128
+ };
129
+ const cliFlags = {
130
+ databaseUser: 'dbuser',
131
+ };
132
+ const result = mergeConfig(configFile, cliFlags);
133
+ expect(result.database).toEqual({
134
+ name: 'mydb',
135
+ user: 'dbuser',
136
+ });
137
+ });
138
+ it('should merge networking configuration', () => {
139
+ const configFile = {
140
+ networking: {
141
+ enableVpcEndpoints: true,
142
+ vpcCidr: '10.0.0.0/16',
143
+ },
144
+ };
145
+ const cliFlags = {
146
+ useCustomNetworking: true,
147
+ customVpcId: 'vpc-12345abc',
148
+ };
149
+ const result = mergeConfig(configFile, cliFlags);
150
+ expect(result.networking?.enableVpcEndpoints).toBe(true);
151
+ expect(result.networking?.vpcCidr).toBe('10.0.0.0/16');
152
+ expect(result.networking?.useCustomNetworking).toBe(true);
153
+ expect(result.networking?.customVpcId).toBe('vpc-12345abc');
154
+ });
155
+ it('should merge security configuration with custom security groups', () => {
156
+ const configFile = {
157
+ security: {
158
+ useCustomSecurityGroups: true,
159
+ customSecurityGroups: {
160
+ aurora: 'sg-aurora123',
161
+ },
162
+ },
163
+ };
164
+ const cliFlags = {
165
+ sgWorkflowEngine: 'sg-workflow456',
166
+ sgBffEcs: 'sg-bff789',
167
+ };
168
+ const result = mergeConfig(configFile, cliFlags);
169
+ expect(result.security?.useCustomSecurityGroups).toBe(true);
170
+ expect(result.security?.customSecurityGroups?.aurora).toBe('sg-aurora123');
171
+ expect(result.security?.customSecurityGroups?.workflowEngine).toBe('sg-workflow456');
172
+ expect(result.security?.customSecurityGroups?.bffEcs).toBe('sg-bff789');
173
+ });
174
+ it('should merge security configuration with custom IAM roles', () => {
175
+ const configFile = {
176
+ security: {
177
+ useCustomIamPolicies: true,
178
+ customIamRoles: {
179
+ workflowEngineExecutionRole: 'arn:aws:iam::123456789012:role/workflow-exec',
180
+ },
181
+ },
182
+ };
183
+ const cliFlags = {
184
+ iamBffEcsTask: 'arn:aws:iam::123456789012:role/bff-task',
185
+ };
186
+ const result = mergeConfig(configFile, cliFlags);
187
+ expect(result.security?.useCustomIamPolicies).toBe(true);
188
+ expect(result.security?.customIamRoles?.workflowEngineExecutionRole).toBe('arn:aws:iam::123456789012:role/workflow-exec');
189
+ expect(result.security?.customIamRoles?.bffEcsTaskRole).toBe('arn:aws:iam::123456789012:role/bff-task');
190
+ });
191
+ it('should merge TLS configuration', () => {
192
+ const configFile = {
193
+ tls: {
194
+ cloudfrontDomain: 'app.example.com',
195
+ hostedZoneId: 'Z1234567890ABC',
196
+ },
197
+ };
198
+ const cliFlags = {
199
+ cloudfrontCertArn: 'arn:aws:acm:us-east-1:123456789012:certificate/abc123',
200
+ bffAlbCertArn: 'arn:aws:acm:us-west-2:123456789012:certificate/def456',
201
+ };
202
+ const result = mergeConfig(configFile, cliFlags);
203
+ expect(result.tls?.cloudfrontDomain).toBe('app.example.com');
204
+ expect(result.tls?.hostedZoneId).toBe('Z1234567890ABC');
205
+ expect(result.tls?.cloudfrontCertArn).toBe('arn:aws:acm:us-east-1:123456789012:certificate/abc123');
206
+ expect(result.tls?.bffAlbCertificateArn).toBe('arn:aws:acm:us-west-2:123456789012:certificate/def456');
207
+ });
208
+ it('should merge feature flags', () => {
209
+ const configFile = {
210
+ features: {
211
+ deploySembixStudioMemory: true,
212
+ },
213
+ };
214
+ const cliFlags = {
215
+ deployStudioNotifications: true,
216
+ enableBffWaf: false,
217
+ };
218
+ const result = mergeConfig(configFile, cliFlags);
219
+ expect(result.features?.deploySembixStudioMemory).toBe(true);
220
+ expect(result.features?.deploySembixStudioNotifications).toBe(true);
221
+ expect(result.features?.enableBffWaf).toBe(false);
222
+ });
223
+ it('should merge frontend configuration', () => {
224
+ const configFile = {
225
+ frontend: {
226
+ githubAppClientId: 'Iv1.abc123',
227
+ },
228
+ };
229
+ const cliFlags = {
230
+ githubAppName: 'my-github-app',
231
+ jiraClientId: 'jira-client-123',
232
+ };
233
+ const result = mergeConfig(configFile, cliFlags);
234
+ expect(result.frontend?.githubAppClientId).toBe('Iv1.abc123');
235
+ expect(result.frontend?.githubAppName).toBe('my-github-app');
236
+ expect(result.frontend?.jiraClientId).toBe('jira-client-123');
237
+ });
238
+ it('should merge hub configuration', () => {
239
+ const configFile = {
240
+ hub: {
241
+ hubRoles: {
242
+ engineExecutionRole: 'arn:aws:iam::123456789012:role/hub-engine',
243
+ },
244
+ },
245
+ };
246
+ const cliFlags = {
247
+ hubConsumerRole: 'arn:aws:iam::123456789012:role/hub-consumer',
248
+ hubAppconfigAppId: 'app-123',
249
+ hubAppconfigEnvId: 'env-456',
250
+ };
251
+ const result = mergeConfig(configFile, cliFlags);
252
+ expect(result.hub?.hubRoles?.engineExecutionRole).toBe('arn:aws:iam::123456789012:role/hub-engine');
253
+ expect(result.hub?.hubRoles?.consumerRole).toBe('arn:aws:iam::123456789012:role/hub-consumer');
254
+ expect(result.hub?.appConfig?.appId).toBe('app-123');
255
+ expect(result.hub?.appConfig?.envId).toBe('env-456');
256
+ });
257
+ it('should throw error for invalid AWS account ID from CLI flag', () => {
258
+ const cliFlags = {
259
+ awsAccountId: '12345', // not 12 digits
260
+ };
261
+ expect(() => mergeConfig(undefined, cliFlags)).toThrow('Invalid CLI flags');
262
+ });
263
+ it('should throw error for invalid IAM role ARN from CLI flag', () => {
264
+ const cliFlags = {
265
+ customerRoleArn: 'invalid-arn',
266
+ };
267
+ expect(() => mergeConfig(undefined, cliFlags)).toThrow('Invalid CLI flags');
268
+ });
269
+ it('should validate CloudFront certificate is in us-east-1', () => {
270
+ const cliFlags = {
271
+ cloudfrontCertArn: 'arn:aws:acm:us-west-2:123456789012:certificate/abc123', // wrong region
272
+ };
273
+ expect(() => mergeConfig(undefined, cliFlags)).toThrow(/us-east-1|Invalid CLI flags/);
274
+ });
275
+ it('should accept valid CloudFront certificate in us-east-1', () => {
276
+ const cliFlags = {
277
+ cloudfrontCertArn: 'arn:aws:acm:us-east-1:123456789012:certificate/abc123',
278
+ };
279
+ expect(() => mergeConfig(undefined, cliFlags)).not.toThrow();
280
+ });
281
+ it('should validate Route53 hosted zone ID format', () => {
282
+ const cliFlags = {
283
+ hostedZoneId: 'invalid-zone-id',
284
+ };
285
+ expect(() => mergeConfig(undefined, cliFlags)).toThrow('Invalid CLI flags');
286
+ });
287
+ it('should not validate config file values (already validated)', () => {
288
+ const configFile = {
289
+ awsAccountId: '123456789012',
290
+ };
291
+ const result = mergeConfig(configFile, {});
292
+ expect(result.awsAccountId).toBe('123456789012');
293
+ });
294
+ });
295
+ describe('displayConfigErrors', () => {
296
+ it('should call ui.error with error messages', async () => {
297
+ const uiModule = await import('../ui.js');
298
+ const errors = ['Error 1', 'Error 2', 'Error 3'];
299
+ const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
300
+ displayConfigErrors(errors);
301
+ expect(uiModule.error).toHaveBeenCalledWith('Configuration file validation failed:');
302
+ expect(consoleSpy).toHaveBeenCalled();
303
+ consoleSpy.mockRestore();
304
+ });
305
+ });
306
+ describe('getConfigFilePath', () => {
307
+ it('should return config path from config option', () => {
308
+ const options = { config: 'config.yaml' };
309
+ expect(getConfigFilePath(options)).toBe('config.yaml');
310
+ });
311
+ it('should return config path from configFile option', () => {
312
+ const options = { configFile: 'config.yaml' };
313
+ expect(getConfigFilePath(options)).toBe('config.yaml');
314
+ });
315
+ it('should prefer config over configFile', () => {
316
+ const options = { config: 'config1.yaml', configFile: 'config2.yaml' };
317
+ expect(getConfigFilePath(options)).toBe('config1.yaml');
318
+ });
319
+ it('should return undefined when no config path provided', () => {
320
+ const options = {};
321
+ expect(getConfigFilePath(options)).toBeUndefined();
322
+ });
323
+ });
324
+ });
325
+ //# sourceMappingURL=config-loader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/config-loader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=github.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/github.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,282 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { GitHubClient } from '../github.js';
3
+ // Create shared mock instances
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ let mockRepos;
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ let mockActions;
8
+ // Mock Octokit
9
+ vi.mock('@octokit/rest', () => {
10
+ return {
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ Octokit: vi.fn(function (_options) {
13
+ mockRepos = {
14
+ listForOrg: vi.fn(),
15
+ listForAuthenticatedUser: vi.fn(),
16
+ get: vi.fn(),
17
+ getAllEnvironments: vi.fn(),
18
+ createOrUpdateEnvironment: vi.fn(),
19
+ getEnvironment: vi.fn(),
20
+ };
21
+ mockActions = {
22
+ createEnvironmentVariable: vi.fn(),
23
+ getEnvironmentPublicKey: vi.fn(),
24
+ createOrUpdateEnvironmentSecret: vi.fn(),
25
+ };
26
+ return {
27
+ repos: mockRepos,
28
+ actions: mockActions,
29
+ };
30
+ }),
31
+ };
32
+ });
33
+ // Mock libsodium-wrappers
34
+ vi.mock('libsodium-wrappers', () => ({
35
+ default: {
36
+ ready: Promise.resolve(),
37
+ from_base64: vi.fn((_key) => new Uint8Array([1, 2, 3])),
38
+ from_string: vi.fn((_secret) => new Uint8Array([4, 5, 6])),
39
+ crypto_box_seal: vi.fn(() => new Uint8Array([7, 8, 9])),
40
+ to_base64: vi.fn(() => 'encrypted-base64'),
41
+ base64_variants: {
42
+ ORIGINAL: 1,
43
+ },
44
+ },
45
+ }));
46
+ // Mock config
47
+ vi.mock('../../config.js', () => ({
48
+ config: {
49
+ githubToken: 'test-token',
50
+ },
51
+ }));
52
+ describe('GitHubClient', () => {
53
+ let client;
54
+ beforeEach(() => {
55
+ vi.clearAllMocks();
56
+ client = new GitHubClient('test-token');
57
+ });
58
+ describe('listRepositories', () => {
59
+ it('should list repositories for organization', async () => {
60
+ const mockRepoData = [
61
+ { owner: { login: 'org' }, name: 'repo1', full_name: 'org/repo1' },
62
+ { owner: { login: 'org' }, name: 'repo2', full_name: 'org/repo2' },
63
+ ];
64
+ mockRepos.listForOrg.mockResolvedValue({ data: mockRepoData });
65
+ const result = await client.listRepositories('org');
66
+ expect(mockRepos.listForOrg).toHaveBeenCalledWith({
67
+ org: 'org',
68
+ type: 'all',
69
+ per_page: 100,
70
+ });
71
+ expect(result).toEqual([
72
+ { owner: 'org', repo: 'repo1', full_name: 'org/repo1' },
73
+ { owner: 'org', repo: 'repo2', full_name: 'org/repo2' },
74
+ ]);
75
+ });
76
+ it('should list repositories for authenticated user', async () => {
77
+ const mockRepoData = [
78
+ { owner: { login: 'user' }, name: 'repo1', full_name: 'user/repo1' },
79
+ ];
80
+ mockRepos.listForAuthenticatedUser.mockResolvedValue({ data: mockRepoData });
81
+ const result = await client.listRepositories();
82
+ expect(mockRepos.listForAuthenticatedUser).toHaveBeenCalledWith({
83
+ per_page: 100,
84
+ });
85
+ expect(result).toEqual([
86
+ { owner: 'user', repo: 'repo1', full_name: 'user/repo1' },
87
+ ]);
88
+ });
89
+ it('should throw error on API failure', async () => {
90
+ mockRepos.listForOrg.mockRejectedValue(new Error('API error'));
91
+ await expect(client.listRepositories('org')).rejects.toThrow('Failed to list repositories');
92
+ });
93
+ });
94
+ describe('getRepository', () => {
95
+ it('should get repository information', async () => {
96
+ const mockRepo = {
97
+ owner: { login: 'owner' },
98
+ name: 'repo',
99
+ full_name: 'owner/repo',
100
+ };
101
+ mockRepos.get.mockResolvedValue({ data: mockRepo });
102
+ const result = await client.getRepository('owner', 'repo');
103
+ expect(mockRepos.get).toHaveBeenCalledWith({
104
+ owner: 'owner',
105
+ repo: 'repo',
106
+ });
107
+ expect(result).toEqual({
108
+ owner: 'owner',
109
+ repo: 'repo',
110
+ full_name: 'owner/repo',
111
+ });
112
+ });
113
+ it('should throw error for non-existent repository', async () => {
114
+ mockRepos.get.mockRejectedValue(new Error('Not found'));
115
+ await expect(client.getRepository('owner', 'repo')).rejects.toThrow('Failed to get repository');
116
+ });
117
+ });
118
+ describe('listEnvironments', () => {
119
+ it('should list environments for repository', async () => {
120
+ const mockEnvironments = [
121
+ { name: 'production', id: 1, html_url: 'https://github.com/owner/repo/settings/environments/production' },
122
+ { name: 'staging', id: 2, html_url: 'https://github.com/owner/repo/settings/environments/staging' },
123
+ ];
124
+ mockRepos.getAllEnvironments.mockResolvedValue({
125
+ data: { environments: mockEnvironments },
126
+ });
127
+ const result = await client.listEnvironments('owner', 'repo');
128
+ expect(mockRepos.getAllEnvironments).toHaveBeenCalledWith({
129
+ owner: 'owner',
130
+ repo: 'repo',
131
+ });
132
+ expect(result).toEqual([
133
+ { name: 'production', id: 1, url: 'https://github.com/owner/repo/settings/environments/production' },
134
+ { name: 'staging', id: 2, url: 'https://github.com/owner/repo/settings/environments/staging' },
135
+ ]);
136
+ });
137
+ it('should handle repository with no environments', async () => {
138
+ mockRepos.getAllEnvironments.mockResolvedValue({
139
+ data: { environments: null },
140
+ });
141
+ const result = await client.listEnvironments('owner', 'repo');
142
+ expect(result).toEqual([]);
143
+ });
144
+ it('should throw error on API failure', async () => {
145
+ mockRepos.getAllEnvironments.mockRejectedValue(new Error('API error'));
146
+ await expect(client.listEnvironments('owner', 'repo')).rejects.toThrow('Failed to list environments');
147
+ });
148
+ });
149
+ describe('createEnvironment', () => {
150
+ it('should create environment', async () => {
151
+ mockRepos.createOrUpdateEnvironment.mockResolvedValue({});
152
+ await client.createEnvironment('owner', 'repo', 'production');
153
+ expect(mockRepos.createOrUpdateEnvironment).toHaveBeenCalledWith({
154
+ owner: 'owner',
155
+ repo: 'repo',
156
+ environment_name: 'production',
157
+ });
158
+ });
159
+ it('should throw error on failure', async () => {
160
+ mockRepos.createOrUpdateEnvironment.mockRejectedValue(new Error('API error'));
161
+ await expect(client.createEnvironment('owner', 'repo', 'production')).rejects.toThrow('Failed to create environment');
162
+ });
163
+ });
164
+ describe('environmentExists', () => {
165
+ it('should return true if environment exists', async () => {
166
+ mockRepos.getEnvironment.mockResolvedValue({});
167
+ const result = await client.environmentExists('owner', 'repo', 'production');
168
+ expect(result).toBe(true);
169
+ expect(mockRepos.getEnvironment).toHaveBeenCalledWith({
170
+ owner: 'owner',
171
+ repo: 'repo',
172
+ environment_name: 'production',
173
+ });
174
+ });
175
+ it('should return false if environment does not exist', async () => {
176
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
+ const error = new Error('Not found');
178
+ error.status = 404;
179
+ mockRepos.getEnvironment.mockRejectedValue(error);
180
+ const result = await client.environmentExists('owner', 'repo', 'production');
181
+ expect(result).toBe(false);
182
+ });
183
+ it('should throw error for non-404 errors', async () => {
184
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
185
+ const error = new Error('API error');
186
+ error.status = 500;
187
+ mockRepos.getEnvironment.mockRejectedValue(error);
188
+ await expect(client.environmentExists('owner', 'repo', 'production')).rejects.toThrow('Failed to check environment');
189
+ });
190
+ });
191
+ describe('createEnvironmentVariables', () => {
192
+ it('should create environment variables', async () => {
193
+ mockActions.createEnvironmentVariable.mockResolvedValue({});
194
+ const variables = {
195
+ VAR1: 'value1',
196
+ VAR2: 'value2',
197
+ };
198
+ await client.createEnvironmentVariables('owner', 'repo', 'production', variables);
199
+ expect(mockActions.createEnvironmentVariable).toHaveBeenCalledTimes(2);
200
+ expect(mockActions.createEnvironmentVariable).toHaveBeenCalledWith({
201
+ owner: 'owner',
202
+ repo: 'repo',
203
+ environment_name: 'production',
204
+ name: 'VAR1',
205
+ value: 'value1',
206
+ });
207
+ expect(mockActions.createEnvironmentVariable).toHaveBeenCalledWith({
208
+ owner: 'owner',
209
+ repo: 'repo',
210
+ environment_name: 'production',
211
+ name: 'VAR2',
212
+ value: 'value2',
213
+ });
214
+ });
215
+ it('should skip empty variable values', async () => {
216
+ mockActions.createEnvironmentVariable.mockResolvedValue({});
217
+ const variables = {
218
+ VAR1: 'value1',
219
+ VAR2: '',
220
+ VAR3: 'value3',
221
+ };
222
+ await client.createEnvironmentVariables('owner', 'repo', 'production', variables);
223
+ expect(mockActions.createEnvironmentVariable).toHaveBeenCalledTimes(2);
224
+ });
225
+ it('should throw error on API failure', async () => {
226
+ mockActions.createEnvironmentVariable.mockRejectedValue(new Error('API error'));
227
+ const variables = { VAR1: 'value1' };
228
+ await expect(client.createEnvironmentVariables('owner', 'repo', 'production', variables)).rejects.toThrow('Failed to create environment variables');
229
+ });
230
+ });
231
+ describe('createEnvironmentSecrets', () => {
232
+ it('should create encrypted environment secrets', async () => {
233
+ mockActions.getEnvironmentPublicKey.mockResolvedValue({
234
+ data: {
235
+ key: 'public-key-base64',
236
+ key_id: 'key-id-123',
237
+ },
238
+ });
239
+ mockActions.createOrUpdateEnvironmentSecret.mockResolvedValue({});
240
+ const secrets = {
241
+ SECRET1: 'secret-value-1',
242
+ SECRET2: 'secret-value-2',
243
+ };
244
+ await client.createEnvironmentSecrets('owner', 'repo', 'production', secrets);
245
+ expect(mockActions.getEnvironmentPublicKey).toHaveBeenCalledWith({
246
+ owner: 'owner',
247
+ repo: 'repo',
248
+ environment_name: 'production',
249
+ });
250
+ expect(mockActions.createOrUpdateEnvironmentSecret).toHaveBeenCalledTimes(2);
251
+ expect(mockActions.createOrUpdateEnvironmentSecret).toHaveBeenCalledWith({
252
+ owner: 'owner',
253
+ repo: 'repo',
254
+ environment_name: 'production',
255
+ secret_name: 'SECRET1',
256
+ encrypted_value: 'encrypted-base64',
257
+ key_id: 'key-id-123',
258
+ });
259
+ });
260
+ it('should skip empty secret values', async () => {
261
+ mockActions.getEnvironmentPublicKey.mockResolvedValue({
262
+ data: {
263
+ key: 'public-key-base64',
264
+ key_id: 'key-id-123',
265
+ },
266
+ });
267
+ mockActions.createOrUpdateEnvironmentSecret.mockResolvedValue({});
268
+ const secrets = {
269
+ SECRET1: 'secret-value',
270
+ SECRET2: '',
271
+ };
272
+ await client.createEnvironmentSecrets('owner', 'repo', 'production', secrets);
273
+ expect(mockActions.createOrUpdateEnvironmentSecret).toHaveBeenCalledTimes(1);
274
+ });
275
+ it('should throw error on API failure', async () => {
276
+ mockActions.getEnvironmentPublicKey.mockRejectedValue(new Error('API error'));
277
+ const secrets = { SECRET1: 'secret-value' };
278
+ await expect(client.createEnvironmentSecrets('owner', 'repo', 'production', secrets)).rejects.toThrow('Failed to create environment secrets');
279
+ });
280
+ });
281
+ });
282
+ //# sourceMappingURL=github.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/github.test.ts"],"names":[],"mappings":"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"}