@simplens/onboard 1.0.0 → 1.0.2
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/README.md +331 -214
- package/dist/__tests__/env-config.test.d.ts +2 -0
- package/dist/__tests__/env-config.test.d.ts.map +1 -0
- package/dist/__tests__/env-config.test.js +23 -0
- package/dist/__tests__/env-config.test.js.map +1 -0
- package/dist/__tests__/infra-prompts.test.d.ts +2 -0
- package/dist/__tests__/infra-prompts.test.d.ts.map +1 -0
- package/dist/__tests__/infra-prompts.test.js +43 -0
- package/dist/__tests__/infra-prompts.test.js.map +1 -0
- package/dist/__tests__/infra.test.d.ts +2 -0
- package/dist/__tests__/infra.test.d.ts.map +1 -0
- package/dist/__tests__/infra.test.js +14 -0
- package/dist/__tests__/infra.test.js.map +1 -0
- package/dist/__tests__/nginx.test.d.ts +2 -0
- package/dist/__tests__/nginx.test.d.ts.map +1 -0
- package/dist/__tests__/nginx.test.js +16 -0
- package/dist/__tests__/nginx.test.js.map +1 -0
- package/dist/env-config.d.ts +27 -12
- package/dist/env-config.d.ts.map +1 -1
- package/dist/env-config.js +258 -141
- package/dist/env-config.js.map +1 -1
- package/dist/index.js +341 -71
- package/dist/index.js.map +1 -1
- package/dist/infra.d.ts +17 -14
- package/dist/infra.d.ts.map +1 -1
- package/dist/infra.js +265 -176
- package/dist/infra.js.map +1 -1
- package/dist/plugins.d.ts +5 -10
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +75 -44
- package/dist/plugins.js.map +1 -1
- package/dist/services.d.ts +1 -23
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +47 -62
- package/dist/services.js.map +1 -1
- package/dist/templates.d.ts +3 -2
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +203 -198
- package/dist/templates.js.map +1 -1
- package/dist/types/domain.d.ts +2 -0
- package/dist/types/domain.d.ts.map +1 -1
- package/dist/ui.d.ts +45 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +93 -0
- package/dist/ui.js.map +1 -0
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +32 -7
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +66 -2
- package/dist/utils.js.map +1 -1
- package/dist/validators.d.ts +1 -52
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +10 -57
- package/dist/validators.js.map +1 -1
- package/package.json +3 -5
- package/src/__tests__/env-config.test.ts +28 -0
- package/src/__tests__/errors.test.ts +187 -187
- package/src/__tests__/infra-prompts.test.ts +54 -0
- package/src/__tests__/infra.test.ts +15 -0
- package/src/__tests__/utils.test.ts +142 -142
- package/src/__tests__/validators.test.ts +195 -195
- package/src/config/constants.ts +86 -86
- package/src/config/index.ts +1 -1
- package/src/env-config.ts +455 -320
- package/src/index.ts +534 -203
- package/src/infra.ts +404 -300
- package/src/plugins.ts +221 -190
- package/src/services.ts +175 -190
- package/src/templates.ts +209 -203
- package/src/types/domain.ts +129 -127
- package/src/types/errors.ts +173 -173
- package/src/types/index.ts +2 -2
- package/src/ui.ts +91 -0
- package/src/utils/index.ts +1 -1
- package/src/utils/logger.ts +144 -118
- package/src/utils.ts +183 -105
- package/src/validators.ts +145 -192
- package/tsconfig.json +18 -18
- package/vitest.config.ts +22 -20
|
@@ -1,187 +1,187 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
OnboardingError,
|
|
4
|
-
DockerNotInstalledError,
|
|
5
|
-
DockerNotRunningError,
|
|
6
|
-
DockerPermissionError,
|
|
7
|
-
DockerComposeError,
|
|
8
|
-
FileSystemError,
|
|
9
|
-
DirectoryNotWritableError,
|
|
10
|
-
isOnboardingError,
|
|
11
|
-
formatErrorForUser,
|
|
12
|
-
} from '../types/errors.js';
|
|
13
|
-
|
|
14
|
-
describe('error types', () => {
|
|
15
|
-
describe('OnboardingError', () => {
|
|
16
|
-
it('should create error with code and message', () => {
|
|
17
|
-
const error = new OnboardingError('TEST_CODE', 'Test message');
|
|
18
|
-
|
|
19
|
-
expect(error.code).toBe('TEST_CODE');
|
|
20
|
-
expect(error.message).toBe('Test message');
|
|
21
|
-
expect(error.name).toBe('OnboardingError');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should include troubleshooting when provided', () => {
|
|
25
|
-
const error = new OnboardingError(
|
|
26
|
-
'TEST_CODE',
|
|
27
|
-
'Test message',
|
|
28
|
-
'Try this fix'
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
expect(error.troubleshooting).toBe('Try this fix');
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('should have proper stack trace', () => {
|
|
35
|
-
const error = new OnboardingError('TEST', 'message');
|
|
36
|
-
|
|
37
|
-
expect(error.stack).toBeDefined();
|
|
38
|
-
expect(error.stack).toContain('OnboardingError');
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe('DockerNotInstalledError', () => {
|
|
43
|
-
it('should have correct message and troubleshooting', () => {
|
|
44
|
-
const error = new DockerNotInstalledError();
|
|
45
|
-
|
|
46
|
-
expect(error.message).toContain('not installed');
|
|
47
|
-
expect(error.troubleshooting).toContain('https://docs.docker.com/get-docker/');
|
|
48
|
-
expect(error.name).toBe('DockerNotInstalledError');
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('DockerNotRunningError', () => {
|
|
53
|
-
it('should have correct message and troubleshooting', () => {
|
|
54
|
-
const error = new DockerNotRunningError();
|
|
55
|
-
|
|
56
|
-
expect(error.message).toContain('not running');
|
|
57
|
-
expect(error.troubleshooting).toContain('Docker daemon');
|
|
58
|
-
expect(error.name).toBe('DockerNotRunningError');
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe('DockerPermissionError', () => {
|
|
63
|
-
it('should have correct message and troubleshooting', () => {
|
|
64
|
-
const error = new DockerPermissionError();
|
|
65
|
-
|
|
66
|
-
expect(error.message).toContain('Permission denied');
|
|
67
|
-
expect(error.troubleshooting).toContain('usermod');
|
|
68
|
-
expect(error.name).toBe('DockerPermissionError');
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
describe('DockerComposeError', () => {
|
|
73
|
-
it('should include operation in message', () => {
|
|
74
|
-
const error = new DockerComposeError('start services');
|
|
75
|
-
|
|
76
|
-
expect(error.message).toContain('start services');
|
|
77
|
-
expect(error.name).toBe('DockerComposeError');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should use custom troubleshooting when provided', () => {
|
|
81
|
-
const error = new DockerComposeError('pull images', 'Check network connection');
|
|
82
|
-
|
|
83
|
-
expect(error.troubleshooting).toBe('Check network connection');
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should have default troubleshooting', () => {
|
|
87
|
-
const error = new DockerComposeError('operation');
|
|
88
|
-
|
|
89
|
-
expect(error.troubleshooting).toContain('docker-compose logs');
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
describe('FileSystemError', () => {
|
|
94
|
-
it('should include path in error', () => {
|
|
95
|
-
const error = new FileSystemError(
|
|
96
|
-
'Cannot write',
|
|
97
|
-
'/path/to/file',
|
|
98
|
-
'Check permissions'
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
expect(error.path).toBe('/path/to/file');
|
|
102
|
-
expect(error.troubleshooting).toBe('Check permissions');
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
describe('DirectoryNotWritableError', () => {
|
|
107
|
-
it('should include path in message and error', () => {
|
|
108
|
-
const error = new DirectoryNotWritableError('/opt/app');
|
|
109
|
-
|
|
110
|
-
expect(error.message).toContain('/opt/app');
|
|
111
|
-
expect(error.path).toBe('/opt/app');
|
|
112
|
-
expect(error.troubleshooting).toContain('permissions');
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe('isOnboardingError', () => {
|
|
117
|
-
it('should return true for OnboardingError instances', () => {
|
|
118
|
-
const error = new OnboardingError('CODE', 'message');
|
|
119
|
-
|
|
120
|
-
expect(isOnboardingError(error)).toBe(true);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('should return true for subclasses of OnboardingError', () => {
|
|
124
|
-
const error = new DockerNotInstalledError();
|
|
125
|
-
|
|
126
|
-
expect(isOnboardingError(error)).toBe(true);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should return false for regular Error', () => {
|
|
130
|
-
const error = new Error('regular error');
|
|
131
|
-
|
|
132
|
-
expect(isOnboardingError(error)).toBe(false);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('should return false for non-error values', () => {
|
|
136
|
-
expect(isOnboardingError('string')).toBe(false);
|
|
137
|
-
expect(isOnboardingError(null)).toBe(false);
|
|
138
|
-
expect(isOnboardingError(undefined)).toBe(false);
|
|
139
|
-
expect(isOnboardingError({})).toBe(false);
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
describe('formatErrorForUser', () => {
|
|
144
|
-
it('should format OnboardingError with troubleshooting', () => {
|
|
145
|
-
const error = new OnboardingError(
|
|
146
|
-
'TEST',
|
|
147
|
-
'Something went wrong',
|
|
148
|
-
'Try this fix'
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
const formatted = formatErrorForUser(error);
|
|
152
|
-
|
|
153
|
-
expect(formatted).toContain('❌ Something went wrong');
|
|
154
|
-
expect(formatted).toContain('💡 Troubleshooting:');
|
|
155
|
-
expect(formatted).toContain('Try this fix');
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should format OnboardingError without troubleshooting', () => {
|
|
159
|
-
const error = new OnboardingError('TEST', 'Something went wrong');
|
|
160
|
-
|
|
161
|
-
const formatted = formatErrorForUser(error);
|
|
162
|
-
|
|
163
|
-
expect(formatted).toBe('❌ Something went wrong');
|
|
164
|
-
expect(formatted).not.toContain('Troubleshooting');
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should format regular Error', () => {
|
|
168
|
-
const error = new Error('Regular error message');
|
|
169
|
-
|
|
170
|
-
const formatted = formatErrorForUser(error);
|
|
171
|
-
|
|
172
|
-
expect(formatted).toContain('Unexpected error');
|
|
173
|
-
expect(formatted).toContain('Regular error message');
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('should handle non-Error values', () => {
|
|
177
|
-
const formatted = formatErrorForUser('some string');
|
|
178
|
-
|
|
179
|
-
expect(formatted).toBe('❌ An unknown error occurred');
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it('should handle null/undefined', () => {
|
|
183
|
-
expect(formatErrorForUser(null)).toBe('❌ An unknown error occurred');
|
|
184
|
-
expect(formatErrorForUser(undefined)).toBe('❌ An unknown error occurred');
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
});
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
OnboardingError,
|
|
4
|
+
DockerNotInstalledError,
|
|
5
|
+
DockerNotRunningError,
|
|
6
|
+
DockerPermissionError,
|
|
7
|
+
DockerComposeError,
|
|
8
|
+
FileSystemError,
|
|
9
|
+
DirectoryNotWritableError,
|
|
10
|
+
isOnboardingError,
|
|
11
|
+
formatErrorForUser,
|
|
12
|
+
} from '../types/errors.js';
|
|
13
|
+
|
|
14
|
+
describe('error types', () => {
|
|
15
|
+
describe('OnboardingError', () => {
|
|
16
|
+
it('should create error with code and message', () => {
|
|
17
|
+
const error = new OnboardingError('TEST_CODE', 'Test message');
|
|
18
|
+
|
|
19
|
+
expect(error.code).toBe('TEST_CODE');
|
|
20
|
+
expect(error.message).toBe('Test message');
|
|
21
|
+
expect(error.name).toBe('OnboardingError');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should include troubleshooting when provided', () => {
|
|
25
|
+
const error = new OnboardingError(
|
|
26
|
+
'TEST_CODE',
|
|
27
|
+
'Test message',
|
|
28
|
+
'Try this fix'
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
expect(error.troubleshooting).toBe('Try this fix');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should have proper stack trace', () => {
|
|
35
|
+
const error = new OnboardingError('TEST', 'message');
|
|
36
|
+
|
|
37
|
+
expect(error.stack).toBeDefined();
|
|
38
|
+
expect(error.stack).toContain('OnboardingError');
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe('DockerNotInstalledError', () => {
|
|
43
|
+
it('should have correct message and troubleshooting', () => {
|
|
44
|
+
const error = new DockerNotInstalledError();
|
|
45
|
+
|
|
46
|
+
expect(error.message).toContain('not installed');
|
|
47
|
+
expect(error.troubleshooting).toContain('https://docs.docker.com/get-docker/');
|
|
48
|
+
expect(error.name).toBe('DockerNotInstalledError');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('DockerNotRunningError', () => {
|
|
53
|
+
it('should have correct message and troubleshooting', () => {
|
|
54
|
+
const error = new DockerNotRunningError();
|
|
55
|
+
|
|
56
|
+
expect(error.message).toContain('not running');
|
|
57
|
+
expect(error.troubleshooting).toContain('Docker daemon');
|
|
58
|
+
expect(error.name).toBe('DockerNotRunningError');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('DockerPermissionError', () => {
|
|
63
|
+
it('should have correct message and troubleshooting', () => {
|
|
64
|
+
const error = new DockerPermissionError();
|
|
65
|
+
|
|
66
|
+
expect(error.message).toContain('Permission denied');
|
|
67
|
+
expect(error.troubleshooting).toContain('usermod');
|
|
68
|
+
expect(error.name).toBe('DockerPermissionError');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe('DockerComposeError', () => {
|
|
73
|
+
it('should include operation in message', () => {
|
|
74
|
+
const error = new DockerComposeError('start services');
|
|
75
|
+
|
|
76
|
+
expect(error.message).toContain('start services');
|
|
77
|
+
expect(error.name).toBe('DockerComposeError');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should use custom troubleshooting when provided', () => {
|
|
81
|
+
const error = new DockerComposeError('pull images', 'Check network connection');
|
|
82
|
+
|
|
83
|
+
expect(error.troubleshooting).toBe('Check network connection');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should have default troubleshooting', () => {
|
|
87
|
+
const error = new DockerComposeError('operation');
|
|
88
|
+
|
|
89
|
+
expect(error.troubleshooting).toContain('docker-compose logs');
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe('FileSystemError', () => {
|
|
94
|
+
it('should include path in error', () => {
|
|
95
|
+
const error = new FileSystemError(
|
|
96
|
+
'Cannot write',
|
|
97
|
+
'/path/to/file',
|
|
98
|
+
'Check permissions'
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(error.path).toBe('/path/to/file');
|
|
102
|
+
expect(error.troubleshooting).toBe('Check permissions');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('DirectoryNotWritableError', () => {
|
|
107
|
+
it('should include path in message and error', () => {
|
|
108
|
+
const error = new DirectoryNotWritableError('/opt/app');
|
|
109
|
+
|
|
110
|
+
expect(error.message).toContain('/opt/app');
|
|
111
|
+
expect(error.path).toBe('/opt/app');
|
|
112
|
+
expect(error.troubleshooting).toContain('permissions');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('isOnboardingError', () => {
|
|
117
|
+
it('should return true for OnboardingError instances', () => {
|
|
118
|
+
const error = new OnboardingError('CODE', 'message');
|
|
119
|
+
|
|
120
|
+
expect(isOnboardingError(error)).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should return true for subclasses of OnboardingError', () => {
|
|
124
|
+
const error = new DockerNotInstalledError();
|
|
125
|
+
|
|
126
|
+
expect(isOnboardingError(error)).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should return false for regular Error', () => {
|
|
130
|
+
const error = new Error('regular error');
|
|
131
|
+
|
|
132
|
+
expect(isOnboardingError(error)).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should return false for non-error values', () => {
|
|
136
|
+
expect(isOnboardingError('string')).toBe(false);
|
|
137
|
+
expect(isOnboardingError(null)).toBe(false);
|
|
138
|
+
expect(isOnboardingError(undefined)).toBe(false);
|
|
139
|
+
expect(isOnboardingError({})).toBe(false);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('formatErrorForUser', () => {
|
|
144
|
+
it('should format OnboardingError with troubleshooting', () => {
|
|
145
|
+
const error = new OnboardingError(
|
|
146
|
+
'TEST',
|
|
147
|
+
'Something went wrong',
|
|
148
|
+
'Try this fix'
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const formatted = formatErrorForUser(error);
|
|
152
|
+
|
|
153
|
+
expect(formatted).toContain('❌ Something went wrong');
|
|
154
|
+
expect(formatted).toContain('💡 Troubleshooting:');
|
|
155
|
+
expect(formatted).toContain('Try this fix');
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should format OnboardingError without troubleshooting', () => {
|
|
159
|
+
const error = new OnboardingError('TEST', 'Something went wrong');
|
|
160
|
+
|
|
161
|
+
const formatted = formatErrorForUser(error);
|
|
162
|
+
|
|
163
|
+
expect(formatted).toBe('❌ Something went wrong');
|
|
164
|
+
expect(formatted).not.toContain('Troubleshooting');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('should format regular Error', () => {
|
|
168
|
+
const error = new Error('Regular error message');
|
|
169
|
+
|
|
170
|
+
const formatted = formatErrorForUser(error);
|
|
171
|
+
|
|
172
|
+
expect(formatted).toContain('Unexpected error');
|
|
173
|
+
expect(formatted).toContain('Regular error message');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should handle non-Error values', () => {
|
|
177
|
+
const formatted = formatErrorForUser('some string');
|
|
178
|
+
|
|
179
|
+
expect(formatted).toBe('❌ An unknown error occurred');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should handle null/undefined', () => {
|
|
183
|
+
expect(formatErrorForUser(null)).toBe('❌ An unknown error occurred');
|
|
184
|
+
expect(formatErrorForUser(undefined)).toBe('❌ An unknown error occurred');
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
|
|
3
|
+
// Mock @clack/prompts
|
|
4
|
+
vi.mock('@clack/prompts', () => ({
|
|
5
|
+
multiselect: vi.fn(),
|
|
6
|
+
spinner: vi.fn(() => ({
|
|
7
|
+
start: vi.fn(),
|
|
8
|
+
stop: vi.fn(),
|
|
9
|
+
error: vi.fn(),
|
|
10
|
+
message: vi.fn(),
|
|
11
|
+
})),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
// Mock the ui.js module
|
|
15
|
+
vi.mock('../ui.js', () => ({
|
|
16
|
+
handleCancel: vi.fn(),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
import { multiselect } from '@clack/prompts';
|
|
20
|
+
import { promptInfraServicesWithBasePath } from '../infra.js';
|
|
21
|
+
|
|
22
|
+
describe('promptInfraServicesWithBasePath', () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vi.clearAllMocks();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('includes nginx when allowNginx is true', async () => {
|
|
28
|
+
const mockMultiselect = vi.mocked(multiselect);
|
|
29
|
+
mockMultiselect.mockResolvedValue(['mongo', 'redis', 'nginx']);
|
|
30
|
+
|
|
31
|
+
const result = await promptInfraServicesWithBasePath({ allowNginx: true });
|
|
32
|
+
|
|
33
|
+
// Should include nginx in options
|
|
34
|
+
const callArgs = mockMultiselect.mock.calls[0][0] as any;
|
|
35
|
+
const values = callArgs.options.map((o: any) => o.value);
|
|
36
|
+
expect(values).toContain('nginx');
|
|
37
|
+
|
|
38
|
+
expect(result).toContain('nginx');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('excludes nginx when allowNginx is false', async () => {
|
|
42
|
+
const mockMultiselect = vi.mocked(multiselect);
|
|
43
|
+
mockMultiselect.mockResolvedValue(['mongo', 'redis']);
|
|
44
|
+
|
|
45
|
+
const result = await promptInfraServicesWithBasePath({ allowNginx: false });
|
|
46
|
+
|
|
47
|
+
// Should NOT include nginx in options
|
|
48
|
+
const callArgs = mockMultiselect.mock.calls[0][0] as any;
|
|
49
|
+
const values = callArgs.options.map((o: any) => o.value);
|
|
50
|
+
expect(values).not.toContain('nginx');
|
|
51
|
+
|
|
52
|
+
expect(result).not.toContain('nginx');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { buildAppComposeContent } from '../infra.js';
|
|
3
|
+
|
|
4
|
+
describe('infra app compose generation', () => {
|
|
5
|
+
it('does not include nginx when disabled', () => {
|
|
6
|
+
const compose = buildAppComposeContent(false);
|
|
7
|
+
expect(compose).not.toContain(' nginx:');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('includes nginx service when enabled', () => {
|
|
11
|
+
const compose = buildAppComposeContent(true);
|
|
12
|
+
expect(compose).toContain(' nginx:');
|
|
13
|
+
expect(compose).toContain('./nginx.conf:/etc/nginx/conf.d/default.conf:ro');
|
|
14
|
+
});
|
|
15
|
+
});
|