harness-mcp-v2 3.2.39 → 3.2.40
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 +9 -3
- package/build/client/harness-client.d.ts +1 -0
- package/build/client/harness-client.d.ts.map +1 -1
- package/build/client/harness-client.js +29 -7
- package/build/client/harness-client.js.map +1 -1
- package/build/client/types.d.ts +2 -2
- package/build/client/types.d.ts.map +1 -1
- package/build/config.d.ts +25 -1
- package/build/config.d.ts.map +1 -1
- package/build/config.js +47 -0
- package/build/config.js.map +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/registry/appsec/builders.d.ts +33 -0
- package/build/registry/appsec/builders.d.ts.map +1 -0
- package/build/registry/appsec/builders.js +1403 -0
- package/build/registry/appsec/builders.js.map +1 -0
- package/build/registry/appsec/extractors.d.ts +46 -0
- package/build/registry/appsec/extractors.d.ts.map +1 -0
- package/build/registry/appsec/extractors.js +699 -0
- package/build/registry/appsec/extractors.js.map +1 -0
- package/build/registry/appsec/queries.d.ts +22 -0
- package/build/registry/appsec/queries.d.ts.map +1 -0
- package/build/registry/appsec/queries.js +322 -0
- package/build/registry/appsec/queries.js.map +1 -0
- package/build/registry/extractors.d.ts +2 -1
- package/build/registry/extractors.d.ts.map +1 -1
- package/build/registry/extractors.js +2 -1
- package/build/registry/extractors.js.map +1 -1
- package/build/registry/index.d.ts.map +1 -1
- package/build/registry/index.js +3 -1
- package/build/registry/index.js.map +1 -1
- package/build/registry/toolsets/appsec.d.ts +5 -0
- package/build/registry/toolsets/appsec.d.ts.map +1 -0
- package/build/registry/toolsets/appsec.js +624 -0
- package/build/registry/toolsets/appsec.js.map +1 -0
- package/build/registry/toolsets/chaos-descriptions.d.ts +12 -11
- package/build/registry/toolsets/chaos-descriptions.d.ts.map +1 -1
- package/build/registry/toolsets/chaos-descriptions.js +15 -13
- package/build/registry/toolsets/chaos-descriptions.js.map +1 -1
- package/build/registry/toolsets/chaos.d.ts.map +1 -1
- package/build/registry/toolsets/chaos.js +90 -32
- package/build/registry/toolsets/chaos.js.map +1 -1
- package/build/registry/toolsets/runbooks.d.ts.map +1 -1
- package/build/registry/toolsets/runbooks.js +6 -2
- package/build/registry/toolsets/runbooks.js.map +1 -1
- package/build/registry/types.d.ts +10 -2
- package/build/registry/types.d.ts.map +1 -1
- package/build/utils/session-headers.d.ts +1 -0
- package/build/utils/session-headers.d.ts.map +1 -1
- package/build/utils/session-headers.js +6 -1
- package/build/utils/session-headers.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ descExperimentManifest, descExperimentInfraType, descExperimentInfraIdCreate, de
|
|
|
22
22
|
// Service Discovery
|
|
23
23
|
descSDAgentIdentity, descSDEnvironmentId, descSDAgentListEnvironmentId, descSDFetchAll, descSDAgentDiagnostic, descDiscoveredAgent, descListDiscoveredAgents, descDiscoveredAgentSearch, descDiscoveredNamespace, descListDiscoveredNamespaces, descSDNamespaceNameFilter, descDiscoveredService, descListDiscoveredServices, descSDNamespaceFilter, descSDSearchFilter,
|
|
24
24
|
// Scanned Risks / Risk Rules / Risk Scans (chaos-manager v3)
|
|
25
|
-
descScannedRisk, descChaosRiskRule, descChaosRiskScan, descListScannedRisks, descGetScannedRisk, descListScannedRiskOccurrences, descSummarizeScannedRisksByService, descListRiskRules, descGetRiskRule, descCreateRiskRule, descUpdateRiskRule, descDeleteRiskRule, descBodyRiskRuleCreate, descBodyRiskRuleUpdate, descRiskRuleIdentity, descRiskRuleName, descRiskRuleDescription, descRiskRuleTags, descRiskRuleSeverity, descRiskRuleCategory, descRiskRuleSpec, descRiskRuleCustomOnly, descListRiskScans, descGetRiskScan, descCreateRiskScan, descUpdateRiskScan, descDeleteRiskScan, descRetryRiskScan, descAbortRiskScan, descSubmitRiskScanFindings, descBodySubmitRiskScanFindings, descRiskScanFindings, descRiskScanDetectionMethod, descGetRiskScanReport, descGetRiskScanReportDownload, descGetRiskScanHeatmap, descBodyRiskScanCreate, descBodyRiskScanUpdate, descRiskScanIdentity, descRiskScanName, descRiskScanDescription, descRiskScanTags, descRiskScanType, descRiskScanSource, descScannedRiskSeverity, descScannedRiskRuleId, descScannedRiskValidationType, descScannedRiskServiceIdentity, descScannedRiskScanType, descRiskEnvironmentIdentity, descRiskAgentIdentity, descRiskPipelineIdentity, descRiskScanStatus, descRiskSearch, descRiskSortField, descRiskSortAscending, descRiskTags, descRiskIncludeAllScope, descRiskStartTime, descRiskEndTime, descRiskRuleDataSource, descRiskRuleIsSystem, descHeatmapSearch, } from "./chaos-descriptions.js";
|
|
25
|
+
descScannedRisk, descChaosRiskRule, descChaosRiskScan, descListScannedRisks, descGetScannedRisk, descListScannedRiskOccurrences, descSummarizeScannedRisksByService, descListRiskRules, descGetRiskRule, descCreateRiskRule, descUpdateRiskRule, descDeleteRiskRule, descBodyRiskRuleCreate, descBodyRiskRuleUpdate, descRiskRuleIdentity, descRiskRuleName, descRiskRuleDescription, descRiskRuleTags, descRiskRuleSeverity, descRiskRuleCategory, descRiskRuleSpec, descRiskRuleCustomOnly, descRiskRuleIncludeInPassiveScan, descListRiskScans, descGetRiskScan, descCreateRiskScan, descUpdateRiskScan, descDeleteRiskScan, descRetryRiskScan, descAbortRiskScan, descSubmitRiskScanFindings, descBodySubmitRiskScanFindings, descRiskScanFindings, descRiskScanDetectionMethod, descGetRiskScanReport, descGetRiskScanReportDownload, descGetRiskScanHeatmap, descBodyRiskScanCreate, descBodyRiskScanUpdate, descRiskScanIdentity, descRiskScanName, descRiskScanDescription, descRiskScanTags, descRiskScanType, descRiskScanSource, descScannedRiskSeverity, descScannedRiskRuleId, descScannedRiskValidationType, descScannedRiskServiceIdentity, descScannedRiskScanType, descRiskEnvironmentIdentity, descRiskAgentIdentity, descRiskPipelineIdentity, descRiskScanStatus, descRiskSearch, descRiskSortField, descRiskSortAscending, descRiskTags, descRiskIncludeAllScope, descRiskStartTime, descRiskEndTime, descRiskRuleDataSource, descRiskRuleIsSystem, descHeatmapSearch, } from "./chaos-descriptions.js";
|
|
26
26
|
/**
|
|
27
27
|
* Chaos API base path.
|
|
28
28
|
* REST endpoints live under rest/v2/ (experiments, probes) and rest/ (templates).
|
|
@@ -124,15 +124,33 @@ function stringList(value) {
|
|
|
124
124
|
return value.map((item) => String(item).trim()).filter(Boolean);
|
|
125
125
|
return String(value).split(",").map((item) => item.trim()).filter(Boolean);
|
|
126
126
|
}
|
|
127
|
+
const LINKED_DISCOVERED_SERVICE_KEYS = new Set([
|
|
128
|
+
"agent_id", "agentId",
|
|
129
|
+
"environment_id", "environmentId",
|
|
130
|
+
"external_id", "externalId",
|
|
131
|
+
]);
|
|
132
|
+
function valueIsSet(value) {
|
|
133
|
+
if (value == null)
|
|
134
|
+
return false;
|
|
135
|
+
if (typeof value === "string")
|
|
136
|
+
return value.trim() !== "";
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
// "absent" leaves the stored link unchanged. "clear" is {} or the three known
|
|
140
|
+
// id fields all blank, with no other key set, and removes the link on update.
|
|
141
|
+
// A discovered-service record or a typo such as agentID is not a clear.
|
|
127
142
|
function linkedDiscoveredService(value) {
|
|
128
|
-
if (
|
|
129
|
-
return
|
|
143
|
+
if (value == null)
|
|
144
|
+
return "absent";
|
|
145
|
+
if (typeof value !== "object" || Array.isArray(value))
|
|
146
|
+
return "absent";
|
|
130
147
|
const linked = value;
|
|
131
148
|
const agentId = optionalText(linked.agent_id ?? linked.agentId);
|
|
132
149
|
const environmentId = optionalText(linked.environment_id ?? linked.environmentId);
|
|
133
150
|
const externalId = optionalText(linked.external_id ?? linked.externalId);
|
|
134
|
-
|
|
135
|
-
|
|
151
|
+
const unrecognized = Object.keys(linked).some((key) => !LINKED_DISCOVERED_SERVICE_KEYS.has(key) && valueIsSet(linked[key]));
|
|
152
|
+
if (!agentId && !environmentId && !externalId && !unrecognized)
|
|
153
|
+
return "clear";
|
|
136
154
|
if (!agentId || !environmentId || !externalId) {
|
|
137
155
|
const missing = [
|
|
138
156
|
!agentId ? "agent_id" : "",
|
|
@@ -143,6 +161,14 @@ function linkedDiscoveredService(value) {
|
|
|
143
161
|
}
|
|
144
162
|
return { agentId, environmentId, externalId };
|
|
145
163
|
}
|
|
164
|
+
function linkedDiscoveredServiceBody(value, allowClear) {
|
|
165
|
+
const linked = linkedDiscoveredService(value);
|
|
166
|
+
if (linked === "absent" || (linked === "clear" && !allowClear))
|
|
167
|
+
return {};
|
|
168
|
+
if (linked === "clear")
|
|
169
|
+
return { linkedDiscoveredService: {} };
|
|
170
|
+
return { linkedDiscoveredService: linked };
|
|
171
|
+
}
|
|
146
172
|
/**
|
|
147
173
|
* A CodeRepository chaos service is the only one that may omit infrastructure,
|
|
148
174
|
* and only when agent_id is the custom discovery agent. Every other service
|
|
@@ -242,19 +268,26 @@ const RISK_RULE_BODY_FIELDS = [
|
|
|
242
268
|
{ name: "category", type: "string", required: true, description: descRiskRuleCategory },
|
|
243
269
|
{ name: "spec", type: "object", required: true, description: descRiskRuleSpec },
|
|
244
270
|
];
|
|
245
|
-
const
|
|
246
|
-
const
|
|
271
|
+
const RISK_RULE_DATA_SOURCES = ["SourceCode", "ApplicationManifest"];
|
|
272
|
+
const DEFAULT_RISK_RULE_DATA_SOURCE = "SourceCode";
|
|
273
|
+
const RISK_RULE_IDENTITY_RE = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
247
274
|
const RISK_RULE_PROMPT_LIST_LIMIT = 10;
|
|
248
275
|
const RISK_RULE_PROMPT_ENTRY_LIMIT = 500;
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
276
|
+
function isRiskRuleDataSource(value) {
|
|
277
|
+
return typeof value === "string" && RISK_RULE_DATA_SOURCES.includes(value);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Validates spec.dataSource. Create passes defaultWhenOmitted so a missing
|
|
281
|
+
* value becomes SourceCode. Update does not: an omitted value is rejected
|
|
282
|
+
* so an ApplicationManifest rule is not rewritten to SourceCode.
|
|
283
|
+
*/
|
|
284
|
+
function riskRuleDataSource(value, defaultWhenOmitted) {
|
|
285
|
+
const dataSource = value ?? (defaultWhenOmitted ? [DEFAULT_RISK_RULE_DATA_SOURCE] : undefined);
|
|
286
|
+
const source = Array.isArray(dataSource) && dataSource.length === 1 ? dataSource[0] : undefined;
|
|
287
|
+
if (!isRiskRuleDataSource(source)) {
|
|
288
|
+
throw new Error('spec.dataSource must be exactly ["SourceCode"] or ["ApplicationManifest"].');
|
|
256
289
|
}
|
|
257
|
-
return
|
|
290
|
+
return [source];
|
|
258
291
|
}
|
|
259
292
|
/**
|
|
260
293
|
* prompt.do and prompt.outcome are required; prompt.dont is optional.
|
|
@@ -284,8 +317,8 @@ function riskRulePromptList(value, field, required) {
|
|
|
284
317
|
}
|
|
285
318
|
}
|
|
286
319
|
}
|
|
287
|
-
/** Builds the mutable part of a custom risk rule
|
|
288
|
-
function buildRiskRuleBody(b) {
|
|
320
|
+
/** Builds the mutable part of a custom risk rule. defaultDataSource is create-only. */
|
|
321
|
+
function buildRiskRuleBody(b, options = {}) {
|
|
289
322
|
const missing = ["name", "severity", "category", "spec"].filter((k) => b[k] == null || b[k] === "");
|
|
290
323
|
if (missing.length > 0) {
|
|
291
324
|
throw new Error(`Missing required field(s): ${missing.join(", ")}.`);
|
|
@@ -293,8 +326,8 @@ function buildRiskRuleBody(b) {
|
|
|
293
326
|
if (typeof b.spec !== "object" || b.spec == null || Array.isArray(b.spec)) {
|
|
294
327
|
throw new Error("spec must be an object.");
|
|
295
328
|
}
|
|
296
|
-
const spec = b.spec;
|
|
297
|
-
const dataSource = riskRuleDataSource(spec.dataSource);
|
|
329
|
+
const spec = { ...b.spec };
|
|
330
|
+
const dataSource = riskRuleDataSource(spec.dataSource, options.defaultDataSource === true);
|
|
298
331
|
if (!Array.isArray(spec.faults) || spec.faults.length === 0) {
|
|
299
332
|
throw new Error("spec.faults must list at least one chaos fault that can prove the risk (e.g. pod-network-latency).");
|
|
300
333
|
}
|
|
@@ -305,6 +338,15 @@ function buildRiskRuleBody(b) {
|
|
|
305
338
|
riskRulePromptList(prompt.do, "spec.prompt.do", true);
|
|
306
339
|
riskRulePromptList(prompt.dont, "spec.prompt.dont", false);
|
|
307
340
|
riskRulePromptList(prompt.outcome, "spec.prompt.outcome", true);
|
|
341
|
+
// The list filter is include_in_passive_scan. Accept that key inside spec and
|
|
342
|
+
// send the camelCase field the API stores. Null is not a boolean.
|
|
343
|
+
if ("include_in_passive_scan" in spec) {
|
|
344
|
+
spec.includeInPassiveScan = spec.include_in_passive_scan;
|
|
345
|
+
delete spec.include_in_passive_scan;
|
|
346
|
+
}
|
|
347
|
+
if (spec.includeInPassiveScan !== undefined && typeof spec.includeInPassiveScan !== "boolean") {
|
|
348
|
+
throw new Error("spec.includeInPassiveScan must be a boolean. Omit it to leave the rule out of the passive scan.");
|
|
349
|
+
}
|
|
308
350
|
return {
|
|
309
351
|
name: b.name,
|
|
310
352
|
...(b.description != null ? { description: b.description } : {}),
|
|
@@ -2496,7 +2538,7 @@ export const chaosToolset = {
|
|
|
2496
2538
|
const infrastructureType = optionalText(b.infrastructure_type ?? b.infrastructureType);
|
|
2497
2539
|
const onboardingId = optionalText(b.onboarding_id ?? b.onboardingId);
|
|
2498
2540
|
const tags = stringList(b.tags);
|
|
2499
|
-
const linked =
|
|
2541
|
+
const linked = linkedDiscoveredServiceBody(b.linked_discovered_service ?? b.linkedDiscoveredService, false);
|
|
2500
2542
|
assertChaosServiceInfrastructure(agentId, environmentId, infrastructureId);
|
|
2501
2543
|
const probes = b.probes?.map((p) => ({
|
|
2502
2544
|
probeId: p.probeId ?? p.probe_id,
|
|
@@ -2520,7 +2562,7 @@ export const chaosToolset = {
|
|
|
2520
2562
|
...(infrastructureId ? { infrastructureId, infrastructure_id: infrastructureId } : {}),
|
|
2521
2563
|
...(infrastructureType ? { infrastructureType } : {}),
|
|
2522
2564
|
...(onboardingId ? { onboardingId } : {}),
|
|
2523
|
-
...
|
|
2565
|
+
...linked,
|
|
2524
2566
|
...(probes && probes.length > 0 ? { probes } : {}),
|
|
2525
2567
|
};
|
|
2526
2568
|
},
|
|
@@ -2553,11 +2595,20 @@ export const chaosToolset = {
|
|
|
2553
2595
|
const b = coerceBody(input);
|
|
2554
2596
|
const externalServiceId = b.external_service_id ?? b.externalServiceId;
|
|
2555
2597
|
const agentId = b.agent_id ?? b.agentId;
|
|
2556
|
-
const environmentId = optionalText(b.environment_id ?? b.environmentId);
|
|
2557
|
-
const infrastructureId = optionalText(b.infrastructure_id ?? b.infrastructureId);
|
|
2558
|
-
const infrastructureType = optionalText(b.infrastructure_type ?? b.infrastructureType);
|
|
2559
2598
|
const tags = stringList(b.tags);
|
|
2560
|
-
|
|
2599
|
+
// A present linkedDiscoveredService is validated for a CodeRepository
|
|
2600
|
+
// service. An empty object is an unlink on every service type, so a
|
|
2601
|
+
// Kubernetes update must not send it. Only the custom discovery agent
|
|
2602
|
+
// may clear the link.
|
|
2603
|
+
const linked = linkedDiscoveredServiceBody(b.linked_discovered_service ?? b.linkedDiscoveredService, optionalText(agentId) === CUSTOM_DISCOVERY_AGENT);
|
|
2604
|
+
// hce-saas stores the environment and infrastructure sent with an
|
|
2605
|
+
// unlink, so values resupplied from harness_get would keep the
|
|
2606
|
+
// workload's Kubernetes mapping on the code-repository service.
|
|
2607
|
+
const clearsLink = linked.linkedDiscoveredService !== undefined
|
|
2608
|
+
&& Object.keys(linked.linkedDiscoveredService).length === 0;
|
|
2609
|
+
const environmentId = clearsLink ? undefined : optionalText(b.environment_id ?? b.environmentId);
|
|
2610
|
+
const infrastructureId = clearsLink ? undefined : optionalText(b.infrastructure_id ?? b.infrastructureId);
|
|
2611
|
+
const infrastructureType = clearsLink ? undefined : optionalText(b.infrastructure_type ?? b.infrastructureType);
|
|
2561
2612
|
assertChaosServiceInfrastructure(optionalText(agentId), environmentId, infrastructureId);
|
|
2562
2613
|
const probes = b.probes?.map((p) => ({
|
|
2563
2614
|
probeId: p.probeId ?? p.probe_id,
|
|
@@ -2586,7 +2637,7 @@ export const chaosToolset = {
|
|
|
2586
2637
|
...(environmentId ? { environmentId, environment_id: environmentId } : {}),
|
|
2587
2638
|
...(infrastructureId ? { infrastructureId, infrastructure_id: infrastructureId } : {}),
|
|
2588
2639
|
...(infrastructureType ? { infrastructureType } : {}),
|
|
2589
|
-
...
|
|
2640
|
+
...linked,
|
|
2590
2641
|
// Full desired-state replace (hce-saas reconcileProbeMappings):
|
|
2591
2642
|
// pass an explicit [] straight through (detach all) rather than
|
|
2592
2643
|
// dropping it, but leave the key absent when the caller omitted it
|
|
@@ -4523,7 +4574,9 @@ export const chaosToolset = {
|
|
|
4523
4574
|
displayName: "Chaos Risk Rule",
|
|
4524
4575
|
description: descChaosRiskRule,
|
|
4525
4576
|
toolset: "chaos",
|
|
4526
|
-
|
|
4577
|
+
// Custom rules are stored on the account. Org and project must not be sent,
|
|
4578
|
+
// or the API stores and lists them as project rules.
|
|
4579
|
+
scope: "account",
|
|
4527
4580
|
scopeParams: CHAOS_SCOPE,
|
|
4528
4581
|
identifierFields: ["identity"],
|
|
4529
4582
|
searchAliases: ["risk rule", "risk check", "manifest risk rule", "code risk rule", "source code risk rule", "umbrella risk rule"],
|
|
@@ -4535,7 +4588,7 @@ export const chaosToolset = {
|
|
|
4535
4588
|
{ name: "is_system", description: descRiskRuleIsSystem, type: "boolean" },
|
|
4536
4589
|
{ name: "custom_only", description: descRiskRuleCustomOnly, type: "boolean" },
|
|
4537
4590
|
{ name: "data_source", description: descRiskRuleDataSource },
|
|
4538
|
-
{ name: "
|
|
4591
|
+
{ name: "include_in_passive_scan", description: descRiskRuleIncludeInPassiveScan, type: "boolean" },
|
|
4539
4592
|
],
|
|
4540
4593
|
relatedResources: [
|
|
4541
4594
|
{ resourceType: "scanned_risk", relationship: "flags", description: "Risk rules flag scanned risks during a scan. Use scanned_risk with risk_rule_id=<this rule's identity> to find findings produced by this rule." },
|
|
@@ -4555,7 +4608,7 @@ export const chaosToolset = {
|
|
|
4555
4608
|
is_system: "isSystem",
|
|
4556
4609
|
custom_only: "customOnly",
|
|
4557
4610
|
data_source: "dataSource",
|
|
4558
|
-
|
|
4611
|
+
include_in_passive_scan: "includeInPassiveScan",
|
|
4559
4612
|
},
|
|
4560
4613
|
defaultQueryParams: { page: "0", limit: "15" },
|
|
4561
4614
|
responseExtractor: chaosPageExtract,
|
|
@@ -4576,12 +4629,16 @@ export const chaosToolset = {
|
|
|
4576
4629
|
bodyBuilder: (input) => {
|
|
4577
4630
|
const b = coerceBody(input);
|
|
4578
4631
|
if (!b.identity) {
|
|
4579
|
-
throw new Error("Missing required field: identity. Use
|
|
4632
|
+
throw new Error("Missing required field: identity. Use a lowercase slug, e.g. retry-without-backoff.");
|
|
4580
4633
|
}
|
|
4581
4634
|
if (typeof b.identity !== "string" || !RISK_RULE_IDENTITY_RE.test(b.identity)) {
|
|
4582
|
-
throw new Error(`identity must match ${RISK_RULE_IDENTITY_RE.source} (lowercase letters, digits and hyphens), e.g.
|
|
4635
|
+
throw new Error(`identity must match ${RISK_RULE_IDENTITY_RE.source} (1-64 lowercase letters, digits and hyphens, starting and ending with a letter or digit, no required prefix), e.g. retry-without-backoff.`);
|
|
4583
4636
|
}
|
|
4584
|
-
return {
|
|
4637
|
+
return {
|
|
4638
|
+
identity: b.identity,
|
|
4639
|
+
...buildRiskRuleBody(b, { defaultDataSource: true }),
|
|
4640
|
+
...(b.confirmNewRule === true ? { confirmNewRule: true } : {}),
|
|
4641
|
+
};
|
|
4585
4642
|
},
|
|
4586
4643
|
responseExtractor: passthrough,
|
|
4587
4644
|
description: descCreateRiskRule,
|
|
@@ -4589,6 +4646,7 @@ export const chaosToolset = {
|
|
|
4589
4646
|
description: descBodyRiskRuleCreate,
|
|
4590
4647
|
fields: [
|
|
4591
4648
|
{ name: "identity", type: "string", required: true, description: descRiskRuleIdentity },
|
|
4649
|
+
{ name: "confirmNewRule", type: "boolean", required: false, description: "Set true only after the user has seen a 409 matches list and still wants a new rule." },
|
|
4592
4650
|
...RISK_RULE_BODY_FIELDS,
|
|
4593
4651
|
],
|
|
4594
4652
|
},
|