@aifabrix/builder 2.31.0 → 2.32.1
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 +9 -9
- package/integration/hubspot/README.md +2 -2
- package/integration/hubspot/hubspot-deploy-company.json +17 -14
- package/integration/hubspot/hubspot-deploy-contact.json +19 -16
- package/integration/hubspot/hubspot-deploy-deal.json +21 -18
- package/lib/api/types/datasources.types.js +31 -5
- package/lib/api/types/wizard.types.js +142 -0
- package/lib/api/wizard.api.js +177 -0
- package/lib/{app-config.js → app/config.js} +4 -4
- package/lib/{app-deploy.js → app/deploy.js} +8 -8
- package/lib/app/display.js +90 -0
- package/lib/{app-dockerfile.js → app/dockerfile.js} +4 -4
- package/lib/{app-down.js → app/down.js} +4 -4
- package/lib/app/helpers.js +218 -0
- package/lib/app/index.js +298 -0
- package/lib/{app-list.js → app/list.js} +6 -6
- package/lib/{app-push.js → app/push.js} +4 -4
- package/lib/{app-readme.js → app/readme.js} +34 -13
- package/lib/{app-register.js → app/register.js} +9 -9
- package/lib/{app-rotate-secret.js → app/rotate-secret.js} +123 -37
- package/lib/{app-run-helpers.js → app/run-helpers.js} +10 -10
- package/lib/{app-run.js → app/run.js} +6 -6
- package/lib/{build.js → build/index.js} +59 -32
- package/lib/build/package.json +7 -0
- package/lib/cli.js +245 -179
- package/lib/commands/app.js +3 -3
- package/lib/commands/datasource.js +4 -4
- package/lib/commands/login-credentials.js +209 -0
- package/lib/commands/login-device.js +254 -0
- package/lib/commands/login.js +67 -378
- package/lib/commands/logout.js +1 -1
- package/lib/commands/secrets-set.js +1 -1
- package/lib/commands/secure.js +2 -2
- package/lib/commands/wizard.js +498 -0
- package/lib/{audit-logger.js → core/audit-logger.js} +1 -1
- package/lib/{config.js → core/config.js} +28 -26
- package/lib/{diff.js → core/diff.js} +157 -72
- package/lib/{secrets.js → core/secrets.js} +86 -49
- package/lib/{templates.js → core/templates-env.js} +14 -222
- package/lib/core/templates.js +279 -0
- package/lib/{datasource-deploy.js → datasource/deploy.js} +6 -6
- package/lib/{datasource-diff.js → datasource/diff.js} +2 -2
- package/lib/datasource/list.js +223 -0
- package/lib/{datasource-validate.js → datasource/validate.js} +2 -2
- package/lib/{deployer.js → deployment/deployer.js} +48 -18
- package/lib/{environment-deploy.js → deployment/environment.js} +163 -84
- package/lib/{push.js → deployment/push.js} +1 -1
- package/lib/external-system/deploy-helpers.js +145 -0
- package/lib/{external-system-deploy.js → external-system/deploy.js} +156 -111
- package/lib/external-system/download-helpers.js +114 -0
- package/lib/{external-system-download.js → external-system/download.js} +92 -135
- package/lib/{external-system-generator.js → external-system/generator.js} +15 -11
- package/lib/external-system/test-auth.js +40 -0
- package/lib/external-system/test-execution.js +84 -0
- package/lib/external-system/test-helpers.js +109 -0
- package/lib/{external-system-test.js → external-system/test.js} +174 -192
- package/lib/{generator-builders.js → generator/builders.js} +87 -10
- package/lib/{generator-external.js → generator/external.js} +115 -52
- package/lib/{github-generator.js → generator/github.js} +116 -15
- package/lib/{generator-helpers.js → generator/helpers.js} +92 -42
- package/lib/{generator.js → generator/index.js} +49 -22
- package/lib/{generator-split.js → generator/split.js} +108 -55
- package/lib/generator/wizard-prompts.js +357 -0
- package/lib/generator/wizard.js +490 -0
- package/lib/{infra.js → infrastructure/index.js} +49 -22
- package/lib/schema/external-datasource.schema.json +145 -133
- package/lib/schema/external-system.schema.json +42 -0
- package/lib/utils/api.js +9 -5
- package/lib/utils/app-register-api.js +60 -32
- package/lib/utils/app-register-auth.js +172 -47
- package/lib/utils/app-register-config.js +130 -59
- package/lib/utils/app-run-containers.js +29 -8
- package/lib/utils/build-helpers.js +1 -1
- package/lib/utils/cli-utils.js +78 -30
- package/lib/utils/compose-generator.js +145 -65
- package/lib/utils/config-paths.js +2 -0
- package/lib/utils/deployment-errors.js +1 -1
- package/lib/utils/device-code.js +99 -41
- package/lib/utils/env-config-loader.js +1 -1
- package/lib/utils/env-copy.js +21 -18
- package/lib/utils/env-endpoints.js +115 -67
- package/lib/utils/env-map.js +13 -14
- package/lib/utils/env-ports.js +45 -25
- package/lib/utils/env-template.js +84 -42
- package/lib/utils/error-formatter.js +26 -9
- package/lib/utils/error-formatters/error-parser.js +90 -4
- package/lib/utils/error-formatters/http-status-errors.js +54 -17
- package/lib/utils/error-formatters/network-errors.js +103 -26
- package/lib/utils/external-system-display.js +184 -90
- package/lib/utils/external-system-validators.js +164 -42
- package/lib/utils/file-upload.js +109 -0
- package/lib/utils/health-check.js +199 -83
- package/lib/utils/infra-containers.js +1 -1
- package/lib/utils/infra-status.js +66 -15
- package/lib/utils/local-secrets.js +45 -25
- package/lib/utils/paths.js +45 -33
- package/lib/utils/schema-loader.js +42 -25
- package/lib/utils/schema-resolver.js +123 -74
- package/lib/utils/secrets-encryption.js +62 -25
- package/lib/utils/secrets-helpers.js +126 -63
- package/lib/utils/secrets-path.js +1 -1
- package/lib/utils/secrets-url.js +1 -1
- package/lib/utils/token-manager-refresh.js +181 -0
- package/lib/utils/token-manager.js +76 -123
- package/lib/utils/variable-transformer.js +154 -77
- package/lib/utils/yaml-preserve.js +41 -47
- package/lib/{template-validator.js → validation/template.js} +54 -23
- package/lib/{validate.js → validation/validate.js} +205 -125
- package/lib/{validator.js → validation/validator.js} +58 -39
- package/package.json +34 -3
- package/scripts/install-local.js +210 -0
- package/templates/external-system/deploy.ps1.hbs +34 -0
- package/templates/external-system/deploy.sh.hbs +34 -0
- package/templates/external-system/external-datasource.json.hbs +31 -12
- package/lib/app.js +0 -467
- package/lib/datasource-list.js +0 -141
- /package/lib/{app-prompts.js → app/prompts.js} +0 -0
- /package/lib/{env-reader.js → core/env-reader.js} +0 -0
- /package/lib/{key-generator.js → core/key-generator.js} +0 -0
package/lib/cli.js
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
* @version 2.0.0
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const infra = require('./
|
|
13
|
+
const infra = require('./infrastructure');
|
|
14
14
|
const app = require('./app');
|
|
15
|
-
const secrets = require('./secrets');
|
|
15
|
+
const secrets = require('./core/secrets');
|
|
16
16
|
const generator = require('./generator');
|
|
17
|
-
const validator = require('./validator');
|
|
18
|
-
const config = require('./config');
|
|
17
|
+
const validator = require('./validation/validator');
|
|
18
|
+
const config = require('./core/config');
|
|
19
19
|
const devConfig = require('./utils/dev-config');
|
|
20
20
|
const chalk = require('chalk');
|
|
21
21
|
const logger = require('./utils/logger');
|
|
@@ -26,11 +26,10 @@ const { handleSecure } = require('./commands/secure');
|
|
|
26
26
|
const { handleSecretsSet } = require('./commands/secrets-set');
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Sets up
|
|
29
|
+
* Sets up authentication commands
|
|
30
30
|
* @param {Command} program - Commander program instance
|
|
31
31
|
*/
|
|
32
|
-
function
|
|
33
|
-
// Authentication command
|
|
32
|
+
function setupAuthCommands(program) {
|
|
34
33
|
program.command('login')
|
|
35
34
|
.description('Authenticate with Miso Controller')
|
|
36
35
|
.option('-c, --controller <url>', 'Controller URL', 'http://localhost:3000')
|
|
@@ -63,8 +62,13 @@ function setupCommands(program) {
|
|
|
63
62
|
process.exit(1);
|
|
64
63
|
}
|
|
65
64
|
});
|
|
65
|
+
}
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Sets up infrastructure commands
|
|
69
|
+
* @param {Command} program - Commander program instance
|
|
70
|
+
*/
|
|
71
|
+
function setupInfraCommands(program) {
|
|
68
72
|
program.command('up')
|
|
69
73
|
.description('Start local infrastructure services (Postgres, Redis, pgAdmin, Redis Commander)')
|
|
70
74
|
.option('-d, --developer <id>', 'Set developer ID and start infrastructure')
|
|
@@ -110,7 +114,100 @@ function setupCommands(program) {
|
|
|
110
114
|
}
|
|
111
115
|
});
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
program.command('doctor')
|
|
118
|
+
.description('Check environment and configuration')
|
|
119
|
+
.action(async() => {
|
|
120
|
+
try {
|
|
121
|
+
const result = await validator.checkEnvironment();
|
|
122
|
+
logger.log('\n🔍 AI Fabrix Environment Check\n');
|
|
123
|
+
|
|
124
|
+
logger.log(`Docker: ${result.docker === 'ok' ? '✅ Running' : '❌ Not available'}`);
|
|
125
|
+
logger.log(`Ports: ${result.ports === 'ok' ? '✅ Available' : '⚠️ Some ports in use'}`);
|
|
126
|
+
logger.log(`Secrets: ${result.secrets === 'ok' ? '✅ Configured' : '❌ Missing'}`);
|
|
127
|
+
|
|
128
|
+
if (result.recommendations.length > 0) {
|
|
129
|
+
logger.log('\n📋 Recommendations:');
|
|
130
|
+
result.recommendations.forEach(rec => logger.log(` • ${rec}`));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Check infrastructure health if Docker is available
|
|
134
|
+
if (result.docker === 'ok') {
|
|
135
|
+
try {
|
|
136
|
+
const health = await infra.checkInfraHealth();
|
|
137
|
+
logger.log('\n🏥 Infrastructure Health:');
|
|
138
|
+
Object.entries(health).forEach(([service, status]) => {
|
|
139
|
+
const icon = status === 'healthy' ? '✅' : status === 'unknown' ? '❓' : '❌';
|
|
140
|
+
logger.log(` ${icon} ${service}: ${status}`);
|
|
141
|
+
});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
logger.log('\n🏥 Infrastructure: Not running');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
logger.log('');
|
|
148
|
+
} catch (error) {
|
|
149
|
+
handleCommandError(error, 'doctor');
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
program.command('status')
|
|
155
|
+
.description('Show detailed infrastructure service status and running applications')
|
|
156
|
+
.action(async() => {
|
|
157
|
+
try {
|
|
158
|
+
const status = await infra.getInfraStatus();
|
|
159
|
+
logger.log('\n📊 Infrastructure Status\n');
|
|
160
|
+
|
|
161
|
+
Object.entries(status).forEach(([service, info]) => {
|
|
162
|
+
// Normalize status value for comparison (handle edge cases)
|
|
163
|
+
const normalizedStatus = String(info.status).trim().toLowerCase();
|
|
164
|
+
const icon = normalizedStatus === 'running' ? '✅' : '❌';
|
|
165
|
+
logger.log(`${icon} ${service}:`);
|
|
166
|
+
logger.log(` Status: ${info.status}`);
|
|
167
|
+
logger.log(` Port: ${info.port}`);
|
|
168
|
+
logger.log(` URL: ${info.url}`);
|
|
169
|
+
logger.log('');
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Show running applications
|
|
173
|
+
const apps = await infra.getAppStatus();
|
|
174
|
+
if (apps.length > 0) {
|
|
175
|
+
logger.log('📱 Running Applications\n');
|
|
176
|
+
apps.forEach((app) => {
|
|
177
|
+
const normalizedStatus = String(app.status).trim().toLowerCase();
|
|
178
|
+
const icon = normalizedStatus.includes('running') || normalizedStatus.includes('up') ? '✅' : '❌';
|
|
179
|
+
logger.log(`${icon} ${app.name}:`);
|
|
180
|
+
logger.log(` Container: ${app.container}`);
|
|
181
|
+
logger.log(` Port: ${app.port}`);
|
|
182
|
+
logger.log(` Status: ${app.status}`);
|
|
183
|
+
logger.log(` URL: ${app.url}`);
|
|
184
|
+
logger.log('');
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
} catch (error) {
|
|
188
|
+
handleCommandError(error, 'status');
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
program.command('restart <service>')
|
|
194
|
+
.description('Restart a specific infrastructure service')
|
|
195
|
+
.action(async(service) => {
|
|
196
|
+
try {
|
|
197
|
+
await infra.restartService(service);
|
|
198
|
+
logger.log(`✅ ${service} service restarted successfully`);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
handleCommandError(error, 'restart');
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Sets up application lifecycle commands
|
|
208
|
+
* @param {Command} program - Commander program instance
|
|
209
|
+
*/
|
|
210
|
+
function setupAppCommands(program) {
|
|
114
211
|
program.command('create <app>')
|
|
115
212
|
.description('Create new application with configuration files')
|
|
116
213
|
.option('-p, --port <port>', 'Application port', '3000')
|
|
@@ -125,6 +222,7 @@ function setupCommands(program) {
|
|
|
125
222
|
.option('-g, --github', 'Generate GitHub Actions workflows')
|
|
126
223
|
.option('--github-steps <steps>', 'Extra GitHub workflow steps (comma-separated, e.g., npm,test)')
|
|
127
224
|
.option('--main-branch <branch>', 'Main branch name for workflows', 'main')
|
|
225
|
+
.option('--wizard', 'Use interactive wizard for external system creation')
|
|
128
226
|
.action(async(appName, options) => {
|
|
129
227
|
try {
|
|
130
228
|
// Validate type if provided
|
|
@@ -132,13 +230,35 @@ function setupCommands(program) {
|
|
|
132
230
|
if (options.type && !validTypes.includes(options.type)) {
|
|
133
231
|
throw new Error(`Invalid type: ${options.type}. Must be one of: ${validTypes.join(', ')}`);
|
|
134
232
|
}
|
|
135
|
-
|
|
233
|
+
// If wizard flag is set and type is external, use wizard instead
|
|
234
|
+
if (options.wizard && (options.type === 'external' || (!options.type && validTypes.includes('external')))) {
|
|
235
|
+
const { handleWizard } = require('./commands/wizard');
|
|
236
|
+
await handleWizard({ app: appName, ...options });
|
|
237
|
+
} else {
|
|
238
|
+
await app.createApp(appName, options);
|
|
239
|
+
}
|
|
136
240
|
} catch (error) {
|
|
137
241
|
handleCommandError(error, 'create');
|
|
138
242
|
process.exit(1);
|
|
139
243
|
}
|
|
140
244
|
});
|
|
141
245
|
|
|
246
|
+
program.command('wizard')
|
|
247
|
+
.description('Interactive wizard for creating external systems')
|
|
248
|
+
.option('-a, --app <app>', 'Application name (if not provided, will prompt)')
|
|
249
|
+
.option('-c, --controller <url>', 'Controller URL')
|
|
250
|
+
.option('-e, --environment <env>', 'Environment (dev, tst, pro)', 'dev')
|
|
251
|
+
.option('--dataplane <url>', 'Dataplane URL (overrides controller lookup)')
|
|
252
|
+
.action(async(options) => {
|
|
253
|
+
try {
|
|
254
|
+
const { handleWizard } = require('./commands/wizard');
|
|
255
|
+
await handleWizard(options);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
handleCommandError(error, 'wizard');
|
|
258
|
+
process.exit(1);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
142
262
|
program.command('build <app>')
|
|
143
263
|
.description('Build container image (auto-detects runtime)')
|
|
144
264
|
.option('-l, --language <lang>', 'Override language detection')
|
|
@@ -167,7 +287,6 @@ function setupCommands(program) {
|
|
|
167
287
|
}
|
|
168
288
|
});
|
|
169
289
|
|
|
170
|
-
// Deployment commands
|
|
171
290
|
program.command('push <app>')
|
|
172
291
|
.description('Push image to Azure Container Registry')
|
|
173
292
|
.option('-r, --registry <registry>', 'ACR registry URL (overrides variables.yaml)')
|
|
@@ -181,14 +300,47 @@ function setupCommands(program) {
|
|
|
181
300
|
}
|
|
182
301
|
});
|
|
183
302
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
.
|
|
187
|
-
.
|
|
303
|
+
program.command('deploy <app>')
|
|
304
|
+
.description('Deploy to Azure via Miso Controller')
|
|
305
|
+
.option('-c, --controller <url>', 'Controller URL')
|
|
306
|
+
.option('-e, --environment <env>', 'Environment (miso, dev, tst, pro)', 'dev')
|
|
307
|
+
.option('--client-id <id>', 'Client ID (overrides config)')
|
|
308
|
+
.option('--client-secret <secret>', 'Client Secret (overrides config)')
|
|
309
|
+
.option('--poll', 'Poll for deployment status', true)
|
|
310
|
+
.option('--no-poll', 'Do not poll for status')
|
|
311
|
+
.action(async(appName, options) => {
|
|
312
|
+
try {
|
|
313
|
+
await app.deployApp(appName, options);
|
|
314
|
+
} catch (error) {
|
|
315
|
+
handleCommandError(error, 'deploy');
|
|
316
|
+
process.exit(1);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
188
319
|
|
|
320
|
+
program.command('dockerfile <app>')
|
|
321
|
+
.description('Generate Dockerfile for an application')
|
|
322
|
+
.option('-l, --language <lang>', 'Override language detection')
|
|
323
|
+
.option('-f, --force', 'Overwrite existing Dockerfile')
|
|
324
|
+
.action(async(appName, options) => {
|
|
325
|
+
try {
|
|
326
|
+
const dockerfilePath = await app.generateDockerfileForApp(appName, options);
|
|
327
|
+
logger.log(chalk.green('\n✅ Dockerfile generated successfully!'));
|
|
328
|
+
logger.log(chalk.gray(`Location: ${dockerfilePath}`));
|
|
329
|
+
} catch (error) {
|
|
330
|
+
handleCommandError(error, 'dockerfile');
|
|
331
|
+
process.exit(1);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Sets up environment deployment commands
|
|
338
|
+
* @param {Command} program - Commander program instance
|
|
339
|
+
*/
|
|
340
|
+
function setupEnvironmentCommands(program) {
|
|
189
341
|
const deployEnvHandler = async(envKey, options) => {
|
|
190
342
|
try {
|
|
191
|
-
const environmentDeploy = require('./environment
|
|
343
|
+
const environmentDeploy = require('./deployment/environment');
|
|
192
344
|
await environmentDeploy.deployEnvironment(envKey, options);
|
|
193
345
|
} catch (error) {
|
|
194
346
|
handleCommandError(error, 'environment deploy');
|
|
@@ -196,6 +348,10 @@ function setupCommands(program) {
|
|
|
196
348
|
}
|
|
197
349
|
};
|
|
198
350
|
|
|
351
|
+
const environment = program
|
|
352
|
+
.command('environment')
|
|
353
|
+
.description('Manage environments');
|
|
354
|
+
|
|
199
355
|
environment
|
|
200
356
|
.command('deploy <env>')
|
|
201
357
|
.description('Deploy/setup environment in Miso Controller')
|
|
@@ -220,114 +376,13 @@ function setupCommands(program) {
|
|
|
220
376
|
.option('--poll', 'Poll for deployment status', true)
|
|
221
377
|
.option('--no-poll', 'Do not poll for status')
|
|
222
378
|
.action(deployEnvHandler);
|
|
379
|
+
}
|
|
223
380
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
.option('--client-secret <secret>', 'Client Secret (overrides config)')
|
|
230
|
-
.option('--poll', 'Poll for deployment status', true)
|
|
231
|
-
.option('--no-poll', 'Do not poll for status')
|
|
232
|
-
.action(async(appName, options) => {
|
|
233
|
-
try {
|
|
234
|
-
await app.deployApp(appName, options);
|
|
235
|
-
} catch (error) {
|
|
236
|
-
handleCommandError(error, 'deploy');
|
|
237
|
-
process.exit(1);
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
// Infrastructure status and management
|
|
242
|
-
program.command('doctor')
|
|
243
|
-
.description('Check environment and configuration')
|
|
244
|
-
.action(async() => {
|
|
245
|
-
try {
|
|
246
|
-
const result = await validator.checkEnvironment();
|
|
247
|
-
logger.log('\n🔍 AI Fabrix Environment Check\n');
|
|
248
|
-
|
|
249
|
-
logger.log(`Docker: ${result.docker === 'ok' ? '✅ Running' : '❌ Not available'}`);
|
|
250
|
-
logger.log(`Ports: ${result.ports === 'ok' ? '✅ Available' : '⚠️ Some ports in use'}`);
|
|
251
|
-
logger.log(`Secrets: ${result.secrets === 'ok' ? '✅ Configured' : '❌ Missing'}`);
|
|
252
|
-
|
|
253
|
-
if (result.recommendations.length > 0) {
|
|
254
|
-
logger.log('\n📋 Recommendations:');
|
|
255
|
-
result.recommendations.forEach(rec => logger.log(` • ${rec}`));
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Check infrastructure health if Docker is available
|
|
259
|
-
if (result.docker === 'ok') {
|
|
260
|
-
try {
|
|
261
|
-
const health = await infra.checkInfraHealth();
|
|
262
|
-
logger.log('\n🏥 Infrastructure Health:');
|
|
263
|
-
Object.entries(health).forEach(([service, status]) => {
|
|
264
|
-
const icon = status === 'healthy' ? '✅' : status === 'unknown' ? '❓' : '❌';
|
|
265
|
-
logger.log(` ${icon} ${service}: ${status}`);
|
|
266
|
-
});
|
|
267
|
-
} catch (error) {
|
|
268
|
-
logger.log('\n🏥 Infrastructure: Not running');
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
logger.log('');
|
|
273
|
-
} catch (error) {
|
|
274
|
-
handleCommandError(error, 'doctor');
|
|
275
|
-
process.exit(1);
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
program.command('status')
|
|
280
|
-
.description('Show detailed infrastructure service status and running applications')
|
|
281
|
-
.action(async() => {
|
|
282
|
-
try {
|
|
283
|
-
const status = await infra.getInfraStatus();
|
|
284
|
-
logger.log('\n📊 Infrastructure Status\n');
|
|
285
|
-
|
|
286
|
-
Object.entries(status).forEach(([service, info]) => {
|
|
287
|
-
// Normalize status value for comparison (handle edge cases)
|
|
288
|
-
const normalizedStatus = String(info.status).trim().toLowerCase();
|
|
289
|
-
const icon = normalizedStatus === 'running' ? '✅' : '❌';
|
|
290
|
-
logger.log(`${icon} ${service}:`);
|
|
291
|
-
logger.log(` Status: ${info.status}`);
|
|
292
|
-
logger.log(` Port: ${info.port}`);
|
|
293
|
-
logger.log(` URL: ${info.url}`);
|
|
294
|
-
logger.log('');
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
// Show running applications
|
|
298
|
-
const apps = await infra.getAppStatus();
|
|
299
|
-
if (apps.length > 0) {
|
|
300
|
-
logger.log('📱 Running Applications\n');
|
|
301
|
-
apps.forEach((app) => {
|
|
302
|
-
const normalizedStatus = String(app.status).trim().toLowerCase();
|
|
303
|
-
const icon = normalizedStatus.includes('running') || normalizedStatus.includes('up') ? '✅' : '❌';
|
|
304
|
-
logger.log(`${icon} ${app.name}:`);
|
|
305
|
-
logger.log(` Container: ${app.container}`);
|
|
306
|
-
logger.log(` Port: ${app.port}`);
|
|
307
|
-
logger.log(` Status: ${app.status}`);
|
|
308
|
-
logger.log(` URL: ${app.url}`);
|
|
309
|
-
logger.log('');
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
} catch (error) {
|
|
313
|
-
handleCommandError(error, 'status');
|
|
314
|
-
process.exit(1);
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
program.command('restart <service>')
|
|
319
|
-
.description('Restart a specific infrastructure service')
|
|
320
|
-
.action(async(service) => {
|
|
321
|
-
try {
|
|
322
|
-
await infra.restartService(service);
|
|
323
|
-
logger.log(`✅ ${service} service restarted successfully`);
|
|
324
|
-
} catch (error) {
|
|
325
|
-
handleCommandError(error, 'restart');
|
|
326
|
-
process.exit(1);
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
// Utility commands
|
|
381
|
+
/**
|
|
382
|
+
* Sets up utility commands
|
|
383
|
+
* @param {Command} program - Commander program instance
|
|
384
|
+
*/
|
|
385
|
+
function setupUtilityCommands(program) {
|
|
331
386
|
program.command('resolve <app>')
|
|
332
387
|
.description('Generate .env file from template and validate application files')
|
|
333
388
|
.option('-f, --force', 'Generate missing secret keys in secrets file')
|
|
@@ -341,7 +396,7 @@ function setupCommands(program) {
|
|
|
341
396
|
|
|
342
397
|
// Validate application files after generating .env
|
|
343
398
|
if (!options.skipValidation) {
|
|
344
|
-
const validate = require('./validate');
|
|
399
|
+
const validate = require('./validation/validate');
|
|
345
400
|
const result = await validate.validateAppOrFile(appName);
|
|
346
401
|
validate.displayValidationResults(result);
|
|
347
402
|
if (!result.valid) {
|
|
@@ -439,12 +494,11 @@ function setupCommands(program) {
|
|
|
439
494
|
}
|
|
440
495
|
});
|
|
441
496
|
|
|
442
|
-
// Validation command
|
|
443
497
|
program.command('validate <appOrFile>')
|
|
444
498
|
.description('Validate application or external integration file')
|
|
445
499
|
.action(async(appOrFile) => {
|
|
446
500
|
try {
|
|
447
|
-
const validate = require('./validate');
|
|
501
|
+
const validate = require('./validation/validate');
|
|
448
502
|
const result = await validate.validateAppOrFile(appOrFile);
|
|
449
503
|
validate.displayValidationResults(result);
|
|
450
504
|
if (!result.valid) {
|
|
@@ -456,12 +510,11 @@ function setupCommands(program) {
|
|
|
456
510
|
}
|
|
457
511
|
});
|
|
458
512
|
|
|
459
|
-
// Diff command
|
|
460
513
|
program.command('diff <file1> <file2>')
|
|
461
514
|
.description('Compare two configuration files (for deployment pipeline)')
|
|
462
515
|
.action(async(file1, file2) => {
|
|
463
516
|
try {
|
|
464
|
-
const diff = require('./diff');
|
|
517
|
+
const diff = require('./core/diff');
|
|
465
518
|
const result = await diff.compareFiles(file1, file2);
|
|
466
519
|
diff.formatDiffOutput(result);
|
|
467
520
|
if (!result.identical) {
|
|
@@ -472,54 +525,46 @@ function setupCommands(program) {
|
|
|
472
525
|
process.exit(1);
|
|
473
526
|
}
|
|
474
527
|
});
|
|
528
|
+
}
|
|
475
529
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
530
|
+
/**
|
|
531
|
+
* Helper function to display developer configuration
|
|
532
|
+
* @param {string} devId - Developer ID
|
|
533
|
+
*/
|
|
534
|
+
async function displayDevConfig(devId) {
|
|
535
|
+
const devIdNum = parseInt(devId, 10);
|
|
536
|
+
const ports = devConfig.getDevPorts(devIdNum);
|
|
537
|
+
const configVars = [
|
|
538
|
+
{ key: 'aifabrix-home', value: await config.getAifabrixHomeOverride() },
|
|
539
|
+
{ key: 'aifabrix-secrets', value: await config.getAifabrixSecretsPath() },
|
|
540
|
+
{ key: 'aifabrix-env-config', value: await config.getAifabrixEnvConfigPath() }
|
|
541
|
+
].filter(v => v.value);
|
|
542
|
+
|
|
543
|
+
logger.log('\n🔧 Developer Configuration\n');
|
|
544
|
+
logger.log(`Developer ID: ${devId}`);
|
|
545
|
+
logger.log('\nPorts:');
|
|
546
|
+
logger.log(` App: ${ports.app}`);
|
|
547
|
+
logger.log(` Postgres: ${ports.postgres}`);
|
|
548
|
+
logger.log(` Redis: ${ports.redis}`);
|
|
549
|
+
logger.log(` pgAdmin: ${ports.pgadmin}`);
|
|
550
|
+
logger.log(` Redis Commander: ${ports.redisCommander}`);
|
|
551
|
+
|
|
552
|
+
if (configVars.length > 0) {
|
|
553
|
+
logger.log('\nConfiguration:');
|
|
554
|
+
configVars.forEach(v => logger.log(` ${v.key}: ${v.value}`));
|
|
555
|
+
}
|
|
556
|
+
logger.log('');
|
|
557
|
+
}
|
|
490
558
|
|
|
491
|
-
|
|
559
|
+
/**
|
|
560
|
+
* Sets up developer configuration commands
|
|
561
|
+
* @param {Command} program - Commander program instance
|
|
562
|
+
*/
|
|
563
|
+
function setupDevCommands(program) {
|
|
492
564
|
const dev = program
|
|
493
565
|
.command('dev')
|
|
494
566
|
.description('Developer configuration and isolation');
|
|
495
567
|
|
|
496
|
-
// Helper function to display developer configuration
|
|
497
|
-
async function displayDevConfig(devId) {
|
|
498
|
-
const devIdNum = parseInt(devId, 10);
|
|
499
|
-
const ports = devConfig.getDevPorts(devIdNum);
|
|
500
|
-
const configVars = [
|
|
501
|
-
{ key: 'aifabrix-home', value: await config.getAifabrixHomeOverride() },
|
|
502
|
-
{ key: 'aifabrix-secrets', value: await config.getAifabrixSecretsPath() },
|
|
503
|
-
{ key: 'aifabrix-env-config', value: await config.getAifabrixEnvConfigPath() }
|
|
504
|
-
].filter(v => v.value);
|
|
505
|
-
|
|
506
|
-
logger.log('\n🔧 Developer Configuration\n');
|
|
507
|
-
logger.log(`Developer ID: ${devId}`);
|
|
508
|
-
logger.log('\nPorts:');
|
|
509
|
-
logger.log(` App: ${ports.app}`);
|
|
510
|
-
logger.log(` Postgres: ${ports.postgres}`);
|
|
511
|
-
logger.log(` Redis: ${ports.redis}`);
|
|
512
|
-
logger.log(` pgAdmin: ${ports.pgadmin}`);
|
|
513
|
-
logger.log(` Redis Commander: ${ports.redisCommander}`);
|
|
514
|
-
|
|
515
|
-
if (configVars.length > 0) {
|
|
516
|
-
logger.log('\nConfiguration:');
|
|
517
|
-
configVars.forEach(v => logger.log(` ${v.key}: ${v.value}`));
|
|
518
|
-
}
|
|
519
|
-
logger.log('');
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
// Config subcommand
|
|
523
568
|
dev
|
|
524
569
|
.command('config')
|
|
525
570
|
.description('Show or set developer configuration')
|
|
@@ -550,7 +595,6 @@ function setupCommands(program) {
|
|
|
550
595
|
}
|
|
551
596
|
});
|
|
552
597
|
|
|
553
|
-
// Set-id subcommand
|
|
554
598
|
dev
|
|
555
599
|
.command('set-id <id>')
|
|
556
600
|
.description('Set developer ID (convenience alias for "dev config --set-id")')
|
|
@@ -571,8 +615,13 @@ function setupCommands(program) {
|
|
|
571
615
|
process.exit(1);
|
|
572
616
|
}
|
|
573
617
|
});
|
|
618
|
+
}
|
|
574
619
|
|
|
575
|
-
|
|
620
|
+
/**
|
|
621
|
+
* Sets up secrets and security commands
|
|
622
|
+
* @param {Command} program - Commander program instance
|
|
623
|
+
*/
|
|
624
|
+
function setupSecretsCommands(program) {
|
|
576
625
|
const secretsCmd = program
|
|
577
626
|
.command('secrets')
|
|
578
627
|
.description('Manage secrets in secrets files');
|
|
@@ -590,7 +639,6 @@ function setupCommands(program) {
|
|
|
590
639
|
}
|
|
591
640
|
});
|
|
592
641
|
|
|
593
|
-
// Security command
|
|
594
642
|
program.command('secure')
|
|
595
643
|
.description('Encrypt secrets in secrets.local.yaml files for ISO 27001 compliance')
|
|
596
644
|
.option('--secrets-encryption <key>', 'Encryption key (32 bytes, hex or base64)')
|
|
@@ -602,8 +650,13 @@ function setupCommands(program) {
|
|
|
602
650
|
process.exit(1);
|
|
603
651
|
}
|
|
604
652
|
});
|
|
653
|
+
}
|
|
605
654
|
|
|
606
|
-
|
|
655
|
+
/**
|
|
656
|
+
* Sets up external system commands
|
|
657
|
+
* @param {Command} program - Commander program instance
|
|
658
|
+
*/
|
|
659
|
+
function setupExternalSystemCommands(program) {
|
|
607
660
|
program.command('download <system-key>')
|
|
608
661
|
.description('Download external system from dataplane to local development structure')
|
|
609
662
|
.option('-e, --environment <env>', 'Environment (dev, tst, pro)', 'dev')
|
|
@@ -611,7 +664,7 @@ function setupCommands(program) {
|
|
|
611
664
|
.option('--dry-run', 'Show what would be downloaded without actually downloading')
|
|
612
665
|
.action(async(systemKey, options) => {
|
|
613
666
|
try {
|
|
614
|
-
const download = require('./external-system
|
|
667
|
+
const download = require('./external-system/download');
|
|
615
668
|
await download.downloadExternalSystem(systemKey, options);
|
|
616
669
|
} catch (error) {
|
|
617
670
|
handleCommandError(error, 'download');
|
|
@@ -619,14 +672,13 @@ function setupCommands(program) {
|
|
|
619
672
|
}
|
|
620
673
|
});
|
|
621
674
|
|
|
622
|
-
// Unit test command (local validation)
|
|
623
675
|
program.command('test <app>')
|
|
624
676
|
.description('Run unit tests for external system (local validation, no API calls)')
|
|
625
677
|
.option('-d, --datasource <key>', 'Test specific datasource only')
|
|
626
678
|
.option('-v, --verbose', 'Show detailed validation output')
|
|
627
679
|
.action(async(appName, options) => {
|
|
628
680
|
try {
|
|
629
|
-
const test = require('./external-system
|
|
681
|
+
const test = require('./external-system/test');
|
|
630
682
|
const results = await test.testExternalSystem(appName, options);
|
|
631
683
|
test.displayTestResults(results, options.verbose);
|
|
632
684
|
if (!results.valid) {
|
|
@@ -638,7 +690,6 @@ function setupCommands(program) {
|
|
|
638
690
|
}
|
|
639
691
|
});
|
|
640
692
|
|
|
641
|
-
// Integration test command (via dataplane)
|
|
642
693
|
program.command('test-integration <app>')
|
|
643
694
|
.description('Run integration tests via dataplane pipeline API')
|
|
644
695
|
.option('-d, --datasource <key>', 'Test specific datasource only')
|
|
@@ -649,7 +700,7 @@ function setupCommands(program) {
|
|
|
649
700
|
.option('--timeout <ms>', 'Request timeout in milliseconds', '30000')
|
|
650
701
|
.action(async(appName, options) => {
|
|
651
702
|
try {
|
|
652
|
-
const test = require('./external-system
|
|
703
|
+
const test = require('./external-system/test');
|
|
653
704
|
const results = await test.testExternalSystemIntegration(appName, options);
|
|
654
705
|
test.displayIntegrationTestResults(results, options.verbose);
|
|
655
706
|
if (!results.success) {
|
|
@@ -662,6 +713,21 @@ function setupCommands(program) {
|
|
|
662
713
|
});
|
|
663
714
|
}
|
|
664
715
|
|
|
716
|
+
/**
|
|
717
|
+
* Sets up all CLI commands on the Commander program instance
|
|
718
|
+
* @param {Command} program - Commander program instance
|
|
719
|
+
*/
|
|
720
|
+
function setupCommands(program) {
|
|
721
|
+
setupAuthCommands(program);
|
|
722
|
+
setupInfraCommands(program);
|
|
723
|
+
setupAppCommands(program);
|
|
724
|
+
setupEnvironmentCommands(program);
|
|
725
|
+
setupUtilityCommands(program);
|
|
726
|
+
setupDevCommands(program);
|
|
727
|
+
setupSecretsCommands(program);
|
|
728
|
+
setupExternalSystemCommands(program);
|
|
729
|
+
}
|
|
730
|
+
|
|
665
731
|
module.exports = {
|
|
666
732
|
setupCommands,
|
|
667
733
|
validateCommand,
|
package/lib/commands/app.js
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
const chalk = require('chalk');
|
|
13
13
|
const logger = require('../utils/logger');
|
|
14
|
-
const { listApplications } = require('../app
|
|
15
|
-
const { registerApplication } = require('../app
|
|
16
|
-
const { rotateSecret } = require('../app
|
|
14
|
+
const { listApplications } = require('../app/list');
|
|
15
|
+
const { registerApplication } = require('../app/register');
|
|
16
|
+
const { rotateSecret } = require('../app/rotate-secret');
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Setup application management commands
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
|
|
12
12
|
const chalk = require('chalk');
|
|
13
13
|
const logger = require('../utils/logger');
|
|
14
|
-
const { validateDatasourceFile } = require('../datasource
|
|
15
|
-
const { listDatasources } = require('../datasource
|
|
16
|
-
const { compareDatasources } = require('../datasource
|
|
17
|
-
const { deployDatasource } = require('../datasource
|
|
14
|
+
const { validateDatasourceFile } = require('../datasource/validate');
|
|
15
|
+
const { listDatasources } = require('../datasource/list');
|
|
16
|
+
const { compareDatasources } = require('../datasource/diff');
|
|
17
|
+
const { deployDatasource } = require('../datasource/deploy');
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Setup datasource management commands
|