@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
package/dist/infra.js
CHANGED
|
@@ -1,181 +1,162 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { APP_COMPOSE_TEMPLATE, APP_NGINX_SERVICE_TEMPLATE } from './templates.js';
|
|
2
|
+
import { writeFile } from './utils.js';
|
|
3
|
+
import { multiselect } from '@clack/prompts';
|
|
4
|
+
import { handleCancel, spinner } from './ui.js';
|
|
4
5
|
import path from 'path';
|
|
5
6
|
const INFRA_SERVICES = [
|
|
6
7
|
{ name: 'MongoDB (Database)', value: 'mongo', checked: true },
|
|
7
8
|
{ name: 'Kafka (Message Queue)', value: 'kafka', checked: true },
|
|
8
9
|
{ name: 'Kafka UI (Dashboard)', value: 'kafka-ui', checked: true },
|
|
9
10
|
{ name: 'Redis (Cache)', value: 'redis', checked: true },
|
|
11
|
+
{ name: 'Nginx (Reverse Proxy)', value: 'nginx', checked: false },
|
|
10
12
|
{ name: 'Loki (Log Aggregation)', value: 'loki', checked: false },
|
|
11
13
|
{ name: 'Grafana (Observability Dashboard)', value: 'grafana', checked: false },
|
|
12
14
|
];
|
|
13
15
|
/**
|
|
14
16
|
* Prompts user to select which infrastructure services to deploy.
|
|
15
|
-
* Services include MongoDB, Kafka, Redis, Loki, and Grafana.
|
|
16
17
|
*
|
|
17
18
|
* @returns Array of selected service IDs (e.g., ['mongo', 'kafka', 'redis'])
|
|
18
19
|
* @throws Error if no services are selected
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```ts
|
|
22
|
-
* const services = await promptInfraServices();
|
|
23
|
-
* // Returns: ['mongo', 'kafka', 'kafka-ui', 'redis']
|
|
24
|
-
* ```
|
|
25
20
|
*/
|
|
26
21
|
export async function promptInfraServices() {
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
type: 'checkbox',
|
|
30
|
-
name: 'services',
|
|
31
|
-
message: 'Select infrastructure services to run:',
|
|
32
|
-
choices: INFRA_SERVICES,
|
|
33
|
-
validate: (input) => {
|
|
34
|
-
if (input.length === 0) {
|
|
35
|
-
return 'Please select at least one service';
|
|
36
|
-
}
|
|
37
|
-
return true;
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
]);
|
|
41
|
-
return answer.services;
|
|
22
|
+
return promptInfraServicesWithBasePath({ allowNginx: true });
|
|
42
23
|
}
|
|
43
24
|
/**
|
|
44
|
-
*
|
|
25
|
+
* Prompts infrastructure services with optional nginx availability.
|
|
26
|
+
* If nginx is disabled, it is removed from choices and from result safety-check.
|
|
45
27
|
*/
|
|
46
|
-
export function
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// },
|
|
71
|
-
// },
|
|
72
|
-
// ]);
|
|
73
|
-
// return answer.hostChoice === 'custom' ? answer.customHost! : answer.hostChoice;
|
|
74
|
-
// }
|
|
75
|
-
// For Windows, linux and macOS, use host.docker.internal
|
|
76
|
-
return 'host.docker.internal';
|
|
28
|
+
export async function promptInfraServicesWithBasePath(options) {
|
|
29
|
+
const choices = options.allowNginx
|
|
30
|
+
? INFRA_SERVICES
|
|
31
|
+
: INFRA_SERVICES.filter(service => service.value !== 'nginx');
|
|
32
|
+
const message = options.allowNginx
|
|
33
|
+
? 'Select infrastructure services to run (Space to select, Enter to confirm):'
|
|
34
|
+
: 'Select infrastructure services to run (Space to select, Enter to confirm) — nginx disabled:';
|
|
35
|
+
const selected = await multiselect({
|
|
36
|
+
message,
|
|
37
|
+
options: choices.map(s => ({
|
|
38
|
+
value: s.value,
|
|
39
|
+
label: s.name,
|
|
40
|
+
hint: s.checked ? 'recommended' : undefined,
|
|
41
|
+
})),
|
|
42
|
+
initialValues: choices.filter(s => s.checked).map(s => s.value),
|
|
43
|
+
required: true,
|
|
44
|
+
withGuide: true,
|
|
45
|
+
});
|
|
46
|
+
handleCancel(selected);
|
|
47
|
+
const result = selected;
|
|
48
|
+
if (options.allowNginx) {
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
return result.filter(service => service !== 'nginx');
|
|
77
52
|
}
|
|
78
53
|
/**
|
|
79
54
|
* Service chunk definitions - each service as a complete block
|
|
80
55
|
*/
|
|
81
56
|
const SERVICE_CHUNKS = {
|
|
82
|
-
'mongo': ` mongo:
|
|
83
|
-
image: mongo:7.0
|
|
84
|
-
container_name: mongo
|
|
85
|
-
command: [ "--replSet", "rs0", "--bind_ip_all", "--port", "27017" ]
|
|
86
|
-
ports:
|
|
87
|
-
- 27017:27017
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
volumes:
|
|
98
|
-
- "mongo_data:/data/db"
|
|
57
|
+
'mongo': ` mongo:
|
|
58
|
+
image: mongo:7.0
|
|
59
|
+
container_name: mongo
|
|
60
|
+
command: [ "--replSet", "rs0", "--bind_ip_all", "--port", "27017" ]
|
|
61
|
+
ports:
|
|
62
|
+
- 27017:27017
|
|
63
|
+
healthcheck:
|
|
64
|
+
test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'mongo:27017'}]}) }" | mongosh --port 27017 --quiet
|
|
65
|
+
interval: 5s
|
|
66
|
+
timeout: 30s
|
|
67
|
+
start_period: 0s
|
|
68
|
+
start_interval: 1s
|
|
69
|
+
retries: 30
|
|
70
|
+
volumes:
|
|
71
|
+
- "mongo_data:/data/db"
|
|
99
72
|
- "mongo_config:/data/configdb"`,
|
|
100
|
-
'kafka': ` kafka:
|
|
101
|
-
image: apache/kafka-native
|
|
102
|
-
container_name: kafka
|
|
103
|
-
ports:
|
|
104
|
-
- "9092:9092"
|
|
105
|
-
environment:
|
|
106
|
-
# Configure listeners for both docker and host communication
|
|
107
|
-
KAFKA_LISTENERS: CONTROLLER://localhost:9091,HOST://0.0.0.0:9092,DOCKER://0.0.0.0:9093
|
|
108
|
-
KAFKA_ADVERTISED_LISTENERS: HOST://
|
|
109
|
-
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,DOCKER:PLAINTEXT,HOST:PLAINTEXT
|
|
110
|
-
|
|
111
|
-
# Settings required for KRaft mode
|
|
112
|
-
KAFKA_NODE_ID: 1
|
|
113
|
-
KAFKA_PROCESS_ROLES: broker,controller
|
|
114
|
-
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
|
115
|
-
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9091
|
|
116
|
-
|
|
117
|
-
# Listener to use for broker-to-broker communication
|
|
118
|
-
KAFKA_INTER_BROKER_LISTENER_NAME: DOCKER
|
|
119
|
-
|
|
120
|
-
# Required for a single node cluster
|
|
121
|
-
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
|
122
|
-
|
|
123
|
-
# Disable auto-topic creation - API server will create topics with correct partitions
|
|
124
|
-
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
|
|
125
|
-
volumes:
|
|
73
|
+
'kafka': ` kafka:
|
|
74
|
+
image: apache/kafka-native
|
|
75
|
+
container_name: kafka
|
|
76
|
+
ports:
|
|
77
|
+
- "9092:9092"
|
|
78
|
+
environment:
|
|
79
|
+
# Configure listeners for both docker and host communication
|
|
80
|
+
KAFKA_LISTENERS: CONTROLLER://localhost:9091,HOST://0.0.0.0:9092,DOCKER://0.0.0.0:9093
|
|
81
|
+
KAFKA_ADVERTISED_LISTENERS: HOST://kafka:9092,DOCKER://kafka:9093
|
|
82
|
+
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,DOCKER:PLAINTEXT,HOST:PLAINTEXT
|
|
83
|
+
|
|
84
|
+
# Settings required for KRaft mode
|
|
85
|
+
KAFKA_NODE_ID: 1
|
|
86
|
+
KAFKA_PROCESS_ROLES: broker,controller
|
|
87
|
+
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
|
88
|
+
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9091
|
|
89
|
+
|
|
90
|
+
# Listener to use for broker-to-broker communication
|
|
91
|
+
KAFKA_INTER_BROKER_LISTENER_NAME: DOCKER
|
|
92
|
+
|
|
93
|
+
# Required for a single node cluster
|
|
94
|
+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
|
95
|
+
|
|
96
|
+
# Disable auto-topic creation - API server will create topics with correct partitions
|
|
97
|
+
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
|
|
98
|
+
volumes:
|
|
126
99
|
- "kafka_data:/var/lib/kafka/data"`,
|
|
127
|
-
'kafka-ui': ` kafka-ui:
|
|
128
|
-
image: kafbat/kafka-ui:main
|
|
129
|
-
container_name: kafka-ui
|
|
130
|
-
ports:
|
|
131
|
-
- 8080:8080
|
|
132
|
-
environment:
|
|
133
|
-
DYNAMIC_CONFIG_ENABLED: "true"
|
|
134
|
-
KAFKA_CLUSTERS_0_NAME: local
|
|
135
|
-
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9093
|
|
136
|
-
depends_on:
|
|
100
|
+
'kafka-ui': ` kafka-ui:
|
|
101
|
+
image: kafbat/kafka-ui:main
|
|
102
|
+
container_name: kafka-ui
|
|
103
|
+
ports:
|
|
104
|
+
- 8080:8080
|
|
105
|
+
environment:
|
|
106
|
+
DYNAMIC_CONFIG_ENABLED: "true"
|
|
107
|
+
KAFKA_CLUSTERS_0_NAME: local
|
|
108
|
+
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9093
|
|
109
|
+
depends_on:
|
|
137
110
|
- kafka`,
|
|
138
|
-
'redis': ` redis:
|
|
139
|
-
image: redis:7-alpine
|
|
140
|
-
container_name: redis
|
|
141
|
-
ports:
|
|
142
|
-
- "6379:6379"
|
|
143
|
-
command: redis-server --appendonly yes
|
|
144
|
-
volumes:
|
|
145
|
-
- "redis_data:/data"
|
|
146
|
-
healthcheck:
|
|
147
|
-
test: [ "CMD", "redis-cli", "ping" ]
|
|
148
|
-
interval: 5s
|
|
149
|
-
timeout: 3s
|
|
111
|
+
'redis': ` redis:
|
|
112
|
+
image: redis:7-alpine
|
|
113
|
+
container_name: redis
|
|
114
|
+
ports:
|
|
115
|
+
- "6379:6379"
|
|
116
|
+
command: redis-server --appendonly yes
|
|
117
|
+
volumes:
|
|
118
|
+
- "redis_data:/data"
|
|
119
|
+
healthcheck:
|
|
120
|
+
test: [ "CMD", "redis-cli", "ping" ]
|
|
121
|
+
interval: 5s
|
|
122
|
+
timeout: 3s
|
|
150
123
|
retries: 5`,
|
|
151
|
-
'loki': ` loki:
|
|
152
|
-
image: grafana/loki:2.9.0
|
|
153
|
-
container_name: loki
|
|
154
|
-
ports:
|
|
155
|
-
- "3100:3100"
|
|
156
|
-
command: -config.file=/etc/loki/local-config.yaml
|
|
157
|
-
volumes:
|
|
158
|
-
- "loki_data:/loki"
|
|
159
|
-
healthcheck:
|
|
160
|
-
test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1" ]
|
|
161
|
-
interval: 10s
|
|
162
|
-
timeout: 5s
|
|
124
|
+
'loki': ` loki:
|
|
125
|
+
image: grafana/loki:2.9.0
|
|
126
|
+
container_name: loki
|
|
127
|
+
ports:
|
|
128
|
+
- "3100:3100"
|
|
129
|
+
command: -config.file=/etc/loki/local-config.yaml
|
|
130
|
+
volumes:
|
|
131
|
+
- "loki_data:/loki"
|
|
132
|
+
healthcheck:
|
|
133
|
+
test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1" ]
|
|
134
|
+
interval: 10s
|
|
135
|
+
timeout: 5s
|
|
163
136
|
retries: 5`,
|
|
164
|
-
'grafana': ` grafana:
|
|
165
|
-
image: grafana/grafana:10.2.0
|
|
166
|
-
container_name: grafana
|
|
167
|
-
ports:
|
|
168
|
-
- "3001:3000"
|
|
169
|
-
environment:
|
|
170
|
-
- GF_PATHS_PROVISIONING=/etc/grafana/provisioning
|
|
171
|
-
- GF_AUTH_ANONYMOUS_ENABLED=true
|
|
172
|
-
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
|
|
173
|
-
- GF_SECURITY_ADMIN_PASSWORD=admin
|
|
174
|
-
volumes:
|
|
175
|
-
- "grafana_data:/var/lib/grafana"
|
|
176
|
-
depends_on:
|
|
177
|
-
loki:
|
|
137
|
+
'grafana': ` grafana:
|
|
138
|
+
image: grafana/grafana:10.2.0
|
|
139
|
+
container_name: grafana
|
|
140
|
+
ports:
|
|
141
|
+
- "3001:3000"
|
|
142
|
+
environment:
|
|
143
|
+
- GF_PATHS_PROVISIONING=/etc/grafana/provisioning
|
|
144
|
+
- GF_AUTH_ANONYMOUS_ENABLED=true
|
|
145
|
+
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
|
|
146
|
+
- GF_SECURITY_ADMIN_PASSWORD=admin
|
|
147
|
+
volumes:
|
|
148
|
+
- "grafana_data:/var/lib/grafana"
|
|
149
|
+
depends_on:
|
|
150
|
+
loki:
|
|
178
151
|
condition: service_healthy`,
|
|
152
|
+
'nginx': ` nginx:
|
|
153
|
+
image: nginx:alpine
|
|
154
|
+
container_name: nginx
|
|
155
|
+
ports:
|
|
156
|
+
- "80:80"
|
|
157
|
+
volumes:
|
|
158
|
+
- "./nginx.conf:/etc/nginx/conf.d/default.conf:ro"
|
|
159
|
+
restart: unless-stopped`,
|
|
179
160
|
};
|
|
180
161
|
/**
|
|
181
162
|
* Service-to-volumes mapping
|
|
@@ -185,6 +166,7 @@ const SERVICE_VOLUMES = {
|
|
|
185
166
|
'kafka': ['kafka_data'],
|
|
186
167
|
'kafka-ui': [],
|
|
187
168
|
'redis': ['redis_data'],
|
|
169
|
+
'nginx': [],
|
|
188
170
|
'loki': ['loki_data'],
|
|
189
171
|
'grafana': ['grafana_data'],
|
|
190
172
|
};
|
|
@@ -193,15 +175,15 @@ const SERVICE_VOLUMES = {
|
|
|
193
175
|
*/
|
|
194
176
|
function buildInfraCompose(selectedServices) {
|
|
195
177
|
// Header
|
|
196
|
-
const header = `# ============================================
|
|
197
|
-
#
|
|
198
|
-
#
|
|
199
|
-
#
|
|
200
|
-
# ============================================
|
|
201
|
-
|
|
202
|
-
services:
|
|
203
|
-
# ============================================
|
|
204
|
-
# Infrastructure Services
|
|
178
|
+
const header = `# ============================================
|
|
179
|
+
# SimpleNS Infrastructure Services
|
|
180
|
+
# All services use Docker service names for container-to-container communication.
|
|
181
|
+
# This ensures cross-platform compatibility (Windows, Linux, macOS).
|
|
182
|
+
# ============================================
|
|
183
|
+
|
|
184
|
+
services:
|
|
185
|
+
# ============================================
|
|
186
|
+
# Infrastructure Services
|
|
205
187
|
# ============================================`;
|
|
206
188
|
// Assemble selected service chunks
|
|
207
189
|
const serviceBlocks = [];
|
|
@@ -231,37 +213,144 @@ services:
|
|
|
231
213
|
networkLines.join('\n'),
|
|
232
214
|
].join('\n');
|
|
233
215
|
}
|
|
234
|
-
/**
|
|
235
|
-
* Replace INFRA_HOST placeholder in template
|
|
236
|
-
*/
|
|
237
|
-
export function replaceInfraHost(template, infraHost) {
|
|
238
|
-
return template.replace(/\{\{INFRA_HOST\}\}/g, infraHost);
|
|
239
|
-
}
|
|
240
216
|
/**
|
|
241
217
|
* Generate and write docker-compose.infra.yaml
|
|
242
218
|
*/
|
|
243
219
|
export async function generateInfraCompose(targetDir, selectedServices) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
const infraHost = getInfraHost();
|
|
247
|
-
logSuccess(`Using infrastructure host: ${infraHost}`);
|
|
220
|
+
const s = spinner();
|
|
221
|
+
s.start('Generating docker-compose.infra.yaml...');
|
|
248
222
|
// Build compose content from service chunks
|
|
249
|
-
|
|
250
|
-
// Replace host placeholder
|
|
251
|
-
infraContent = replaceInfraHost(infraContent, infraHost);
|
|
223
|
+
const infraContent = buildInfraCompose(selectedServices);
|
|
252
224
|
// Write infrastructure compose file
|
|
253
225
|
const infraPath = path.join(targetDir, 'docker-compose.infra.yaml');
|
|
254
226
|
await writeFile(infraPath, infraContent);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
227
|
+
s.stop('Generated docker-compose.infra.yaml');
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Build app docker-compose content.
|
|
231
|
+
* Optionally inject nginx reverse-proxy service before the volumes section.
|
|
232
|
+
*/
|
|
233
|
+
export function buildAppComposeContent(includeNginx) {
|
|
234
|
+
if (!includeNginx) {
|
|
235
|
+
return APP_COMPOSE_TEMPLATE;
|
|
236
|
+
}
|
|
237
|
+
const marker = '\nvolumes:';
|
|
238
|
+
if (!APP_COMPOSE_TEMPLATE.includes(marker)) {
|
|
239
|
+
return APP_COMPOSE_TEMPLATE;
|
|
240
|
+
}
|
|
241
|
+
return APP_COMPOSE_TEMPLATE.replace(marker, `\n${APP_NGINX_SERVICE_TEMPLATE}\n${marker}`);
|
|
258
242
|
}
|
|
259
243
|
/**
|
|
260
244
|
* Write app docker-compose.yaml
|
|
261
245
|
*/
|
|
262
|
-
export async function writeAppCompose(targetDir) {
|
|
246
|
+
export async function writeAppCompose(targetDir, options = {}) {
|
|
247
|
+
const s = spinner();
|
|
248
|
+
s.start('Generating docker-compose.yaml...');
|
|
263
249
|
const appPath = path.join(targetDir, 'docker-compose.yaml');
|
|
264
|
-
|
|
265
|
-
|
|
250
|
+
const appContent = buildAppComposeContent(options.includeNginx === true);
|
|
251
|
+
await writeFile(appPath, appContent);
|
|
252
|
+
s.stop('Generated docker-compose.yaml');
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Generate nginx.conf based on basePath configuration
|
|
256
|
+
*/
|
|
257
|
+
export async function generateNginxConfig(targetDir, basePath) {
|
|
258
|
+
const s = spinner();
|
|
259
|
+
s.start('Generating nginx.conf...');
|
|
260
|
+
// Normalize basePath (remove leading/trailing slashes for template)
|
|
261
|
+
const normalizedPath = basePath.trim().replace(/^\/|\/$/g, '');
|
|
262
|
+
const hasBasePath = normalizedPath.length > 0;
|
|
263
|
+
// Template for nginx.conf
|
|
264
|
+
const nginxTemplate = `server {
|
|
265
|
+
listen 80;
|
|
266
|
+
server_name localhost;
|
|
267
|
+
|
|
268
|
+
location /api/notification/ {
|
|
269
|
+
proxy_pass http://api:3000;
|
|
270
|
+
proxy_http_version 1.1;
|
|
271
|
+
|
|
272
|
+
proxy_set_header Host $host;
|
|
273
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
274
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
275
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
location = /runtime-config.js {
|
|
279
|
+
proxy_pass http://dashboard:3002/runtime-config.js;
|
|
280
|
+
proxy_http_version 1.1;
|
|
281
|
+
|
|
282
|
+
proxy_set_header Host $host;
|
|
283
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
284
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
285
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
286
|
+
|
|
287
|
+
# optional: prevent caching if config is dynamic
|
|
288
|
+
add_header Cache-Control "no-store";
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
location ^~ /_next/ {
|
|
292
|
+
proxy_pass http://dashboard:3002/_next/;
|
|
293
|
+
proxy_http_version 1.1;
|
|
294
|
+
|
|
295
|
+
proxy_set_header Host $host;
|
|
296
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
297
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
298
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
299
|
+
|
|
300
|
+
expires 1y;
|
|
301
|
+
add_header Cache-Control "public, immutable";
|
|
302
|
+
}
|
|
303
|
+
${hasBasePath ? `
|
|
304
|
+
location ^~ /${normalizedPath}/_next/ {
|
|
305
|
+
proxy_pass http://dashboard:3002/_next/;
|
|
306
|
+
proxy_http_version 1.1;
|
|
307
|
+
|
|
308
|
+
proxy_set_header Host $host;
|
|
309
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
310
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
311
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
312
|
+
|
|
313
|
+
expires 1y;
|
|
314
|
+
add_header Cache-Control "public, immutable";
|
|
315
|
+
}
|
|
316
|
+
` : ''}
|
|
317
|
+
location ~* \\.(png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|eot)$ {
|
|
318
|
+
proxy_pass http://dashboard:3002;
|
|
319
|
+
proxy_http_version 1.1;
|
|
320
|
+
|
|
321
|
+
proxy_set_header Host $host;
|
|
322
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
323
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
324
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
325
|
+
|
|
326
|
+
expires 1y;
|
|
327
|
+
add_header Cache-Control "public, max-age=31536000";
|
|
328
|
+
}
|
|
329
|
+
${hasBasePath ? `
|
|
330
|
+
location ^~ /${normalizedPath} {
|
|
331
|
+
proxy_pass http://dashboard:3002;
|
|
332
|
+
proxy_http_version 1.1;
|
|
333
|
+
|
|
334
|
+
proxy_set_header Host $host;
|
|
335
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
336
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
337
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
338
|
+
}
|
|
339
|
+
` : `
|
|
340
|
+
location / {
|
|
341
|
+
proxy_pass http://dashboard:3002;
|
|
342
|
+
proxy_http_version 1.1;
|
|
343
|
+
|
|
344
|
+
proxy_set_header Host $host;
|
|
345
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
346
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
347
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
348
|
+
}
|
|
349
|
+
`}
|
|
350
|
+
}
|
|
351
|
+
`;
|
|
352
|
+
const nginxPath = path.join(targetDir, 'nginx.conf');
|
|
353
|
+
await writeFile(nginxPath, nginxTemplate);
|
|
354
|
+
s.stop(`Generated nginx.conf${hasBasePath ? ` with base path: /${normalizedPath}` : ' (root path)'}`);
|
|
266
355
|
}
|
|
267
356
|
//# sourceMappingURL=infra.js.map
|
package/dist/infra.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infra.js","sourceRoot":"","sources":["../src/infra.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"infra.js","sourceRoot":"","sources":["../src/infra.ts"],"names":[],"mappings":"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"}
|
package/dist/plugins.d.ts
CHANGED
|
@@ -4,16 +4,6 @@ import type { PluginInfo } from './types/domain.js';
|
|
|
4
4
|
* Falls back to default plugins if fetching fails.
|
|
5
5
|
*
|
|
6
6
|
* @returns Array of available plugin information
|
|
7
|
-
*
|
|
8
|
-
* @remarks
|
|
9
|
-
* Uses `npx @simplens/config-gen list --official` to fetch plugins.
|
|
10
|
-
* Default fallback plugins: mock, nodemailer-gmail, resend
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* const plugins = await fetchAvailablePlugins();
|
|
15
|
-
* // Returns: [{ package: '@simplens/mock', name: 'Mock Provider', ... }, ...]
|
|
16
|
-
* ```
|
|
17
7
|
*/
|
|
18
8
|
export declare function fetchAvailablePlugins(): Promise<PluginInfo[]>;
|
|
19
9
|
/**
|
|
@@ -28,6 +18,11 @@ export declare function generatePluginConfig(targetDir: string, selectedPlugins:
|
|
|
28
18
|
* Parse simplens.config.yaml to extract credential keys
|
|
29
19
|
*/
|
|
30
20
|
export declare function parseConfigCredentials(configPath: string): Promise<string[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Generate default placeholder values for plugin credentials
|
|
23
|
+
* Used in --full mode for non-interactive setup
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateDefaultPluginCredentials(credentialKeys: string[]): Map<string, string>;
|
|
31
26
|
/**
|
|
32
27
|
* Prompt for plugin-specific credentials
|
|
33
28
|
*/
|
package/dist/plugins.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,mBAAmB,CAAC;AAEpE;;;;;GAKG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CA0CnE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,gBAAgB,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqB7F;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACtC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BlF;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAoB9F;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA0CpG"}
|