@aifabrix/builder 2.45.0 → 2.45.5
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/docs-rules.mdc +3 -1
- 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/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
- package/jest.projects.js +44 -1
- package/lib/api/agent-metadata-validation.api.js +93 -0
- package/lib/api/audit-api-helpers.js +68 -0
- package/lib/api/audit.api.js +119 -0
- package/lib/api/auth-cache.api.js +44 -0
- package/lib/api/certificates.api.js +4 -4
- package/lib/api/credential.api.js +2 -2
- package/lib/api/dataplane-health.api.js +137 -0
- package/lib/api/dataplane-sync.api.js +27 -0
- package/lib/api/datasources-core.api.js +21 -18
- package/lib/api/datasources-extended.api.js +22 -22
- package/lib/api/dimensions.api.js +3 -0
- package/lib/api/external-systems.api.js +13 -13
- package/lib/api/governance-scenarios.api.js +39 -0
- package/lib/api/groups.api.js +79 -0
- package/lib/api/index.js +45 -2
- package/lib/api/pipeline.api.js +4 -4
- package/lib/api/protection.api.js +157 -0
- package/lib/api/records-bulk.api.js +30 -0
- package/lib/api/records-search-parse.js +49 -0
- package/lib/api/records-search.api.js +29 -0
- package/lib/api/types/agent-metadata-validation.types.js +67 -0
- package/lib/api/types/audit.types.js +72 -0
- package/lib/api/types/dataplane-health.types.js +27 -0
- package/lib/api/types/dimensions.types.js +2 -0
- package/lib/api/types/governance-scenarios.types.js +39 -0
- package/lib/api/types/protection.types.js +69 -0
- package/lib/api/types/records-bulk.types.js +35 -0
- package/lib/api/types/records-search.types.js +28 -0
- package/lib/api/user-groups.api.js +50 -0
- package/lib/api/users.api.js +95 -0
- package/lib/api/validation-run.api.js +3 -3
- package/lib/api/validation-runner.js +3 -3
- package/lib/api/wizard-platform.api.js +3 -3
- package/lib/api/wizard.api.js +21 -21
- package/lib/app/deploy.js +34 -19
- package/lib/cli/index.js +4 -2
- package/lib/cli/infra-guided.js +22 -3
- package/lib/cli/setup-app.help.js +50 -2
- package/lib/cli/setup-app.js +33 -24
- package/lib/cli/setup-app.test-commands.js +80 -21
- package/lib/cli/setup-auth.js +30 -3
- package/lib/cli/setup-external-system.js +37 -3
- package/lib/cli/setup-utility-help-after.js +45 -0
- package/lib/cli/setup-utility-resolve.js +2 -2
- package/lib/cli/setup-utility.js +99 -81
- package/lib/commands/auth-status-dataplane-version.js +231 -0
- package/lib/commands/auth-status-display.js +94 -0
- package/lib/commands/auth-status.js +70 -6
- package/lib/commands/credential-push.js +10 -5
- package/lib/commands/datasource-load-export-cli.js +178 -0
- package/lib/commands/datasource-test-trust-cli.js +114 -0
- package/lib/commands/datasource-unified-test-cli.js +25 -17
- package/lib/commands/datasource-unified-test-cli.options.js +18 -3
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
- package/lib/commands/datasource-verify-audit-cli.js +96 -0
- package/lib/commands/datasource.js +68 -1
- package/lib/commands/dimension-value.js +43 -13
- package/lib/commands/dimension.js +38 -7
- package/lib/commands/identity-apply-sync.js +131 -0
- package/lib/commands/identity-group-cli.js +146 -0
- package/lib/commands/identity-membership-role-cache.js +175 -0
- package/lib/commands/identity-shared.js +94 -0
- package/lib/commands/identity-user-cli.js +158 -0
- package/lib/commands/identity.js +43 -0
- package/lib/commands/login.js +46 -16
- package/lib/commands/protection-cli-leaves.js +286 -0
- package/lib/commands/protection.js +50 -0
- package/lib/commands/repair.js +13 -3
- package/lib/commands/test-e2e-external.js +40 -9
- package/lib/commands/test-governance-cli-options.js +47 -0
- package/lib/commands/test-governance-command-action.js +55 -0
- package/lib/commands/test-governance-external.js +88 -0
- package/lib/commands/test-trust-cli-options.js +32 -0
- package/lib/commands/test-trust-command-action.js +118 -0
- package/lib/commands/test-trust-external.js +127 -0
- package/lib/commands/upload.js +34 -13
- package/lib/commands/wizard-core.js +3 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/datasource/agent-trust-debug-log.js +45 -0
- package/lib/datasource/agent-trust-fetch.js +115 -0
- package/lib/datasource/agent-trust-map.js +101 -0
- package/lib/datasource/agent-trust-mock.js +44 -0
- package/lib/datasource/agent-trust-run.js +93 -0
- package/lib/datasource/agent-trust-timeout.js +25 -0
- package/lib/datasource/audit-evidence-display.js +80 -0
- package/lib/datasource/audit-evidence-extract-debug.js +103 -0
- package/lib/datasource/audit-evidence-extract.js +177 -0
- package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
- package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
- package/lib/datasource/audit-evidence-poll.js +109 -0
- package/lib/datasource/audit-evidence-run.js +177 -0
- package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
- package/lib/datasource/audit-evidence-verify-matrix.js +177 -0
- package/lib/datasource/audit-evidence-verify.js +108 -0
- package/lib/datasource/bulk-loader-run-batches.js +88 -0
- package/lib/datasource/bulk-loader-service-retry.js +52 -0
- package/lib/datasource/bulk-loader-service.js +127 -0
- package/lib/datasource/capability/run-capability-dimension.js +2 -1
- package/lib/datasource/datasource-exporter-resolve.js +82 -0
- package/lib/datasource/datasource-exporter-service.js +144 -0
- package/lib/datasource/datasource-identifier.js +148 -0
- package/lib/datasource/datasource-load-export-context.js +92 -0
- package/lib/datasource/integration-context.js +6 -4
- package/lib/datasource/local-data-paths.js +145 -0
- package/lib/datasource/log-cleaner.js +241 -0
- package/lib/datasource/log-viewer.js +111 -6
- package/lib/datasource/record-file-parser.js +85 -0
- package/lib/datasource/record-mapper.js +129 -0
- package/lib/datasource/resolve-app.js +74 -55
- package/lib/datasource/test-e2e.js +26 -2
- package/lib/datasource/unified-validation-run-resolve.js +45 -12
- package/lib/datasource/unified-validation-run.js +43 -17
- package/lib/datasource/validate.js +37 -20
- package/lib/external-system/test-system-level.js +25 -4
- package/lib/external-system/test.js +3 -1
- package/lib/governance/governance-pack-loader.js +70 -0
- package/lib/governance/governance-run-display.js +119 -0
- package/lib/identity/identity-apply-core.js +108 -0
- package/lib/identity/identity-apply-phases.js +244 -0
- package/lib/identity/identity-apply-service.js +77 -0
- package/lib/identity/identity-csv-parser.js +114 -0
- package/lib/internal/fs-real-sync.js +29 -1
- package/lib/protection/auth-context.js +45 -0
- package/lib/protection/convert-batch.js +90 -0
- package/lib/protection/load.js +41 -0
- package/lib/protection/paths.js +158 -0
- package/lib/protection/preflight-datasource-ready.js +46 -0
- package/lib/protection/protection-create-probe-lines.js +142 -0
- package/lib/protection/protection-create-probes.js +95 -0
- package/lib/protection/protection-create-scaffold.js +281 -0
- package/lib/protection/protection-display-helpers.js +445 -0
- package/lib/protection/protection-display.js +215 -0
- package/lib/protection/protection-preset-registry.js +97 -0
- package/lib/protection/report-exit.js +62 -0
- package/lib/protection/resolve.js +202 -0
- package/lib/protection/run-commands-validate.js +130 -0
- package/lib/protection/run-commands.js +216 -0
- package/lib/protection/run-protection-create-helpers.js +134 -0
- package/lib/protection/run-protection-create-probes-flow.js +43 -0
- package/lib/protection/run-protection-create.js +191 -0
- package/lib/protection/scope.js +22 -0
- package/lib/protection/sync-after-upload.js +64 -0
- package/lib/protection/upload-batch.js +127 -0
- package/lib/protection/validate-batch.js +113 -0
- package/lib/protection/validate-local.js +65 -0
- package/lib/resolvers/dimension-file.js +29 -4
- package/lib/schema/external-datasource.schema.json +47 -13
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/protection.schema.json +374 -0
- package/lib/schema/type/credential-field-registry.json +636 -0
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/agent-trust-run-display.js +231 -0
- package/lib/utils/agent-trust-run-exit.js +59 -0
- package/lib/utils/agent-trust-wait-ui.js +94 -0
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/credential-push-ui.js +90 -0
- package/lib/utils/dataplane-cli-version-gate.js +202 -0
- package/lib/utils/dataplane-cli-version-help.js +74 -0
- package/lib/utils/datasource-export-display.js +137 -0
- package/lib/utils/datasource-load-display.js +174 -0
- package/lib/utils/datasource-load-export-ui.js +120 -0
- package/lib/utils/datasource-test-run-capability-scope.js +3 -3
- package/lib/utils/datasource-test-run-display.js +3 -3
- package/lib/utils/datasource-test-run-tty-log.js +5 -1
- package/lib/utils/help-builder.js +30 -24
- package/lib/utils/manifest-source-emit.js +22 -0
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/upload-pipeline-ui.js +91 -0
- package/lib/utils/validation-poll-ui.js +14 -7
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +1 -1
- package/templates/applications/dataplane/env.template +13 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- package/templates/external-system/README.md.hbs +56 -8
|
@@ -5,10 +5,12 @@ alwaysApply: true
|
|
|
5
5
|
|
|
6
6
|
## Audience
|
|
7
7
|
|
|
8
|
-
Documents under **docs/** (including **docs/commands/**) are **CLI
|
|
8
|
+
Documents under **docs/** (including **docs/commands/**) are **public CLI user documentation**. The audience is people who use the AI Fabrix Builder CLI or integrate it into workflows—they may **not** have access to private monorepos (dataplane, miso-controller, internal plans). They do not need to know how the CLI talks to the Controller or Dataplane over HTTP.
|
|
9
9
|
|
|
10
10
|
## Do Not Include in CLI User Docs
|
|
11
11
|
|
|
12
|
+
- **Links or paths into other product repos (FORBIDDEN)** – No markdown links, examples, or prerequisites that point at private/sibling repositories or their trees: `../../../aifabrix-dataplane/...`, `../../aifabrix-miso/...`, `packages/miso-controller/...`, `integration/<fixture>/README.md` in another repo, `.cursor/plans/` anywhere, `/workspace/...` monorepo layouts, or “see the dataplane/miso-controller repo”. **Only** cross-link within **`docs/`** and use on-disk paths the user owns (`integration/<systemKey>/...`, `builder/<appKey>/...`, `~/.aifabrix/...`).
|
|
13
|
+
- **Internal plan or ticket IDs** – No “Plan 407.1”, “plan section 2.3”, or similar; describe behavior in user terms.
|
|
12
14
|
- **REST API details** – No HTTP methods, URL paths, or endpoint names (e.g. `GET /api/v1/...`, `POST .../pipeline/upload`).
|
|
13
15
|
- **Request/response shapes** – No payload structures, status codes, or field names from backend APIs.
|
|
14
16
|
- **Backend implementation terms** – Avoid referring to “pipeline config endpoint”, “upload endpoint”, or similar; describe what the **command** does from the user’s perspective.
|
|
@@ -2,7 +2,7 @@ appName: wizard-e2e-env-vars
|
|
|
2
2
|
mode: create-system
|
|
3
3
|
source:
|
|
4
4
|
type: openapi-file
|
|
5
|
-
filePath:
|
|
5
|
+
filePath: ./integration/hubspot-test/companies.json
|
|
6
6
|
deployment:
|
|
7
7
|
controller: ${CONTROLLER_URL}
|
|
8
8
|
dataplane: ${DATAPLANE_URL}
|
package/jest.projects.js
CHANGED
|
@@ -278,7 +278,35 @@ const defaultProject = {
|
|
|
278
278
|
'/tests/lib/datasource/run-capability-remove.test.js',
|
|
279
279
|
'\\\\tests\\\\lib\\\\datasource\\\\run-capability-remove.test.js',
|
|
280
280
|
'lib/datasource/run-capability-remove.test.js',
|
|
281
|
-
'run-capability-remove\\.test\\.js'
|
|
281
|
+
'run-capability-remove\\.test\\.js',
|
|
282
|
+
'/tests/lib/datasource/log-cleaner.test.js',
|
|
283
|
+
'\\\\tests\\\\lib\\\\datasource\\\\log-cleaner.test.js',
|
|
284
|
+
'lib/datasource/log-cleaner.test.js',
|
|
285
|
+
'log-cleaner\\.test\\.js',
|
|
286
|
+
'/tests/lib/datasource/datasource-exporter-service.test.js',
|
|
287
|
+
'\\\\tests\\\\lib\\\\datasource\\\\datasource-exporter-service.test.js',
|
|
288
|
+
'lib/datasource/datasource-exporter-service.test.js',
|
|
289
|
+
'datasource-exporter-service\\.test\\.js',
|
|
290
|
+
'/tests/lib/protection/paths.test.js',
|
|
291
|
+
'\\\\tests\\\\lib\\\\protection\\\\paths.test.js',
|
|
292
|
+
'lib/protection/paths.test.js',
|
|
293
|
+
'protection/paths\\.test\\.js',
|
|
294
|
+
'/tests/lib/protection/protection-resolve.test.js',
|
|
295
|
+
'\\\\tests\\\\lib\\\\protection\\\\protection-resolve.test.js',
|
|
296
|
+
'lib/protection/protection-resolve.test.js',
|
|
297
|
+
'protection-resolve\\.test\\.js',
|
|
298
|
+
'/tests/lib/protection/run-protection-create-helpers.test.js',
|
|
299
|
+
'\\\\tests\\\\lib\\\\protection\\\\run-protection-create-helpers.test.js',
|
|
300
|
+
'lib/protection/run-protection-create-helpers.test.js',
|
|
301
|
+
'run-protection-create-helpers\\.test\\.js',
|
|
302
|
+
'/tests/lib/governance/governance-pack-loader.test.js',
|
|
303
|
+
'\\\\tests\\\\lib\\\\governance\\\\governance-pack-loader.test.js',
|
|
304
|
+
'lib/governance/governance-pack-loader.test.js',
|
|
305
|
+
'governance-pack-loader\\.test\\.js',
|
|
306
|
+
'/tests/lib/protection/validate-batch.test.js',
|
|
307
|
+
'\\\\tests\\\\lib\\\\protection\\\\validate-batch.test.js',
|
|
308
|
+
'lib/protection/validate-batch.test.js',
|
|
309
|
+
'validate-batch\\.test\\.js'
|
|
282
310
|
];
|
|
283
311
|
if (process.env.INCLUDE_LOCAL_TESTS !== 'true') {
|
|
284
312
|
patterns.push('/tests/local/');
|
|
@@ -404,6 +432,21 @@ const isolatedProjects = [
|
|
|
404
432
|
'**/tests/lib/datasource/run-capability-diff.test.js',
|
|
405
433
|
'**/tests/lib/datasource/run-capability-edit.test.js',
|
|
406
434
|
'**/tests/lib/datasource/run-capability-remove.test.js'
|
|
435
|
+
]),
|
|
436
|
+
makeIsolatedProject('log-cleaner', ['**/tests/lib/datasource/log-cleaner.test.js']),
|
|
437
|
+
makeIsolatedProject('datasource-exporter-service', [
|
|
438
|
+
'**/tests/lib/datasource/datasource-exporter-service.test.js'
|
|
439
|
+
]),
|
|
440
|
+
makeIsolatedProject('protection-paths', ['**/tests/lib/protection/paths.test.js']),
|
|
441
|
+
makeIsolatedProject('protection-resolve', ['**/tests/lib/protection/protection-resolve.test.js']),
|
|
442
|
+
makeIsolatedProject('protection-create-helpers', [
|
|
443
|
+
'**/tests/lib/protection/run-protection-create-helpers.test.js'
|
|
444
|
+
]),
|
|
445
|
+
makeIsolatedProject('governance-pack-loader', [
|
|
446
|
+
'**/tests/lib/governance/governance-pack-loader.test.js'
|
|
447
|
+
]),
|
|
448
|
+
makeIsolatedProject('protection-validate-batch', [
|
|
449
|
+
'**/tests/lib/protection/validate-batch.test.js'
|
|
407
450
|
])
|
|
408
451
|
];
|
|
409
452
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Agent metadata validation API (dataplane 404.5)
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { createDataplaneApiClient } = require('./index');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Run agent metadata validation for a datasource.
|
|
11
|
+
* POST /api/v1/external/{sourceIdOrKey}/agent-metadata-validation
|
|
12
|
+
* @requiresPermission {Dataplane} external-data-source:update
|
|
13
|
+
* @async
|
|
14
|
+
* @function runAgentMetadataValidation
|
|
15
|
+
* @param {string} dataplaneUrl - Dataplane base URL
|
|
16
|
+
* @param {string} sourceIdOrKey - Datasource key or ID
|
|
17
|
+
* @param {Object} authConfig - Authentication configuration
|
|
18
|
+
* @param {import('./types/agent-metadata-validation.types').AgentMetadataValidationRunRequest} [body]
|
|
19
|
+
* @returns {Promise<import('./types/agent-metadata-validation.types').AgentMetadataValidationRunResponse>}
|
|
20
|
+
*/
|
|
21
|
+
async function runAgentMetadataValidation(
|
|
22
|
+
dataplaneUrl,
|
|
23
|
+
sourceIdOrKey,
|
|
24
|
+
authConfig,
|
|
25
|
+
body = {},
|
|
26
|
+
opts = {}
|
|
27
|
+
) {
|
|
28
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
29
|
+
const requestOpts = { body };
|
|
30
|
+
if (opts.timeoutMs !== undefined && opts.timeoutMs !== null) {
|
|
31
|
+
requestOpts.timeoutMs = opts.timeoutMs;
|
|
32
|
+
}
|
|
33
|
+
return await client.post(
|
|
34
|
+
`/api/v1/external/${encodeURIComponent(sourceIdOrKey)}/agent-metadata-validation`,
|
|
35
|
+
requestOpts
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get latest agent metadata validation result.
|
|
41
|
+
* GET /api/v1/external/{sourceIdOrKey}/agent-validation
|
|
42
|
+
* @requiresPermission {Dataplane} external-data-source:read
|
|
43
|
+
* @async
|
|
44
|
+
* @function getLatestAgentMetadataValidation
|
|
45
|
+
* @param {string} dataplaneUrl - Dataplane base URL
|
|
46
|
+
* @param {string} sourceIdOrKey - Datasource key or ID
|
|
47
|
+
* @param {Object} authConfig - Authentication configuration
|
|
48
|
+
* @returns {Promise<import('./types/agent-metadata-validation.types').AgentMetadataValidationResult>}
|
|
49
|
+
*/
|
|
50
|
+
async function getLatestAgentMetadataValidation(
|
|
51
|
+
dataplaneUrl,
|
|
52
|
+
sourceIdOrKey,
|
|
53
|
+
authConfig,
|
|
54
|
+
opts = {}
|
|
55
|
+
) {
|
|
56
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
57
|
+
const requestOpts = {};
|
|
58
|
+
if (opts.timeoutMs !== undefined && opts.timeoutMs !== null) {
|
|
59
|
+
requestOpts.timeoutMs = opts.timeoutMs;
|
|
60
|
+
}
|
|
61
|
+
return await client.get(
|
|
62
|
+
`/api/v1/external/${encodeURIComponent(sourceIdOrKey)}/agent-validation`,
|
|
63
|
+
requestOpts
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* List agent metadata validation history.
|
|
69
|
+
* GET /api/v1/external/{sourceIdOrKey}/agent-validation/history
|
|
70
|
+
* @requiresPermission {Dataplane} external-data-source:read
|
|
71
|
+
* @async
|
|
72
|
+
* @function listAgentMetadataValidationHistory
|
|
73
|
+
* @param {string} dataplaneUrl - Dataplane base URL
|
|
74
|
+
* @param {string} sourceIdOrKey - Datasource key or ID
|
|
75
|
+
* @param {Object} authConfig - Authentication configuration
|
|
76
|
+
* @returns {Promise<import('./types/agent-metadata-validation.types').AgentMetadataValidationHistoryItem[]>}
|
|
77
|
+
*/
|
|
78
|
+
async function listAgentMetadataValidationHistory(
|
|
79
|
+
dataplaneUrl,
|
|
80
|
+
sourceIdOrKey,
|
|
81
|
+
authConfig
|
|
82
|
+
) {
|
|
83
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
84
|
+
return await client.get(
|
|
85
|
+
`/api/v1/external/${encodeURIComponent(sourceIdOrKey)}/agent-validation/history`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = {
|
|
90
|
+
runAgentMetadataValidation,
|
|
91
|
+
getLatestAgentMetadataValidation,
|
|
92
|
+
listAgentMetadataValidationHistory
|
|
93
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared helpers for dataplane audit API responses
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {*} res
|
|
13
|
+
* @throws {Error}
|
|
14
|
+
*/
|
|
15
|
+
function assertAuditApiSuccess(res) {
|
|
16
|
+
if (!res || typeof res !== 'object') {
|
|
17
|
+
throw new Error('Audit API returned an empty response');
|
|
18
|
+
}
|
|
19
|
+
if (res.success === false) {
|
|
20
|
+
const msg =
|
|
21
|
+
(res.error && (res.error.formattedError || res.error.error || res.error.message)) ||
|
|
22
|
+
res.formattedError ||
|
|
23
|
+
'Audit API request failed';
|
|
24
|
+
const err = new Error(msg);
|
|
25
|
+
if (res.status) err.status = res.status;
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {*} res
|
|
32
|
+
* @returns {{ data: Array, meta: Object|null, raw: Object|null }}
|
|
33
|
+
*/
|
|
34
|
+
function unwrapPaginatedAuditList(res) {
|
|
35
|
+
assertAuditApiSuccess(res);
|
|
36
|
+
const body = unwrapApiData(res);
|
|
37
|
+
if (!body || typeof body !== 'object') {
|
|
38
|
+
return { data: [], meta: null, raw: null };
|
|
39
|
+
}
|
|
40
|
+
const data = Array.isArray(body.data)
|
|
41
|
+
? body.data
|
|
42
|
+
: Array.isArray(body.items)
|
|
43
|
+
? body.items
|
|
44
|
+
: [];
|
|
45
|
+
const meta = body.meta && typeof body.meta === 'object' ? body.meta : null;
|
|
46
|
+
return { data, meta, raw: body };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Unwrap execution sub-resource envelope `{ root: T }`.
|
|
51
|
+
* @param {*} res
|
|
52
|
+
* @returns {*|null}
|
|
53
|
+
*/
|
|
54
|
+
function unwrapExecutionSubresource(res) {
|
|
55
|
+
assertAuditApiSuccess(res);
|
|
56
|
+
const body = unwrapApiData(res);
|
|
57
|
+
if (body === null || body === undefined) return null;
|
|
58
|
+
if (typeof body === 'object' && Object.prototype.hasOwnProperty.call(body, 'root')) {
|
|
59
|
+
return body.root;
|
|
60
|
+
}
|
|
61
|
+
return body;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = {
|
|
65
|
+
assertAuditApiSuccess,
|
|
66
|
+
unwrapPaginatedAuditList,
|
|
67
|
+
unwrapExecutionSubresource
|
|
68
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dataplane audit read API (Plan 407.1 / 407.3 evidence matrix)
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { createDataplaneApiClient } = require('./index');
|
|
10
|
+
const { unwrapPaginatedAuditList, unwrapExecutionSubresource } = require('./audit-api-helpers');
|
|
11
|
+
|
|
12
|
+
const AUDIT_BASE = '/api/v1/audit';
|
|
13
|
+
const DEFAULT_PAGE_SIZE = 100;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} dataplaneUrl
|
|
17
|
+
* @param {Object} authConfig
|
|
18
|
+
* @param {Object} [query]
|
|
19
|
+
* @returns {Promise<{ data: import('./types/audit.types').AuditExecutionListItem[], meta: import('./types/audit.types').AuditListMeta|null }>}
|
|
20
|
+
* @requiresPermission {Dataplane} audit:read
|
|
21
|
+
*/
|
|
22
|
+
async function queryExecutions(dataplaneUrl, authConfig, query = {}) {
|
|
23
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
24
|
+
const res = await client.get(`${AUDIT_BASE}/executions`, {
|
|
25
|
+
params: {
|
|
26
|
+
page: 1,
|
|
27
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
28
|
+
...query
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return unwrapPaginatedAuditList(res);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @requiresPermission {Dataplane} audit:read
|
|
36
|
+
*/
|
|
37
|
+
async function queryRbacDecisions(dataplaneUrl, authConfig, query = {}) {
|
|
38
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
39
|
+
const res = await client.get(`${AUDIT_BASE}/rbac-decisions`, {
|
|
40
|
+
params: {
|
|
41
|
+
page: 1,
|
|
42
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
43
|
+
sort: '-timestamp',
|
|
44
|
+
...query
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return unwrapPaginatedAuditList(res);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @requiresPermission {Dataplane} audit:read
|
|
52
|
+
*/
|
|
53
|
+
async function queryAbacTraces(dataplaneUrl, authConfig, query = {}) {
|
|
54
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
55
|
+
const res = await client.get(`${AUDIT_BASE}/abac-traces`, {
|
|
56
|
+
params: {
|
|
57
|
+
page: 1,
|
|
58
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
59
|
+
...query
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return unwrapPaginatedAuditList(res);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @requiresPermission {Dataplane} audit:read
|
|
67
|
+
*/
|
|
68
|
+
async function getExecutionRbac(dataplaneUrl, authConfig, executionId) {
|
|
69
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
70
|
+
const res = await client.get(`${AUDIT_BASE}/executions/${executionId}/rbac`);
|
|
71
|
+
return unwrapExecutionSubresource(res);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @requiresPermission {Dataplane} audit:read
|
|
76
|
+
*/
|
|
77
|
+
async function getExecutionAbac(dataplaneUrl, authConfig, executionId) {
|
|
78
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
79
|
+
const res = await client.get(`${AUDIT_BASE}/executions/${executionId}/abac`);
|
|
80
|
+
return unwrapExecutionSubresource(res);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @requiresPermission {Dataplane} audit:read
|
|
85
|
+
*/
|
|
86
|
+
async function getExecutionTrace(dataplaneUrl, authConfig, executionId) {
|
|
87
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
88
|
+
const res = await client.get(`${AUDIT_BASE}/executions/${executionId}/trace`);
|
|
89
|
+
return unwrapExecutionSubresource(res);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @requiresPermission {Dataplane} audit:read
|
|
94
|
+
*/
|
|
95
|
+
async function getExecutionSteps(dataplaneUrl, authConfig, executionId) {
|
|
96
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
97
|
+
const res = await client.get(`${AUDIT_BASE}/executions/${executionId}/steps`);
|
|
98
|
+
return unwrapExecutionSubresource(res);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @requiresPermission {Dataplane} audit:read
|
|
103
|
+
*/
|
|
104
|
+
async function getExecutionErrors(dataplaneUrl, authConfig, executionId) {
|
|
105
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
106
|
+
const res = await client.get(`${AUDIT_BASE}/executions/${executionId}/errors`);
|
|
107
|
+
return unwrapExecutionSubresource(res);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = {
|
|
111
|
+
queryExecutions,
|
|
112
|
+
queryRbacDecisions,
|
|
113
|
+
queryAbacTraces,
|
|
114
|
+
getExecutionRbac,
|
|
115
|
+
getExecutionAbac,
|
|
116
|
+
getExecutionTrace,
|
|
117
|
+
getExecutionSteps,
|
|
118
|
+
getExecutionErrors
|
|
119
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Controller auth/RBAC cache API
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { ApiClient } = require('./index');
|
|
10
|
+
|
|
11
|
+
const CLEAR_PATH = '/api/v1/auth/cache/clear';
|
|
12
|
+
const INVALIDATE_PATH = '/api/v1/auth/cache/invalidate';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Clear all controller cache entries
|
|
16
|
+
* @requiresPermission {Controller} cache:admin
|
|
17
|
+
* @async
|
|
18
|
+
* @param {string} controllerUrl
|
|
19
|
+
* @param {Object} authConfig
|
|
20
|
+
* @returns {Promise<Object>}
|
|
21
|
+
*/
|
|
22
|
+
async function clearAuthCache(controllerUrl, authConfig) {
|
|
23
|
+
const client = new ApiClient(controllerUrl, authConfig);
|
|
24
|
+
return await client.post(CLEAR_PATH);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Invalidate cache entries matching a pattern
|
|
29
|
+
* @requiresPermission {Controller} cache:admin
|
|
30
|
+
* @async
|
|
31
|
+
* @param {string} controllerUrl
|
|
32
|
+
* @param {Object} authConfig
|
|
33
|
+
* @param {string} pattern
|
|
34
|
+
* @returns {Promise<Object>}
|
|
35
|
+
*/
|
|
36
|
+
async function invalidateAuthCache(controllerUrl, authConfig, pattern) {
|
|
37
|
+
const client = new ApiClient(controllerUrl, authConfig);
|
|
38
|
+
return await client.post(INVALIDATE_PATH, { body: { pattern } });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
clearAuthCache,
|
|
43
|
+
invalidateAuthCache
|
|
44
|
+
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @version 2.0.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { createDataplaneApiClient } = require('./index');
|
|
8
8
|
const { normalizeDataplaneAuth } = require('./validation-run.api');
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -36,7 +36,7 @@ function dataplaneAuthForBearerGet(authConfig) {
|
|
|
36
36
|
* @returns {Promise<Object>} API envelope `{ success, data?, status, ... }`
|
|
37
37
|
*/
|
|
38
38
|
async function getActiveIntegrationCertificate(dataplaneUrl, authConfig, systemKey, datasourceKey) {
|
|
39
|
-
const client =
|
|
39
|
+
const client = createDataplaneApiClient(dataplaneUrl, dataplaneAuthForBearerGet(authConfig));
|
|
40
40
|
const path = `/api/v1/systems/${encodeURIComponent(systemKey)}/datasources/${encodeURIComponent(
|
|
41
41
|
datasourceKey
|
|
42
42
|
)}/certificates/active`;
|
|
@@ -54,7 +54,7 @@ async function getActiveIntegrationCertificate(dataplaneUrl, authConfig, systemK
|
|
|
54
54
|
* @returns {Promise<Object>}
|
|
55
55
|
*/
|
|
56
56
|
async function listIntegrationCertificates(dataplaneUrl, authConfig, params = {}) {
|
|
57
|
-
const client =
|
|
57
|
+
const client = createDataplaneApiClient(dataplaneUrl, dataplaneAuthForBearerGet(authConfig));
|
|
58
58
|
return await client.get('/api/v1/certificates', { params });
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -69,7 +69,7 @@ async function listIntegrationCertificates(dataplaneUrl, authConfig, params = {}
|
|
|
69
69
|
* @returns {Promise<Object>}
|
|
70
70
|
*/
|
|
71
71
|
async function verifyIntegrationCertificate(dataplaneUrl, authConfig, body) {
|
|
72
|
-
const client =
|
|
72
|
+
const client = createDataplaneApiClient(dataplaneUrl, dataplaneAuthForBearerGet(authConfig));
|
|
73
73
|
return await client.post('/api/v1/certificates/verify', { body: body || {} });
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @version 2.0.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { createDataplaneApiClient } = require('./index');
|
|
8
8
|
|
|
9
9
|
const CREDENTIAL_SECRET_ENDPOINT = '/api/v1/credential/secret';
|
|
10
10
|
|
|
@@ -29,7 +29,7 @@ async function storeCredentialSecrets(dataplaneUrl, authConfig, items) {
|
|
|
29
29
|
if (!items || !Array.isArray(items) || items.length === 0) {
|
|
30
30
|
return { stored: 0 };
|
|
31
31
|
}
|
|
32
|
-
const client =
|
|
32
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
33
33
|
return await client.post(CREDENTIAL_SECRET_ENDPOINT, {
|
|
34
34
|
body: items
|
|
35
35
|
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dataplane health (public) — read dataplane `version` and optional
|
|
3
|
+
* `minBuilderCliVersion` for the Builder CLI compatibility gate (plan 142.0).
|
|
4
|
+
*
|
|
5
|
+
* Reads `GET /api/v1/health` first (canonical, plan 403.0) and falls back to
|
|
6
|
+
* `GET /health` for older dataplanes during rollout. The endpoint is public
|
|
7
|
+
* (`security: []`); no auth header is sent.
|
|
8
|
+
*
|
|
9
|
+
* @fileoverview Read dataplane health JSON without authentication
|
|
10
|
+
* @author AI Fabrix Team
|
|
11
|
+
* @version 2.0.0
|
|
12
|
+
* @requiresPermission none — public dataplane health endpoint (security: [])
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
require('./types/dataplane-health.types');
|
|
18
|
+
const { ApiClient } = require('./index');
|
|
19
|
+
|
|
20
|
+
const PRIMARY_ENDPOINT = '/api/v1/health';
|
|
21
|
+
const FALLBACK_ENDPOINT = '/health';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Extract the inner JSON body from the harmonized ApiClient response shape.
|
|
25
|
+
* @private
|
|
26
|
+
* @param {Object} response
|
|
27
|
+
* @returns {Object|null}
|
|
28
|
+
*/
|
|
29
|
+
function unwrapBody(response) {
|
|
30
|
+
if (!response || response.success === false || response.data === null || response.data === undefined) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const outer = response.data;
|
|
34
|
+
if (!outer || typeof outer !== 'object') {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
// Some dataplane shapes return `{ data: { ... } }`; the general health route
|
|
38
|
+
// returns the payload directly. Accept both.
|
|
39
|
+
const inner = outer.data !== undefined && outer.data !== null && typeof outer.data === 'object'
|
|
40
|
+
? outer.data
|
|
41
|
+
: outer;
|
|
42
|
+
if (!inner || typeof inner !== 'object') {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return inner;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Parse a raw ApiClient response into a normalized health snapshot.
|
|
50
|
+
*
|
|
51
|
+
* @param {Object} response - ApiClient.get response (`{ success, data, ... }`)
|
|
52
|
+
* @param {string} [endpoint] - Endpoint that produced the response (recorded on snapshot)
|
|
53
|
+
* @returns {import('./types/dataplane-health.types').DataplaneHealthSnapshot|null}
|
|
54
|
+
* Snapshot, or null when the response is not parseable
|
|
55
|
+
*/
|
|
56
|
+
function parseGeneralHealthResponse(response, endpoint) {
|
|
57
|
+
const body = unwrapBody(response);
|
|
58
|
+
if (!body) return null;
|
|
59
|
+
|
|
60
|
+
const status = typeof body.status === 'string' ? body.status : 'unknown';
|
|
61
|
+
const version = typeof body.version === 'string' && body.version.trim()
|
|
62
|
+
? body.version.trim()
|
|
63
|
+
: undefined;
|
|
64
|
+
|
|
65
|
+
let minBuilderCliVersion;
|
|
66
|
+
if (typeof body.minBuilderCliVersion === 'string') {
|
|
67
|
+
const trimmed = body.minBuilderCliVersion.trim();
|
|
68
|
+
if (trimmed) minBuilderCliVersion = trimmed;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
status,
|
|
73
|
+
version,
|
|
74
|
+
minBuilderCliVersion,
|
|
75
|
+
endpoint: endpoint || null
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Fetch dataplane general health (public endpoint, no auth).
|
|
81
|
+
*
|
|
82
|
+
* Tries `/api/v1/health` first; on failure falls back to `/health` (compatibility
|
|
83
|
+
* with older dataplanes that did not expose the v1 health route during rollout).
|
|
84
|
+
*
|
|
85
|
+
* @async
|
|
86
|
+
* @param {string} dataplaneUrl - Dataplane base URL (e.g. `http://localhost:3201`)
|
|
87
|
+
* @param {Object} [options]
|
|
88
|
+
* @param {number} [options.timeoutMs] - Optional timeout in milliseconds
|
|
89
|
+
* @returns {Promise<import('./types/dataplane-health.types').DataplaneHealthSnapshot|null>}
|
|
90
|
+
* Snapshot, or null when both endpoints fail
|
|
91
|
+
* @throws {Error} When dataplaneUrl is missing or not a string
|
|
92
|
+
*/
|
|
93
|
+
async function fetchDataplaneGeneralHealth(dataplaneUrl, options = {}) {
|
|
94
|
+
if (!dataplaneUrl || typeof dataplaneUrl !== 'string') {
|
|
95
|
+
throw new Error('dataplaneUrl is required and must be a string');
|
|
96
|
+
}
|
|
97
|
+
const client = new ApiClient(dataplaneUrl);
|
|
98
|
+
const requestOpts = {};
|
|
99
|
+
if (options.timeoutMs !== undefined && options.timeoutMs !== null) {
|
|
100
|
+
requestOpts.timeoutMs = options.timeoutMs;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const primary = await safeGet(client, PRIMARY_ENDPOINT, requestOpts);
|
|
104
|
+
const primarySnapshot = parseGeneralHealthResponse(primary, PRIMARY_ENDPOINT);
|
|
105
|
+
if (primarySnapshot) return primarySnapshot;
|
|
106
|
+
|
|
107
|
+
const fallback = await safeGet(client, FALLBACK_ENDPOINT, requestOpts);
|
|
108
|
+
const fallbackSnapshot = parseGeneralHealthResponse(fallback, FALLBACK_ENDPOINT);
|
|
109
|
+
if (fallbackSnapshot) return fallbackSnapshot;
|
|
110
|
+
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* GET that swallows transport errors (timeouts / DNS / ECONNREFUSED) so callers
|
|
116
|
+
* can attempt a fallback endpoint without try/catch noise.
|
|
117
|
+
* @private
|
|
118
|
+
* @async
|
|
119
|
+
* @param {ApiClient} client
|
|
120
|
+
* @param {string} endpoint
|
|
121
|
+
* @param {Object} options
|
|
122
|
+
* @returns {Promise<Object|null>}
|
|
123
|
+
*/
|
|
124
|
+
async function safeGet(client, endpoint, options) {
|
|
125
|
+
try {
|
|
126
|
+
return await client.get(endpoint, options);
|
|
127
|
+
} catch (_error) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
module.exports = {
|
|
133
|
+
fetchDataplaneGeneralHealth,
|
|
134
|
+
parseGeneralHealthResponse,
|
|
135
|
+
PRIMARY_ENDPOINT,
|
|
136
|
+
FALLBACK_ENDPOINT
|
|
137
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dataplane sync API (Controller)
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { ApiClient } = require('./index');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Trigger full identity sync to dataplane for an environment
|
|
13
|
+
* @requiresPermission {Controller} admin:sync
|
|
14
|
+
* @async
|
|
15
|
+
* @param {string} controllerUrl
|
|
16
|
+
* @param {Object} authConfig
|
|
17
|
+
* @param {string} envKey
|
|
18
|
+
* @returns {Promise<Object>}
|
|
19
|
+
*/
|
|
20
|
+
async function fullSyncToDataplane(controllerUrl, authConfig, envKey) {
|
|
21
|
+
const client = new ApiClient(controllerUrl, authConfig);
|
|
22
|
+
return await client.post(`/api/v1/sync/dataplane/${encodeURIComponent(envKey)}/full`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
fullSyncToDataplane
|
|
27
|
+
};
|