@aifabrix/builder 2.46.0 ā 2.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.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 +18 -4
- package/lib/cli/infra-guided-auth.js +36 -12
- 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-npm.js +59 -0
- package/lib/cli/setup-platform.js +1 -1
- package/lib/cli/setup-secrets.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/login-device.js +11 -3
- package/lib/commands/login.js +8 -3
- package/lib/commands/npm-config.js +103 -0
- 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/api.js +2 -1
- 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/controller-url.js +4 -1
- 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/dev-platform-tls.js +148 -0
- 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/health-check-request.js +114 -0
- package/lib/utils/health-check-url.js +3 -1
- package/lib/utils/health-check.js +1 -113
- package/lib/utils/help-builder.js +3 -0
- package/lib/utils/keycloak-realm-ready.js +5 -1
- package/lib/utils/localhost-public-host.js +31 -0
- package/lib/utils/npm-user-config.js +145 -0
- package/lib/utils/paths.js +25 -0
- package/lib/utils/platform-controller-url.js +58 -4
- 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/url-declarative-public-base.js +33 -25
- 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
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
const { repairOpenapiSection } = require('./repair-datasource-openapi');
|
|
13
13
|
const { normalizeAutoRbacOperationKeys } = require('./repair-datasource-auto-rbac');
|
|
14
14
|
const { repairTestPayload } = require('./repair-datasource-test-payload');
|
|
15
|
+
const { repairComV2Manifest } = require('./repair-datasource-com-v2');
|
|
16
|
+
const {
|
|
17
|
+
isDeprecatedNoneLlmManifest,
|
|
18
|
+
repairNoneLlmToServiceContract,
|
|
19
|
+
stripDeprecatedServiceCategory
|
|
20
|
+
} = require('./repair-datasource-service-contract');
|
|
15
21
|
|
|
16
22
|
const DEFAULT_SYNC = {
|
|
17
23
|
mode: 'pull',
|
|
@@ -380,6 +386,41 @@ function sanitizeTestPayloadTopLevel(parsed, changes) {
|
|
|
380
386
|
return true;
|
|
381
387
|
}
|
|
382
388
|
|
|
389
|
+
/**
|
|
390
|
+
* @param {Object} parsed
|
|
391
|
+
* @param {Object} options
|
|
392
|
+
* @returns {boolean}
|
|
393
|
+
*/
|
|
394
|
+
function shouldApplyServiceContractRepair(parsed, options) {
|
|
395
|
+
return (
|
|
396
|
+
isDeprecatedNoneLlmManifest(parsed) ||
|
|
397
|
+
(options.serviceContract && parsed?.resourceType === 'llm')
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* @param {Object} parsed
|
|
403
|
+
* @param {Object} options
|
|
404
|
+
* @param {boolean} none
|
|
405
|
+
* @param {string[]} changes
|
|
406
|
+
* @returns {boolean}
|
|
407
|
+
*/
|
|
408
|
+
function applyOptionalDatasourceRepairs(parsed, options, none, changes) {
|
|
409
|
+
let updated = false;
|
|
410
|
+
if (options.expose) {
|
|
411
|
+
updated = repairExposeFromAttributes(parsed, changes) || updated;
|
|
412
|
+
}
|
|
413
|
+
if (!none && options.sync) {
|
|
414
|
+
updated = repairSyncSection(parsed, changes) || updated;
|
|
415
|
+
}
|
|
416
|
+
if (options.test) {
|
|
417
|
+
sanitizeTestPayloadTopLevel(parsed, changes);
|
|
418
|
+
updated = repairTestPayload(parsed, changes) || updated;
|
|
419
|
+
updated = sanitizeTestPayloadTopLevel(parsed, changes) || updated;
|
|
420
|
+
}
|
|
421
|
+
return updated;
|
|
422
|
+
}
|
|
423
|
+
|
|
383
424
|
/**
|
|
384
425
|
* Runs all requested datasource repairs.
|
|
385
426
|
*
|
|
@@ -390,32 +431,24 @@ function sanitizeTestPayloadTopLevel(parsed, changes) {
|
|
|
390
431
|
*/
|
|
391
432
|
function repairDatasourceFile(parsed, options = {}, changes = []) {
|
|
392
433
|
const out = Array.isArray(changes) ? changes : [];
|
|
393
|
-
let updated =
|
|
394
|
-
const none = isNoneEntityType(parsed?.entityType);
|
|
434
|
+
let updated = stripDeprecatedServiceCategory(parsed, out);
|
|
395
435
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
if (options.expose) {
|
|
400
|
-
updated = repairExposeFromAttributes(parsed, out) || updated;
|
|
436
|
+
if (shouldApplyServiceContractRepair(parsed, options)) {
|
|
437
|
+
updated = repairNoneLlmToServiceContract(parsed, out) || updated;
|
|
401
438
|
}
|
|
402
439
|
|
|
403
|
-
|
|
404
|
-
updated = repairSyncSection(parsed, out) || updated;
|
|
405
|
-
}
|
|
440
|
+
const none = isNoneEntityType(parsed?.entityType);
|
|
406
441
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
updated = sanitizeTestPayloadTopLevel(parsed, out) || updated;
|
|
411
|
-
}
|
|
442
|
+
updated = applyBaseDatasourceRepairs(parsed, none, out) || updated;
|
|
443
|
+
updated = applyOpenapiDatasourceRepairs(parsed, out) || updated;
|
|
444
|
+
updated = applyOptionalDatasourceRepairs(parsed, options, none, out) || updated;
|
|
412
445
|
|
|
413
446
|
return { updated, changes: out };
|
|
414
447
|
}
|
|
415
448
|
|
|
416
449
|
function applyBaseDatasourceRepairs(parsed, none, changes) {
|
|
417
|
-
|
|
418
|
-
|
|
450
|
+
let updated = repairComV2Manifest(parsed, changes);
|
|
451
|
+
if (none) return updated;
|
|
419
452
|
updated = repairDimensionBindingShape(parsed, changes) || updated;
|
|
420
453
|
updated = repairRootDimensionsFromAttributes(parsed, changes) || updated;
|
|
421
454
|
updated = repairMetadataSchemaFromAttributes(parsed, changes) || updated;
|
|
@@ -444,5 +477,7 @@ module.exports = {
|
|
|
444
477
|
DEFAULT_SYNC,
|
|
445
478
|
MINIMAL_METADATA_SCHEMA,
|
|
446
479
|
TEST_PAYLOAD_TOP_LEVEL_ALLOW,
|
|
447
|
-
isNoneEntityType
|
|
480
|
+
isNoneEntityType,
|
|
481
|
+
isDeprecatedNoneLlmManifest,
|
|
482
|
+
repairNoneLlmToServiceContract
|
|
448
483
|
};
|
|
@@ -77,9 +77,16 @@ function addFromConfiguration(effective, config, prefix, seenNames, systemKey) {
|
|
|
77
77
|
* @param {string} systemKey - System key for path namespace
|
|
78
78
|
*/
|
|
79
79
|
function addFromAuthSecurity(effective, systemParsed, prefix, seenNames, systemKey) {
|
|
80
|
-
const
|
|
80
|
+
const { getAuthCredentialTemplate } = require('../utils/authentication-shape');
|
|
81
|
+
const { isPlatformCatalogKvRef } = require('../utils/platform-kv-ref');
|
|
82
|
+
const credential = getAuthCredentialTemplate(systemParsed.authentication);
|
|
83
|
+
const security = credential?.security ?? systemParsed.authentication?.security;
|
|
81
84
|
if (!security || typeof security !== 'object') return;
|
|
82
85
|
for (const key of Object.keys(security)) {
|
|
86
|
+
const securityVal = security[key];
|
|
87
|
+
if (typeof securityVal === 'string' && isPlatformCatalogKvRef(securityVal)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
83
90
|
const envName = `KV_${prefix}_${securityKeyToVar(key)}`;
|
|
84
91
|
if (seenNames.has(envName)) continue;
|
|
85
92
|
const pathVal = kvEnvKeyToPath(envName, systemKey);
|
|
@@ -316,16 +323,7 @@ function repairEnvTemplate(appPath, systemParsed, systemKey, dryRun, changes, ba
|
|
|
316
323
|
return true;
|
|
317
324
|
}
|
|
318
325
|
|
|
319
|
-
|
|
320
|
-
* Returns true if a kv value looks like legacy format (KeyVault suffix or no path segments).
|
|
321
|
-
* @param {string} val - Value from authentication.security or configuration
|
|
322
|
-
* @returns {boolean}
|
|
323
|
-
*/
|
|
324
|
-
function isLegacyKvValue(val) {
|
|
325
|
-
if (typeof val !== 'string' || !val.trim().toLowerCase().startsWith('kv://')) return false;
|
|
326
|
-
const after = val.trim().slice(5); // after 'kv://'
|
|
327
|
-
return after.includes('KeyVault') || !after.includes('/');
|
|
328
|
-
}
|
|
326
|
+
const { isLegacyKvValue } = require('../utils/platform-kv-ref');
|
|
329
327
|
|
|
330
328
|
/**
|
|
331
329
|
* Normalizes authentication.security values to path-style kv:// (kv://systemKey/variable).
|
|
@@ -392,7 +390,9 @@ function normalizeConfigurationSection(config, prefix, systemKey, changes) {
|
|
|
392
390
|
function normalizeSystemFileAuthAndConfig(systemParsed, systemKey, changes) {
|
|
393
391
|
const prefix = systemKeyToKvPrefix(systemKey);
|
|
394
392
|
if (!prefix) return false;
|
|
395
|
-
const
|
|
393
|
+
const { getAuthCredentialTemplate } = require('../utils/authentication-shape');
|
|
394
|
+
const credential = getAuthCredentialTemplate(systemParsed.authentication);
|
|
395
|
+
const security = credential?.security ?? systemParsed.authentication?.security;
|
|
396
396
|
let updated = (security && typeof security === 'object' && normalizeSecuritySection(security, prefix, systemKey, changes));
|
|
397
397
|
const config = systemParsed.configuration;
|
|
398
398
|
if (Array.isArray(config)) {
|
|
@@ -15,10 +15,15 @@ const path = require('path');
|
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
|
|
17
17
|
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
18
|
-
const {
|
|
18
|
+
const {
|
|
19
|
+
getDeploymentAuth,
|
|
20
|
+
requireBearerForDataplanePipeline,
|
|
21
|
+
applyLabDataplaneApiKeyBearer
|
|
22
|
+
} = require('../utils/token-manager');
|
|
19
23
|
const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
|
|
20
24
|
const { uploadFileAs } = require('../utils/file-upload');
|
|
21
25
|
const { listOpenAPIFiles } = require('../api/external-systems.api');
|
|
26
|
+
const { resolveLabDataplaneApiKey } = require('../utils/credential-secrets-env');
|
|
22
27
|
|
|
23
28
|
async function fileExistsAsync(filePath) {
|
|
24
29
|
try {
|
|
@@ -29,11 +34,25 @@ async function fileExistsAsync(filePath) {
|
|
|
29
34
|
}
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
function authForJwtOnlyDataplaneRoutes(authConfig) {
|
|
38
|
+
const copy = { ...(authConfig || {}) };
|
|
39
|
+
if (copy.type === 'client-token' && resolveLabDataplaneApiKey()) {
|
|
40
|
+
return applyLabDataplaneApiKeyBearer(copy);
|
|
41
|
+
}
|
|
42
|
+
return copy;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function resolveDataplaneAndAuth(systemKey, preResolved = {}) {
|
|
46
|
+
if (preResolved.dataplaneUrl && preResolved.authConfig) {
|
|
47
|
+
const authConfig = authForJwtOnlyDataplaneRoutes(preResolved.authConfig);
|
|
48
|
+
return { dataplaneUrl: preResolved.dataplaneUrl, authConfig };
|
|
49
|
+
}
|
|
33
50
|
const { resolveEnvironment } = require('../core/config');
|
|
34
51
|
const environment = await resolveEnvironment();
|
|
35
52
|
const controllerUrl = await resolveControllerUrl();
|
|
36
|
-
const authConfig =
|
|
53
|
+
const authConfig = authForJwtOnlyDataplaneRoutes(
|
|
54
|
+
await getDeploymentAuth(controllerUrl, environment, systemKey)
|
|
55
|
+
);
|
|
37
56
|
requireBearerForDataplanePipeline(authConfig);
|
|
38
57
|
const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig, { silent: true });
|
|
39
58
|
return { dataplaneUrl, authConfig };
|
|
@@ -115,7 +134,10 @@ async function syncOpenApiFilesForMcp(opts) {
|
|
|
115
134
|
const openapiDir = path.join(appPath, 'openapi');
|
|
116
135
|
if (!(await fileExistsAsync(openapiDir))) return { uploaded: 0, skipped: 0 };
|
|
117
136
|
|
|
118
|
-
const { dataplaneUrl, authConfig } = await resolveDataplaneAndAuth(systemKey
|
|
137
|
+
const { dataplaneUrl, authConfig } = await resolveDataplaneAndAuth(systemKey, {
|
|
138
|
+
dataplaneUrl: opts.dataplaneUrl,
|
|
139
|
+
authConfig: opts.authConfig
|
|
140
|
+
});
|
|
119
141
|
const existingKeys = await getExistingOpenApiKeys(dataplaneUrl, systemKey, authConfig);
|
|
120
142
|
const uploadedKeys = new Set(existingKeys);
|
|
121
143
|
let uploaded = 0;
|
|
@@ -26,7 +26,9 @@ const {
|
|
|
26
26
|
buildAuthenticationForRepair,
|
|
27
27
|
mergePreservedAuthVariables,
|
|
28
28
|
repairAuthChangeLabel,
|
|
29
|
-
auditRepairAuthenticationWarnings
|
|
29
|
+
auditRepairAuthenticationWarnings,
|
|
30
|
+
normalizeAuthenticationSchemaShape,
|
|
31
|
+
getAuthCredentialTemplate
|
|
30
32
|
} = require('./repair-auth-apply');
|
|
31
33
|
|
|
32
34
|
/**
|
|
@@ -45,19 +47,24 @@ function applyAuthMethod(ctx) {
|
|
|
45
47
|
}
|
|
46
48
|
const existingAuth = ctx.systemParsed.authentication || ctx.systemParsed.auth || {};
|
|
47
49
|
const newAuth = buildAuthenticationForRepair(ctx.systemKey, authOption);
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
50
|
+
const existingCredential = getAuthCredentialTemplate(existingAuth) || {};
|
|
51
|
+
const mergedVariables = { ...(newAuth.credential?.variables || {}) };
|
|
52
|
+
mergePreservedAuthVariables(
|
|
53
|
+
mergedVariables,
|
|
54
|
+
existingCredential.variables && typeof existingCredential.variables === 'object'
|
|
55
|
+
? existingCredential.variables
|
|
56
|
+
: existingAuth.variables
|
|
57
|
+
);
|
|
58
|
+
if (newAuth.authType === 'credential' && newAuth.credential) {
|
|
59
|
+
newAuth.credential.variables = mergedVariables;
|
|
60
|
+
if (existingCredential.displayName !== undefined) {
|
|
61
|
+
newAuth.credential.displayName = existingCredential.displayName;
|
|
62
|
+
} else if (existingAuth.displayName !== undefined) {
|
|
63
|
+
newAuth.credential.displayName = existingAuth.displayName;
|
|
64
|
+
}
|
|
60
65
|
}
|
|
66
|
+
ctx.systemParsed.authentication = newAuth;
|
|
67
|
+
delete ctx.systemParsed.auth;
|
|
61
68
|
ctx.changes.push(`Set authentication method to ${repairAuthChangeLabel(authOption)}`);
|
|
62
69
|
return true;
|
|
63
70
|
}
|
|
@@ -70,6 +77,7 @@ function applyAuthMethod(ctx) {
|
|
|
70
77
|
function persistSystemFileRepair(ctx, flags) {
|
|
71
78
|
const systemFileUpdated =
|
|
72
79
|
flags.authReplaced ||
|
|
80
|
+
flags.authShapeNormalized ||
|
|
73
81
|
flags.systemAuthConfigNormalized ||
|
|
74
82
|
flags.systemDataSourcesAligned ||
|
|
75
83
|
flags.authVarsRemoved;
|
|
@@ -95,6 +103,12 @@ function runRepairSteps(ctx) {
|
|
|
95
103
|
);
|
|
96
104
|
const authReplaced = applyAuthMethod(ctx);
|
|
97
105
|
updated = updated || authReplaced;
|
|
106
|
+
const authShapeNormalized = normalizeAuthenticationSchemaShape(
|
|
107
|
+
ctx.systemParsed,
|
|
108
|
+
ctx.systemKey,
|
|
109
|
+
ctx.changes
|
|
110
|
+
);
|
|
111
|
+
updated = updated || authShapeNormalized;
|
|
98
112
|
const systemAuthConfigNormalized = normalizeSystemFileAuthAndConfig(
|
|
99
113
|
ctx.systemParsed, ctx.systemKey, ctx.changes
|
|
100
114
|
);
|
|
@@ -106,6 +120,7 @@ function runRepairSteps(ctx) {
|
|
|
106
120
|
);
|
|
107
121
|
const systemFileUpdated = persistSystemFileRepair(ctx, {
|
|
108
122
|
authReplaced,
|
|
123
|
+
authShapeNormalized,
|
|
109
124
|
systemAuthConfigNormalized,
|
|
110
125
|
systemDataSourcesAligned,
|
|
111
126
|
authVarsRemoved
|
|
@@ -177,13 +177,16 @@ function alignSystemFileDataSources(appPath, systemParsed, datasourceFiles, syst
|
|
|
177
177
|
function buildAuthVarNames(systemParsed, _systemKey) {
|
|
178
178
|
const names = new Set();
|
|
179
179
|
const auth = systemParsed.authentication;
|
|
180
|
-
if (auth
|
|
181
|
-
|
|
180
|
+
if (!auth || typeof auth !== 'object') return names;
|
|
181
|
+
const credential =
|
|
182
|
+
auth.credential && typeof auth.credential === 'object' ? auth.credential : auth;
|
|
183
|
+
if (typeof credential.variables === 'object') {
|
|
184
|
+
for (const k of Object.keys(credential.variables)) {
|
|
182
185
|
names.add(String(k).toUpperCase().replace(/_/g, ''));
|
|
183
186
|
}
|
|
184
187
|
}
|
|
185
|
-
if (
|
|
186
|
-
for (const k of Object.keys(
|
|
188
|
+
if (typeof credential.security === 'object') {
|
|
189
|
+
for (const k of Object.keys(credential.security)) {
|
|
187
190
|
names.add(securityKeyToVar(k));
|
|
188
191
|
}
|
|
189
192
|
}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource type catalog commands (Controller).
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* - aifabrix resource-type create
|
|
6
|
+
* - aifabrix resource-type import
|
|
7
|
+
* - aifabrix resource-type get
|
|
8
|
+
* - aifabrix resource-type list
|
|
9
|
+
*
|
|
10
|
+
* @fileoverview Resource type CLI commands
|
|
11
|
+
* @author AI Fabrix Team
|
|
12
|
+
* @version 1.0.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const chalk = require('chalk');
|
|
18
|
+
const logger = require('../utils/logger');
|
|
19
|
+
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
20
|
+
const { normalizeControllerUrl, resolveEnvironment } = require('../core/config');
|
|
21
|
+
const { getOrRefreshDeviceToken } = require('../utils/token-manager');
|
|
22
|
+
const {
|
|
23
|
+
readResourceTypeCreateFile,
|
|
24
|
+
readResourceTypeCatalogFile
|
|
25
|
+
} = require('../resolvers/resource-type-file');
|
|
26
|
+
const {
|
|
27
|
+
formatBlockingError,
|
|
28
|
+
formatSuccessLine,
|
|
29
|
+
infoLine,
|
|
30
|
+
headerKeyValue
|
|
31
|
+
} = require('../utils/cli-layout-chalk');
|
|
32
|
+
const {
|
|
33
|
+
listResourceTypes,
|
|
34
|
+
getResourceType,
|
|
35
|
+
createResourceTypeIdempotent
|
|
36
|
+
} = require('../api/resource-types.api');
|
|
37
|
+
|
|
38
|
+
const RESOURCE_TYPE_KEY_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
39
|
+
|
|
40
|
+
/** Parent help for `aifabrix resource-type -h`. */
|
|
41
|
+
const RESOURCE_TYPE_HELP_AFTER = `
|
|
42
|
+
|
|
43
|
+
Examples:
|
|
44
|
+
$ aifabrix resource-type create --key customer --display-name "Customer"
|
|
45
|
+
$ aifabrix resource-type get customer
|
|
46
|
+
$ aifabrix resource-type list --search customer
|
|
47
|
+
|
|
48
|
+
Per-command help: aifabrix resource-type <command> --help
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
const RESOURCE_TYPE_IMPORT_HELP_AFTER = `
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
$ aifabrix resource-type import --file ./baseline-resourcetypes.json
|
|
55
|
+
$ aifabrix resource-type import --file /path/to/catalog.json
|
|
56
|
+
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
const RESOURCE_TYPE_CREATE_HELP_AFTER = `
|
|
60
|
+
|
|
61
|
+
Examples:
|
|
62
|
+
$ aifabrix resource-type create --key customer --display-name "Customer"
|
|
63
|
+
$ aifabrix resource-type create --key deal --display-name "Deal" --category business --default-risk-level medium
|
|
64
|
+
$ aifabrix resource-type create --file ./customer.json
|
|
65
|
+
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
const RESOURCE_TYPE_GET_HELP_AFTER = `
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
$ aifabrix resource-type get customer
|
|
72
|
+
$ aifabrix resource-type get clx1234567890abcdef
|
|
73
|
+
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
const RESOURCE_TYPE_LIST_HELP_AFTER = `
|
|
77
|
+
|
|
78
|
+
Examples:
|
|
79
|
+
$ aifabrix resource-type list
|
|
80
|
+
$ aifabrix resource-type list --page 1 --page-size 50
|
|
81
|
+
$ aifabrix resource-type list --search customer
|
|
82
|
+
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {string} raw
|
|
87
|
+
* @returns {string}
|
|
88
|
+
*/
|
|
89
|
+
function requireResourceTypeKey(raw) {
|
|
90
|
+
const key = String(raw || '').trim();
|
|
91
|
+
if (!key) {
|
|
92
|
+
throw new Error('Resource type key is required (--key <key> or --file <path>).');
|
|
93
|
+
}
|
|
94
|
+
if (!RESOURCE_TYPE_KEY_PATTERN.test(key)) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
'Resource type key must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens.'
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
return key;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @param {Object} options
|
|
104
|
+
* @returns {Promise<{ controllerUrl: string, authConfig: Object }>}
|
|
105
|
+
*/
|
|
106
|
+
async function resolveControllerAndAuth(_options) {
|
|
107
|
+
const controllerUrl = await resolveControllerUrl();
|
|
108
|
+
if (!controllerUrl) {
|
|
109
|
+
throw new Error('Controller URL is required. Run "aifabrix login" first.');
|
|
110
|
+
}
|
|
111
|
+
const normalized = normalizeControllerUrl(controllerUrl);
|
|
112
|
+
const deviceToken = await getOrRefreshDeviceToken(normalized);
|
|
113
|
+
if (!deviceToken || !deviceToken.token) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Not authenticated for controller: ${controllerUrl}. ` +
|
|
116
|
+
'Run "aifabrix login" and try again.'
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
controllerUrl: deviceToken.controller || normalized,
|
|
121
|
+
authConfig: { type: 'bearer', token: deviceToken.token }
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function resolveHeaderContext() {
|
|
126
|
+
const env = await resolveEnvironment();
|
|
127
|
+
const controllerUrl = await resolveControllerUrl();
|
|
128
|
+
const normalized = normalizeControllerUrl(controllerUrl);
|
|
129
|
+
return { environment: env || 'dev', controllerUrl: normalized };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @param {Object} options
|
|
134
|
+
* @returns {Object}
|
|
135
|
+
*/
|
|
136
|
+
function buildCreatePayload(options) {
|
|
137
|
+
let base = {};
|
|
138
|
+
if (options.file) {
|
|
139
|
+
base = readResourceTypeCreateFile(options.file);
|
|
140
|
+
}
|
|
141
|
+
const payload = { ...base };
|
|
142
|
+
if (options.key) payload.key = options.key;
|
|
143
|
+
if (options.displayName) payload.displayName = options.displayName;
|
|
144
|
+
if (options.description !== undefined) payload.description = options.description;
|
|
145
|
+
if (options.category) payload.category = options.category;
|
|
146
|
+
if (options.defaultRiskLevel) payload.defaultRiskLevel = options.defaultRiskLevel;
|
|
147
|
+
if (options.status) payload.status = options.status;
|
|
148
|
+
payload.key = requireResourceTypeKey(payload.key);
|
|
149
|
+
if (!payload.displayName) {
|
|
150
|
+
throw new Error('displayName is required (--display-name <name> or in --file).');
|
|
151
|
+
}
|
|
152
|
+
return payload;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @param {Object} response
|
|
157
|
+
* @returns {any}
|
|
158
|
+
*/
|
|
159
|
+
function unwrapControllerData(response) {
|
|
160
|
+
return response?.data?.data ?? response?.data ?? response;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @param {import('commander').Command} rt
|
|
165
|
+
*/
|
|
166
|
+
/**
|
|
167
|
+
* @param {Object[]} rows
|
|
168
|
+
* @param {string} controllerUrl
|
|
169
|
+
* @param {Object} authConfig
|
|
170
|
+
* @returns {Promise<{ created: number, existed: number, total: number }>}
|
|
171
|
+
*/
|
|
172
|
+
async function importResourceTypeRows(rows, controllerUrl, authConfig) {
|
|
173
|
+
let created = 0;
|
|
174
|
+
let existed = 0;
|
|
175
|
+
for (const row of rows) {
|
|
176
|
+
const payload = { ...row };
|
|
177
|
+
payload.key = requireResourceTypeKey(payload.key);
|
|
178
|
+
const out = await createResourceTypeIdempotent(controllerUrl, authConfig, payload);
|
|
179
|
+
if (out.created) {
|
|
180
|
+
created += 1;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
existed += 1;
|
|
184
|
+
}
|
|
185
|
+
return { created, existed, total: rows.length };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function setupResourceTypeImportCommand(rt) {
|
|
189
|
+
rt
|
|
190
|
+
.command('import')
|
|
191
|
+
.description('Import resource types from baseline catalog JSON (idempotent)')
|
|
192
|
+
.addHelpText('after', RESOURCE_TYPE_IMPORT_HELP_AFTER)
|
|
193
|
+
.requiredOption('--file <path>', 'Baseline catalog (resourceTypes[]) or JSON array')
|
|
194
|
+
.action(async(options) => {
|
|
195
|
+
try {
|
|
196
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
197
|
+
const rows = readResourceTypeCatalogFile(options.file);
|
|
198
|
+
const summary = await importResourceTypeRows(rows, controllerUrl, authConfig);
|
|
199
|
+
logger.log(
|
|
200
|
+
formatSuccessLine(
|
|
201
|
+
`Resource types imported: ${summary.total} total ` +
|
|
202
|
+
`(${summary.created} created, ${summary.existed} already existed)`
|
|
203
|
+
)
|
|
204
|
+
);
|
|
205
|
+
} catch (e) {
|
|
206
|
+
logger.error(formatBlockingError(e.message));
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function setupResourceTypeCreateCommand(rt) {
|
|
213
|
+
rt
|
|
214
|
+
.command('create')
|
|
215
|
+
.description('Create resource type (idempotent; success if it already exists)')
|
|
216
|
+
.addHelpText('after', RESOURCE_TYPE_CREATE_HELP_AFTER)
|
|
217
|
+
.option('--file <path>', 'Read resource type create payload from JSON file')
|
|
218
|
+
.option('--key <key>', 'Catalog key (lowercase letters, digits, hyphens)')
|
|
219
|
+
.option('--display-name <name>', 'Display name')
|
|
220
|
+
.option('--description <text>', 'Description')
|
|
221
|
+
.option(
|
|
222
|
+
'--category <category>',
|
|
223
|
+
'business | collaboration | governance | content | communication | people'
|
|
224
|
+
)
|
|
225
|
+
.option('--default-risk-level <level>', 'low | medium | high | critical')
|
|
226
|
+
.option('--status <status>', 'draft | active | deprecated | retired')
|
|
227
|
+
.action(async(options) => {
|
|
228
|
+
try {
|
|
229
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
230
|
+
const payload = buildCreatePayload(options);
|
|
231
|
+
const out = await createResourceTypeIdempotent(controllerUrl, authConfig, payload);
|
|
232
|
+
const row = unwrapControllerData(out.response);
|
|
233
|
+
const category = row.category || payload.category || 'business';
|
|
234
|
+
const risk = row.defaultRiskLevel || payload.defaultRiskLevel || 'medium';
|
|
235
|
+
if (out.created) {
|
|
236
|
+
logger.log(
|
|
237
|
+
formatSuccessLine(`Resource type created: ${row.key} (category: ${category}, risk: ${risk})`)
|
|
238
|
+
);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
logger.log(formatSuccessLine(`Resource type exists: ${row.key} (category: ${category}, risk: ${risk})`));
|
|
242
|
+
logger.log(infoLine('No changes were needed.'));
|
|
243
|
+
} catch (e) {
|
|
244
|
+
logger.error(formatBlockingError(e.message));
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function setupResourceTypeGetCommand(rt) {
|
|
251
|
+
rt
|
|
252
|
+
.command('get <resourceTypeIdOrKey>')
|
|
253
|
+
.description('Get resource type by id or key')
|
|
254
|
+
.addHelpText('after', RESOURCE_TYPE_GET_HELP_AFTER)
|
|
255
|
+
.action(async(resourceTypeIdOrKey, options) => {
|
|
256
|
+
try {
|
|
257
|
+
const { environment, controllerUrl: headerControllerUrl } = await resolveHeaderContext();
|
|
258
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
259
|
+
const res = await getResourceType(controllerUrl, authConfig, String(resourceTypeIdOrKey).trim());
|
|
260
|
+
const row = unwrapControllerData(res);
|
|
261
|
+
logger.log(
|
|
262
|
+
chalk.bold(`\nš·ļø Resource type in ${environment} environment (${headerControllerUrl}):\n`)
|
|
263
|
+
);
|
|
264
|
+
logger.log(headerKeyValue('Key:', row.key || 'ā'));
|
|
265
|
+
logger.log(headerKeyValue('Display:', row.displayName || 'ā'));
|
|
266
|
+
logger.log(headerKeyValue('Category:', row.category || 'ā'));
|
|
267
|
+
logger.log(headerKeyValue('Default risk:', row.defaultRiskLevel || 'ā'));
|
|
268
|
+
logger.log(headerKeyValue('Status:', row.status || 'ā'));
|
|
269
|
+
if (row.description) {
|
|
270
|
+
logger.log(headerKeyValue('Description:', row.description));
|
|
271
|
+
}
|
|
272
|
+
logger.log('');
|
|
273
|
+
} catch (e) {
|
|
274
|
+
logger.error(formatBlockingError(e.message));
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* @param {Array<Object>} items
|
|
282
|
+
* @param {string} environment
|
|
283
|
+
* @param {string} controllerUrl
|
|
284
|
+
*/
|
|
285
|
+
function displayResourceTypeList(items, environment, controllerUrl) {
|
|
286
|
+
logger.log(
|
|
287
|
+
chalk.bold(`\nš·ļø Resource types in ${environment} environment (${controllerUrl}):\n`)
|
|
288
|
+
);
|
|
289
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
290
|
+
logger.log(chalk.gray(' No resource types found.\n'));
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const KEY_WIDTH = 22;
|
|
295
|
+
const DISPLAY_WIDTH = 30;
|
|
296
|
+
const CATEGORY_WIDTH = 16;
|
|
297
|
+
const RISK_WIDTH = 10;
|
|
298
|
+
const STATUS_WIDTH = 12;
|
|
299
|
+
const SEP_LEN = KEY_WIDTH + DISPLAY_WIDTH + CATEGORY_WIDTH + RISK_WIDTH + STATUS_WIDTH;
|
|
300
|
+
|
|
301
|
+
const keyCol = 'Key'.padEnd(KEY_WIDTH);
|
|
302
|
+
const displayCol = 'Display'.padEnd(DISPLAY_WIDTH);
|
|
303
|
+
const categoryCol = 'Category'.padEnd(CATEGORY_WIDTH);
|
|
304
|
+
const riskCol = 'Risk'.padEnd(RISK_WIDTH);
|
|
305
|
+
const statusCol = 'Status'.padEnd(STATUS_WIDTH);
|
|
306
|
+
logger.log(chalk.gray(`${keyCol}${displayCol}${categoryCol}${riskCol}${statusCol}`));
|
|
307
|
+
logger.log(chalk.gray('-'.repeat(SEP_LEN)));
|
|
308
|
+
|
|
309
|
+
items.forEach((d) => {
|
|
310
|
+
const key = (d?.key ?? 'ā').toString().padEnd(KEY_WIDTH);
|
|
311
|
+
const displayName = (d?.displayName ?? 'ā').toString().padEnd(DISPLAY_WIDTH);
|
|
312
|
+
const category = (d?.category ?? 'ā').toString().padEnd(CATEGORY_WIDTH);
|
|
313
|
+
const risk = (d?.defaultRiskLevel ?? 'ā').toString().padEnd(RISK_WIDTH);
|
|
314
|
+
const status = (d?.status ?? 'ā').toString().padEnd(STATUS_WIDTH);
|
|
315
|
+
logger.log(`${key}${displayName}${category}${risk}${status}`);
|
|
316
|
+
});
|
|
317
|
+
logger.log('');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function setupResourceTypeListCommand(rt) {
|
|
321
|
+
rt
|
|
322
|
+
.command('list')
|
|
323
|
+
.description('List resource types')
|
|
324
|
+
.addHelpText('after', RESOURCE_TYPE_LIST_HELP_AFTER)
|
|
325
|
+
.option('--page <n>', 'Page', (v) => parseInt(v, 10))
|
|
326
|
+
.option('--page-size <n>', 'Page size', (v) => parseInt(v, 10))
|
|
327
|
+
.option('--search <text>', 'Search by key/displayName/description')
|
|
328
|
+
.option('--category <category>', 'Filter by category')
|
|
329
|
+
.option('--status <status>', 'Filter by status')
|
|
330
|
+
.action(async(options) => {
|
|
331
|
+
try {
|
|
332
|
+
const { environment, controllerUrl: headerControllerUrl } = await resolveHeaderContext();
|
|
333
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
334
|
+
const res = await listResourceTypes(controllerUrl, authConfig, {
|
|
335
|
+
page: options.page,
|
|
336
|
+
pageSize: options.pageSize,
|
|
337
|
+
search: options.search,
|
|
338
|
+
category: options.category,
|
|
339
|
+
status: options.status
|
|
340
|
+
});
|
|
341
|
+
const payload = unwrapControllerData(res);
|
|
342
|
+
const items = payload?.data ?? payload ?? [];
|
|
343
|
+
displayResourceTypeList(items, environment, headerControllerUrl);
|
|
344
|
+
} catch (e) {
|
|
345
|
+
logger.error(formatBlockingError(e.message));
|
|
346
|
+
process.exit(1);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @param {import('commander').Command} program
|
|
353
|
+
*/
|
|
354
|
+
function setupResourceTypeCommands(program) {
|
|
355
|
+
const rt = program
|
|
356
|
+
.command('resource-type')
|
|
357
|
+
.description('Manage the Controller Resource Type Catalog (COM)')
|
|
358
|
+
.addHelpText('after', RESOURCE_TYPE_HELP_AFTER);
|
|
359
|
+
setupResourceTypeCreateCommand(rt);
|
|
360
|
+
setupResourceTypeImportCommand(rt);
|
|
361
|
+
setupResourceTypeGetCommand(rt);
|
|
362
|
+
setupResourceTypeListCommand(rt);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
module.exports = {
|
|
366
|
+
setupResourceTypeCommands,
|
|
367
|
+
requireResourceTypeKey,
|
|
368
|
+
buildCreatePayload,
|
|
369
|
+
unwrapControllerData,
|
|
370
|
+
importResourceTypeRows
|
|
371
|
+
};
|
|
@@ -263,7 +263,7 @@ async function runUpPlatform(opts = {}) {
|
|
|
263
263
|
if (opts.force === true && opts.skipForceClean !== true) {
|
|
264
264
|
const cleanedApps =
|
|
265
265
|
preflight.skipClean !== true
|
|
266
|
-
? await upCommon.cleanBuilderAppDirs(
|
|
266
|
+
? await upCommon.cleanBuilderAppDirs(upCommon.PLATFORM_BUILDER_CLEAN_APP_KEYS, { silent: true })
|
|
267
267
|
: [];
|
|
268
268
|
forceCleanSummary = { forceSummary: authCtx.forceSummary, cleanedApps };
|
|
269
269
|
}
|