@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.
Files changed (82) hide show
  1. package/README.md +331 -214
  2. package/dist/__tests__/env-config.test.d.ts +2 -0
  3. package/dist/__tests__/env-config.test.d.ts.map +1 -0
  4. package/dist/__tests__/env-config.test.js +23 -0
  5. package/dist/__tests__/env-config.test.js.map +1 -0
  6. package/dist/__tests__/infra-prompts.test.d.ts +2 -0
  7. package/dist/__tests__/infra-prompts.test.d.ts.map +1 -0
  8. package/dist/__tests__/infra-prompts.test.js +43 -0
  9. package/dist/__tests__/infra-prompts.test.js.map +1 -0
  10. package/dist/__tests__/infra.test.d.ts +2 -0
  11. package/dist/__tests__/infra.test.d.ts.map +1 -0
  12. package/dist/__tests__/infra.test.js +14 -0
  13. package/dist/__tests__/infra.test.js.map +1 -0
  14. package/dist/__tests__/nginx.test.d.ts +2 -0
  15. package/dist/__tests__/nginx.test.d.ts.map +1 -0
  16. package/dist/__tests__/nginx.test.js +16 -0
  17. package/dist/__tests__/nginx.test.js.map +1 -0
  18. package/dist/env-config.d.ts +27 -12
  19. package/dist/env-config.d.ts.map +1 -1
  20. package/dist/env-config.js +258 -141
  21. package/dist/env-config.js.map +1 -1
  22. package/dist/index.js +341 -71
  23. package/dist/index.js.map +1 -1
  24. package/dist/infra.d.ts +17 -14
  25. package/dist/infra.d.ts.map +1 -1
  26. package/dist/infra.js +265 -176
  27. package/dist/infra.js.map +1 -1
  28. package/dist/plugins.d.ts +5 -10
  29. package/dist/plugins.d.ts.map +1 -1
  30. package/dist/plugins.js +75 -44
  31. package/dist/plugins.js.map +1 -1
  32. package/dist/services.d.ts +1 -23
  33. package/dist/services.d.ts.map +1 -1
  34. package/dist/services.js +47 -62
  35. package/dist/services.js.map +1 -1
  36. package/dist/templates.d.ts +3 -2
  37. package/dist/templates.d.ts.map +1 -1
  38. package/dist/templates.js +203 -198
  39. package/dist/templates.js.map +1 -1
  40. package/dist/types/domain.d.ts +2 -0
  41. package/dist/types/domain.d.ts.map +1 -1
  42. package/dist/ui.d.ts +45 -0
  43. package/dist/ui.d.ts.map +1 -0
  44. package/dist/ui.js +93 -0
  45. package/dist/ui.js.map +1 -0
  46. package/dist/utils/logger.d.ts +1 -0
  47. package/dist/utils/logger.d.ts.map +1 -1
  48. package/dist/utils/logger.js +32 -7
  49. package/dist/utils/logger.js.map +1 -1
  50. package/dist/utils.d.ts +8 -0
  51. package/dist/utils.d.ts.map +1 -1
  52. package/dist/utils.js +66 -2
  53. package/dist/utils.js.map +1 -1
  54. package/dist/validators.d.ts +1 -52
  55. package/dist/validators.d.ts.map +1 -1
  56. package/dist/validators.js +10 -57
  57. package/dist/validators.js.map +1 -1
  58. package/package.json +3 -5
  59. package/src/__tests__/env-config.test.ts +28 -0
  60. package/src/__tests__/errors.test.ts +187 -187
  61. package/src/__tests__/infra-prompts.test.ts +54 -0
  62. package/src/__tests__/infra.test.ts +15 -0
  63. package/src/__tests__/utils.test.ts +142 -142
  64. package/src/__tests__/validators.test.ts +195 -195
  65. package/src/config/constants.ts +86 -86
  66. package/src/config/index.ts +1 -1
  67. package/src/env-config.ts +455 -320
  68. package/src/index.ts +534 -203
  69. package/src/infra.ts +404 -300
  70. package/src/plugins.ts +221 -190
  71. package/src/services.ts +175 -190
  72. package/src/templates.ts +209 -203
  73. package/src/types/domain.ts +129 -127
  74. package/src/types/errors.ts +173 -173
  75. package/src/types/index.ts +2 -2
  76. package/src/ui.ts +91 -0
  77. package/src/utils/index.ts +1 -1
  78. package/src/utils/logger.ts +144 -118
  79. package/src/utils.ts +183 -105
  80. package/src/validators.ts +145 -192
  81. package/tsconfig.json +18 -18
  82. package/vitest.config.ts +22 -20
@@ -1,127 +1,129 @@
1
- /**
2
- * Domain type definitions for the onboarding system
3
- */
4
-
5
- /**
6
- * Plugin information returned by config-gen
7
- */
8
- export interface PluginInfo {
9
- /** Package name (e.g., '@simplens/nodemailer-gmail') */
10
- package: string;
11
- /** Display name */
12
- name: string;
13
- /** Description of what the plugin does */
14
- description: string;
15
- }
16
-
17
- /**
18
- * Infrastructure service option
19
- */
20
- export interface InfraService {
21
- /** Display name (e.g., 'MongoDB (Database)') */
22
- name: string;
23
- /** Service identifier (e.g., 'mongo') */
24
- value: string;
25
- /** Whether checked by default */
26
- checked: boolean;
27
- }
28
-
29
- /**
30
- * Environment variable definition
31
- */
32
- export interface EnvVariable {
33
- /** Environment variable key */
34
- key: string;
35
- /** Current or default value */
36
- value: string;
37
- /** Optional description/comment */
38
- description?: string;
39
- /** Whether this variable is required */
40
- required: boolean;
41
- }
42
-
43
- /**
44
- * Setup options provided via CLI or prompts
45
- */
46
- export interface SetupOptions {
47
- /** Whether to setup infrastructure services */
48
- infra: boolean;
49
- /** Environment configuration mode */
50
- envMode: 'default' | 'interactive';
51
- /** Target directory for setup */
52
- targetDir: string;
53
- }
54
-
55
- /**
56
- * Service definition for docker-compose generation
57
- */
58
- export interface ServiceDefinition {
59
- /** Service identifier */
60
- id: string;
61
- /** Display name */
62
- name: string;
63
- /** Docker compose YAML block */
64
- dockerCompose: string;
65
- /** Required volumes */
66
- volumes: string[];
67
- /** Service dependencies */
68
- dependencies?: string[];
69
- /** Whether service has health check */
70
- healthCheck?: boolean;
71
- }
72
-
73
- /**
74
- * SimplensConfig YAML structure
75
- */
76
- export interface SimplensConfig {
77
- providers: ProviderConfig[];
78
- }
79
-
80
- /**
81
- * Provider configuration in simplens.config.yaml
82
- */
83
- export interface ProviderConfig {
84
- /** Package name */
85
- package: string;
86
- /** Provider ID */
87
- id: string;
88
- /** Required credentials as key-value pairs */
89
- credentials: Record<string, string>;
90
- /** Optional configuration */
91
- optionalConfig?: Record<string, string | number | boolean>;
92
- }
93
-
94
- /**
95
- * Docker compose file structure (simplified)
96
- */
97
- export interface DockerComposeFile {
98
- services: Record<string, DockerService>;
99
- volumes?: Record<string, DockerVolume>;
100
- networks?: Record<string, DockerNetwork>;
101
- }
102
-
103
- export interface DockerService {
104
- image: string;
105
- container_name?: string;
106
- ports?: string[];
107
- environment?: Record<string, string> | string[];
108
- volumes?: string[];
109
- command?: string | string[];
110
- depends_on?: string[] | Record<string, { condition: string }>;
111
- healthcheck?: {
112
- test: string | string[];
113
- interval?: string;
114
- timeout?: string;
115
- retries?: number;
116
- start_period?: string;
117
- };
118
- }
119
-
120
- export interface DockerVolume {
121
- driver?: string;
122
- driver_opts?: Record<string, string>;
123
- }
124
-
125
- export interface DockerNetwork {
126
- driver?: string;
127
- }
1
+ /**
2
+ * Domain type definitions for the onboarding system
3
+ */
4
+
5
+ /**
6
+ * Plugin information returned by config-gen
7
+ */
8
+ export interface PluginInfo {
9
+ /** Package name (e.g., '@simplens/nodemailer-gmail') */
10
+ package: string;
11
+ /** Display name */
12
+ name: string;
13
+ /** Description of what the plugin does */
14
+ description: string;
15
+ }
16
+
17
+ /**
18
+ * Infrastructure service option
19
+ */
20
+ export interface InfraService {
21
+ /** Display name (e.g., 'MongoDB (Database)') */
22
+ name: string;
23
+ /** Service identifier (e.g., 'mongo') */
24
+ value: string;
25
+ /** Whether checked by default */
26
+ checked: boolean;
27
+ }
28
+
29
+ /**
30
+ * Environment variable definition
31
+ */
32
+ export interface EnvVariable {
33
+ /** Environment variable key */
34
+ key: string;
35
+ /** Current or default value */
36
+ value: string;
37
+ /** Optional description/comment */
38
+ description?: string;
39
+ /** Whether this variable is required */
40
+ required: boolean;
41
+ }
42
+
43
+ /**
44
+ * Setup options provided via CLI or prompts
45
+ */
46
+ export interface SetupOptions {
47
+ /** Whether to setup infrastructure services */
48
+ infra: boolean;
49
+ /** Environment configuration mode */
50
+ envMode: 'default' | 'interactive';
51
+ /** Target directory for setup */
52
+ targetDir: string;
53
+ /** Dashboard base path (empty string means root) */
54
+ basePath: string;
55
+ }
56
+
57
+ /**
58
+ * Service definition for docker-compose generation
59
+ */
60
+ export interface ServiceDefinition {
61
+ /** Service identifier */
62
+ id: string;
63
+ /** Display name */
64
+ name: string;
65
+ /** Docker compose YAML block */
66
+ dockerCompose: string;
67
+ /** Required volumes */
68
+ volumes: string[];
69
+ /** Service dependencies */
70
+ dependencies?: string[];
71
+ /** Whether service has health check */
72
+ healthCheck?: boolean;
73
+ }
74
+
75
+ /**
76
+ * SimplensConfig YAML structure
77
+ */
78
+ export interface SimplensConfig {
79
+ providers: ProviderConfig[];
80
+ }
81
+
82
+ /**
83
+ * Provider configuration in simplens.config.yaml
84
+ */
85
+ export interface ProviderConfig {
86
+ /** Package name */
87
+ package: string;
88
+ /** Provider ID */
89
+ id: string;
90
+ /** Required credentials as key-value pairs */
91
+ credentials: Record<string, string>;
92
+ /** Optional configuration */
93
+ optionalConfig?: Record<string, string | number | boolean>;
94
+ }
95
+
96
+ /**
97
+ * Docker compose file structure (simplified)
98
+ */
99
+ export interface DockerComposeFile {
100
+ services: Record<string, DockerService>;
101
+ volumes?: Record<string, DockerVolume>;
102
+ networks?: Record<string, DockerNetwork>;
103
+ }
104
+
105
+ export interface DockerService {
106
+ image: string;
107
+ container_name?: string;
108
+ ports?: string[];
109
+ environment?: Record<string, string> | string[];
110
+ volumes?: string[];
111
+ command?: string | string[];
112
+ depends_on?: string[] | Record<string, { condition: string }>;
113
+ healthcheck?: {
114
+ test: string | string[];
115
+ interval?: string;
116
+ timeout?: string;
117
+ retries?: number;
118
+ start_period?: string;
119
+ };
120
+ }
121
+
122
+ export interface DockerVolume {
123
+ driver?: string;
124
+ driver_opts?: Record<string, string>;
125
+ }
126
+
127
+ export interface DockerNetwork {
128
+ driver?: string;
129
+ }
@@ -1,173 +1,173 @@
1
- /**
2
- * Custom error types for better error handling and troubleshooting
3
- */
4
-
5
- /**
6
- * Base error class for all onboarding errors
7
- */
8
- export class OnboardingError extends Error {
9
- constructor(
10
- public readonly code: string,
11
- message: string,
12
- public readonly troubleshooting?: string
13
- ) {
14
- super(message);
15
- this.name = 'OnboardingError';
16
- Error.captureStackTrace(this, this.constructor);
17
- }
18
- }
19
-
20
- /**
21
- * Docker-related errors
22
- */
23
- export class DockerError extends OnboardingError {
24
- constructor(message: string, troubleshooting?: string) {
25
- super('DOCKER_ERROR', message, troubleshooting);
26
- this.name = 'DockerError';
27
- }
28
- }
29
-
30
- export class DockerNotInstalledError extends DockerError {
31
- constructor() {
32
- super(
33
- 'Docker is not installed on this system',
34
- 'Please install Docker from: https://docs.docker.com/get-docker/'
35
- );
36
- this.name = 'DockerNotInstalledError';
37
- }
38
- }
39
-
40
- export class DockerNotRunningError extends DockerError {
41
- constructor() {
42
- super(
43
- 'Docker daemon is not running',
44
- 'Please start Docker Desktop or Docker daemon, then try again'
45
- );
46
- this.name = 'DockerNotRunningError';
47
- }
48
- }
49
-
50
- export class DockerPermissionError extends DockerError {
51
- constructor() {
52
- super(
53
- 'Permission denied when accessing Docker',
54
- 'Try running with sudo or add your user to the docker group:\n' +
55
- ' sudo usermod -aG docker $USER\n' +
56
- ' Then log out and log back in'
57
- );
58
- this.name = 'DockerPermissionError';
59
- }
60
- }
61
-
62
- export class DockerComposeError extends DockerError {
63
- constructor(operation: string, details?: string) {
64
- super(
65
- `Failed to ${operation} with docker-compose`,
66
- details || 'Check docker-compose logs for more details:\n docker-compose logs'
67
- );
68
- this.name = 'DockerComposeError';
69
- }
70
- }
71
-
72
- /**
73
- * File system errors
74
- */
75
- export class FileSystemError extends OnboardingError {
76
- constructor(message: string, public readonly path: string, troubleshooting?: string) {
77
- super('FILESYSTEM_ERROR', message, troubleshooting);
78
- this.name = 'FileSystemError';
79
- }
80
- }
81
-
82
- export class DirectoryNotWritableError extends FileSystemError {
83
- constructor(path: string) {
84
- super(
85
- `Directory is not writable: ${path}`,
86
- path,
87
- 'Check directory permissions or choose a different directory'
88
- );
89
- this.name = 'DirectoryNotWritableError';
90
- }
91
- }
92
-
93
- export class FileNotFoundError extends FileSystemError {
94
- constructor(path: string) {
95
- super(
96
- `File not found: ${path}`,
97
- path,
98
- 'Ensure the file exists or check the path'
99
- );
100
- this.name = 'FileNotFoundError';
101
- }
102
- }
103
-
104
- /**
105
- * Configuration errors
106
- */
107
- export class ConfigurationError extends OnboardingError {
108
- constructor(message: string, troubleshooting?: string) {
109
- super('CONFIG_ERROR', message, troubleshooting);
110
- this.name = 'ConfigurationError';
111
- }
112
- }
113
-
114
- export class InvalidEnvironmentValueError extends ConfigurationError {
115
- constructor(key: string, value: string, expectedFormat: string) {
116
- super(
117
- `Invalid value for ${key}: ${value}`,
118
- `Expected format: ${expectedFormat}`
119
- );
120
- this.name = 'InvalidEnvironmentValueError';
121
- }
122
- }
123
-
124
- export class PluginConfigurationError extends ConfigurationError {
125
- constructor(pluginName: string, details: string) {
126
- super(
127
- `Failed to configure plugin ${pluginName}`,
128
- details
129
- );
130
- this.name = 'PluginConfigurationError';
131
- }
132
- }
133
-
134
- /**
135
- * Service health errors
136
- */
137
- export class ServiceHealthError extends OnboardingError {
138
- constructor(serviceName: string, timeout: number) {
139
- super(
140
- 'SERVICE_HEALTH_ERROR',
141
- `Service '${serviceName}' did not become healthy within ${timeout}ms`,
142
- `Check service logs:\n docker-compose logs ${serviceName}\n\n` +
143
- 'Or check container status:\n docker ps -a'
144
- );
145
- this.name = 'ServiceHealthError';
146
- }
147
- }
148
-
149
- /**
150
- * Type guard to check if an error is an OnboardingError
151
- */
152
- export function isOnboardingError(error: unknown): error is OnboardingError {
153
- return error instanceof OnboardingError;
154
- }
155
-
156
- /**
157
- * Format error for user display
158
- */
159
- export function formatErrorForUser(error: unknown): string {
160
- if (isOnboardingError(error)) {
161
- let message = `āŒ ${error.message}`;
162
- if (error.troubleshooting) {
163
- message += `\n\nšŸ’” Troubleshooting:\n${error.troubleshooting}`;
164
- }
165
- return message;
166
- }
167
-
168
- if (error instanceof Error) {
169
- return `āŒ Unexpected error: ${error.message}`;
170
- }
171
-
172
- return `āŒ An unknown error occurred`;
173
- }
1
+ /**
2
+ * Custom error types for better error handling and troubleshooting
3
+ */
4
+
5
+ /**
6
+ * Base error class for all onboarding errors
7
+ */
8
+ export class OnboardingError extends Error {
9
+ constructor(
10
+ public readonly code: string,
11
+ message: string,
12
+ public readonly troubleshooting?: string
13
+ ) {
14
+ super(message);
15
+ this.name = 'OnboardingError';
16
+ Error.captureStackTrace(this, this.constructor);
17
+ }
18
+ }
19
+
20
+ /**
21
+ * Docker-related errors
22
+ */
23
+ export class DockerError extends OnboardingError {
24
+ constructor(message: string, troubleshooting?: string) {
25
+ super('DOCKER_ERROR', message, troubleshooting);
26
+ this.name = 'DockerError';
27
+ }
28
+ }
29
+
30
+ export class DockerNotInstalledError extends DockerError {
31
+ constructor() {
32
+ super(
33
+ 'Docker is not installed on this system',
34
+ 'Please install Docker from: https://docs.docker.com/get-docker/'
35
+ );
36
+ this.name = 'DockerNotInstalledError';
37
+ }
38
+ }
39
+
40
+ export class DockerNotRunningError extends DockerError {
41
+ constructor() {
42
+ super(
43
+ 'Docker daemon is not running',
44
+ 'Please start Docker Desktop or Docker daemon, then try again'
45
+ );
46
+ this.name = 'DockerNotRunningError';
47
+ }
48
+ }
49
+
50
+ export class DockerPermissionError extends DockerError {
51
+ constructor() {
52
+ super(
53
+ 'Permission denied when accessing Docker',
54
+ 'Try running with sudo or add your user to the docker group:\n' +
55
+ ' sudo usermod -aG docker $USER\n' +
56
+ ' Then log out and log back in'
57
+ );
58
+ this.name = 'DockerPermissionError';
59
+ }
60
+ }
61
+
62
+ export class DockerComposeError extends DockerError {
63
+ constructor(operation: string, details?: string) {
64
+ super(
65
+ `Failed to ${operation} with docker-compose`,
66
+ details || 'Check docker-compose logs for more details:\n docker-compose logs'
67
+ );
68
+ this.name = 'DockerComposeError';
69
+ }
70
+ }
71
+
72
+ /**
73
+ * File system errors
74
+ */
75
+ export class FileSystemError extends OnboardingError {
76
+ constructor(message: string, public readonly path: string, troubleshooting?: string) {
77
+ super('FILESYSTEM_ERROR', message, troubleshooting);
78
+ this.name = 'FileSystemError';
79
+ }
80
+ }
81
+
82
+ export class DirectoryNotWritableError extends FileSystemError {
83
+ constructor(path: string) {
84
+ super(
85
+ `Directory is not writable: ${path}`,
86
+ path,
87
+ 'Check directory permissions or choose a different directory'
88
+ );
89
+ this.name = 'DirectoryNotWritableError';
90
+ }
91
+ }
92
+
93
+ export class FileNotFoundError extends FileSystemError {
94
+ constructor(path: string) {
95
+ super(
96
+ `File not found: ${path}`,
97
+ path,
98
+ 'Ensure the file exists or check the path'
99
+ );
100
+ this.name = 'FileNotFoundError';
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Configuration errors
106
+ */
107
+ export class ConfigurationError extends OnboardingError {
108
+ constructor(message: string, troubleshooting?: string) {
109
+ super('CONFIG_ERROR', message, troubleshooting);
110
+ this.name = 'ConfigurationError';
111
+ }
112
+ }
113
+
114
+ export class InvalidEnvironmentValueError extends ConfigurationError {
115
+ constructor(key: string, value: string, expectedFormat: string) {
116
+ super(
117
+ `Invalid value for ${key}: ${value}`,
118
+ `Expected format: ${expectedFormat}`
119
+ );
120
+ this.name = 'InvalidEnvironmentValueError';
121
+ }
122
+ }
123
+
124
+ export class PluginConfigurationError extends ConfigurationError {
125
+ constructor(pluginName: string, details: string) {
126
+ super(
127
+ `Failed to configure plugin ${pluginName}`,
128
+ details
129
+ );
130
+ this.name = 'PluginConfigurationError';
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Service health errors
136
+ */
137
+ export class ServiceHealthError extends OnboardingError {
138
+ constructor(serviceName: string, timeout: number) {
139
+ super(
140
+ 'SERVICE_HEALTH_ERROR',
141
+ `Service '${serviceName}' did not become healthy within ${timeout}ms`,
142
+ `Check service logs:\n docker-compose logs ${serviceName}\n\n` +
143
+ 'Or check container status:\n docker ps -a'
144
+ );
145
+ this.name = 'ServiceHealthError';
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Type guard to check if an error is an OnboardingError
151
+ */
152
+ export function isOnboardingError(error: unknown): error is OnboardingError {
153
+ return error instanceof OnboardingError;
154
+ }
155
+
156
+ /**
157
+ * Format error for user display
158
+ */
159
+ export function formatErrorForUser(error: unknown): string {
160
+ if (isOnboardingError(error)) {
161
+ let message = `āŒ ${error.message}`;
162
+ if (error.troubleshooting) {
163
+ message += `\n\nšŸ’” Troubleshooting:\n${error.troubleshooting}`;
164
+ }
165
+ return message;
166
+ }
167
+
168
+ if (error instanceof Error) {
169
+ return `āŒ Unexpected error: ${error.message}`;
170
+ }
171
+
172
+ return `āŒ An unknown error occurred`;
173
+ }
@@ -1,2 +1,2 @@
1
- export * from './errors.js';
2
- export * from './domain.js';
1
+ export * from './errors.js';
2
+ export * from './domain.js';