@aifabrix/builder 2.54.1 → 2.55.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/lib/agent-kit/apply-ops.js +82 -0
- package/lib/agent-kit/checksums.js +28 -0
- package/lib/agent-kit/classify.js +113 -0
- package/lib/agent-kit/claude-shim.js +61 -0
- package/lib/agent-kit/constants.js +55 -0
- package/lib/agent-kit/file-list.js +103 -0
- package/lib/agent-kit/host-approve.js +172 -0
- package/lib/agent-kit/hosting/github.js +63 -0
- package/lib/agent-kit/hosts.js +71 -0
- package/lib/agent-kit/init.js +319 -0
- package/lib/agent-kit/kit-root.js +17 -0
- package/lib/agent-kit/managed-section.js +79 -0
- package/lib/agent-kit/package-load.js +45 -0
- package/lib/agent-kit/plan-ops.js +69 -0
- package/lib/agent-kit/remote-prompts.js +272 -0
- package/lib/agent-kit/render-host-markdown.js +40 -0
- package/lib/agent-kit/repo-guard.js +47 -0
- package/lib/agent-kit/report.js +107 -0
- package/lib/agent-kit/run.js +82 -0
- package/lib/agent-kit/scm/git.js +122 -0
- package/lib/agent-kit/start.js +310 -0
- package/lib/agent-kit/state-file.js +83 -0
- package/lib/agent-kit/status.js +50 -0
- package/lib/agent-kit/v1-detect.js +81 -0
- package/lib/agent-kit/validate-kit.js +87 -0
- package/lib/agent-kit/workspace-name.js +40 -0
- package/lib/agent-kit/workspace-skeleton.js +103 -0
- package/lib/api/role-assistant-test-pack.api.js +86 -0
- package/lib/api/work-search.api.js +31 -4
- package/lib/api/work.api.js +19 -12
- package/lib/app/deploy.js +7 -4
- package/lib/app/list-external-systems.js +2 -1
- package/lib/app/offer-create-from-template.js +184 -0
- package/lib/app/show-display.js +33 -6
- package/lib/app/show.js +25 -2
- package/lib/channels/add-channel.js +1 -0
- package/lib/channels/approval-guides/claude.js +2 -2
- package/lib/channels/channel-add-failure.js +1 -0
- package/lib/channels/channel-add-remaining.js +15 -9
- package/lib/channels/channel-definition-status.js +115 -0
- package/lib/channels/channel-description.js +2 -1
- package/lib/channels/channel-install-envelope.js +4 -2
- package/lib/channels/channel-integration-generator.js +2 -0
- package/lib/channels/channel-runtime-resolver.js +14 -0
- package/lib/channels/channel-targets.js +31 -5
- package/lib/channels/claude-setup-values.js +4 -1
- package/lib/channels/slack-channel-add.js +59 -6
- package/lib/channels/slack-mcp-callback.js +51 -0
- package/lib/channels/slack-mcp-runtime.js +156 -0
- package/lib/channels/slack-provisioning/install-cli.js +14 -2
- package/lib/channels/slack-provisioning/with-curl-on-path.js +6 -1
- package/lib/cli/index.js +4 -0
- package/lib/cli/setup-app.js +8 -1
- package/lib/cli/setup-auth.js +11 -2
- package/lib/cli/setup-certification-commands.js +2 -2
- package/lib/cli/setup-certification.help.js +3 -1
- package/lib/commands/agent-kit-help.js +149 -0
- package/lib/commands/agent-kit.js +417 -0
- package/lib/commands/auth-status-user.js +99 -0
- package/lib/commands/auth-status.js +14 -4
- package/lib/commands/channel-add-help.js +5 -5
- package/lib/commands/datasource-capability-relate-cli.js +5 -4
- package/lib/commands/datasource-load-export-cli.js +7 -2
- package/lib/commands/datasource-test-trust-cli.js +5 -1
- package/lib/commands/governance-command-action.js +5 -4
- package/lib/commands/identity-membership-role-cache.js +6 -1
- package/lib/commands/lifecycle-command-action.js +16 -15
- package/lib/commands/login-credentials.js +8 -3
- package/lib/commands/login-device.js +14 -5
- package/lib/commands/login.js +14 -1
- package/lib/commands/logout.js +50 -15
- package/lib/commands/repair-auth-apply.js +1 -1
- package/lib/commands/repair-datasource-key-skip.js +39 -0
- package/lib/commands/repair-datasource-keys.js +24 -12
- package/lib/commands/repair-rbac.js +16 -10
- package/lib/commands/role-assistant-copy-output.js +61 -0
- package/lib/commands/role-assistant-copy.js +155 -0
- package/lib/commands/role-assistant-test-output.js +8 -9
- package/lib/commands/role-assistant-test-result-rows.js +42 -0
- package/lib/commands/role-assistant.js +140 -59
- package/lib/commands/search.js +143 -0
- package/lib/commands/test-trust-external.js +7 -5
- package/lib/commands/upload-sidecar-followups.js +4 -1
- package/lib/commands/verify-governance-command-action.js +9 -7
- package/lib/commands/verify-operations-command-action.js +9 -8
- package/lib/commands/verify-operations-skip-e2e.js +131 -0
- package/lib/commands/verify-operations-step-plan.js +6 -33
- package/lib/commands/verify-operations-steps.js +3 -1
- package/lib/commands/verify-trust-command-action.js +6 -5
- package/lib/datasource/capability/relate-operations.js +28 -10
- package/lib/datasource/capability/run-capability-relate.js +48 -25
- package/lib/datasource/datasource-identifier.js +13 -5
- package/lib/deployment/deployer-poll-run.js +117 -35
- package/lib/external-system/deploy-dataplane-published.js +70 -0
- package/lib/external-system/deploy.js +12 -2
- package/lib/external-system/download-role-assistant.js +41 -15
- package/lib/external-system/download.js +8 -3
- package/lib/generator/helpers.js +12 -1
- package/lib/generator/wizard-datasource-key.js +54 -0
- package/lib/generator/wizard.js +55 -54
- package/lib/integration-definition/apply-datasource-keys.js +75 -0
- package/lib/integration-definition/apply-relationships.js +195 -0
- package/lib/integration-definition/apply-static-enterprise.js +232 -0
- package/lib/integration-definition/apply-system-file.js +71 -0
- package/lib/integration-definition/apply-test-endpoint.js +89 -0
- package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
- package/lib/integration-definition/apply.js +78 -59
- package/lib/integration-definition/enrich-openapi-operations.js +36 -10
- package/lib/integration-definition/enrich-openapi-pick.js +87 -0
- package/lib/lifecycle/role-assistant-governance.js +56 -21
- package/lib/programmatic/capability-registry.js +1 -0
- package/lib/programmatic/index.js +2 -0
- package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
- package/lib/programmatic/openapi-channel-install-schemas.js +4 -1
- package/lib/programmatic/openapi-component-schemas.js +1 -0
- package/lib/programmatic/openapi-descriptions.js +9 -3
- package/lib/programmatic/openapi-envelope-examples.js +7 -0
- package/lib/programmatic/openapi-operation-bindings.js +5 -0
- package/lib/programmatic/openapi-request-schemas.js +5 -0
- package/lib/programmatic/openapi-schema-descriptions-channel.js +8 -5
- package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
- package/lib/programmatic/openapi-spec.js +1 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +7 -0
- package/lib/programmatic/run-channel-catalog.js +50 -8
- package/lib/programmatic/run-channel-install-options.js +5 -1
- package/lib/programmatic/run-download.js +41 -0
- package/lib/protection/auth-context.js +3 -1
- package/lib/protection/protection-display.js +3 -2
- package/lib/protection/report-exit.js +50 -0
- package/lib/protection/run-commands.js +2 -0
- package/lib/role-assistant/knowledge-sync-settings-push.js +172 -0
- package/lib/role-assistant/knowledge-sync.js +9 -126
- package/lib/role-assistant/package-validate.js +175 -0
- package/lib/role-assistant/test-case-assertion-row.js +36 -0
- package/lib/role-assistant/test-case-copy-bind.js +77 -0
- package/lib/role-assistant/test-case-copy-expected.js +127 -0
- package/lib/role-assistant/test-case-copy-from-work.js +90 -0
- package/lib/role-assistant/test-case-copy-interactions.js +67 -0
- package/lib/role-assistant/test-case-copy.js +119 -0
- package/lib/role-assistant/test-case-expected-catalog.js +135 -0
- package/lib/role-assistant/test-case-validate.js +88 -0
- package/lib/role-assistant/test-cases-bid.js +117 -4
- package/lib/role-assistant/test-cases-evaluate.js +149 -31
- package/lib/role-assistant/test-cases-evidence.js +44 -5
- package/lib/role-assistant/test-cases-honesty.js +155 -6
- package/lib/role-assistant/test-cases-lifecycle.js +297 -0
- package/lib/role-assistant/test-cases-search-graph.js +122 -0
- package/lib/role-assistant/test-cases-search.js +20 -2
- package/lib/role-assistant/test-cases.js +34 -168
- package/lib/role-assistant/test-pack-map.js +180 -0
- package/lib/role-assistant/test-pack-sync.js +187 -0
- package/lib/role-assistant/test-runner-debug.js +54 -0
- package/lib/role-assistant/test-runner-respond-body.js +36 -0
- package/lib/role-assistant/test-runner-search.js +20 -5
- package/lib/role-assistant/test-runner-start-payload.js +63 -10
- package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
- package/lib/role-assistant/test-runner-workhub.js +45 -21
- package/lib/role-assistant/test-runner.js +53 -10
- package/lib/schema/external-datasource.schema.json +36 -5
- package/lib/schema/external-system.schema.json +20 -2
- package/lib/schema/infra-parameter.schema.json +51 -3
- package/lib/schema/infra.parameter.yaml +476 -40
- package/lib/schema/role-assistant-test-case.schema.json +408 -0
- package/lib/schema/type/document-storage.json +1 -1
- package/lib/search/dataplane-context.js +23 -0
- package/lib/search/search-args.js +211 -0
- package/lib/search/search-display.js +238 -0
- package/lib/search/search-errors.js +50 -0
- package/lib/search/search-prompts.js +119 -0
- package/lib/search/search-roles.js +85 -0
- package/lib/search/search-run.js +241 -0
- package/lib/search/search-skills.js +198 -0
- package/lib/utils/api-required-permissions.js +271 -0
- package/lib/utils/api.js +16 -13
- package/lib/utils/authentication-slot-show.js +153 -0
- package/lib/utils/cli-json-exit.js +41 -0
- package/lib/utils/cli-utils.js +23 -5
- package/lib/utils/controller-url.js +78 -4
- package/lib/utils/credential-display.js +43 -1
- package/lib/utils/deployment-errors.js +15 -0
- package/lib/utils/deployment-validation-helpers.js +4 -1
- package/lib/utils/device-code.js +31 -10
- package/lib/utils/error-formatters/error-parser.js +16 -1
- package/lib/utils/error-formatters/permission-errors.js +19 -5
- package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
- package/lib/utils/external-system-readiness-compact-display.js +30 -1
- package/lib/utils/external-system-validators.js +2 -1
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/keycloak-realm-ready.js +5 -2
- package/lib/utils/logger.js +1 -0
- package/lib/utils/paths.js +26 -5
- package/lib/utils/schema-loader.js +37 -0
- package/lib/utils/secrets-helpers.js +2 -2
- package/lib/utils/write-stream-and-wait.js +63 -0
- package/lib/validation/validate-external-file.js +5 -1
- package/lib/validation/validate.js +3 -2
- package/package.json +20 -6
- package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
- package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
- package/templates/agent-kit/agent-kit.yaml +45 -0
- package/templates/agent-kit/instructions/AGENTKIT.md +104 -0
- package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
- package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
- package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
- package/templates/agent-kit/parity-inventory.yaml +188 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +59 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +52 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +51 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +43 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
- package/templates/agent-kit/skills/shared/hosts.md +65 -0
- package/templates/agent-kit/skills/shared/login.md +16 -0
- package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
- package/templates/agent-kit/workspace/LICENSE.mit +21 -0
- package/templates/agent-kit/workspace/README.md +89 -0
- package/templates/applications/builder-api/Dockerfile +3 -1
- package/templates/applications/dataplane/application.yaml +2 -3
- package/templates/applications/dataplane/env.template +5 -5
- package/templates/applications/dataplane/rbac.yaml +28 -0
- package/templates/applications/keycloak/env.template +3 -3
- package/templates/applications/miso-controller/application.yaml +21 -2
- package/templates/applications/miso-controller/env.template +96 -25
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/channels/claude/TROUBLESHOOTING.md +3 -0
- package/templates/channels/claude/channel.json +1 -1
- package/templates/channels/claude/install.template.md.hbs +1 -0
- package/templates/channels/claude/integration/claude-system.json +1 -1
- package/templates/channels/slack/channel.json +11 -0
- package/templates/channels/slack/install.template.md.hbs +9 -0
- package/templates/channels/slack/integration/slack-system.json +11 -0
- package/templates/channels/slack/manifest.template.json.hbs +6 -3
- package/templates/channels/teams-bot/channel.json +1 -0
- package/templates/python/docker-compose.hbs +14 -0
- package/templates/typescript/docker-compose.hbs +14 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Viewpoint grain and inherited date filter keys for BID apply.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Prefer joined storage resourceType; copy date filterable fields
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { remapKey } = require('./apply-datasource-keys');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {unknown} format
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
*/
|
|
15
|
+
function isDateFormat(format) {
|
|
16
|
+
const raw = String(format || '').toLowerCase();
|
|
17
|
+
return raw === 'date' || raw === 'date-time' || raw === 'datetime';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {Record<string, unknown>} body
|
|
22
|
+
* @returns {string[]}
|
|
23
|
+
*/
|
|
24
|
+
function dateFilterableKeys(body) {
|
|
25
|
+
const props = body.metadataSchema && body.metadataSchema.properties;
|
|
26
|
+
if (!props || typeof props !== 'object') {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const exposed = body.exposed && Array.isArray(body.exposed.filterable)
|
|
30
|
+
? body.exposed.filterable
|
|
31
|
+
: [];
|
|
32
|
+
const keys = [];
|
|
33
|
+
for (const [name, node] of Object.entries(props)) {
|
|
34
|
+
if (!node || typeof node !== 'object') {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!isDateFormat(node.format)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (exposed.includes(name) || node.filter === true) {
|
|
41
|
+
keys.push(name);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return keys;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {Record<string, unknown>} viewBody
|
|
49
|
+
* @param {Record<string, unknown>} factBody
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
function copyOneDateField(viewBody, factBody, key, props, filterable) {
|
|
53
|
+
const src = factBody.metadataSchema.properties[key];
|
|
54
|
+
if (!props[key]) {
|
|
55
|
+
props[key] = { ...src, filter: true };
|
|
56
|
+
} else if (typeof props[key] === 'object') {
|
|
57
|
+
props[key].filter = true;
|
|
58
|
+
if (!props[key].format && src && src.format) {
|
|
59
|
+
props[key].format = src.format;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!filterable.includes(key)) {
|
|
63
|
+
filterable.push(key);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function copyDateFilterableOntoView(viewBody, factBody) {
|
|
68
|
+
const keys = dateFilterableKeys(factBody);
|
|
69
|
+
if (keys.length === 0) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (!viewBody.metadataSchema || typeof viewBody.metadataSchema !== 'object') {
|
|
73
|
+
viewBody.metadataSchema = { type: 'object', properties: {} };
|
|
74
|
+
}
|
|
75
|
+
const schema = /** @type {Record<string, unknown>} */ (viewBody.metadataSchema);
|
|
76
|
+
if (!schema.properties || typeof schema.properties !== 'object') {
|
|
77
|
+
schema.properties = {};
|
|
78
|
+
}
|
|
79
|
+
const props = /** @type {Record<string, unknown>} */ (schema.properties);
|
|
80
|
+
if (!viewBody.exposed || typeof viewBody.exposed !== 'object') {
|
|
81
|
+
viewBody.exposed = {};
|
|
82
|
+
}
|
|
83
|
+
const exposed = /** @type {Record<string, unknown>} */ (viewBody.exposed);
|
|
84
|
+
const filterable = Array.isArray(exposed.filterable) ? [...exposed.filterable] : [];
|
|
85
|
+
for (const key of keys) {
|
|
86
|
+
copyOneDateField(viewBody, factBody, key, props, filterable);
|
|
87
|
+
}
|
|
88
|
+
exposed.filterable = filterable;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {Record<string, unknown>} body
|
|
93
|
+
* @returns {boolean}
|
|
94
|
+
*/
|
|
95
|
+
function isViewpointBody(body) {
|
|
96
|
+
const entityType = String(body.entityType || '');
|
|
97
|
+
const storageType = String(body.storageType || '');
|
|
98
|
+
return entityType === 'viewpoint' || storageType === 'view';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @param {Array<{ body: Record<string, unknown> }>} dsFiles
|
|
103
|
+
* @returns {Map<string, Record<string, unknown>>}
|
|
104
|
+
*/
|
|
105
|
+
function bodiesByKey(dsFiles) {
|
|
106
|
+
const map = new Map();
|
|
107
|
+
for (const file of dsFiles || []) {
|
|
108
|
+
const key = String(file.body && file.body.key ? file.body.key : '').trim();
|
|
109
|
+
if (key) {
|
|
110
|
+
map.set(key, file.body);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return map;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @param {Array<{ body: Record<string, unknown> }>} dsFiles
|
|
118
|
+
* @param {unknown[]} relationships
|
|
119
|
+
* @param {Map<string, string>} keyMap
|
|
120
|
+
* @returns {void}
|
|
121
|
+
*/
|
|
122
|
+
function applyOneViewpoint(viewBody, rels, keyMap, bodies) {
|
|
123
|
+
const fromKey = String(viewBody.key || '');
|
|
124
|
+
const rel = rels.find((row) => row && remapKey(String(row.from || ''), keyMap) === fromKey);
|
|
125
|
+
if (!rel || typeof rel !== 'object') {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const factKey = remapKey(String(rel.to || ''), keyMap);
|
|
129
|
+
const factBody = bodies.get(factKey);
|
|
130
|
+
if (!factBody) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const factType = String(factBody.resourceType || '').trim();
|
|
134
|
+
const viewType = String(viewBody.resourceType || '').trim();
|
|
135
|
+
if (factType && (!viewType || viewType === 'document')) {
|
|
136
|
+
viewBody.resourceType = factType;
|
|
137
|
+
}
|
|
138
|
+
copyDateFilterableOntoView(viewBody, factBody);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function applyViewpointDefaults(dsFiles, relationships, keyMap) {
|
|
142
|
+
const bodies = bodiesByKey(dsFiles);
|
|
143
|
+
const rels = Array.isArray(relationships) ? relationships : [];
|
|
144
|
+
for (const file of dsFiles || []) {
|
|
145
|
+
const viewBody = file.body;
|
|
146
|
+
if (!viewBody || !isViewpointBody(viewBody)) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
applyOneViewpoint(viewBody, rels, keyMap, bodies);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
module.exports = {
|
|
154
|
+
applyViewpointDefaults,
|
|
155
|
+
dateFilterableKeys,
|
|
156
|
+
copyDateFilterableOntoView
|
|
157
|
+
};
|
|
@@ -9,6 +9,15 @@ const path = require('path');
|
|
|
9
9
|
const fsReal = require('../internal/fs-real-sync');
|
|
10
10
|
const { getIntegrationPath } = require('../utils/paths');
|
|
11
11
|
const { validateIntegrationDefinition } = require('./validate');
|
|
12
|
+
const {
|
|
13
|
+
canonicalDatasourceKeyMap,
|
|
14
|
+
datasourceFileName
|
|
15
|
+
} = require('./apply-datasource-keys');
|
|
16
|
+
const { applyBidRelationships } = require('./apply-relationships');
|
|
17
|
+
const { applyStaticAndEnterprise } = require('./apply-static-enterprise');
|
|
18
|
+
const { applyViewpointDefaults } = require('./apply-viewpoint-defaults');
|
|
19
|
+
const { stampCredentialTestEndpoint } = require('./apply-test-endpoint');
|
|
20
|
+
const { buildSystemFile } = require('./apply-system-file');
|
|
12
21
|
|
|
13
22
|
const STAMP_FILE = '.aifabrix-integration-definition.json';
|
|
14
23
|
|
|
@@ -96,6 +105,21 @@ function buildDatasourceSchema(labelField) {
|
|
|
96
105
|
};
|
|
97
106
|
}
|
|
98
107
|
|
|
108
|
+
function mergeBidSchemaProperties(body, ds) {
|
|
109
|
+
const extra = ds.metadataSchema && ds.metadataSchema.properties;
|
|
110
|
+
if (!extra || typeof extra !== 'object') {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (!body.metadataSchema || typeof body.metadataSchema !== 'object') {
|
|
114
|
+
body.metadataSchema = { type: 'object', properties: {} };
|
|
115
|
+
}
|
|
116
|
+
const schema = /** @type {Record<string, unknown>} */ (body.metadataSchema);
|
|
117
|
+
if (!schema.properties || typeof schema.properties !== 'object') {
|
|
118
|
+
schema.properties = {};
|
|
119
|
+
}
|
|
120
|
+
Object.assign(schema.properties, extra);
|
|
121
|
+
}
|
|
122
|
+
|
|
99
123
|
function enrichDatasourceFile(body, ds, enrichOptions) {
|
|
100
124
|
const { enrichDatasourceFromOpenApi } = require('./enrich-openapi-operations');
|
|
101
125
|
const openapiSourceRef =
|
|
@@ -133,6 +157,8 @@ function buildDatasourceFile(ds, systemKey, capabilities, sync, enrichOptions =
|
|
|
133
157
|
entityType: ds.entityType || 'recordStorage',
|
|
134
158
|
resourceType: ds.resourceType,
|
|
135
159
|
version: '1.0.0',
|
|
160
|
+
...(ds.storageType ? { storageType: ds.storageType } : {}),
|
|
161
|
+
...(ds.dimensions && typeof ds.dimensions === 'object' ? { dimensions: ds.dimensions } : {}),
|
|
136
162
|
capabilities: buildDatasourceCapabilities(caps, key),
|
|
137
163
|
// Schema sync is mode/schedule/batchSize only; BID sync.mode=incremental is operational intent.
|
|
138
164
|
sync: { mode: 'pull', schedule: /** @type {any} */ (sync).schedule || '0 */6 * * *', batchSize: 100 },
|
|
@@ -143,6 +169,7 @@ function buildDatasourceFile(ds, systemKey, capabilities, sync, enrichOptions =
|
|
|
143
169
|
// Mirror capabilities → openapi.operations + execution.cip.operations stubs (154.7).
|
|
144
170
|
repairSyncOperationsFromCapabilities(body, []);
|
|
145
171
|
seedPropertyKeysOnDatasource(body, ds.propertyKeys);
|
|
172
|
+
mergeBidSchemaProperties(body, ds);
|
|
146
173
|
enrichDatasourceFile(body, ds, enrichOptions);
|
|
147
174
|
return body;
|
|
148
175
|
}
|
|
@@ -192,42 +219,6 @@ function collectAssociationObjectTypes(datasources, systemOpenapiSourceRef, enri
|
|
|
192
219
|
return [...types];
|
|
193
220
|
}
|
|
194
221
|
|
|
195
|
-
/**
|
|
196
|
-
* @param {Record<string, unknown>} bid
|
|
197
|
-
* @returns {Record<string, unknown>}
|
|
198
|
-
*/
|
|
199
|
-
function buildSystemFile(bid) {
|
|
200
|
-
const system = /** @type {Record<string, unknown>} */ (bid.system);
|
|
201
|
-
const identity = /** @type {Record<string, unknown>} */ (bid.packageIdentity);
|
|
202
|
-
const refs = /** @type {Record<string, string>} */ (system.connectionRefs || {});
|
|
203
|
-
const tokenRef = refs.token || refs.apiKey || Object.values(refs)[0] || `kv://${identity.systemKey}/token`;
|
|
204
|
-
return {
|
|
205
|
-
key: system.key,
|
|
206
|
-
displayName: system.displayName || identity.displayName,
|
|
207
|
-
description: system.description || identity.displayName,
|
|
208
|
-
type: system.type || 'openapi',
|
|
209
|
-
enabled: true,
|
|
210
|
-
systemKind: system.systemKind || 'crm',
|
|
211
|
-
authentication: {
|
|
212
|
-
authType: 'credential',
|
|
213
|
-
credential: {
|
|
214
|
-
credentialKey: `${identity.systemKey}-cred`,
|
|
215
|
-
method: 'bearerToken',
|
|
216
|
-
variables: {
|
|
217
|
-
baseUrl: refs.baseUrl || 'https://example.invalid',
|
|
218
|
-
headerName: 'Authorization',
|
|
219
|
-
prefix: 'Bearer'
|
|
220
|
-
},
|
|
221
|
-
security: {
|
|
222
|
-
token: tokenRef
|
|
223
|
-
},
|
|
224
|
-
writeOnce: true
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
dataSources: (/** @type {any[]} */ (bid.datasources) || []).map((d) => d.key)
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
222
|
/**
|
|
232
223
|
* @param {Record<string, unknown>} bid
|
|
233
224
|
* @param {string[]} datasourceFiles
|
|
@@ -290,45 +281,73 @@ function buildEnvTemplate(bid) {
|
|
|
290
281
|
* nextStamp: Record<string, unknown>
|
|
291
282
|
* }}
|
|
292
283
|
*/
|
|
284
|
+
function remappedCapabilities(capabilities, keyMap) {
|
|
285
|
+
const out = {};
|
|
286
|
+
for (const [key, value] of Object.entries(capabilities || {})) {
|
|
287
|
+
out[keyMap.get(key) || key] = value;
|
|
288
|
+
}
|
|
289
|
+
return out;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function buildApplyStamp(bid, systemKey, identity) {
|
|
293
|
+
return {
|
|
294
|
+
schemaName: bid.schemaName,
|
|
295
|
+
schemaVersion: bid.schemaVersion,
|
|
296
|
+
definitionId: bid.definitionId,
|
|
297
|
+
definitionHash: bid.definitionHash,
|
|
298
|
+
suiteRunId: /** @type {any} */ (bid.meta).suiteRunId,
|
|
299
|
+
systemKey,
|
|
300
|
+
packageVersion: identity.packageVersion,
|
|
301
|
+
appliedAt: new Date().toISOString()
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
293
305
|
function buildPackageArtifacts(bid, systemKey, enrichOptions = {}) {
|
|
294
306
|
const identity = /** @type {Record<string, unknown>} */ (bid.packageIdentity);
|
|
295
307
|
const datasources = /** @type {Record<string, unknown>[]} */ (bid.datasources || []);
|
|
296
|
-
const capabilities =
|
|
308
|
+
const capabilities = remappedCapabilities(
|
|
309
|
+
/** @type {Record<string, string[]>} */ (bid.capabilities || {}),
|
|
310
|
+
canonicalDatasourceKeyMap(datasources, systemKey)
|
|
311
|
+
);
|
|
297
312
|
const sync = /** @type {Record<string, unknown>} */ (bid.sync || {});
|
|
298
|
-
const
|
|
313
|
+
const systemBlock = /** @type {Record<string, unknown>} */ (bid.system || {});
|
|
299
314
|
const systemOpenapiSourceRef =
|
|
300
|
-
typeof
|
|
315
|
+
typeof systemBlock.openapiSourceRef === 'string' ? systemBlock.openapiSourceRef : '';
|
|
301
316
|
const associationTargets = collectAssociationObjectTypes(
|
|
302
317
|
datasources,
|
|
303
318
|
systemOpenapiSourceRef,
|
|
304
319
|
enrichOptions
|
|
305
320
|
);
|
|
321
|
+
const keyMap = canonicalDatasourceKeyMap(datasources, systemKey);
|
|
306
322
|
const systemFile = `${systemKey}-system.json`;
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
system: buildSystemFile(bid),
|
|
313
|
-
dsFiles: datasources.map((ds) => ({
|
|
314
|
-
name: `${systemKey}-datasource-${ds.key}.json`,
|
|
315
|
-
body: buildDatasourceFile(ds, systemKey, capabilities, sync, {
|
|
323
|
+
const dsFiles = datasources.map((ds) => {
|
|
324
|
+
const canonicalKey = keyMap.get(String(ds.key)) || String(ds.key);
|
|
325
|
+
return {
|
|
326
|
+
name: datasourceFileName(systemKey, canonicalKey),
|
|
327
|
+
body: buildDatasourceFile({ ...ds, key: canonicalKey }, systemKey, capabilities, sync, {
|
|
316
328
|
...enrichOptions,
|
|
317
329
|
systemOpenapiSourceRef,
|
|
318
330
|
associationTargets
|
|
319
331
|
})
|
|
320
|
-
}
|
|
332
|
+
};
|
|
333
|
+
});
|
|
334
|
+
applyBidRelationships(dsFiles, /** @type {any[]} */ (bid.relationships) || [], keyMap);
|
|
335
|
+
applyStaticAndEnterprise(dsFiles, bid);
|
|
336
|
+
applyViewpointDefaults(dsFiles, /** @type {any[]} */ (bid.relationships) || [], keyMap);
|
|
337
|
+
const system = buildSystemFile(bid);
|
|
338
|
+
stampCredentialTestEndpoint(system, dsFiles);
|
|
339
|
+
return {
|
|
340
|
+
systemFile,
|
|
341
|
+
datasourceFiles: dsFiles.map((file) => file.name),
|
|
342
|
+
application: buildApplicationFile(
|
|
343
|
+
bid,
|
|
344
|
+
dsFiles.map((file) => file.name),
|
|
345
|
+
systemFile
|
|
346
|
+
),
|
|
347
|
+
system,
|
|
348
|
+
dsFiles,
|
|
321
349
|
envTemplate: buildEnvTemplate(bid),
|
|
322
|
-
nextStamp:
|
|
323
|
-
schemaName: bid.schemaName,
|
|
324
|
-
schemaVersion: bid.schemaVersion,
|
|
325
|
-
definitionId: bid.definitionId,
|
|
326
|
-
definitionHash: bid.definitionHash,
|
|
327
|
-
suiteRunId: /** @type {any} */ (bid.meta).suiteRunId,
|
|
328
|
-
systemKey,
|
|
329
|
-
packageVersion: identity.packageVersion,
|
|
330
|
-
appliedAt: new Date().toISOString()
|
|
331
|
-
}
|
|
350
|
+
nextStamp: buildApplyStamp(bid, systemKey, identity)
|
|
332
351
|
};
|
|
333
352
|
}
|
|
334
353
|
|
|
@@ -10,6 +10,7 @@ const fsReal = require('../internal/fs-real-sync');
|
|
|
10
10
|
const {
|
|
11
11
|
maybeEnrichCrmStyleFieldMappings
|
|
12
12
|
} = require('./enrich-crm-field-mappings');
|
|
13
|
+
const { pickBestMatchingOp, entityTokensFromDatasource } = require('./enrich-openapi-pick');
|
|
13
14
|
|
|
14
15
|
const PATH_PARAM_RE = /\{(\w+)\}/g;
|
|
15
16
|
|
|
@@ -171,7 +172,8 @@ function normalizeOp(method, opPath, op) {
|
|
|
171
172
|
method: String(method || '').toUpperCase(),
|
|
172
173
|
path: String(opPath),
|
|
173
174
|
operationId: typeof op.operationId === 'string' ? op.operationId : '',
|
|
174
|
-
pathParamCount: params.length
|
|
175
|
+
pathParamCount: params.length,
|
|
176
|
+
tags: Array.isArray(op.tags) ? op.tags.map((row) => String(row || '')) : []
|
|
175
177
|
};
|
|
176
178
|
}
|
|
177
179
|
|
|
@@ -212,12 +214,29 @@ function isBatchOrSearch(text) {
|
|
|
212
214
|
* @param {Array<{ method: string, path: string, operationId: string, pathParamCount: number }>} ops
|
|
213
215
|
* @returns {{ method: string, path: string, operationId: string } | null}
|
|
214
216
|
*/
|
|
215
|
-
function
|
|
216
|
-
const
|
|
217
|
-
|
|
217
|
+
function requiredQueryDefaults(doc, method, opPath) {
|
|
218
|
+
const out = {};
|
|
219
|
+
for (const param of operationParameters(doc, method, opPath)) {
|
|
220
|
+
if (!param || param.in !== 'query' || param.required !== true) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const name = String(param.name || '').trim();
|
|
224
|
+
if (!name) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const schema = param.schema && typeof param.schema === 'object' ? param.schema : {};
|
|
228
|
+
if (schema.default !== undefined) {
|
|
229
|
+
out[name] = schema.default;
|
|
230
|
+
} else if (typeof schema.minimum === 'number') {
|
|
231
|
+
out[name] = schema.minimum;
|
|
232
|
+
} else {
|
|
233
|
+
out[name] = `{{${name}}}`;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return out;
|
|
218
237
|
}
|
|
219
238
|
|
|
220
|
-
function pickOperationForCapability(capabilityKey, ops) {
|
|
239
|
+
function pickOperationForCapability(capabilityKey, ops, entityTokens) {
|
|
221
240
|
const key = String(capabilityKey || '').toLowerCase();
|
|
222
241
|
const candidates = ops.filter((op) => !isBatchOrSearch(`${op.path} ${op.operationId}`));
|
|
223
242
|
const rules = {
|
|
@@ -256,7 +275,7 @@ function pickOperationForCapability(capabilityKey, ops) {
|
|
|
256
275
|
if (!rule) {
|
|
257
276
|
return null;
|
|
258
277
|
}
|
|
259
|
-
return
|
|
278
|
+
return pickBestMatchingOp(candidates, rule.predicate, rule.idPattern, entityTokens);
|
|
260
279
|
}
|
|
261
280
|
|
|
262
281
|
/**
|
|
@@ -293,7 +312,11 @@ function bindOpenApiOperation(body, binding, capabilityKey) {
|
|
|
293
312
|
|
|
294
313
|
function createCipQuery(capabilityKey, bindOptions) {
|
|
295
314
|
const cap = String(capabilityKey || '').toLowerCase();
|
|
296
|
-
const query = {
|
|
315
|
+
const query = {
|
|
316
|
+
...(bindOptions.requiredQuery && typeof bindOptions.requiredQuery === 'object'
|
|
317
|
+
? bindOptions.requiredQuery
|
|
318
|
+
: {})
|
|
319
|
+
};
|
|
297
320
|
const targets = Array.isArray(bindOptions.associationTargets)
|
|
298
321
|
? bindOptions.associationTargets.map((row) => String(row || '').trim()).filter(Boolean)
|
|
299
322
|
: [];
|
|
@@ -394,10 +417,11 @@ function enrichDatasourceFromOpenApi(body, openapiSourceRef, options = {}) {
|
|
|
394
417
|
)
|
|
395
418
|
.map((row) => String(row || '').trim())
|
|
396
419
|
.filter((row) => row && row !== selfType);
|
|
420
|
+
const entityTokens = entityTokensFromDatasource(body);
|
|
397
421
|
const bound = [];
|
|
398
422
|
let samplePath = '';
|
|
399
423
|
for (const capabilityKey of caps) {
|
|
400
|
-
const picked = pickOperationForCapability(capabilityKey, indexed);
|
|
424
|
+
const picked = pickOperationForCapability(capabilityKey, indexed, entityTokens);
|
|
401
425
|
if (!picked) {
|
|
402
426
|
continue;
|
|
403
427
|
}
|
|
@@ -408,7 +432,8 @@ function enrichDatasourceFromOpenApi(body, openapiSourceRef, options = {}) {
|
|
|
408
432
|
picked.path
|
|
409
433
|
),
|
|
410
434
|
associationTargets,
|
|
411
|
-
cursorPagination: operationCursorPagination(doc, picked.method, picked.path)
|
|
435
|
+
cursorPagination: operationCursorPagination(doc, picked.method, picked.path),
|
|
436
|
+
requiredQuery: requiredQueryDefaults(doc, picked.method, picked.path)
|
|
412
437
|
});
|
|
413
438
|
bound.push(capabilityKey);
|
|
414
439
|
if (!samplePath) {
|
|
@@ -429,5 +454,6 @@ module.exports = {
|
|
|
429
454
|
enrichDatasourceFromOpenApi,
|
|
430
455
|
objectTypeFromOpenApiPath,
|
|
431
456
|
operationDeclaresAssociationsQuery,
|
|
432
|
-
operationCursorPagination
|
|
457
|
+
operationCursorPagination,
|
|
458
|
+
requiredQueryDefaults
|
|
433
459
|
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score OpenAPI operations by datasource entity tokens.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Prefer path/tag overlap over first GET in a multi-entity spec
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {Record<string, unknown>} body
|
|
11
|
+
* @returns {string[]}
|
|
12
|
+
*/
|
|
13
|
+
function entityTokensFromDatasource(body) {
|
|
14
|
+
const tokens = new Set();
|
|
15
|
+
for (const raw of [body.key, body.resourceType, body.displayName]) {
|
|
16
|
+
const value = String(raw || '').trim().toLowerCase();
|
|
17
|
+
if (!value) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
tokens.add(value);
|
|
21
|
+
for (const part of value.split(/[-_]/g)) {
|
|
22
|
+
if (part.length > 1) {
|
|
23
|
+
tokens.add(part);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return [...tokens];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {{ path?: string, operationId?: string, tags?: string[] }} op
|
|
32
|
+
* @param {string[]} tokens
|
|
33
|
+
* @returns {number}
|
|
34
|
+
*/
|
|
35
|
+
function scoreOpForEntity(op, tokens) {
|
|
36
|
+
if (!Array.isArray(tokens) || tokens.length === 0) {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
const path = String(op.path || '').toLowerCase();
|
|
40
|
+
const id = String(op.operationId || '').toLowerCase();
|
|
41
|
+
const tags = Array.isArray(op.tags)
|
|
42
|
+
? op.tags.map((row) => String(row || '').toLowerCase()).join(' ')
|
|
43
|
+
: '';
|
|
44
|
+
const hay = `${path} ${id} ${tags}`;
|
|
45
|
+
const segments = path.split('/').filter(Boolean);
|
|
46
|
+
let score = 0;
|
|
47
|
+
for (const token of tokens) {
|
|
48
|
+
if (segments.includes(token)) {
|
|
49
|
+
score += 20;
|
|
50
|
+
} else if (hay.includes(token)) {
|
|
51
|
+
score += 10;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return score;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {Array<{ method: string, path: string, operationId: string }>} candidates
|
|
59
|
+
* @param {(op: object) => boolean} predicate
|
|
60
|
+
* @param {RegExp} idPattern
|
|
61
|
+
* @param {string[]} [entityTokens]
|
|
62
|
+
* @returns {object | null}
|
|
63
|
+
*/
|
|
64
|
+
function pickBestMatchingOp(candidates, predicate, idPattern, entityTokens) {
|
|
65
|
+
const hits = candidates.filter(predicate);
|
|
66
|
+
if (hits.length === 0) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const tokens = Array.isArray(entityTokens) ? entityTokens : [];
|
|
70
|
+
if (tokens.length > 0) {
|
|
71
|
+
const scored = hits.map((op) => ({
|
|
72
|
+
op,
|
|
73
|
+
score: scoreOpForEntity(op, tokens) + (idPattern.test(op.operationId) ? 5 : 0)
|
|
74
|
+
}));
|
|
75
|
+
scored.sort((left, right) => right.score - left.score);
|
|
76
|
+
if (scored[0].score > 0) {
|
|
77
|
+
return scored[0].op;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return hits.find((op) => idPattern.test(op.operationId)) || hits[0] || null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = {
|
|
84
|
+
entityTokensFromDatasource,
|
|
85
|
+
scoreOpForEntity,
|
|
86
|
+
pickBestMatchingOp
|
|
87
|
+
};
|
|
@@ -11,7 +11,9 @@ const { VERDICT } = require('./product-model');
|
|
|
11
11
|
|
|
12
12
|
const GOVERNANCE_SCENARIOS_MISSING = 'GOVERNANCE_SCENARIOS_MISSING';
|
|
13
13
|
const GOVERNANCE_NOT_VERIFIED = 'GOVERNANCE_NOT_VERIFIED';
|
|
14
|
+
const OPERATIONS_NOT_VERIFIED = 'OPERATIONS_NOT_VERIFIED';
|
|
14
15
|
const ROLE_ASSISTANT_GOVERNANCE_WARNING = 'ROLE_ASSISTANT_GOVERNANCE_PACKS';
|
|
16
|
+
const ROLE_ASSISTANT_OPERATIONS_WARNING = 'ROLE_ASSISTANT_CS_OPERATIONS';
|
|
15
17
|
|
|
16
18
|
const VERDICT_RANK = Object.freeze({
|
|
17
19
|
[VERDICT.FAILED]: 4,
|
|
@@ -70,37 +72,50 @@ function rollupGovernanceFromDatasources(datasources) {
|
|
|
70
72
|
return worst;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
function
|
|
75
|
+
function stripCsNotVerified(recommendations) {
|
|
74
76
|
if (!Array.isArray(recommendations)) {
|
|
75
77
|
return [];
|
|
76
78
|
}
|
|
77
|
-
return recommendations.filter(
|
|
79
|
+
return recommendations.filter(
|
|
80
|
+
(rec) =>
|
|
81
|
+
rec && rec.code !== GOVERNANCE_NOT_VERIFIED && rec.code !== OPERATIONS_NOT_VERIFIED
|
|
82
|
+
);
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
function
|
|
85
|
+
function appendRoleAssistantCsWarning(warnings, code, message) {
|
|
81
86
|
const next = Array.isArray(warnings) ? [...warnings] : [];
|
|
82
|
-
const exists = next.some((row) => row && row.code ===
|
|
87
|
+
const exists = next.some((row) => row && row.code === code);
|
|
83
88
|
if (!exists) {
|
|
84
|
-
next.push({
|
|
85
|
-
code: ROLE_ASSISTANT_GOVERNANCE_WARNING,
|
|
86
|
-
message:
|
|
87
|
-
'Role Assistant datasources do not use Connected System governance packs. ' +
|
|
88
|
-
'Isolation is Work Hub cases and role-assistant.yaml.'
|
|
89
|
-
});
|
|
89
|
+
next.push({ code, message });
|
|
90
90
|
}
|
|
91
91
|
return next;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
function remapRoleAssistantGovernanceReport(report) {
|
|
100
|
-
if (!report || typeof report !== 'object') {
|
|
101
|
-
return report;
|
|
94
|
+
function notApplicableCsPillar(block, errorCode) {
|
|
95
|
+
const base = block && typeof block === 'object' ? { ...block } : {};
|
|
96
|
+
base.verdict = VERDICT.NOT_APPLICABLE;
|
|
97
|
+
if (errorCode) {
|
|
98
|
+
base.errorCode = errorCode;
|
|
102
99
|
}
|
|
103
|
-
|
|
100
|
+
return base;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function remapCsPillars(next) {
|
|
104
|
+
let remapped = false;
|
|
105
|
+
const opsVerdict = String((next.operations && next.operations.verdict) || '');
|
|
106
|
+
if (opsVerdict === VERDICT.FAILED || opsVerdict === VERDICT.NOT_VERIFIED) {
|
|
107
|
+
next.operations = notApplicableCsPillar(next.operations, OPERATIONS_NOT_VERIFIED);
|
|
108
|
+
remapped = true;
|
|
109
|
+
}
|
|
110
|
+
const govVerdict = String((next.governance && next.governance.verdict) || '');
|
|
111
|
+
if (govVerdict === VERDICT.FAILED || govVerdict === VERDICT.NOT_VERIFIED) {
|
|
112
|
+
next.governance = notApplicableCsPillar(next.governance, GOVERNANCE_NOT_VERIFIED);
|
|
113
|
+
remapped = true;
|
|
114
|
+
}
|
|
115
|
+
return remapped;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function remapMissingPackRows(report, next) {
|
|
104
119
|
let remapped = false;
|
|
105
120
|
if (Array.isArray(report.datasources)) {
|
|
106
121
|
next.datasources = report.datasources.map((row) => {
|
|
@@ -120,11 +135,30 @@ function remapRoleAssistantGovernanceReport(report) {
|
|
|
120
135
|
next.governance = notApplicableMissingPack(next.governance);
|
|
121
136
|
remapped = true;
|
|
122
137
|
}
|
|
138
|
+
return remapped;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function remapRoleAssistantGovernanceReport(report) {
|
|
142
|
+
if (!report || typeof report !== 'object') {
|
|
143
|
+
return report;
|
|
144
|
+
}
|
|
145
|
+
const next = { ...report };
|
|
146
|
+
const remapped = remapMissingPackRows(report, next) || remapCsPillars(next);
|
|
123
147
|
if (!remapped) {
|
|
124
148
|
return report;
|
|
125
149
|
}
|
|
126
|
-
next.recommendations =
|
|
127
|
-
next.warnings =
|
|
150
|
+
next.recommendations = stripCsNotVerified(report.recommendations);
|
|
151
|
+
next.warnings = appendRoleAssistantCsWarning(
|
|
152
|
+
report.warnings,
|
|
153
|
+
ROLE_ASSISTANT_GOVERNANCE_WARNING,
|
|
154
|
+
'Role Assistant datasources do not use Connected System governance packs. ' +
|
|
155
|
+
'Isolation is Work Hub cases and role-assistant.yaml.'
|
|
156
|
+
);
|
|
157
|
+
next.warnings = appendRoleAssistantCsWarning(
|
|
158
|
+
next.warnings,
|
|
159
|
+
ROLE_ASSISTANT_OPERATIONS_WARNING,
|
|
160
|
+
'Role Assistant prove does not require Connected System operations verification.'
|
|
161
|
+
);
|
|
128
162
|
return next;
|
|
129
163
|
}
|
|
130
164
|
|
|
@@ -140,6 +174,7 @@ function lifecyclePillarSatisfied(verdict) {
|
|
|
140
174
|
module.exports = {
|
|
141
175
|
GOVERNANCE_SCENARIOS_MISSING,
|
|
142
176
|
ROLE_ASSISTANT_GOVERNANCE_WARNING,
|
|
177
|
+
ROLE_ASSISTANT_OPERATIONS_WARNING,
|
|
143
178
|
governanceIsMissingPack,
|
|
144
179
|
remapRoleAssistantGovernanceReport,
|
|
145
180
|
lifecyclePillarSatisfied
|
|
@@ -49,6 +49,7 @@ const CAPABILITIES = Object.freeze([
|
|
|
49
49
|
{ method: 'GET', route: '/systems/:systemKey/lifecycle', handlerId: 'getLifecycleReport', operationType: 'certify.read', mutating: false },
|
|
50
50
|
{ method: 'POST', route: '/systems/:systemKey/upload', handlerId: 'runUpload', operationType: 'apply.dev', mutating: true },
|
|
51
51
|
{ method: 'POST', route: '/systems/:systemKey/deploy', handlerId: 'runDeploySystem', operationType: 'apply.prod', mutating: true },
|
|
52
|
+
{ method: 'POST', route: '/systems/:systemKey/download', handlerId: 'runDownload', operationType: 'workspace.write', mutating: true },
|
|
52
53
|
{
|
|
53
54
|
method: 'POST',
|
|
54
55
|
route: '/systems/:systemKey/datasources/:datasourceKey/protection/upload',
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const workspaceContext = require('./workspace-context');
|
|
8
8
|
const runUpload = require('./run-upload');
|
|
9
9
|
const runDeploy = require('./run-deploy');
|
|
10
|
+
const runDownload = require('./run-download');
|
|
10
11
|
const runProtection = require('./run-protection');
|
|
11
12
|
const runWizard = require('./run-wizard');
|
|
12
13
|
const runRepair = require('./run-repair');
|
|
@@ -32,6 +33,7 @@ module.exports = {
|
|
|
32
33
|
...workspaceContext,
|
|
33
34
|
...runUpload,
|
|
34
35
|
...runDeploy,
|
|
36
|
+
...runDownload,
|
|
35
37
|
...runProtection,
|
|
36
38
|
...runWizard,
|
|
37
39
|
...runRepair,
|