@aifabrix/builder 2.45.5 → 2.46.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/cli-layout.mdc +2 -0
- package/.cursor/rules/cli-product-neutral.mdc +43 -0
- package/.cursor/rules/project-rules.mdc +1 -0
- package/README.md +43 -17
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
- package/jest.config.default.js +2 -1
- package/jest.config.isolated.js +2 -1
- package/jest.global-live-fabrix-hooks.js +36 -0
- package/jest.isolated-projects.js +130 -0
- package/jest.projects.js +41 -136
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/index.js +43 -3
- package/lib/api/lifecycle.api.js +77 -0
- package/lib/api/pipeline.api.js +3 -1
- package/lib/api/records-bulk.api.js +14 -1
- package/lib/api/validation-runner.js +3 -1
- package/lib/app/deploy-config.js +4 -1
- package/lib/app/down.js +20 -1
- package/lib/app/push.js +4 -5
- package/lib/app/register.js +7 -4
- package/lib/app/run-env-compose.js +84 -30
- package/lib/build/index.js +5 -0
- package/lib/certification/sync-system-certification.js +13 -6
- package/lib/cli/index.js +4 -0
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +84 -81
- package/lib/cli/setup-app.help.js +0 -31
- package/lib/cli/setup-app.js +28 -2
- package/lib/cli/setup-app.test-commands.js +5 -57
- package/lib/cli/setup-auth.js +25 -0
- package/lib/cli/setup-certification-commands.js +147 -0
- package/lib/cli/setup-certification.help.js +141 -0
- package/lib/cli/setup-environment.js +19 -2
- package/lib/cli/setup-external-system-help.js +62 -0
- package/lib/cli/setup-external-system.js +25 -3
- package/lib/cli/setup-infra.js +9 -1
- package/lib/cli/setup-platform.js +6 -1
- package/lib/cli/setup-secrets.js +33 -1
- package/lib/cli/setup-utility-help-after.js +22 -2
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +40 -4
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +4 -239
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +58 -20
- package/lib/commands/auth-status.js +41 -47
- package/lib/commands/datasource-test-trust-cli.js +27 -23
- package/lib/commands/datasource-unified-test-cli.js +6 -3
- package/lib/commands/datasource-unified-test-cli.options.js +5 -1
- package/lib/commands/datasource.js +7 -7
- package/lib/commands/dev-show-display.js +8 -1
- package/lib/commands/governance-cli-shared.js +94 -0
- package/lib/commands/governance-command-action.js +132 -0
- package/lib/commands/governance-download-external.js +34 -0
- package/lib/commands/governance-generate-external.js +71 -0
- package/lib/commands/governance-upload-external.js +36 -0
- package/lib/commands/governance-verify-external.js +64 -0
- package/lib/commands/governance.js +144 -0
- package/lib/commands/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +11 -2
- package/lib/commands/repair-auth-apply.js +127 -0
- package/lib/commands/repair-changed-files.js +41 -0
- package/lib/commands/repair-datasource-keys.js +4 -1
- package/lib/commands/repair-datasource-run.js +59 -0
- package/lib/commands/repair-datasource-test-payload.js +259 -0
- package/lib/commands/repair-datasource.js +1 -51
- package/lib/commands/repair-env-template.js +64 -13
- package/lib/commands/repair-external-run.js +216 -0
- package/lib/commands/repair-openapi-sync.js +23 -0
- package/lib/commands/repair-persist.js +4 -0
- package/lib/commands/repair-rbac.js +52 -1
- package/lib/commands/repair-steps.js +145 -0
- package/lib/commands/repair.js +29 -296
- package/lib/commands/secrets-get.js +184 -0
- package/lib/commands/secrets-remove-all.js +3 -1
- package/lib/commands/setup-image-refresh.js +146 -0
- package/lib/commands/setup-modes.js +158 -162
- package/lib/commands/setup-platform-auth.js +76 -0
- package/lib/commands/setup-prompts-admin.js +244 -0
- package/lib/commands/setup-prompts-platform-mode.js +67 -0
- package/lib/commands/setup-prompts-validators.js +36 -0
- package/lib/commands/setup-prompts.js +24 -76
- package/lib/commands/setup-run-context.js +45 -0
- package/lib/commands/setup-spinners.js +39 -0
- package/lib/commands/setup.js +27 -5
- package/lib/commands/teardown.js +39 -0
- package/lib/commands/test-e2e-external.js +24 -8
- package/lib/commands/test-governance-external.js +3 -24
- package/lib/commands/test-trust-external.js +20 -21
- package/lib/commands/up-common.js +25 -13
- package/lib/commands/up-dataplane.js +50 -13
- package/lib/commands/upload-publish-context.js +75 -0
- package/lib/commands/upload-sidecar-followups.js +89 -0
- package/lib/commands/upload.js +90 -108
- package/lib/commands/verify-governance-combined-external.js +61 -0
- package/lib/commands/verify-governance-command-action.js +64 -0
- package/lib/commands/verify-governance-db.js +102 -0
- package/lib/commands/verify-governance-external.js +77 -0
- package/lib/commands/verify-governance-result-builders.js +71 -0
- package/lib/commands/verify-operations-command-action.js +68 -0
- package/lib/commands/verify-operations-external.js +268 -0
- package/lib/commands/verify-operations-persist.js +75 -0
- package/lib/commands/verify-operations-step-plan.js +68 -0
- package/lib/commands/verify-operations-steps.js +111 -0
- package/lib/commands/verify-trust-command-action.js +70 -0
- package/lib/commands/verify-trust-external.js +67 -0
- package/lib/commands/wizard-config-normalizer.js +43 -23
- package/lib/commands/wizard-core.js +2 -0
- package/lib/core/admin-password-generator.js +38 -0
- package/lib/core/admin-secrets-bundle.js +111 -0
- package/lib/core/admin-secrets-env-overlay.js +62 -0
- package/lib/core/admin-secrets.js +32 -4
- package/lib/core/config-attach-extensions.js +3 -0
- package/lib/core/config-platform-controller.js +44 -0
- package/lib/core/config-setup-installation-profile.js +42 -0
- package/lib/core/config-setup-platform-mode.js +46 -0
- package/lib/core/config.js +46 -36
- package/lib/core/secrets-admin-env.js +6 -2
- package/lib/core/secrets-ensure.js +4 -0
- package/lib/core/secrets-env-content.js +54 -48
- package/lib/core/secrets-env-write.js +10 -1
- package/lib/core/secrets-infra-placeholder-sync.js +2 -0
- package/lib/core/setup-installation-profile.js +43 -0
- package/lib/core/setup-platform-mode.js +55 -0
- package/lib/datasource/agent-trust-debug-log.js +1 -1
- package/lib/datasource/agent-trust-run.js +5 -3
- package/lib/datasource/audit-evidence-extract-debug.js +30 -18
- package/lib/datasource/audit-evidence-extract.js +7 -4
- package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
- package/lib/datasource/bulk-loader-run-batches.js +15 -3
- package/lib/datasource/datasource-load-export-context.js +3 -0
- package/lib/datasource/log-cleaner.js +2 -2
- package/lib/datasource/log-viewer.js +8 -8
- package/lib/datasource/test-e2e.js +4 -1
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run.js +5 -2
- package/lib/deployment/environment-poll-status.js +138 -0
- package/lib/deployment/environment.js +42 -34
- package/lib/external-system/download.js +21 -20
- package/lib/external-system/generator.js +5 -1
- package/lib/external-system/integration-auth-context.js +45 -0
- package/lib/external-system/test-auth.js +12 -5
- package/lib/external-system/test.js +6 -6
- package/lib/generator/external-controller-manifest.js +15 -0
- package/lib/governance/governance-cli-errors.js +96 -0
- package/lib/governance/governance-download-display.js +38 -0
- package/lib/governance/governance-run-display.js +215 -25
- package/lib/infrastructure/admin-secrets-apply.js +84 -0
- package/lib/infrastructure/admin-secrets-ensure.js +130 -0
- package/lib/infrastructure/admin-secrets-resolve.js +95 -0
- package/lib/infrastructure/admin-secrets-sync.js +91 -0
- package/lib/infrastructure/helpers.js +23 -129
- package/lib/infrastructure/index.js +5 -6
- package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
- package/lib/lifecycle/certification-progress.js +231 -0
- package/lib/lifecycle/dataplane-ui-url.js +145 -0
- package/lib/lifecycle/exit-codes.js +24 -0
- package/lib/lifecycle/json-envelope.js +25 -0
- package/lib/lifecycle/lifecycle-governance-options.js +51 -0
- package/lib/lifecycle/logger-quiet.js +29 -0
- package/lib/lifecycle/open-api-published.js +59 -0
- package/lib/lifecycle/operations-readiness-metrics.js +101 -0
- package/lib/lifecycle/product-model.js +196 -0
- package/lib/lifecycle/report-display.js +471 -0
- package/lib/lifecycle/scenario-upload.js +191 -0
- package/lib/lifecycle/verify-step-progress.js +87 -0
- package/lib/parameters/infra-kv-discovery.js +27 -2
- package/lib/protection/auth-context.js +10 -4
- package/lib/schema/application-schema.json +1 -1
- package/lib/schema/datasource-test-run.schema.json +89 -6
- package/lib/schema/external-datasource.schema.json +2636 -2622
- package/lib/schema/external-system.schema.json +1089 -761
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/type/credential-field-registry.json +103 -97
- package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
- package/lib/utils/api.js +55 -31
- package/lib/utils/app-relative-path-env.js +112 -0
- package/lib/utils/cli-secrets-error-format.js +83 -21
- package/lib/utils/cli-utils.js +16 -4
- package/lib/utils/compose-generate-docker-compose.js +4 -0
- package/lib/utils/compose-traefik-ingress-base.js +16 -1
- package/lib/utils/config-secrets-path.js +46 -0
- package/lib/utils/controller-url.js +88 -1
- package/lib/utils/credential-secrets-env.js +137 -9
- package/lib/utils/dataplane-resolver.js +129 -2
- package/lib/utils/declarative-url-ports.js +3 -3
- package/lib/utils/deployment-auth-mode.js +41 -0
- package/lib/utils/developer-volume-id.js +33 -0
- package/lib/utils/env-copy.js +14 -9
- package/lib/utils/env-kv-orphan-lines.js +43 -0
- package/lib/utils/error-formatters/network-errors.js +13 -4
- package/lib/utils/external-env-template.js +1 -0
- package/lib/utils/external-system-readiness-core.js +10 -0
- package/lib/utils/external-system-readiness-display.js +80 -23
- package/lib/utils/health-check.js +4 -1
- package/lib/utils/help-builder.js +11 -8
- package/lib/utils/keycloak-realm-ready.js +101 -0
- package/lib/utils/load-cip-capacity-display-config.js +61 -15
- package/lib/utils/manifest-source-emit.js +2 -0
- package/lib/utils/pipeline-upload-auth-retry.js +82 -0
- package/lib/utils/platform-controller-url.js +156 -0
- package/lib/utils/postgres-platform-bootstrap.js +199 -0
- package/lib/utils/postgres-wipe.js +9 -2
- package/lib/utils/resolve-env-mode.js +47 -0
- package/lib/utils/secrets-generator.js +31 -25
- package/lib/utils/secrets-missing-error.js +164 -0
- package/lib/utils/service-url-label.js +81 -0
- package/lib/utils/setup-quiet-output.js +25 -0
- package/lib/utils/template-helpers.js +15 -0
- package/lib/utils/token-manager-client-credentials.js +201 -0
- package/lib/utils/token-manager-messages.js +8 -0
- package/lib/utils/token-manager-refresh.js +12 -2
- package/lib/utils/token-manager.js +86 -105
- package/lib/utils/upload-pipeline-ui.js +12 -5
- package/lib/utils/upload-sync-options.js +42 -0
- package/lib/utils/url-declarative-public-base.js +21 -3
- package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
- package/lib/utils/validation-poll-ui.js +8 -0
- package/lib/utils/validation-run-stage.js +45 -0
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +2 -1
- package/templates/applications/dataplane/env.template +24 -1
- package/templates/applications/miso-controller/env.template +16 -0
- package/templates/external-system/README.md.hbs +74 -17
- package/templates/python/docker-compose.hbs +19 -18
- package/templates/typescript/docker-compose.hbs +18 -17
- package/lib/commands/test-governance-command-action.js +0 -55
- package/lib/commands/test-trust-command-action.js +0 -118
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Throw CLI errors from ApiClient responses with formatted output preserved.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Dataplane/controller API failure helpers
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const { formatApiError } = require('../utils/api-error-handler');
|
|
12
|
+
const {
|
|
13
|
+
enrichUnresolvableGovernanceSubjectsError
|
|
14
|
+
} = require('../governance/governance-cli-errors');
|
|
15
|
+
const { inferServiceLabelFromUrl } = require('../utils/service-url-label');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {Object|undefined} res - ApiClient response
|
|
19
|
+
* @param {string} fallbackMessage
|
|
20
|
+
* @returns {string}
|
|
21
|
+
*/
|
|
22
|
+
function resolveApiErrorMessage(res, fallbackMessage) {
|
|
23
|
+
if (!res) {
|
|
24
|
+
return fallbackMessage;
|
|
25
|
+
}
|
|
26
|
+
const fromError =
|
|
27
|
+
res.error &&
|
|
28
|
+
(res.error.formattedError || res.error.error || res.error.message);
|
|
29
|
+
return (
|
|
30
|
+
res.formattedError ||
|
|
31
|
+
fromError ||
|
|
32
|
+
(typeof res.error === 'string' ? res.error : null) ||
|
|
33
|
+
fallbackMessage
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {Object|undefined} res
|
|
39
|
+
* @param {string} endpointUrl
|
|
40
|
+
* @returns {{ endpoint: string, serviceLabel: string }}
|
|
41
|
+
*/
|
|
42
|
+
function resolveApiFailureEndpointContext(res, endpointUrl) {
|
|
43
|
+
const endpoint =
|
|
44
|
+
(res && res.errorData && res.errorData.endpointUrl) || endpointUrl || '';
|
|
45
|
+
const serviceLabel =
|
|
46
|
+
(res && res.errorData && res.errorData.serviceLabel) ||
|
|
47
|
+
inferServiceLabelFromUrl(endpoint);
|
|
48
|
+
return { endpoint, serviceLabel };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {Object|undefined} res
|
|
53
|
+
* @param {string} endpoint
|
|
54
|
+
* @param {string} serviceLabel
|
|
55
|
+
* @returns {Object}
|
|
56
|
+
*/
|
|
57
|
+
function buildEnrichedApiFailureResponse(res, endpoint, serviceLabel) {
|
|
58
|
+
return {
|
|
59
|
+
...res,
|
|
60
|
+
errorData: {
|
|
61
|
+
...(res && res.errorData),
|
|
62
|
+
endpointUrl: endpoint,
|
|
63
|
+
serviceLabel
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param {Error} err
|
|
70
|
+
* @param {Object|undefined} res
|
|
71
|
+
* @param {string} endpoint
|
|
72
|
+
* @param {string} serviceLabel
|
|
73
|
+
* @param {Object} enriched
|
|
74
|
+
*/
|
|
75
|
+
function assignApiFailureErrorFields(err, res, endpoint, serviceLabel, enriched) {
|
|
76
|
+
err.formatted =
|
|
77
|
+
res && res.formattedError ? res.formattedError : formatApiError(enriched, null);
|
|
78
|
+
err.network = Boolean(res && res.network === true);
|
|
79
|
+
err.status = res && typeof res.status === 'number' ? res.status : 0;
|
|
80
|
+
err.endpointUrl = endpoint;
|
|
81
|
+
err.serviceLabel = serviceLabel;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {Object|undefined} res
|
|
86
|
+
* @param {string} endpointUrl
|
|
87
|
+
* @returns {Error}
|
|
88
|
+
*/
|
|
89
|
+
function buildApiFailureError(res, endpointUrl, context = {}) {
|
|
90
|
+
const message = resolveApiErrorMessage(res, 'Request failed');
|
|
91
|
+
const err = new Error(message);
|
|
92
|
+
const { endpoint, serviceLabel } = resolveApiFailureEndpointContext(res, endpointUrl);
|
|
93
|
+
const enriched = buildEnrichedApiFailureResponse(res, endpoint, serviceLabel);
|
|
94
|
+
assignApiFailureErrorFields(err, res, endpoint, serviceLabel, enriched);
|
|
95
|
+
if (
|
|
96
|
+
typeof endpoint === 'string' &&
|
|
97
|
+
endpoint.includes('/governance-scenarios/generate')
|
|
98
|
+
) {
|
|
99
|
+
enrichUnresolvableGovernanceSubjectsError(err, context);
|
|
100
|
+
}
|
|
101
|
+
return err;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @param {Object} res - ApiClient response (`success: false`)
|
|
106
|
+
* @param {{ fallbackMessage?: string, endpointUrl?: string }} [context]
|
|
107
|
+
* @throws {Error}
|
|
108
|
+
*/
|
|
109
|
+
function throwIfApiFailed(res, context = {}) {
|
|
110
|
+
if (!res || res.success !== false) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const endpointUrl =
|
|
114
|
+
context.endpointUrl ||
|
|
115
|
+
(res.errorData && res.errorData.endpointUrl) ||
|
|
116
|
+
'';
|
|
117
|
+
throw buildApiFailureError(res, endpointUrl || context.endpointUrl || '', context);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = {
|
|
121
|
+
throwIfApiFailed,
|
|
122
|
+
buildApiFailureError,
|
|
123
|
+
resolveApiErrorMessage
|
|
124
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dataplane governance scenario pack CRUD + run API (419.0).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { createDataplaneApiClient } = require('./index');
|
|
10
|
+
const { throwIfApiFailed } = require('./api-response-errors');
|
|
11
|
+
const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
12
|
+
const {
|
|
13
|
+
governanceUploadSchemaHint,
|
|
14
|
+
isGovernanceCoverageSchemaError
|
|
15
|
+
} = require('../governance/governance-cli-errors');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} dataplaneUrl
|
|
19
|
+
* @param {string} datasourceKey
|
|
20
|
+
* @param {string} suffix
|
|
21
|
+
* @returns {string}
|
|
22
|
+
*/
|
|
23
|
+
function governanceScenarioEndpoint(dataplaneUrl, datasourceKey, suffix) {
|
|
24
|
+
const base = String(dataplaneUrl || '').replace(/\/$/, '');
|
|
25
|
+
return `${base}/api/v1/external/${encodeURIComponent(datasourceKey)}${suffix}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* PUT /api/v1/external/{datasourceKey}/governance-scenarios
|
|
30
|
+
* @requiresPermission {Dataplane} external-data-source:update
|
|
31
|
+
* @async
|
|
32
|
+
*/
|
|
33
|
+
async function upsertDatasourceGovernancePack(dataplaneUrl, authConfig, datasourceKey, pack) {
|
|
34
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
35
|
+
const res = await client.put(
|
|
36
|
+
`/api/v1/external/${encodeURIComponent(datasourceKey)}/governance-scenarios`,
|
|
37
|
+
{ body: { pack } }
|
|
38
|
+
);
|
|
39
|
+
if (res && res.success === false) {
|
|
40
|
+
try {
|
|
41
|
+
throwIfApiFailed(res, {
|
|
42
|
+
endpointUrl: governanceScenarioEndpoint(
|
|
43
|
+
dataplaneUrl,
|
|
44
|
+
datasourceKey,
|
|
45
|
+
'/governance-scenarios'
|
|
46
|
+
)
|
|
47
|
+
});
|
|
48
|
+
} catch (err) {
|
|
49
|
+
if (isGovernanceCoverageSchemaError(err)) {
|
|
50
|
+
err.friendlyHint = governanceUploadSchemaHint(
|
|
51
|
+
(pack && pack.spec && pack.spec.systemKey) || datasourceKey
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
throw err;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return unwrapApiData(res);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* GET /api/v1/external/{datasourceKey}/governance-scenarios
|
|
62
|
+
* @requiresPermission {Dataplane} external-data-source:read
|
|
63
|
+
* @async
|
|
64
|
+
*/
|
|
65
|
+
async function getDatasourceGovernancePack(dataplaneUrl, authConfig, datasourceKey) {
|
|
66
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
67
|
+
const res = await client.get(
|
|
68
|
+
`/api/v1/external/${encodeURIComponent(datasourceKey)}/governance-scenarios`
|
|
69
|
+
);
|
|
70
|
+
throwIfApiFailed(res, {
|
|
71
|
+
endpointUrl: governanceScenarioEndpoint(dataplaneUrl, datasourceKey, '/governance-scenarios')
|
|
72
|
+
});
|
|
73
|
+
return unwrapApiData(res);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* POST /api/v1/external/{datasourceKey}/governance-scenarios/run
|
|
78
|
+
* @requiresPermission {Dataplane} governance:evaluate
|
|
79
|
+
* @async
|
|
80
|
+
*/
|
|
81
|
+
async function runDatasourceGovernanceScenarios(dataplaneUrl, authConfig, datasourceKey) {
|
|
82
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
83
|
+
const res = await client.post(
|
|
84
|
+
`/api/v1/external/${encodeURIComponent(datasourceKey)}/governance-scenarios/run`,
|
|
85
|
+
{ body: {} }
|
|
86
|
+
);
|
|
87
|
+
throwIfApiFailed(res, {
|
|
88
|
+
endpointUrl: governanceScenarioEndpoint(
|
|
89
|
+
dataplaneUrl,
|
|
90
|
+
datasourceKey,
|
|
91
|
+
'/governance-scenarios/run'
|
|
92
|
+
)
|
|
93
|
+
});
|
|
94
|
+
const unwrapped = unwrapApiData(res);
|
|
95
|
+
if (!unwrapped || !unwrapped.summary) {
|
|
96
|
+
throw new Error('Governance scenario run returned an unexpected response shape');
|
|
97
|
+
}
|
|
98
|
+
return unwrapped;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* POST /api/v1/external/{datasourceKey}/governance-scenarios/generate
|
|
103
|
+
* @requiresPermission {Dataplane} external-data-source:update
|
|
104
|
+
* @async
|
|
105
|
+
*/
|
|
106
|
+
async function generateDatasourceGovernancePack(
|
|
107
|
+
dataplaneUrl,
|
|
108
|
+
authConfig,
|
|
109
|
+
datasourceKey,
|
|
110
|
+
body
|
|
111
|
+
) {
|
|
112
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
113
|
+
const res = await client.post(
|
|
114
|
+
`/api/v1/external/${encodeURIComponent(datasourceKey)}/governance-scenarios/generate`,
|
|
115
|
+
{ body }
|
|
116
|
+
);
|
|
117
|
+
const subjectEmails = Array.isArray(body.subjects)
|
|
118
|
+
? body.subjects
|
|
119
|
+
.map(entry => entry && entry.subjectEmail)
|
|
120
|
+
.filter(email => typeof email === 'string' && email.trim())
|
|
121
|
+
: [];
|
|
122
|
+
throwIfApiFailed(res, {
|
|
123
|
+
endpointUrl: governanceScenarioEndpoint(
|
|
124
|
+
dataplaneUrl,
|
|
125
|
+
datasourceKey,
|
|
126
|
+
'/governance-scenarios/generate'
|
|
127
|
+
),
|
|
128
|
+
subjectEmails
|
|
129
|
+
});
|
|
130
|
+
return unwrapApiData(res);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* GET /api/v1/external/{datasourceKey}/governance-scenarios/versions
|
|
135
|
+
* @requiresPermission {Dataplane} external-data-source:read
|
|
136
|
+
* @async
|
|
137
|
+
*/
|
|
138
|
+
async function listDatasourceGovernancePackVersions(dataplaneUrl, authConfig, datasourceKey) {
|
|
139
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
140
|
+
const res = await client.get(
|
|
141
|
+
`/api/v1/external/${encodeURIComponent(datasourceKey)}/governance-scenarios/versions`
|
|
142
|
+
);
|
|
143
|
+
throwIfApiFailed(res, {
|
|
144
|
+
endpointUrl: governanceScenarioEndpoint(
|
|
145
|
+
dataplaneUrl,
|
|
146
|
+
datasourceKey,
|
|
147
|
+
'/governance-scenarios/versions'
|
|
148
|
+
)
|
|
149
|
+
});
|
|
150
|
+
return unwrapApiData(res);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
module.exports = {
|
|
154
|
+
upsertDatasourceGovernancePack,
|
|
155
|
+
getDatasourceGovernancePack,
|
|
156
|
+
runDatasourceGovernanceScenarios,
|
|
157
|
+
generateDatasourceGovernancePack,
|
|
158
|
+
listDatasourceGovernancePackVersions
|
|
159
|
+
};
|
package/lib/api/index.js
CHANGED
|
@@ -14,11 +14,13 @@ const { makeApiCall, authenticatedApiCall } = require('../utils/api');
|
|
|
14
14
|
class ApiClient {
|
|
15
15
|
/**
|
|
16
16
|
* Create an API client instance.
|
|
17
|
-
* App endpoints receive token-only auth (Bearer). x-client-id/x-client-secret are
|
|
17
|
+
* App endpoints receive token-only auth (Bearer). x-client-id/x-client-secret are used only for the controller token endpoint.
|
|
18
18
|
* @param {string} baseUrl - Base URL for the API (controller URL)
|
|
19
19
|
* @param {Object} [authConfig] - Authentication configuration
|
|
20
|
-
* @param {string} [authConfig.type] - Auth type ('bearer' | 'client-token')
|
|
20
|
+
* @param {string} [authConfig.type] - Auth type ('bearer' | 'client-token' | 'client-credentials')
|
|
21
21
|
* @param {string} [authConfig.token] - Bearer token
|
|
22
|
+
* @param {string} [authConfig.clientId] - Client ID (client-credentials)
|
|
23
|
+
* @param {string} [authConfig.clientSecret] - Client secret (client-credentials)
|
|
22
24
|
*/
|
|
23
25
|
constructor(baseUrl, authConfig = {}, clientOptions = {}) {
|
|
24
26
|
if (baseUrl === null || baseUrl === undefined || typeof baseUrl !== 'string') {
|
|
@@ -87,6 +89,41 @@ class ApiClient {
|
|
|
87
89
|
return headers;
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
/**
|
|
93
|
+
* True when endpoint is the controller client-credentials token exchange.
|
|
94
|
+
* @private
|
|
95
|
+
* @param {string} endpoint - API endpoint path
|
|
96
|
+
* @returns {boolean}
|
|
97
|
+
*/
|
|
98
|
+
_isClientCredentialsTokenEndpoint(endpoint) {
|
|
99
|
+
const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
|
|
100
|
+
return path === '/api/v1/auth/token';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Add x-client-id/x-client-secret only for POST /api/v1/auth/token (never for app endpoints).
|
|
105
|
+
* @private
|
|
106
|
+
* @param {string} endpoint - API endpoint path
|
|
107
|
+
* @param {Object} headers - Request headers built by _buildHeaders
|
|
108
|
+
* @returns {Object}
|
|
109
|
+
*/
|
|
110
|
+
_applyClientCredentialHeadersForTokenEndpoint(endpoint, headers) {
|
|
111
|
+
if (this.authConfig.type !== 'client-credentials') {
|
|
112
|
+
return headers;
|
|
113
|
+
}
|
|
114
|
+
if (!this._isClientCredentialsTokenEndpoint(endpoint)) {
|
|
115
|
+
return headers;
|
|
116
|
+
}
|
|
117
|
+
const out = { ...headers };
|
|
118
|
+
if (this.authConfig.clientId) {
|
|
119
|
+
out['x-client-id'] = String(this.authConfig.clientId);
|
|
120
|
+
}
|
|
121
|
+
if (this.authConfig.clientSecret) {
|
|
122
|
+
out['x-client-secret'] = String(this.authConfig.clientSecret);
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
|
|
90
127
|
/**
|
|
91
128
|
* Make a GET request
|
|
92
129
|
* @async
|
|
@@ -141,7 +178,10 @@ class ApiClient {
|
|
|
141
178
|
async post(endpoint, options = {}) {
|
|
142
179
|
await this._ensureDataplaneCliVersionGate();
|
|
143
180
|
let url = this._buildUrl(endpoint);
|
|
144
|
-
const headers = this.
|
|
181
|
+
const headers = this._applyClientCredentialHeadersForTokenEndpoint(
|
|
182
|
+
endpoint,
|
|
183
|
+
this._buildHeaders(options.headers)
|
|
184
|
+
);
|
|
145
185
|
|
|
146
186
|
// Add query parameters if provided
|
|
147
187
|
if (options.params) {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dataplane Enterprise AI Certification lifecycle API client (419.0).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { createDataplaneApiClient } = require('./index');
|
|
10
|
+
const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* GET /api/v1/external/systems/{systemKey}/lifecycle
|
|
14
|
+
* @requiresPermission {Dataplane} external-system:read
|
|
15
|
+
* @async
|
|
16
|
+
* @param {string} dataplaneUrl
|
|
17
|
+
* @param {Object} authConfig
|
|
18
|
+
* @param {string} systemKey
|
|
19
|
+
* @param {{ details?: boolean, summary?: boolean }} [opts]
|
|
20
|
+
* @returns {Promise<Object>}
|
|
21
|
+
*/
|
|
22
|
+
async function getSystemLifecycleReport(dataplaneUrl, authConfig, systemKey, opts = {}) {
|
|
23
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
24
|
+
const params = {};
|
|
25
|
+
if (opts.details === true) params.details = true;
|
|
26
|
+
if (opts.summary === true) params.summary = true;
|
|
27
|
+
const res = await client.get(`/api/v1/external/systems/${encodeURIComponent(systemKey)}/lifecycle`, {
|
|
28
|
+
params
|
|
29
|
+
});
|
|
30
|
+
if (res && res.success === false) {
|
|
31
|
+
const msg =
|
|
32
|
+
(res.error && (res.error.formattedError || res.error.error || res.error.message)) ||
|
|
33
|
+
res.formattedError ||
|
|
34
|
+
'Lifecycle report request failed';
|
|
35
|
+
throw new Error(msg);
|
|
36
|
+
}
|
|
37
|
+
const unwrapped = unwrapApiData(res);
|
|
38
|
+
if (!unwrapped || !unwrapped.systemKey) {
|
|
39
|
+
throw new Error('Lifecycle report returned an unexpected response shape');
|
|
40
|
+
}
|
|
41
|
+
return unwrapped;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* POST /api/v1/external/systems/{systemKey}/lifecycle/run
|
|
46
|
+
* @requiresPermission {Dataplane} external-system:update
|
|
47
|
+
* @async
|
|
48
|
+
* @param {string} dataplaneUrl
|
|
49
|
+
* @param {Object} authConfig
|
|
50
|
+
* @param {string} systemKey
|
|
51
|
+
* @param {Object} [body]
|
|
52
|
+
* @returns {Promise<Object>}
|
|
53
|
+
*/
|
|
54
|
+
async function runSystemLifecycle(dataplaneUrl, authConfig, systemKey, body = {}) {
|
|
55
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
56
|
+
const res = await client.post(
|
|
57
|
+
`/api/v1/external/systems/${encodeURIComponent(systemKey)}/lifecycle/run`,
|
|
58
|
+
{ body }
|
|
59
|
+
);
|
|
60
|
+
if (res && res.success === false) {
|
|
61
|
+
const msg =
|
|
62
|
+
(res.error && (res.error.formattedError || res.error.error || res.error.message)) ||
|
|
63
|
+
res.formattedError ||
|
|
64
|
+
'Lifecycle run request failed';
|
|
65
|
+
throw new Error(msg);
|
|
66
|
+
}
|
|
67
|
+
const unwrapped = unwrapApiData(res);
|
|
68
|
+
if (!unwrapped || !unwrapped.report) {
|
|
69
|
+
throw new Error('Lifecycle run returned an unexpected response shape');
|
|
70
|
+
}
|
|
71
|
+
return unwrapped;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = {
|
|
75
|
+
getSystemLifecycleReport,
|
|
76
|
+
runSystemLifecycle
|
|
77
|
+
};
|
package/lib/api/pipeline.api.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const { ApiClient, createDataplaneApiClient } = require('./index');
|
|
8
8
|
const { postValidationRunAndOptionalPoll } = require('./validation-runner');
|
|
9
|
+
const { withStageOnValidationRunBody } = require('../utils/validation-run-stage');
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @param {Object} opts
|
|
@@ -30,7 +31,7 @@ function buildValidationRunPayloadTestBody({ validationScope, systemKey, datasou
|
|
|
30
31
|
if (validationScope === 'externalDataSource') {
|
|
31
32
|
body.datasourceKey = datasourceKey;
|
|
32
33
|
}
|
|
33
|
-
return body;
|
|
34
|
+
return withStageOnValidationRunBody(body, body.runType);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
/**
|
|
@@ -242,6 +243,7 @@ async function testDatasourceViaPipeline({ dataplaneUrl, systemKey, datasourceKe
|
|
|
242
243
|
* @param {Object} authConfig - Authentication configuration (must include token for Bearer; client id/secret rejected)
|
|
243
244
|
* @param {Object} payload - { version, application, dataSources }; optional status (default "draft")
|
|
244
245
|
* @param {string} [payload.status="draft"] - "draft" or "published"; Builder uses "draft"
|
|
246
|
+
* @param {boolean} [payload.force=false] - When true, bypass guards on active datasource publish
|
|
245
247
|
* @returns {Promise<Object>} API envelope `{ success, data }` where `data` is PublicationResult (uploadId, system, datasources, generateMcpContract, …)
|
|
246
248
|
* @throws {Error} If upload fails
|
|
247
249
|
*/
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const { createDataplaneApiClient } = require('./index');
|
|
8
|
+
const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Bulk sync external records for a datasource.
|
|
@@ -19,10 +20,22 @@ const { createDataplaneApiClient } = require('./index');
|
|
|
19
20
|
*/
|
|
20
21
|
async function bulkSyncRecords(dataplaneUrl, sourceIdOrKey, authConfig, body) {
|
|
21
22
|
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
22
|
-
|
|
23
|
+
const res = await client.post(
|
|
23
24
|
`/api/v1/data-storage/${encodeURIComponent(sourceIdOrKey)}/records/bulk`,
|
|
24
25
|
{ body }
|
|
25
26
|
);
|
|
27
|
+
if (res && res.success === false) {
|
|
28
|
+
const msg =
|
|
29
|
+
res.formattedError ||
|
|
30
|
+
res.error ||
|
|
31
|
+
`Bulk sync failed (HTTP ${res.status || 0})`;
|
|
32
|
+
throw new Error(msg);
|
|
33
|
+
}
|
|
34
|
+
const payload = unwrapApiData(res);
|
|
35
|
+
if (!payload || typeof payload !== 'object') {
|
|
36
|
+
throw new Error('Bulk sync returned an unexpected response shape');
|
|
37
|
+
}
|
|
38
|
+
return payload;
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
module.exports = {
|
|
@@ -22,6 +22,7 @@ const { createValidationPollHandlers } = require('../utils/validation-poll-ui');
|
|
|
22
22
|
* @param {boolean} opts.useAsync
|
|
23
23
|
* @param {boolean} opts.noAsync
|
|
24
24
|
* @param {boolean} [opts.verbosePoll] - Throttled poll lines when no TTY poll UI (see validation-run-poll)
|
|
25
|
+
* @param {boolean} [opts.quietPollUi] - Suppress poll spinner/lines (orchestrated verify-* owns progress)
|
|
25
26
|
* @param {Function} [opts.onPollProgress] - Extra hook: `(envelope, attemptIndex, meta)` during poll
|
|
26
27
|
* @returns {Promise<{ envelope: Object|null, apiError: Object|null, pollTimedOut: boolean, incompleteNoAsync: boolean }>}
|
|
27
28
|
*/
|
|
@@ -60,7 +61,8 @@ async function postValidationRunAndOptionalPoll(opts) {
|
|
|
60
61
|
const deadlineMs = Date.now() + remaining;
|
|
61
62
|
|
|
62
63
|
const pollUi = createValidationPollHandlers(deadlineMs, {
|
|
63
|
-
subject: opts.pollSubject
|
|
64
|
+
subject: opts.pollSubject,
|
|
65
|
+
quiet: opts.quietPollUi === true
|
|
64
66
|
});
|
|
65
67
|
const mergeOnPollProgress =
|
|
66
68
|
typeof opts.onPollProgress === 'function'
|
package/lib/app/deploy-config.js
CHANGED
|
@@ -60,7 +60,10 @@ async function extractDeploymentConfig(options, _variables) {
|
|
|
60
60
|
const { resolveEnvironment } = require('../core/config');
|
|
61
61
|
|
|
62
62
|
const controllerUrl = await resolveControllerUrl();
|
|
63
|
-
const envKey =
|
|
63
|
+
const envKey =
|
|
64
|
+
options && options.envKey
|
|
65
|
+
? String(options.envKey).trim().toLowerCase()
|
|
66
|
+
: await resolveEnvironment();
|
|
64
67
|
|
|
65
68
|
const pollIntervalExplicit =
|
|
66
69
|
options.pollInterval !== undefined && options.pollInterval !== null
|
package/lib/app/down.js
CHANGED
|
@@ -48,6 +48,8 @@ function execAsync(command, options = {}) {
|
|
|
48
48
|
* @param {number|string} developerId - Developer ID
|
|
49
49
|
* @returns {string} Docker volume name
|
|
50
50
|
*/
|
|
51
|
+
const { collectDeveloperVolumeIdSuffixes } = require('../utils/developer-volume-id');
|
|
52
|
+
|
|
51
53
|
function getAppVolumeName(appName, developerId) {
|
|
52
54
|
const idNum = typeof developerId === 'string' ? parseInt(developerId, 10) : developerId;
|
|
53
55
|
if (idNum === 0) {
|
|
@@ -56,6 +58,22 @@ function getAppVolumeName(appName, developerId) {
|
|
|
56
58
|
return `aifabrix_dev${developerId}_${appName}_data`;
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Docker volume name candidates for an app (handles dev6 vs dev06 naming drift).
|
|
63
|
+
*
|
|
64
|
+
* @param {string} appName
|
|
65
|
+
* @param {string|number} developerId
|
|
66
|
+
* @returns {string[]}
|
|
67
|
+
*/
|
|
68
|
+
function getAppVolumeNameCandidates(appName, developerId) {
|
|
69
|
+
const idNum = typeof developerId === 'string' ? parseInt(developerId, 10) : developerId;
|
|
70
|
+
if (idNum === 0) {
|
|
71
|
+
return [`aifabrix_${appName}_data`, `aifabrix_dev0_${appName}_data`];
|
|
72
|
+
}
|
|
73
|
+
const suffixes = collectDeveloperVolumeIdSuffixes(developerId);
|
|
74
|
+
return suffixes.map((suffix) => `aifabrix_dev${suffix}_${appName}_data`);
|
|
75
|
+
}
|
|
76
|
+
|
|
59
77
|
/**
|
|
60
78
|
* Stops and removes a specific application's container.
|
|
61
79
|
* If --volumes is passed, attempts to remove the app's named Docker volume.
|
|
@@ -120,6 +138,7 @@ async function downApp(appName, options = {}) {
|
|
|
120
138
|
|
|
121
139
|
module.exports = {
|
|
122
140
|
downApp,
|
|
123
|
-
getAppVolumeName
|
|
141
|
+
getAppVolumeName,
|
|
142
|
+
getAppVolumeNameCandidates
|
|
124
143
|
};
|
|
125
144
|
|
package/lib/app/push.js
CHANGED
|
@@ -19,7 +19,7 @@ const {
|
|
|
19
19
|
|
|
20
20
|
const pushUtils = require('../deployment/push');
|
|
21
21
|
const logger = require('../utils/logger');
|
|
22
|
-
const
|
|
22
|
+
const paths = require('../utils/paths');
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Validate application name format
|
|
@@ -92,11 +92,10 @@ function extractImageName(config, appName) {
|
|
|
92
92
|
* @throws {Error} If configuration cannot be loaded
|
|
93
93
|
*/
|
|
94
94
|
async function loadPushConfig(appName, options) {
|
|
95
|
-
const { detectAppType, resolveApplicationConfigPath } = require('../utils/paths');
|
|
96
95
|
const { loadConfigFile } = require('../utils/config-format');
|
|
97
|
-
const { appPath } = await detectAppType(appName);
|
|
98
96
|
try {
|
|
99
|
-
const
|
|
97
|
+
const { appPath } = await paths.detectAppType(appName);
|
|
98
|
+
const configPath = paths.resolveApplicationConfigPath(appPath);
|
|
100
99
|
const config = loadConfigFile(configPath);
|
|
101
100
|
const effective = getEffectiveConfig(config);
|
|
102
101
|
const registry = options.registry || effective.image?.registry;
|
|
@@ -242,7 +241,7 @@ function displayPushResults(registry, imageName, tags) {
|
|
|
242
241
|
*/
|
|
243
242
|
async function pushApp(appName, options = {}) {
|
|
244
243
|
try {
|
|
245
|
-
const { isExternal } = await detectAppType(appName);
|
|
244
|
+
const { isExternal } = await paths.detectAppType(appName);
|
|
246
245
|
if (isExternal) {
|
|
247
246
|
logExternalIntegrationPushNotice(appName);
|
|
248
247
|
return;
|
package/lib/app/register.js
CHANGED
|
@@ -25,6 +25,8 @@ const { callRegisterApi } = require('../utils/app-register-api');
|
|
|
25
25
|
const { displayRegistrationResults, getEnvironmentPrefix } = require('../utils/app-register-display');
|
|
26
26
|
const pathsUtil = require('../utils/paths');
|
|
27
27
|
const { refreshUrlsLocalRegistryFromBuilder } = require('../utils/urls-local-registry');
|
|
28
|
+
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
29
|
+
const config = require('../core/config');
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
32
|
* Build registration data payload from app configuration
|
|
@@ -152,9 +154,6 @@ async function applyLocalhostPortAdjustment(appConfig, apiUrl, options) {
|
|
|
152
154
|
*/
|
|
153
155
|
async function registerApplication(appKey, options = {}) {
|
|
154
156
|
logger.log(chalk.blue('📋 Registering application...\n'));
|
|
155
|
-
|
|
156
|
-
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
157
|
-
const config = require('../core/config');
|
|
158
157
|
await config.ensureSecretsEncryptionKey();
|
|
159
158
|
const { resolveEnvironment } = config;
|
|
160
159
|
|
|
@@ -168,7 +167,11 @@ async function registerApplication(appKey, options = {}) {
|
|
|
168
167
|
const appConfig = await extractAppConfiguration(finalVariables, appKey, options);
|
|
169
168
|
await validateAppRegistrationData(appConfig, appKey);
|
|
170
169
|
|
|
171
|
-
const
|
|
170
|
+
const controllerUrl = await resolveControllerUrl();
|
|
171
|
+
const environmentKey =
|
|
172
|
+
options && options.envKey
|
|
173
|
+
? String(options.envKey).trim().toLowerCase()
|
|
174
|
+
: await resolveEnvironment();
|
|
172
175
|
const authConfig = await checkAuthentication(controllerUrl, environmentKey);
|
|
173
176
|
const environment = registerApplicationSchema.environmentId(environmentKey);
|
|
174
177
|
|