@aifabrix/builder 2.32.3 → 2.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/project-rules.mdc +8 -0
- package/README.md +36 -8
- package/bin/aifabrix.js +6 -8
- package/integration/hubspot/README.md +8 -7
- package/integration/hubspot/companies.json +2048 -0
- package/integration/hubspot/create-hubspot.js +665 -0
- package/integration/hubspot/{hubspot-deploy-company.json → hubspot-datasource-company.json} +1 -1
- package/integration/hubspot/{hubspot-deploy-contact.json → hubspot-datasource-contact.json} +1 -1
- package/integration/hubspot/{hubspot-deploy-deal.json → hubspot-datasource-deal.json} +1 -1
- package/integration/hubspot/hubspot-deploy.json +832 -81
- package/integration/hubspot/hubspot-system.json +99 -0
- package/integration/hubspot/test-artifacts/wizard-hubspot-credential-real.yaml +20 -0
- package/integration/hubspot/test-artifacts/wizard-hubspot-env-vars.yaml +9 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-add-datasource.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-app-name.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-credential-create.yaml +7 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-credential-select.yaml +7 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-known-platform.yaml +4 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-missing-app.yaml +4 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-missing-source.yaml +2 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-mode.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-openapi-file.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-openapi-url.yaml +4 -0
- package/integration/hubspot/test-artifacts/wizard-invalid-source.yaml +4 -0
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-array-test.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-key-test.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-path-test.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-test.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-valid-for-rbac-test.yaml +5 -0
- package/integration/hubspot/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +5 -0
- package/integration/hubspot/test-dataplane-down-helpers.js +246 -0
- package/integration/hubspot/test-dataplane-down-tests.js +419 -0
- package/integration/hubspot/test-dataplane-down.js +157 -0
- package/integration/hubspot/test.js +1517 -0
- package/integration/hubspot/variables.yaml +4 -4
- package/integration/hubspot/wizard-hubspot-e2e.yaml +16 -0
- package/integration/hubspot/wizard-hubspot-platform.yaml +8 -0
- package/lib/api/applications.api.js +1 -0
- package/lib/api/types/wizard.types.js +176 -38
- package/lib/api/wizard.api.js +161 -23
- package/lib/app/deploy.js +116 -54
- package/lib/app/display.js +6 -5
- package/lib/app/dockerfile.js +2 -1
- package/lib/app/list.js +17 -10
- package/lib/app/readme.js +41 -112
- package/lib/app/register.js +44 -9
- package/lib/app/rotate-secret.js +48 -31
- package/lib/cli.js +219 -70
- package/lib/commands/app.js +4 -9
- package/lib/commands/auth-config.js +125 -0
- package/lib/commands/auth-status.js +7 -8
- package/lib/commands/datasource.js +3 -6
- package/lib/commands/login-credentials.js +4 -4
- package/lib/commands/login-device.js +26 -17
- package/lib/commands/login.js +12 -10
- package/lib/commands/wizard-config-normalizer.js +92 -0
- package/lib/commands/wizard-core.js +515 -0
- package/lib/commands/wizard-dataplane.js +122 -0
- package/lib/commands/wizard-headless.js +115 -0
- package/lib/commands/wizard.js +110 -332
- package/lib/core/config.js +46 -0
- package/lib/core/secrets.js +3 -22
- package/lib/core/templates-env.js +1 -1
- package/lib/datasource/deploy.js +29 -21
- package/lib/datasource/list.js +8 -6
- package/lib/deployment/deployer.js +25 -0
- package/lib/deployment/environment.js +10 -13
- package/lib/external-system/delete.js +151 -0
- package/lib/external-system/deploy.js +53 -378
- package/lib/external-system/download-helpers.js +45 -65
- package/lib/external-system/download.js +33 -13
- package/lib/external-system/generator.js +11 -7
- package/lib/external-system/test-auth.js +4 -3
- package/lib/generator/builders.js +3 -1
- package/lib/generator/external-controller-manifest.js +157 -0
- package/lib/generator/external-schema-utils.js +236 -0
- package/lib/generator/external.js +55 -3
- package/lib/generator/index.js +22 -10
- package/lib/generator/wizard-prompts.js +33 -10
- package/lib/generator/wizard.js +69 -86
- package/lib/infrastructure/compose.js +100 -0
- package/lib/infrastructure/helpers.js +139 -0
- package/lib/infrastructure/index.js +52 -311
- package/lib/infrastructure/services.js +168 -0
- package/lib/schema/application-schema.json +23 -4
- package/lib/schema/external-datasource.schema.json +2 -2
- package/lib/schema/wizard-config.schema.json +234 -0
- package/lib/utils/api.js +32 -50
- package/lib/utils/app-existence.js +42 -0
- package/lib/utils/app-register-config.js +7 -2
- package/lib/utils/auth-config-validator.js +92 -0
- package/lib/utils/command-header.js +43 -0
- package/lib/utils/compose-generator.js +113 -70
- package/lib/utils/controller-url.js +65 -17
- package/lib/utils/dataplane-health.js +115 -0
- package/lib/utils/dataplane-resolver.js +29 -0
- package/lib/utils/dev-config.js +6 -2
- package/lib/utils/env-copy.js +2 -1
- package/lib/utils/env-ports.js +2 -1
- package/lib/utils/env-template.js +1 -1
- package/lib/utils/error-formatter.js +49 -0
- package/lib/utils/external-readme.js +125 -0
- package/lib/utils/help-builder.js +190 -0
- package/lib/utils/infra-status.js +13 -3
- package/lib/utils/paths.js +17 -2
- package/lib/utils/port-resolver.js +111 -0
- package/lib/utils/secrets-helpers.js +3 -15
- package/lib/utils/secrets-utils.js +2 -2
- package/lib/utils/token-manager.js +9 -4
- package/lib/utils/variable-transformer.js +7 -2
- package/lib/validation/external-manifest-validator.js +202 -0
- package/lib/validation/validate-display.js +406 -0
- package/lib/validation/validate.js +159 -123
- package/lib/validation/validator.js +36 -3
- package/lib/validation/wizard-config-validator.js +267 -0
- package/package.json +4 -2
- package/templates/applications/README.md.hbs +18 -16
- package/templates/applications/miso-controller/env.template +1 -1
- package/templates/applications/miso-controller/rbac.yaml +7 -7
- package/templates/external-system/README.md.hbs +99 -0
- package/templates/infra/compose.yaml.hbs +35 -0
- package/templates/python/docker-compose.hbs +26 -0
- package/templates/typescript/docker-compose.hbs +26 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication Configuration Commands
|
|
3
|
+
*
|
|
4
|
+
* Handles setting controller, environment, and dataplane URLs in config.yaml
|
|
5
|
+
*
|
|
6
|
+
* @fileoverview Authentication configuration commands
|
|
7
|
+
* @author AI Fabrix Team
|
|
8
|
+
* @version 2.0.0
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
const {
|
|
13
|
+
setControllerUrl,
|
|
14
|
+
setCurrentEnvironment,
|
|
15
|
+
getControllerUrl
|
|
16
|
+
} = require('../core/config');
|
|
17
|
+
const {
|
|
18
|
+
validateControllerUrl,
|
|
19
|
+
validateEnvironment,
|
|
20
|
+
checkUserLoggedIn
|
|
21
|
+
} = require('../utils/auth-config-validator');
|
|
22
|
+
const logger = require('../utils/logger');
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Handle set-controller command
|
|
26
|
+
* @async
|
|
27
|
+
* @function handleSetController
|
|
28
|
+
* @param {string} url - Controller URL to set
|
|
29
|
+
* @returns {Promise<void>}
|
|
30
|
+
* @throws {Error} If validation fails
|
|
31
|
+
*/
|
|
32
|
+
async function handleSetController(url) {
|
|
33
|
+
try {
|
|
34
|
+
// Validate URL format
|
|
35
|
+
validateControllerUrl(url);
|
|
36
|
+
|
|
37
|
+
// Check if user is logged in to that controller
|
|
38
|
+
const isLoggedIn = await checkUserLoggedIn(url);
|
|
39
|
+
if (!isLoggedIn) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`You are not logged in to controller ${url}.\n` +
|
|
42
|
+
'Please run "aifabrix login" first to authenticate with this controller.'
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Save controller URL
|
|
47
|
+
await setControllerUrl(url);
|
|
48
|
+
|
|
49
|
+
logger.log(chalk.green(`✓ Controller URL set to: ${url}`));
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger.error(chalk.red(`✗ Failed to set controller URL: ${error.message}`));
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Handle set-environment command
|
|
58
|
+
* @async
|
|
59
|
+
* @function handleSetEnvironment
|
|
60
|
+
* @param {string} environment - Environment key to set
|
|
61
|
+
* @returns {Promise<void>}
|
|
62
|
+
* @throws {Error} If validation fails
|
|
63
|
+
*/
|
|
64
|
+
async function handleSetEnvironment(environment) {
|
|
65
|
+
try {
|
|
66
|
+
// Validate environment format
|
|
67
|
+
validateEnvironment(environment);
|
|
68
|
+
|
|
69
|
+
// Get current controller from config
|
|
70
|
+
const controllerUrl = await getControllerUrl();
|
|
71
|
+
if (!controllerUrl) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
'No controller URL found in config.\n' +
|
|
74
|
+
'Please run "aifabrix login" first to set the controller URL.'
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check if user is logged in to that controller
|
|
79
|
+
const isLoggedIn = await checkUserLoggedIn(controllerUrl);
|
|
80
|
+
if (!isLoggedIn) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`You are not logged in to controller ${controllerUrl}.\n` +
|
|
83
|
+
'Please run "aifabrix login" first to authenticate with this controller.'
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Save environment
|
|
88
|
+
await setCurrentEnvironment(environment);
|
|
89
|
+
|
|
90
|
+
logger.log(chalk.green(`✓ Environment set to: ${environment}`));
|
|
91
|
+
} catch (error) {
|
|
92
|
+
logger.error(chalk.red(`✗ Failed to set environment: ${error.message}`));
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Handle auth config command
|
|
99
|
+
* @async
|
|
100
|
+
* @function handleAuthConfig
|
|
101
|
+
* @param {Object} options - Command options
|
|
102
|
+
* @param {string} [options.setController] - Controller URL to set
|
|
103
|
+
* @param {string} [options.setEnvironment] - Environment to set
|
|
104
|
+
* @returns {Promise<void>}
|
|
105
|
+
* @throws {Error} If command fails
|
|
106
|
+
*/
|
|
107
|
+
async function handleAuthConfig(options) {
|
|
108
|
+
if (!options.setController && !options.setEnvironment) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
'No action specified. Use one of:\n' +
|
|
111
|
+
' --set-controller <url>\n' +
|
|
112
|
+
' --set-environment <env>'
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
if (options.setController) {
|
|
116
|
+
await handleSetController(options.setController);
|
|
117
|
+
}
|
|
118
|
+
if (options.setEnvironment) {
|
|
119
|
+
await handleSetEnvironment(options.setEnvironment);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = {
|
|
124
|
+
handleAuthConfig
|
|
125
|
+
};
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
const chalk = require('chalk');
|
|
12
12
|
const logger = require('../utils/logger');
|
|
13
13
|
const config = require('../core/config');
|
|
14
|
-
const { getConfig
|
|
14
|
+
const { getConfig } = config;
|
|
15
15
|
const { getOrRefreshDeviceToken } = require('../utils/token-manager');
|
|
16
16
|
const { getAuthUser } = require('../api/auth.api');
|
|
17
17
|
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
@@ -236,17 +236,16 @@ function displayStatus(controllerUrl, environment, tokenInfo) {
|
|
|
236
236
|
|
|
237
237
|
/**
|
|
238
238
|
* Handle auth status command
|
|
239
|
+
* Controller and environment come from config.yaml (set via aifabrix login or aifabrix auth config).
|
|
239
240
|
* @async
|
|
240
241
|
* @function handleAuthStatus
|
|
241
|
-
* @param {Object}
|
|
242
|
-
* @param {string} [options.controller] - Controller URL (uses developer ID-based default if not provided)
|
|
243
|
-
* @param {string} [options.environment] - Environment key (uses current environment from config if not provided)
|
|
242
|
+
* @param {Object} _options - Command options (unused; controller/environment from config only)
|
|
244
243
|
* @returns {Promise<void>} Resolves when status is displayed
|
|
245
244
|
*/
|
|
246
|
-
async function handleAuthStatus(
|
|
247
|
-
const
|
|
248
|
-
const controllerUrl = await resolveControllerUrl(
|
|
249
|
-
const environment =
|
|
245
|
+
async function handleAuthStatus(_options) {
|
|
246
|
+
const { resolveEnvironment } = require('../core/config');
|
|
247
|
+
const controllerUrl = await resolveControllerUrl();
|
|
248
|
+
const environment = await resolveEnvironment();
|
|
250
249
|
|
|
251
250
|
// Check device token first (preferred)
|
|
252
251
|
let tokenInfo = await checkDeviceToken(controllerUrl);
|
|
@@ -50,11 +50,10 @@ function setupDatasourceCommands(program) {
|
|
|
50
50
|
// List command
|
|
51
51
|
datasource
|
|
52
52
|
.command('list')
|
|
53
|
-
.description('List datasources from environment')
|
|
54
|
-
.
|
|
55
|
-
.action(async(options) => {
|
|
53
|
+
.description('List datasources from environment (uses environment from config.yaml)')
|
|
54
|
+
.action(async() => {
|
|
56
55
|
try {
|
|
57
|
-
await listDatasources(
|
|
56
|
+
await listDatasources({});
|
|
58
57
|
} catch (error) {
|
|
59
58
|
logger.error(chalk.red('❌ Failed to list datasources:'), error.message);
|
|
60
59
|
process.exit(1);
|
|
@@ -78,8 +77,6 @@ function setupDatasourceCommands(program) {
|
|
|
78
77
|
datasource
|
|
79
78
|
.command('deploy <myapp> <file>')
|
|
80
79
|
.description('Deploy datasource to dataplane')
|
|
81
|
-
.requiredOption('--controller <url>', 'Controller URL')
|
|
82
|
-
.requiredOption('-e, --environment <env>', 'Environment (miso, dev, tst, pro)')
|
|
83
80
|
.action(async(myapp, file, options) => {
|
|
84
81
|
try {
|
|
85
82
|
await deployDatasource(myapp, file, options);
|
|
@@ -54,7 +54,7 @@ async function promptForCredentials(clientId, clientSecret) {
|
|
|
54
54
|
message: 'Client ID:',
|
|
55
55
|
default: clientId || '',
|
|
56
56
|
validate: (input) => {
|
|
57
|
-
const value = input.trim();
|
|
57
|
+
const value = input ? input.trim() : '';
|
|
58
58
|
if (!value || value.length === 0) {
|
|
59
59
|
return 'Client ID is required';
|
|
60
60
|
}
|
|
@@ -68,7 +68,7 @@ async function promptForCredentials(clientId, clientSecret) {
|
|
|
68
68
|
default: clientSecret || '',
|
|
69
69
|
mask: '*',
|
|
70
70
|
validate: (input) => {
|
|
71
|
-
const value = input.trim();
|
|
71
|
+
const value = input ? input.trim() : '';
|
|
72
72
|
if (!value || value.length === 0) {
|
|
73
73
|
return 'Client Secret is required';
|
|
74
74
|
}
|
|
@@ -78,8 +78,8 @@ async function promptForCredentials(clientId, clientSecret) {
|
|
|
78
78
|
]);
|
|
79
79
|
|
|
80
80
|
return {
|
|
81
|
-
clientId: credentials.clientId.trim(),
|
|
82
|
-
clientSecret: credentials.clientSecret.trim()
|
|
81
|
+
clientId: (credentials.clientId || '').trim(),
|
|
82
|
+
clientSecret: (credentials.clientSecret || '').trim()
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
const inquirer = require('inquirer');
|
|
12
12
|
const chalk = require('chalk');
|
|
13
13
|
const ora = require('ora');
|
|
14
|
-
const { setCurrentEnvironment, saveDeviceToken } = require('../core/config');
|
|
14
|
+
const { setCurrentEnvironment, saveDeviceToken, setControllerUrl } = require('../core/config');
|
|
15
15
|
const { initiateDeviceCodeFlow } = require('../api/auth.api');
|
|
16
16
|
const { pollDeviceCodeToken, displayDeviceCodeInfo } = require('../utils/api');
|
|
17
17
|
const logger = require('../utils/logger');
|
|
@@ -68,6 +68,30 @@ async function saveDeviceLoginConfig(controllerUrl, token, refreshToken, expires
|
|
|
68
68
|
await saveDeviceToken(controllerUrl, token, refreshToken, expiresAt);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Save token configuration and display success message
|
|
73
|
+
* @async
|
|
74
|
+
* @param {string} controllerUrl - Controller URL
|
|
75
|
+
* @param {string} token - Access token
|
|
76
|
+
* @param {string} refreshToken - Refresh token
|
|
77
|
+
* @param {string} expiresAt - Token expiration time
|
|
78
|
+
* @param {string} envKey - Environment key
|
|
79
|
+
* @returns {Promise<void>}
|
|
80
|
+
*/
|
|
81
|
+
async function saveTokenAndDisplaySuccess(controllerUrl, token, refreshToken, expiresAt, envKey) {
|
|
82
|
+
await saveDeviceLoginConfig(controllerUrl, token, refreshToken, expiresAt);
|
|
83
|
+
await setControllerUrl(controllerUrl);
|
|
84
|
+
if (envKey) {
|
|
85
|
+
await setCurrentEnvironment(envKey);
|
|
86
|
+
}
|
|
87
|
+
logger.log(chalk.green('\n✅ Successfully logged in!'));
|
|
88
|
+
logger.log(chalk.gray(`Controller: ${controllerUrl}`));
|
|
89
|
+
if (envKey) {
|
|
90
|
+
logger.log(chalk.gray(`Environment: ${envKey}`));
|
|
91
|
+
}
|
|
92
|
+
logger.log(chalk.gray('Token stored securely in ~/.aifabrix/config.yaml\n'));
|
|
93
|
+
}
|
|
94
|
+
|
|
71
95
|
/**
|
|
72
96
|
* Poll for device code token and save configuration
|
|
73
97
|
* @async
|
|
@@ -105,23 +129,8 @@ async function pollAndSaveDeviceCodeToken(controllerUrl, deviceCode, interval, e
|
|
|
105
129
|
const refreshToken = tokenResponse.refresh_token;
|
|
106
130
|
const expiresAt = new Date(Date.now() + (tokenResponse.expires_in * 1000)).toISOString();
|
|
107
131
|
|
|
108
|
-
|
|
109
|
-
await saveDeviceLoginConfig(controllerUrl, token, refreshToken, expiresAt);
|
|
110
|
-
|
|
111
|
-
// Still set current environment if provided (for other purposes)
|
|
112
|
-
if (envKey) {
|
|
113
|
-
await setCurrentEnvironment(envKey);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
logger.log(chalk.green('\n✅ Successfully logged in!'));
|
|
117
|
-
logger.log(chalk.gray(`Controller: ${controllerUrl}`));
|
|
118
|
-
if (envKey) {
|
|
119
|
-
logger.log(chalk.gray(`Environment: ${envKey}`));
|
|
120
|
-
}
|
|
121
|
-
logger.log(chalk.gray('Token stored securely in ~/.aifabrix/config.yaml\n'));
|
|
122
|
-
|
|
132
|
+
await saveTokenAndDisplaySuccess(controllerUrl, token, refreshToken, expiresAt, envKey);
|
|
123
133
|
return { token, environment: envKey };
|
|
124
|
-
|
|
125
134
|
} catch (pollError) {
|
|
126
135
|
spinner.fail('Authentication failed');
|
|
127
136
|
throw pollError;
|
package/lib/commands/login.js
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
|
|
12
12
|
const inquirer = require('inquirer');
|
|
13
13
|
const chalk = require('chalk');
|
|
14
|
-
const { setCurrentEnvironment, saveClientToken } = require('../core/config');
|
|
14
|
+
const { setCurrentEnvironment, saveClientToken, setControllerUrl } = require('../core/config');
|
|
15
15
|
const logger = require('../utils/logger');
|
|
16
16
|
const { handleCredentialsLogin } = require('./login-credentials');
|
|
17
17
|
const { handleDeviceCodeLogin } = require('./login-device');
|
|
18
|
-
const {
|
|
18
|
+
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Determine and validate authentication method
|
|
@@ -62,7 +62,7 @@ async function saveCredentialsLoginConfig(controllerUrl, token, expiresAt, envir
|
|
|
62
62
|
* @async
|
|
63
63
|
* @function handleLogin
|
|
64
64
|
* @param {Object} options - Login options
|
|
65
|
-
* @param {string} [options.controller] - Controller URL (default:
|
|
65
|
+
* @param {string} [options.controller] - Controller URL (default: from config, device tokens, or developer ID)
|
|
66
66
|
* @param {string} [options.method] - Authentication method ('device' or 'credentials', default: 'device')
|
|
67
67
|
* @param {string} [options.app] - Application name (for credentials method, reads from secrets.local.yaml)
|
|
68
68
|
* @param {string} [options.clientId] - Client ID (for credentials method, overrides secrets.local.yaml)
|
|
@@ -72,8 +72,7 @@ async function saveCredentialsLoginConfig(controllerUrl, token, expiresAt, envir
|
|
|
72
72
|
* @throws {Error} If login fails
|
|
73
73
|
*/
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
76
|
-
* Calculates default URL based on developer ID if not provided
|
|
75
|
+
* Resolves and logs controller URL from --controller, config, device tokens, or developer-ID default
|
|
77
76
|
* @async
|
|
78
77
|
* @function normalizeControllerUrl
|
|
79
78
|
* @param {Object} options - Login options
|
|
@@ -82,9 +81,11 @@ async function saveCredentialsLoginConfig(controllerUrl, token, expiresAt, envir
|
|
|
82
81
|
async function normalizeControllerUrl(options) {
|
|
83
82
|
let controllerUrl = options.controller || options.url;
|
|
84
83
|
if (!controllerUrl) {
|
|
85
|
-
controllerUrl = await
|
|
84
|
+
controllerUrl = await resolveControllerUrl();
|
|
86
85
|
}
|
|
87
|
-
controllerUrl = controllerUrl.replace(
|
|
86
|
+
controllerUrl = String(controllerUrl).replace(/\/+$/, '');
|
|
87
|
+
// Save controller URL to config
|
|
88
|
+
await setControllerUrl(controllerUrl);
|
|
88
89
|
logger.log(chalk.gray(`Controller URL: ${controllerUrl}`));
|
|
89
90
|
return controllerUrl;
|
|
90
91
|
}
|
|
@@ -144,11 +145,12 @@ async function handleCredentialsLoginFlow(controllerUrl, environment, options) {
|
|
|
144
145
|
* @async
|
|
145
146
|
* @function handleDeviceCodeLoginFlow
|
|
146
147
|
* @param {string} controllerUrl - Controller URL
|
|
148
|
+
* @param {string} environment - Resolved environment key (from config or -e/--environment)
|
|
147
149
|
* @param {Object} options - Login options
|
|
148
150
|
* @returns {Promise<{token: string, environment: string}>} Login result
|
|
149
151
|
*/
|
|
150
|
-
async function handleDeviceCodeLoginFlow(controllerUrl, options) {
|
|
151
|
-
return await handleDeviceCodeLogin(controllerUrl,
|
|
152
|
+
async function handleDeviceCodeLoginFlow(controllerUrl, environment, options) {
|
|
153
|
+
return await handleDeviceCodeLogin(controllerUrl, environment, options.online, options.scope);
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
async function handleLogin(options) {
|
|
@@ -163,7 +165,7 @@ async function handleLogin(options) {
|
|
|
163
165
|
if (method === 'credentials') {
|
|
164
166
|
await handleCredentialsLoginFlow(controllerUrl, environment, options);
|
|
165
167
|
} else if (method === 'device') {
|
|
166
|
-
await handleDeviceCodeLoginFlow(controllerUrl, options);
|
|
168
|
+
await handleDeviceCodeLoginFlow(controllerUrl, environment, options);
|
|
167
169
|
return; // Early return for device flow (already saved config)
|
|
168
170
|
}
|
|
169
171
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Normalize wizard-generated configs before validation
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 2.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const ENTITY_TYPE_FALLBACK = 'record-storage';
|
|
8
|
+
const VALID_ENTITY_TYPES = new Set([
|
|
9
|
+
'document-storage',
|
|
10
|
+
'documentStorage',
|
|
11
|
+
'vector-store',
|
|
12
|
+
'vectorStore',
|
|
13
|
+
'record-storage',
|
|
14
|
+
'recordStorage',
|
|
15
|
+
'message-service',
|
|
16
|
+
'messageService',
|
|
17
|
+
'none'
|
|
18
|
+
]);
|
|
19
|
+
const VALID_PORTAL_FIELDS = new Set(['text', 'textarea', 'select', 'json', 'boolean', 'number']);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Normalize system config fields to schema constraints
|
|
23
|
+
* @function normalizeSystemConfig
|
|
24
|
+
* @param {Object} systemConfig - External system config
|
|
25
|
+
* @returns {Object} Normalized config
|
|
26
|
+
*/
|
|
27
|
+
function normalizeSystemConfig(systemConfig) {
|
|
28
|
+
if (!systemConfig || typeof systemConfig !== 'object') {
|
|
29
|
+
return systemConfig;
|
|
30
|
+
}
|
|
31
|
+
if (typeof systemConfig.description === 'string' && systemConfig.description.length > 500) {
|
|
32
|
+
systemConfig.description = systemConfig.description.slice(0, 500);
|
|
33
|
+
}
|
|
34
|
+
return systemConfig;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Normalize datasource config fields to schema constraints
|
|
39
|
+
* @function normalizeDatasourceConfig
|
|
40
|
+
* @param {Object} datasourceConfig - Datasource config
|
|
41
|
+
* @returns {Object} Normalized config
|
|
42
|
+
*/
|
|
43
|
+
function normalizeDatasourceConfig(datasourceConfig) {
|
|
44
|
+
if (!datasourceConfig || typeof datasourceConfig !== 'object') {
|
|
45
|
+
return datasourceConfig;
|
|
46
|
+
}
|
|
47
|
+
if (datasourceConfig.entityType && !VALID_ENTITY_TYPES.has(datasourceConfig.entityType)) {
|
|
48
|
+
datasourceConfig.entityType = ENTITY_TYPE_FALLBACK;
|
|
49
|
+
}
|
|
50
|
+
if (Array.isArray(datasourceConfig.portalInput)) {
|
|
51
|
+
datasourceConfig.portalInput = datasourceConfig.portalInput.filter(item => {
|
|
52
|
+
if (!item || typeof item !== 'object') {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
if (!item.name || !item.field || !item.label) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return VALID_PORTAL_FIELDS.has(item.field);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (datasourceConfig.execution?.cip?.operations) {
|
|
62
|
+
for (const operation of Object.values(datasourceConfig.execution.cip.operations)) {
|
|
63
|
+
if (!operation || !Array.isArray(operation.steps)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
for (const step of operation.steps) {
|
|
67
|
+
if (step?.output?.mode && step.output.mode !== 'records') {
|
|
68
|
+
step.output.mode = 'records';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return datasourceConfig;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Normalize system and datasource configs
|
|
78
|
+
* @function normalizeWizardConfigs
|
|
79
|
+
* @param {Object} systemConfig - System config
|
|
80
|
+
* @param {Object|Object[]} datasourceConfigs - Datasource config(s)
|
|
81
|
+
* @returns {{ systemConfig: Object, datasourceConfigs: Object[] }} Normalized configs
|
|
82
|
+
*/
|
|
83
|
+
function normalizeWizardConfigs(systemConfig, datasourceConfigs) {
|
|
84
|
+
const normalizedSystem = normalizeSystemConfig(systemConfig);
|
|
85
|
+
const configs = Array.isArray(datasourceConfigs) ? datasourceConfigs : [datasourceConfigs];
|
|
86
|
+
const normalizedDatasources = configs.map(normalizeDatasourceConfig);
|
|
87
|
+
return { systemConfig: normalizedSystem, datasourceConfigs: normalizedDatasources };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
normalizeWizardConfigs
|
|
92
|
+
};
|