@aifabrix/builder 2.46.0 → 2.47.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/.npmrc.token +1 -0
- package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
- package/.temp/validation/summary.txt +5 -0
- package/jest.isolated-projects.js +18 -2
- package/jest.projects.js +24 -0
- package/lib/api/dataplane-health.api.js +19 -7
- package/lib/api/lifecycle.api.js +22 -1
- package/lib/api/resource-types.api.js +107 -0
- package/lib/api/runtime-configuration.api.js +72 -0
- package/lib/api/types/resource-types.types.js +45 -0
- package/lib/api/user-groups.api.js +9 -9
- package/lib/api/users.api.js +8 -8
- package/lib/api/wizard.api.js +10 -2
- package/lib/app/down.js +58 -26
- package/lib/app/index.js +2 -2
- package/lib/app/run-resolve-image.js +2 -1
- package/lib/app/run-stop-containers.js +113 -0
- package/lib/app/run.js +1 -31
- package/lib/app/show-display.js +35 -0
- package/lib/app/show.js +32 -1
- package/lib/build/index.js +17 -5
- package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
- package/lib/channels/add-channel.js +348 -0
- package/lib/channels/channel-artifact-generator.js +141 -0
- package/lib/channels/channel-audit.js +101 -0
- package/lib/channels/channel-auth-context.js +37 -0
- package/lib/channels/channel-credential.js +200 -0
- package/lib/channels/channel-display-name.js +64 -0
- package/lib/channels/channel-external-system.js +106 -0
- package/lib/channels/channel-integration-generator.js +274 -0
- package/lib/channels/channel-probe.js +89 -0
- package/lib/channels/channel-runtime-resolver.js +152 -0
- package/lib/channels/channel-status-display.js +141 -0
- package/lib/channels/channel-targets.js +115 -0
- package/lib/cli/index.js +16 -4
- package/lib/cli/setup-app.js +54 -3
- package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
- package/lib/cli/setup-infra-up-platform-action.js +2 -1
- package/lib/cli/setup-platform.js +1 -1
- package/lib/cli/setup-utility-help-after.js +4 -1
- package/lib/cli/setup-utility-resolve.js +8 -5
- package/lib/commands/app-logs.js +54 -26
- package/lib/commands/app.js +41 -0
- package/lib/commands/auth-status-dataplane-version.js +97 -61
- package/lib/commands/auth-status.js +2 -7
- package/lib/commands/channel.js +58 -0
- package/lib/commands/datasource.js +1 -1
- package/lib/commands/identity-apply-sync.js +49 -8
- package/lib/commands/identity-group-cli.js +66 -26
- package/lib/commands/identity-membership-role-cache.js +58 -37
- package/lib/commands/identity-shared.js +22 -1
- package/lib/commands/identity-user-cli.js +80 -34
- package/lib/commands/repair-auth-apply.js +30 -4
- package/lib/commands/repair-auth-config.js +8 -13
- package/lib/commands/repair-datasource-com-v2.js +15 -0
- package/lib/commands/repair-datasource-service-contract.js +206 -0
- package/lib/commands/repair-datasource.js +53 -18
- package/lib/commands/repair-env-template.js +12 -12
- package/lib/commands/repair-openapi-sync.js +26 -4
- package/lib/commands/repair-steps.js +28 -13
- package/lib/commands/repair-system-alignment.js +7 -4
- package/lib/commands/resource-type.js +371 -0
- package/lib/commands/setup-modes.js +1 -1
- package/lib/commands/setup-prompts-platform-mode.js +24 -21
- package/lib/commands/test-trust-external.js +39 -90
- package/lib/commands/up-common.js +33 -1
- package/lib/commands/up-dataplane.js +8 -4
- package/lib/commands/upload.js +24 -3
- package/lib/commands/verify-trust-command-action.js +4 -1
- package/lib/commands/verify-trust-external.js +12 -20
- package/lib/core/config-setup-platform-mode.js +3 -3
- package/lib/core/setup-platform-mode.js +41 -6
- package/lib/datasource/capability/capability-diff-slice.js +2 -2
- package/lib/datasource/capability/capability-manifest.js +254 -0
- package/lib/datasource/capability/capability-resolve.js +3 -4
- package/lib/datasource/capability/copy-operations.js +5 -3
- package/lib/datasource/capability/remove-operations.js +2 -1
- package/lib/datasource/capability/run-capability-copy.js +32 -4
- package/lib/datasource/capability/run-capability-diff.js +3 -3
- package/lib/datasource/capability/run-capability-dimension.js +2 -4
- package/lib/datasource/capability/run-capability-edit.js +4 -7
- package/lib/datasource/capability/run-capability-relate.js +2 -4
- package/lib/datasource/capability/run-capability-remove.js +2 -4
- package/lib/datasource/capability/validate-capability-slice.js +2 -1
- package/lib/datasource/datasource-identifier.js +2 -1
- package/lib/datasource/datasource-validate-display.js +1 -1
- package/lib/datasource/field-reference-validator.js +24 -3
- package/lib/datasource/orphan-profiles-validator.js +98 -0
- package/lib/datasource/validate.js +41 -23
- package/lib/external-system/download-helpers.js +87 -0
- package/lib/external-system/download.js +61 -122
- package/lib/external-system/generator.js +1 -59
- package/lib/external-system/test.js +10 -15
- package/lib/generator/builders.js +11 -1
- package/lib/generator/external-controller-manifest.js +5 -2
- package/lib/generator/split.js +3 -1
- package/lib/generator/wizard.js +1 -28
- package/lib/identity/fk-reference.js +65 -0
- package/lib/identity/identity-apply-core.js +13 -58
- package/lib/identity/identity-apply-phases.js +5 -1
- package/lib/identity/identity-display.js +243 -0
- package/lib/identity/identity-response-helpers.js +52 -0
- package/lib/identity/identity-sync-errors.js +62 -0
- package/lib/identity/resolve-user-id.js +129 -0
- package/lib/identity/username-default.js +31 -0
- package/lib/lifecycle/certification-progress.js +2 -2
- package/lib/lifecycle/report-display-trust.js +70 -0
- package/lib/lifecycle/report-display.js +14 -13
- package/lib/resolvers/datasource-resolver.js +2 -3
- package/lib/resolvers/resource-type-file.js +159 -0
- package/lib/schema/application-schema.json +16 -0
- package/lib/schema/deployment-rules.yaml +2 -1
- package/lib/schema/external-datasource.schema.json +372 -58
- package/lib/schema/external-system.schema.json +331 -2
- package/lib/schema/type/document-storage.json +9 -5
- package/lib/utils/app-run-containers.js +25 -2
- package/lib/utils/authentication-shape.js +224 -0
- package/lib/utils/build-copy.js +36 -5
- package/lib/utils/build-resolve-image.js +66 -12
- package/lib/utils/celery-companion-apps.js +53 -0
- package/lib/utils/cli-utils.js +4 -0
- package/lib/utils/compose-celery-worker.js +23 -0
- package/lib/utils/compose-generate-docker-compose.js +9 -1
- package/lib/utils/configuration-env-resolver.js +36 -0
- package/lib/utils/credential-secrets-env-kv.js +216 -0
- package/lib/utils/credential-secrets-env.js +52 -262
- package/lib/utils/dataplane-resolver.js +4 -115
- package/lib/utils/declarative-url-ports.js +24 -1
- package/lib/utils/docker-build.js +1 -4
- package/lib/utils/external-env-template.js +10 -3
- package/lib/utils/external-system-validators.js +8 -2
- package/lib/utils/help-builder.js +2 -0
- package/lib/utils/paths.js +25 -0
- package/lib/utils/platform-controller-url.js +2 -1
- package/lib/utils/platform-kv-ref.js +57 -0
- package/lib/utils/runtime-configuration-download.js +189 -0
- package/lib/utils/runtime-configuration-values.js +119 -0
- package/lib/utils/schema-loader.js +19 -4
- package/lib/utils/worker-sidecars.js +142 -0
- package/lib/validation/external-manifest-validator.js +2 -0
- package/lib/validation/runtime-configuration-rules.js +98 -0
- package/lib/validation/validate-display-dimensions.js +154 -0
- package/lib/validation/validate-display-sections.js +276 -0
- package/lib/validation/validate-display-steps.js +67 -0
- package/lib/validation/validate-display.js +24 -402
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +5 -0
- package/templates/applications/dataplane/env.template +26 -13
- package/templates/applications/dataplane/rbac.yaml +108 -1
- package/templates/applications/miso-controller/application.yaml +2 -2
- package/templates/applications/miso-controller/env.template +37 -122
- package/templates/applications/miso-controller/rbac.yaml +28 -13
- package/templates/channels/chatgpt/install.template.md.hbs +49 -0
- package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
- package/templates/channels/slack/install.template.md.hbs +49 -0
- package/templates/channels/slack/manifest.template.json.hbs +66 -0
- package/templates/channels/teams-bot/install.template.md.hbs +49 -0
- package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
- package/templates/channels/web-embed/install.template.md.hbs +49 -0
- package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
- package/templates/python/docker-compose.hbs +56 -0
- package/templates/typescript/docker-compose.hbs +52 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime configuration validation for external system manifests.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Datasource override rules (v1: no keyvault overrides)
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {Array<{ name?: string, location?: string }>|undefined} systemConfiguration
|
|
11
|
+
* @returns {Map<string, { name?: string, location?: string }>}
|
|
12
|
+
*/
|
|
13
|
+
function systemConfigDefsByName(systemConfiguration) {
|
|
14
|
+
const defsByName = new Map();
|
|
15
|
+
for (const item of systemConfiguration || []) {
|
|
16
|
+
if (item && item.name) {
|
|
17
|
+
defsByName.set(String(item.name).trim(), item);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return defsByName;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} prefix
|
|
25
|
+
* @param {Map<string, { name?: string, location?: string }>} defsByName
|
|
26
|
+
* @param {{ name?: string, value?: string }} override
|
|
27
|
+
* @returns {string[]}
|
|
28
|
+
*/
|
|
29
|
+
function validateOverrideEntry(prefix, defsByName, override) {
|
|
30
|
+
if (!override || !override.name) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
const name = String(override.name).trim();
|
|
34
|
+
const def = defsByName.get(name);
|
|
35
|
+
if (!def) {
|
|
36
|
+
return [`${prefix}configuration override '${name}' is not declared on the parent system.`];
|
|
37
|
+
}
|
|
38
|
+
const errors = [];
|
|
39
|
+
if (String(def.location || 'variable').toLowerCase() === 'keyvault') {
|
|
40
|
+
errors.push(
|
|
41
|
+
`${prefix}configuration override '${name}' targets a keyvault system definition (not allowed in v1).`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
const extraKeys = Object.keys(override).filter((key) => key !== 'name' && key !== 'value');
|
|
45
|
+
if (extraKeys.length > 0) {
|
|
46
|
+
errors.push(
|
|
47
|
+
`${prefix}configuration override '${name}' must contain only name and value (found: ${extraKeys.join(', ')}).`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return errors;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Validates datasource configuration[] overrides against parent system definitions.
|
|
55
|
+
*
|
|
56
|
+
* @param {Array<{ name?: string, location?: string }>|undefined} systemConfiguration
|
|
57
|
+
* @param {Array<{ name?: string, value?: string }>|undefined} datasourceConfiguration
|
|
58
|
+
* @param {string} [datasourceKey] - For error prefixes
|
|
59
|
+
* @returns {string[]} Validation errors
|
|
60
|
+
*/
|
|
61
|
+
function validateDatasourceConfigurationOverrides(
|
|
62
|
+
systemConfiguration,
|
|
63
|
+
datasourceConfiguration,
|
|
64
|
+
datasourceKey
|
|
65
|
+
) {
|
|
66
|
+
if (!Array.isArray(datasourceConfiguration) || datasourceConfiguration.length === 0) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
const prefix = datasourceKey ? `Datasource '${datasourceKey}': ` : '';
|
|
70
|
+
const defsByName = systemConfigDefsByName(systemConfiguration);
|
|
71
|
+
return datasourceConfiguration.flatMap((override) =>
|
|
72
|
+
validateOverrideEntry(prefix, defsByName, override)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {{ system?: { configuration?: unknown[] }, dataSources?: Array<{ key?: string, configuration?: unknown[] }> }} manifest
|
|
78
|
+
* @returns {string[]}
|
|
79
|
+
*/
|
|
80
|
+
function validateManifestRuntimeConfiguration(manifest) {
|
|
81
|
+
const errors = [];
|
|
82
|
+
const systemConfiguration = manifest?.system?.configuration;
|
|
83
|
+
for (const ds of manifest?.dataSources || []) {
|
|
84
|
+
errors.push(
|
|
85
|
+
...validateDatasourceConfigurationOverrides(
|
|
86
|
+
systemConfiguration,
|
|
87
|
+
ds?.configuration,
|
|
88
|
+
ds?.key
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
return errors;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = {
|
|
96
|
+
validateDatasourceConfigurationOverrides,
|
|
97
|
+
validateManifestRuntimeConfiguration
|
|
98
|
+
};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dimensions (ABAC) display helpers for validate-display.
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { loadConfigFile } = require('../utils/config-format');
|
|
10
|
+
const { flattenRootDimensionsForDisplay } = require('./dimension-display-helpers');
|
|
11
|
+
const { formatDatasourceListRow } = require('../utils/cli-test-layout-chalk');
|
|
12
|
+
const logger = require('../utils/logger');
|
|
13
|
+
const {
|
|
14
|
+
logSectionTitle,
|
|
15
|
+
logWarnRow,
|
|
16
|
+
logDimLine
|
|
17
|
+
} = require('./validate-display-log-helpers');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* True when datasource is orchestration-only (no ABAC dimensions contract).
|
|
21
|
+
* @param {string} filePath - Path to datasource JSON
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
*/
|
|
24
|
+
function isOrchestrationOnlyDatasource(filePath) {
|
|
25
|
+
try {
|
|
26
|
+
const parsed = loadConfigFile(filePath);
|
|
27
|
+
return String(parsed?.entityType || '').trim() === 'none';
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Extracts dimensions from a datasource file for CLI display.
|
|
35
|
+
* Local bindings become `metadata.<field>`; FK bindings become `fk:<fk>→<dimension>...` plus optional `(actor: ...)`.
|
|
36
|
+
* @function extractDimensionsFromDatasource
|
|
37
|
+
* @param {string} filePath - Path to datasource file
|
|
38
|
+
* @returns {Object} Dimensions info { dimensions: Object, dimensionKeys: string[], hasDimensions: boolean }
|
|
39
|
+
*/
|
|
40
|
+
function extractDimensionsFromDatasource(filePath) {
|
|
41
|
+
try {
|
|
42
|
+
const parsed = loadConfigFile(filePath);
|
|
43
|
+
|
|
44
|
+
const rootFlat = flattenRootDimensionsForDisplay(parsed.dimensions);
|
|
45
|
+
const abacDimensions = parsed.abac?.dimensions || {};
|
|
46
|
+
const allDimensions = { ...rootFlat, ...abacDimensions };
|
|
47
|
+
const dimensionKeys = Object.keys(allDimensions);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
dimensions: allDimensions,
|
|
51
|
+
dimensionKeys,
|
|
52
|
+
hasDimensions: dimensionKeys.length > 0
|
|
53
|
+
};
|
|
54
|
+
} catch {
|
|
55
|
+
return { dimensions: {}, dimensionKeys: [], hasDimensions: false };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Displays Dimensions (ABAC) validation results for datasources
|
|
61
|
+
* @function displayDimensionsValidation
|
|
62
|
+
* @param {Array} externalFiles - External files validation results
|
|
63
|
+
* @returns {Array} Warnings to add to aggregated warnings
|
|
64
|
+
*/
|
|
65
|
+
function displayDimensionsValidation(externalFiles) {
|
|
66
|
+
if (!externalFiles || externalFiles.length === 0) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const datasourceFiles = externalFiles.filter(f =>
|
|
71
|
+
f.type === 'datasource' || f.type === 'external-datasource'
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (datasourceFiles.length === 0) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
logSectionTitle('Dimensions (ABAC)');
|
|
79
|
+
|
|
80
|
+
const warnings = [];
|
|
81
|
+
let anyDatasourceHasDimensions = false;
|
|
82
|
+
|
|
83
|
+
datasourceFiles.forEach(file => {
|
|
84
|
+
if (file.path && isOrchestrationOnlyDatasource(file.path)) {
|
|
85
|
+
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
86
|
+
logDimLine('orchestration-only (entityType=none) — dimensions N/A');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const dimensionsInfo = extractDimensionsFromDatasource(file.path);
|
|
90
|
+
|
|
91
|
+
if (dimensionsInfo.hasDimensions) {
|
|
92
|
+
anyDatasourceHasDimensions = true;
|
|
93
|
+
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
94
|
+
dimensionsInfo.dimensionKeys.forEach(key => {
|
|
95
|
+
const mapping = dimensionsInfo.dimensions[key];
|
|
96
|
+
logDimLine(`${key} → ${mapping}`);
|
|
97
|
+
});
|
|
98
|
+
} else {
|
|
99
|
+
logWarnRow(`${file.file} — no dimensions configured`);
|
|
100
|
+
warnings.push(`${file.file} - no dimensions configured, ABAC filtering disabled`);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (!anyDatasourceHasDimensions && datasourceFiles.some(
|
|
105
|
+
(file) => !(file.path && isOrchestrationOnlyDatasource(file.path))
|
|
106
|
+
)) {
|
|
107
|
+
logWarnRow('No dimensions configured — ABAC filtering disabled for all datasources');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return warnings;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Displays dimensions validation for datasources
|
|
115
|
+
* @function displayDimensionsStep
|
|
116
|
+
* @param {Array} datasourceFiles - Datasource files
|
|
117
|
+
* @returns {void}
|
|
118
|
+
*/
|
|
119
|
+
function displayDimensionsStep(datasourceFiles) {
|
|
120
|
+
if (datasourceFiles.length === 0) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
logSectionTitle('Dimensions (ABAC)');
|
|
125
|
+
datasourceFiles.forEach(file => {
|
|
126
|
+
try {
|
|
127
|
+
const dsPath = file.path || file.file;
|
|
128
|
+
if (dsPath && isOrchestrationOnlyDatasource(dsPath)) {
|
|
129
|
+
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
130
|
+
logDimLine('orchestration-only (entityType=none) — dimensions N/A');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const dimensionsInfo = extractDimensionsFromDatasource(dsPath);
|
|
134
|
+
if (dimensionsInfo.hasDimensions) {
|
|
135
|
+
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
136
|
+
dimensionsInfo.dimensionKeys.forEach(key => {
|
|
137
|
+
const mapping = dimensionsInfo.dimensions[key];
|
|
138
|
+
logDimLine(`${key} → ${mapping}`);
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
logWarnRow(`${file.file} — no dimensions configured`);
|
|
142
|
+
}
|
|
143
|
+
} catch {
|
|
144
|
+
// Skip if file path not available
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = {
|
|
150
|
+
isOrchestrationOnlyDatasource,
|
|
151
|
+
extractDimensionsFromDatasource,
|
|
152
|
+
displayDimensionsValidation,
|
|
153
|
+
displayDimensionsStep
|
|
154
|
+
};
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Section renderers for validate-display (application, files, RBAC, manifest).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
const logger = require('../utils/logger');
|
|
11
|
+
const {
|
|
12
|
+
headerKeyValue,
|
|
13
|
+
formatDatasourceListRow,
|
|
14
|
+
formatBlockingError,
|
|
15
|
+
successGlyph,
|
|
16
|
+
failureGlyph
|
|
17
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
18
|
+
const {
|
|
19
|
+
logSectionTitle,
|
|
20
|
+
logOkRowRest,
|
|
21
|
+
logErrorDetail
|
|
22
|
+
} = require('./validate-display-log-helpers');
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Displays application validation results
|
|
26
|
+
* @function displayApplicationValidation
|
|
27
|
+
* @param {Object} application - Application validation result
|
|
28
|
+
*/
|
|
29
|
+
function displayApplicationValidation(application) {
|
|
30
|
+
if (!application) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
logSectionTitle('Application');
|
|
35
|
+
if (application.valid) {
|
|
36
|
+
logOkRowRest('Application configuration is valid');
|
|
37
|
+
} else {
|
|
38
|
+
logger.log(` ${failureGlyph()} ${chalk.red('Application configuration has errors:')}`);
|
|
39
|
+
if (application.errors && application.errors.length > 0) {
|
|
40
|
+
application.errors.forEach(error => {
|
|
41
|
+
logErrorDetail(error);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (application.warnings && application.warnings.length > 0) {
|
|
46
|
+
application.warnings.forEach(warning => {
|
|
47
|
+
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Displays external files validation results
|
|
54
|
+
* @function displayExternalFilesValidation
|
|
55
|
+
* @param {Array} externalFiles - External files validation results
|
|
56
|
+
*/
|
|
57
|
+
function displayExternalFilesValidation(externalFiles) {
|
|
58
|
+
if (!externalFiles || externalFiles.length === 0) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
logSectionTitle('External integration files');
|
|
63
|
+
externalFiles.forEach(file => {
|
|
64
|
+
if (file.valid) {
|
|
65
|
+
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
66
|
+
} else {
|
|
67
|
+
logger.log(formatDatasourceListRow('fail', file.file, file.type));
|
|
68
|
+
file.errors.forEach(error => {
|
|
69
|
+
logErrorDetail(error);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (file.warnings && file.warnings.length > 0) {
|
|
73
|
+
file.warnings.forEach(warning => {
|
|
74
|
+
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Displays RBAC validation results
|
|
82
|
+
* @function displayRbacValidation
|
|
83
|
+
* @param {Object} rbac - RBAC validation result
|
|
84
|
+
*/
|
|
85
|
+
function displayRbacValidation(rbac) {
|
|
86
|
+
if (!rbac) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
logSectionTitle('RBAC configuration');
|
|
91
|
+
if (rbac.valid) {
|
|
92
|
+
logOkRowRest('RBAC configuration is valid');
|
|
93
|
+
} else {
|
|
94
|
+
logger.log(` ${failureGlyph()} ${chalk.red('RBAC configuration has errors:')}`);
|
|
95
|
+
rbac.errors.forEach(error => {
|
|
96
|
+
logErrorDetail(error);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (rbac.warnings && rbac.warnings.length > 0) {
|
|
100
|
+
rbac.warnings.forEach(warning => {
|
|
101
|
+
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Displays file validation results (for direct file validation)
|
|
108
|
+
* @function displayFileValidation
|
|
109
|
+
* @param {Object} result - Validation result
|
|
110
|
+
*/
|
|
111
|
+
function displayFileValidation(result) {
|
|
112
|
+
if (!result.file) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
logSectionTitle('File');
|
|
117
|
+
logger.log(` ${headerKeyValue('Path:', result.file)}`);
|
|
118
|
+
logger.log(` ${headerKeyValue('Type:', String(result.type))}`);
|
|
119
|
+
if (result.valid) {
|
|
120
|
+
logOkRowRest('File is valid');
|
|
121
|
+
} else {
|
|
122
|
+
logger.log(` ${failureGlyph()} ${chalk.red('File has errors:')}`);
|
|
123
|
+
result.errors.forEach(error => {
|
|
124
|
+
logErrorDetail(error);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
128
|
+
result.warnings.forEach(warning => {
|
|
129
|
+
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Displays aggregated warnings
|
|
136
|
+
* @function displayAggregatedWarnings
|
|
137
|
+
* @param {Array} warnings - Array of warning messages
|
|
138
|
+
*/
|
|
139
|
+
function displayAggregatedWarnings(warnings) {
|
|
140
|
+
if (!warnings || warnings.length === 0) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
logSectionTitle('Warnings');
|
|
145
|
+
warnings.forEach(warning => {
|
|
146
|
+
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Displays application validation step
|
|
152
|
+
* @function displayApplicationStep
|
|
153
|
+
* @param {Object} application - Application validation result
|
|
154
|
+
* @returns {void}
|
|
155
|
+
*/
|
|
156
|
+
function displayApplicationStep(application) {
|
|
157
|
+
logSectionTitle('Application');
|
|
158
|
+
if (application.valid) {
|
|
159
|
+
logOkRowRest('Application configuration is valid');
|
|
160
|
+
} else {
|
|
161
|
+
logger.log(` ${failureGlyph()} ${chalk.red('Application configuration has errors:')}`);
|
|
162
|
+
application.errors.forEach(error => {
|
|
163
|
+
logErrorDetail(error);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (application.warnings && application.warnings.length > 0) {
|
|
167
|
+
application.warnings.forEach(warning => {
|
|
168
|
+
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Displays external integration files step
|
|
175
|
+
* @function displayComponentsStep
|
|
176
|
+
* @param {Object} components - Components validation result
|
|
177
|
+
* @returns {void}
|
|
178
|
+
*/
|
|
179
|
+
function displayComponentsStep(components) {
|
|
180
|
+
const hasFiles = components.files && components.files.length > 0;
|
|
181
|
+
const hasErrors = components.errors && components.errors.length > 0;
|
|
182
|
+
if (!hasFiles && !hasErrors) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
logSectionTitle('External integration files');
|
|
187
|
+
if (hasFiles) {
|
|
188
|
+
components.files.forEach(file => {
|
|
189
|
+
if (file.valid) {
|
|
190
|
+
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
191
|
+
} else {
|
|
192
|
+
logger.log(formatDatasourceListRow('fail', file.file, file.type));
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
if (hasErrors) {
|
|
197
|
+
components.errors.forEach(error => {
|
|
198
|
+
logger.log(formatBlockingError(error));
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Displays deployment manifest step
|
|
205
|
+
* @function displayManifestStep
|
|
206
|
+
* @param {Object} manifest - Manifest validation result
|
|
207
|
+
* @param {Array} componentFiles - Component files
|
|
208
|
+
* @returns {void}
|
|
209
|
+
*/
|
|
210
|
+
function displayManifestStep(manifest, componentFiles) {
|
|
211
|
+
logSectionTitle('Deployment manifest');
|
|
212
|
+
if (manifest.skipped) {
|
|
213
|
+
logger.log(` ${chalk.gray('⏭')} ${chalk.white('Skipped (fix errors above first)')}`);
|
|
214
|
+
} else if (manifest.valid) {
|
|
215
|
+
logOkRowRest('Full deployment manifest is valid');
|
|
216
|
+
if (componentFiles) {
|
|
217
|
+
const datasourceFiles = componentFiles.filter(f => f.type === 'datasource' || f.type === 'external-datasource');
|
|
218
|
+
logger.log(` ${successGlyph()} ${chalk.white('System configuration valid')}`);
|
|
219
|
+
logger.log(` ${successGlyph()} ${chalk.white(`${datasourceFiles.length} datasource(s) valid`)}`);
|
|
220
|
+
logger.log(` ${successGlyph()} ${chalk.white('Schema validation passed')}`);
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
logger.log(` ${failureGlyph()} ${chalk.red('Full deployment manifest validation failed:')}`);
|
|
224
|
+
const errs = manifest.errors && manifest.errors.length > 0 ? manifest.errors : [];
|
|
225
|
+
if (errs.length > 0) {
|
|
226
|
+
errs.forEach(error => {
|
|
227
|
+
const msg = typeof error === 'string' ? error : String(error);
|
|
228
|
+
logErrorDetail(msg);
|
|
229
|
+
});
|
|
230
|
+
} else {
|
|
231
|
+
logErrorDetail('No error details available (check schema and manifest structure).');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (manifest.warnings && manifest.warnings.length > 0) {
|
|
235
|
+
manifest.warnings.forEach(warning => {
|
|
236
|
+
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Displays overall validation status
|
|
243
|
+
* @param {Object} result - Validation result
|
|
244
|
+
*/
|
|
245
|
+
function displayOverallStatus(result) {
|
|
246
|
+
let hasErrors = result.errors && result.errors.length > 0;
|
|
247
|
+
if (!hasErrors && result.steps) {
|
|
248
|
+
const stepErrors = [result.steps.application, result.steps.components, result.steps.manifest]
|
|
249
|
+
.filter(Boolean)
|
|
250
|
+
.some(s => s.errors && s.errors.length > 0);
|
|
251
|
+
if (stepErrors) {
|
|
252
|
+
hasErrors = true;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const hasWarnings = result.warnings && result.warnings.length > 0;
|
|
256
|
+
logger.log('');
|
|
257
|
+
if (hasErrors) {
|
|
258
|
+
logger.log(headerKeyValue('Overall:', chalk.red('Failed')));
|
|
259
|
+
} else if (hasWarnings) {
|
|
260
|
+
logger.log(headerKeyValue('Overall:', chalk.yellow('Passed with warnings')));
|
|
261
|
+
} else {
|
|
262
|
+
logger.log(headerKeyValue('Overall:', chalk.green('Passed')));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
module.exports = {
|
|
267
|
+
displayApplicationValidation,
|
|
268
|
+
displayExternalFilesValidation,
|
|
269
|
+
displayRbacValidation,
|
|
270
|
+
displayFileValidation,
|
|
271
|
+
displayAggregatedWarnings,
|
|
272
|
+
displayApplicationStep,
|
|
273
|
+
displayComponentsStep,
|
|
274
|
+
displayManifestStep,
|
|
275
|
+
displayOverallStatus
|
|
276
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Step-by-step validation display for external-system validate flow.
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const logger = require('../utils/logger');
|
|
11
|
+
const {
|
|
12
|
+
metadata,
|
|
13
|
+
formatBlockingError,
|
|
14
|
+
formatSuccessParagraph
|
|
15
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
16
|
+
const {
|
|
17
|
+
displayApplicationStep,
|
|
18
|
+
displayComponentsStep,
|
|
19
|
+
displayManifestStep,
|
|
20
|
+
displayRbacValidation,
|
|
21
|
+
displayAggregatedWarnings,
|
|
22
|
+
displayOverallStatus
|
|
23
|
+
} = require('./validate-display-sections');
|
|
24
|
+
const { displayDimensionsStep } = require('./validate-display-dimensions');
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Displays step-by-step validation results for external systems
|
|
28
|
+
* @function displayStepByStepValidation
|
|
29
|
+
* @param {Object} result - Validation result with steps
|
|
30
|
+
*/
|
|
31
|
+
function displayStepByStepValidation(result) {
|
|
32
|
+
if (result.valid) {
|
|
33
|
+
logger.log(formatSuccessParagraph('Validation passed!'));
|
|
34
|
+
} else {
|
|
35
|
+
logger.log(`\n${formatBlockingError('Validation failed!')}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
displayApplicationStep(result.steps.application);
|
|
39
|
+
|
|
40
|
+
if (!result.steps.components.valid || (result.steps.components.files && result.steps.components.files.length > 0)) {
|
|
41
|
+
displayComponentsStep(result.steps.components);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const datasourceFiles = result.steps.components.files?.filter(f =>
|
|
45
|
+
f.type === 'datasource' || f.type === 'external-datasource'
|
|
46
|
+
) || [];
|
|
47
|
+
displayDimensionsStep(datasourceFiles);
|
|
48
|
+
|
|
49
|
+
if (result.rbac) {
|
|
50
|
+
displayRbacValidation(result.rbac);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
displayManifestStep(result.steps.manifest, result.steps.components.files);
|
|
54
|
+
|
|
55
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
56
|
+
displayAggregatedWarnings(result.warnings);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
displayOverallStatus(result);
|
|
60
|
+
if (result.appPath) {
|
|
61
|
+
logger.log(`\n${metadata(path.resolve(result.appPath))}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = {
|
|
66
|
+
displayStepByStepValidation
|
|
67
|
+
};
|