@salesforce/plugin-bre-to-cml 1.0.48 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/lib/commands/cml/convert/surcharge-rules.d.ts +29 -0
- package/lib/commands/cml/convert/surcharge-rules.js +86 -0
- package/lib/commands/cml/convert/surcharge-rules.js.map +1 -0
- package/lib/commands/cml/convert/underwriting-rules.d.ts +32 -0
- package/lib/commands/cml/convert/underwriting-rules.js +136 -0
- package/lib/commands/cml/convert/underwriting-rules.js.map +1 -0
- package/lib/shared/bre-rules-generator.js +1 -57
- package/lib/shared/bre-rules-generator.js.map +1 -1
- package/lib/shared/cml-operators.d.ts +8 -0
- package/lib/shared/cml-operators.js +87 -0
- package/lib/shared/cml-operators.js.map +1 -0
- package/lib/shared/insurance/insurance-org.d.ts +9 -0
- package/lib/shared/insurance/insurance-org.js +40 -0
- package/lib/shared/insurance/insurance-org.js.map +1 -0
- package/lib/shared/insurance/insurance-rule-convert-command.d.ts +38 -0
- package/lib/shared/insurance/insurance-rule-convert-command.js +144 -0
- package/lib/shared/insurance/insurance-rule-convert-command.js.map +1 -0
- package/lib/shared/insurance/insurance-rule-generator.d.ts +26 -0
- package/lib/shared/insurance/insurance-rule-generator.js +144 -0
- package/lib/shared/insurance/insurance-rule-generator.js.map +1 -0
- package/lib/shared/insurance/models.d.ts +44 -0
- package/lib/shared/insurance/models.js +2 -0
- package/lib/shared/insurance/models.js.map +1 -0
- package/messages/cml.convert.insurance-shared.md +11 -0
- package/messages/cml.convert.surcharge-rules.md +17 -0
- package/messages/cml.convert.underwriting-rules.md +17 -0
- package/oclif.lock +352 -130
- package/oclif.manifest.json +199 -1
- package/package.json +7 -7
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export function escapeQuotes(str) {
|
|
2
|
+
return str.replace(/['"]/g, '\\$&');
|
|
3
|
+
}
|
|
4
|
+
export function doubleQuoted(str) {
|
|
5
|
+
if (str) {
|
|
6
|
+
return `"${escapeQuotes(str)}"`;
|
|
7
|
+
}
|
|
8
|
+
return str ?? "''";
|
|
9
|
+
}
|
|
10
|
+
export function doubleQuotedIfNeeded(value, dataType) {
|
|
11
|
+
if (typeof value === 'string' || typeof value === 'undefined') {
|
|
12
|
+
return `${dataType === 'string' ? doubleQuoted(value) ?? '' : value ?? "''"}`;
|
|
13
|
+
}
|
|
14
|
+
const singleValue = value[0];
|
|
15
|
+
return `${dataType === 'string' ? doubleQuoted(singleValue) ?? '' : singleValue ?? "''"}`;
|
|
16
|
+
}
|
|
17
|
+
export function generateInCmlExpression(left, right) {
|
|
18
|
+
if (typeof right === 'string') {
|
|
19
|
+
return `${left} == ${doubleQuoted(right)}`;
|
|
20
|
+
}
|
|
21
|
+
return right.map((r) => `${left} == ${doubleQuoted(r)}`).join(' || ');
|
|
22
|
+
}
|
|
23
|
+
function firstValue(right) {
|
|
24
|
+
if (right === undefined)
|
|
25
|
+
return undefined;
|
|
26
|
+
return typeof right === 'string' ? right : right[0];
|
|
27
|
+
}
|
|
28
|
+
export function convertToCmlExpression(left, ruleExprOperator, right, dataType) {
|
|
29
|
+
switch (ruleExprOperator) {
|
|
30
|
+
case 'Equals':
|
|
31
|
+
return `${left} == ${doubleQuotedIfNeeded(right, dataType)}`;
|
|
32
|
+
case 'NotEquals':
|
|
33
|
+
return `${left} != ${doubleQuotedIfNeeded(right, dataType)}`;
|
|
34
|
+
case 'LessThan':
|
|
35
|
+
return `${left} < ${right ?? ''}`;
|
|
36
|
+
case 'LessThanOrEquals':
|
|
37
|
+
return `${left} <= ${right ?? ''}`;
|
|
38
|
+
case 'GreaterThan':
|
|
39
|
+
return `${left} > ${right ?? ''}`;
|
|
40
|
+
case 'GreaterThanOrEquals':
|
|
41
|
+
return `${left} >= ${right ?? ''}`;
|
|
42
|
+
case 'IsNotNull':
|
|
43
|
+
return `${left} != null`;
|
|
44
|
+
case 'IsNull':
|
|
45
|
+
return `${left} == null`;
|
|
46
|
+
case 'Contains':
|
|
47
|
+
return `strcontain(${left}, ${doubleQuoted(firstValue(right))})`;
|
|
48
|
+
case 'DoesNotContain':
|
|
49
|
+
return `!strcontain(${left}, ${doubleQuoted(firstValue(right))})`;
|
|
50
|
+
case 'In':
|
|
51
|
+
if (right) {
|
|
52
|
+
return `(${generateInCmlExpression(left, right)})`;
|
|
53
|
+
}
|
|
54
|
+
return `${left} == null`;
|
|
55
|
+
case 'NotIn':
|
|
56
|
+
if (right) {
|
|
57
|
+
return `!(${generateInCmlExpression(left, right)})`;
|
|
58
|
+
}
|
|
59
|
+
return `${left} != null`;
|
|
60
|
+
default: {
|
|
61
|
+
const exhaustive = ruleExprOperator;
|
|
62
|
+
throw new Error(`Unsupported rule operator: ${String(exhaustive)}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const KNOWN_OPERATORS = new Set([
|
|
67
|
+
'Equals',
|
|
68
|
+
'NotEquals',
|
|
69
|
+
'LessThan',
|
|
70
|
+
'LessThanOrEquals',
|
|
71
|
+
'GreaterThan',
|
|
72
|
+
'GreaterThanOrEquals',
|
|
73
|
+
'IsNotNull',
|
|
74
|
+
'IsNull',
|
|
75
|
+
'Contains',
|
|
76
|
+
'DoesNotContain',
|
|
77
|
+
'In',
|
|
78
|
+
'NotIn',
|
|
79
|
+
]);
|
|
80
|
+
export function isKnownOperator(op) {
|
|
81
|
+
return KNOWN_OPERATORS.has(op);
|
|
82
|
+
}
|
|
83
|
+
const NULL_OPERATORS = new Set(['IsNull', 'IsNotNull']);
|
|
84
|
+
export function operatorRequiresValues(op) {
|
|
85
|
+
return !NULL_OPERATORS.has(op);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=cml-operators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cml-operators.js","sourceRoot":"","sources":["../../src/shared/cml-operators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Connection } from '@salesforce/core';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a quoted, comma-separated SOQL id list, keeping only well-formed Salesforce ids.
|
|
4
|
+
* Product ids originate from rule definitions that may be supplied via --surcharge-file /
|
|
5
|
+
* --uw-file, so validating here prevents SOQL injection through the `IN (...)` clause.
|
|
6
|
+
*/
|
|
7
|
+
export declare function quoteSoqlIdList(ids: Iterable<string>): string;
|
|
8
|
+
export declare function fetchProductCodes(conn: Connection, productIds: Set<string>): Promise<Map<string, string>>;
|
|
9
|
+
export declare function discoverCmlApiByProducts(conn: Connection, productIds: Set<string>): Promise<string | undefined>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Matches a well-formed 15- or 18-character Salesforce record id. */
|
|
2
|
+
const SALESFORCE_ID_PATTERN = /^[a-zA-Z0-9]{15,18}$/;
|
|
3
|
+
/**
|
|
4
|
+
* Builds a quoted, comma-separated SOQL id list, keeping only well-formed Salesforce ids.
|
|
5
|
+
* Product ids originate from rule definitions that may be supplied via --surcharge-file /
|
|
6
|
+
* --uw-file, so validating here prevents SOQL injection through the `IN (...)` clause.
|
|
7
|
+
*/
|
|
8
|
+
export function quoteSoqlIdList(ids) {
|
|
9
|
+
return Array.from(ids)
|
|
10
|
+
.filter((id) => SALESFORCE_ID_PATTERN.test(id))
|
|
11
|
+
.map((id) => `'${id}'`)
|
|
12
|
+
.join(',');
|
|
13
|
+
}
|
|
14
|
+
export async function fetchProductCodes(conn, productIds) {
|
|
15
|
+
const idToCode = new Map();
|
|
16
|
+
const idList = quoteSoqlIdList(productIds);
|
|
17
|
+
if (!idList)
|
|
18
|
+
return idToCode;
|
|
19
|
+
const result = await conn.query(`SELECT Id, ProductCode, Name FROM Product2 WHERE Id IN (${idList})`);
|
|
20
|
+
for (const p of result.records) {
|
|
21
|
+
idToCode.set(p.Id, p.ProductCode ?? p.Name ?? p.Id);
|
|
22
|
+
}
|
|
23
|
+
return idToCode;
|
|
24
|
+
}
|
|
25
|
+
export async function discoverCmlApiByProducts(conn, productIds) {
|
|
26
|
+
const idList = quoteSoqlIdList(productIds);
|
|
27
|
+
if (!idList)
|
|
28
|
+
return undefined;
|
|
29
|
+
const assocResult = await conn.query(`SELECT ExpressionSetId FROM ExpressionSetConstraintObj WHERE ReferenceObjectId IN (${idList}) AND ConstraintModelTagType = 'Type' LIMIT 1`);
|
|
30
|
+
if (assocResult.records.length === 0)
|
|
31
|
+
return undefined;
|
|
32
|
+
const esId = assocResult.records[0].ExpressionSetId;
|
|
33
|
+
if (!SALESFORCE_ID_PATTERN.test(esId))
|
|
34
|
+
return undefined;
|
|
35
|
+
const esResult = await conn.query(`SELECT ApiName FROM ExpressionSet WHERE Id = '${esId}'`);
|
|
36
|
+
if (esResult.records.length === 0)
|
|
37
|
+
return undefined;
|
|
38
|
+
return esResult.records[0].ApiName;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=insurance-org.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insurance-org.js","sourceRoot":"","sources":["../../../src/shared/insurance/insurance-org.ts"],"names":[],"mappings":"AAiBA,sEAAsE;AACtE,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAErD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAqB;IACnD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;SACnB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SAC9C,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC;SACtB,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAgB,EAAE,UAAuB;IAC/E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAC7B,2DAA2D,MAAM,GAAG,CACrE,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAAgB,EAAE,UAAuB;IACtF,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAE9B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAClC,sFAAsF,MAAM,+CAA+C,CAC5I,CAAC;IACF,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEvD,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;IACpD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAExD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAsB,iDAAiD,IAAI,GAAG,CAAC,CAAC;IACjH,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEpD,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { Connection, Org } from '@salesforce/core';
|
|
3
|
+
import { ParsedRuleDefinition, RuleKeyEntry, RuleRecord } from './models.js';
|
|
4
|
+
export type InsuranceRuleConvertResult = {
|
|
5
|
+
cmlFile: string;
|
|
6
|
+
associationsFile: string;
|
|
7
|
+
ruleKeyMapping: RuleKeyEntry[];
|
|
8
|
+
};
|
|
9
|
+
export type InsuranceRuleConvertContext = {
|
|
10
|
+
targetOrg: Org;
|
|
11
|
+
apiVersion: string | undefined;
|
|
12
|
+
cmlApi: string | undefined;
|
|
13
|
+
workspaceDir: string | undefined;
|
|
14
|
+
inputFile: string | undefined;
|
|
15
|
+
updateRecords: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare abstract class InsuranceRuleConvertCommand<R extends RuleRecord> extends SfCommand<InsuranceRuleConvertResult> {
|
|
18
|
+
static readonly flags: {
|
|
19
|
+
'target-org': import("@oclif/core/interfaces").OptionFlag<Org, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
'cml-api': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
22
|
+
'workspace-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
23
|
+
'update-records': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
};
|
|
25
|
+
protected abstract readonly recordLabel: string;
|
|
26
|
+
protected abstract readonly keyPrefix: string;
|
|
27
|
+
protected abstract readonly constraintLabel: string;
|
|
28
|
+
protected abstract readonly apiNamePrefix: string;
|
|
29
|
+
protected abstract readonly soql: string;
|
|
30
|
+
protected runConvert(ctx: InsuranceRuleConvertContext): Promise<InsuranceRuleConvertResult>;
|
|
31
|
+
private loadRecords;
|
|
32
|
+
private parseAllRecords;
|
|
33
|
+
private resolveProductCodes;
|
|
34
|
+
private discoverCmlApi;
|
|
35
|
+
private writeOutputFiles;
|
|
36
|
+
protected abstract parseRecord(record: R): ParsedRuleDefinition | null;
|
|
37
|
+
protected abstract updateOrgRecords(records: R[], ruleKeyMapping: RuleKeyEntry[], conn: Connection): Promise<void>;
|
|
38
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/* eslint-disable sf-plugin/command-summary, sf-plugin/command-example, sf-plugin/no-hardcoded-messages-commands */
|
|
17
|
+
// This file is a shared abstract base, not a user-invocable command, so the
|
|
18
|
+
// command-shape lint rules do not apply.
|
|
19
|
+
import * as fs from 'node:fs/promises';
|
|
20
|
+
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
21
|
+
import { Messages } from '@salesforce/core';
|
|
22
|
+
import { generateCsvForAssociations } from '../utils/association.utils.js';
|
|
23
|
+
import { buildCmlModel } from './insurance-rule-generator.js';
|
|
24
|
+
import { discoverCmlApiByProducts, fetchProductCodes } from './insurance-org.js';
|
|
25
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
26
|
+
const messages = Messages.loadMessages('@salesforce/plugin-bre-to-cml', 'cml.convert.insurance-shared');
|
|
27
|
+
export class InsuranceRuleConvertCommand extends SfCommand {
|
|
28
|
+
static flags = {
|
|
29
|
+
'target-org': Flags.requiredOrg(),
|
|
30
|
+
'api-version': Flags.orgApiVersion(),
|
|
31
|
+
'cml-api': Flags.string({
|
|
32
|
+
summary: messages.getMessage('flags.cml-api.summary'),
|
|
33
|
+
char: 'c',
|
|
34
|
+
}),
|
|
35
|
+
'workspace-dir': Flags.directory({
|
|
36
|
+
summary: messages.getMessage('flags.workspace-dir.summary'),
|
|
37
|
+
char: 'd',
|
|
38
|
+
exists: true,
|
|
39
|
+
}),
|
|
40
|
+
'update-records': Flags.boolean({
|
|
41
|
+
summary: messages.getMessage('flags.update-records.summary'),
|
|
42
|
+
default: false,
|
|
43
|
+
}),
|
|
44
|
+
};
|
|
45
|
+
async runConvert(ctx) {
|
|
46
|
+
const workspaceDir = ctx.workspaceDir ?? '.';
|
|
47
|
+
this.log(`Using Workspace Directory: ${ctx.workspaceDir ?? 'not specified'}`);
|
|
48
|
+
const conn = ctx.targetOrg.getConnection(ctx.apiVersion);
|
|
49
|
+
const records = await this.loadRecords(conn, ctx.inputFile);
|
|
50
|
+
if (records.length === 0) {
|
|
51
|
+
this.log(`No ${this.recordLabel} rules to convert.`);
|
|
52
|
+
return { cmlFile: '', associationsFile: '', ruleKeyMapping: [] };
|
|
53
|
+
}
|
|
54
|
+
const ruleDefs = this.parseAllRecords(records);
|
|
55
|
+
const productIdToCode = await this.resolveProductCodes(conn, ruleDefs);
|
|
56
|
+
const api = ctx.cmlApi ?? (await this.discoverCmlApi(conn, ruleDefs, productIdToCode));
|
|
57
|
+
const safeApi = api.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
58
|
+
const { cmlModel, ruleKeyMapping } = buildCmlModel(ruleDefs, productIdToCode, this.keyPrefix, this.constraintLabel);
|
|
59
|
+
ruleKeyMapping.forEach((m) => this.log(` -> ${m.name} => ${m.ruleKey}`));
|
|
60
|
+
if (ctx.updateRecords) {
|
|
61
|
+
await this.updateOrgRecords(records, ruleKeyMapping, conn);
|
|
62
|
+
}
|
|
63
|
+
return this.writeOutputFiles(cmlModel, ruleKeyMapping, safeApi, workspaceDir, api);
|
|
64
|
+
}
|
|
65
|
+
async loadRecords(conn, inputFile) {
|
|
66
|
+
if (inputFile) {
|
|
67
|
+
this.log(`Reading ${this.recordLabel} records from file: ${inputFile}`);
|
|
68
|
+
const contents = await fs.readFile(inputFile, 'utf8');
|
|
69
|
+
return JSON.parse(contents);
|
|
70
|
+
}
|
|
71
|
+
this.log(`Querying ${this.recordLabel} records from org...`);
|
|
72
|
+
const result = await conn.query(this.soql);
|
|
73
|
+
this.log(`Found ${result.records.length} ${this.recordLabel} records with BRE rules`);
|
|
74
|
+
return result.records;
|
|
75
|
+
}
|
|
76
|
+
parseAllRecords(records) {
|
|
77
|
+
const parsed = [];
|
|
78
|
+
for (const record of records) {
|
|
79
|
+
try {
|
|
80
|
+
const ruleDef = this.parseRecord(record);
|
|
81
|
+
if (ruleDef) {
|
|
82
|
+
parsed.push({ record, ruleDef });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
this.warn(`Failed to convert ${record.Name}: ${e.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
this.log(`Parsed ${parsed.length} valid rule definitions`);
|
|
90
|
+
return parsed;
|
|
91
|
+
}
|
|
92
|
+
async resolveProductCodes(conn, ruleDefs) {
|
|
93
|
+
const productIds = collectRootProductIds(ruleDefs);
|
|
94
|
+
try {
|
|
95
|
+
return await fetchProductCodes(conn, productIds);
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
this.warn(`Could not fetch product codes: ${e.message}. Using product IDs instead.`);
|
|
99
|
+
return new Map();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async discoverCmlApi(conn, ruleDefs, productIdToCode) {
|
|
103
|
+
const productIds = collectRootProductIds(ruleDefs);
|
|
104
|
+
try {
|
|
105
|
+
const discovered = await discoverCmlApiByProducts(conn, productIds);
|
|
106
|
+
if (discovered) {
|
|
107
|
+
this.log(`Auto-discovered existing CML API: ${discovered}`);
|
|
108
|
+
return discovered;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
this.warn(`CML auto-discovery failed: ${e.message}`);
|
|
113
|
+
}
|
|
114
|
+
const codes = Array.from(productIds).map((id) => productIdToCode.get(id) ?? id);
|
|
115
|
+
const generated = `${this.apiNamePrefix}${codes.join('_')}`;
|
|
116
|
+
this.log(`No existing CML found. Generated new CML API name: ${generated}`);
|
|
117
|
+
return generated;
|
|
118
|
+
}
|
|
119
|
+
async writeOutputFiles(cmlModel, ruleKeyMapping, safeApi, workspaceDir, api) {
|
|
120
|
+
const cmlPath = `${workspaceDir}/${safeApi}.cml`;
|
|
121
|
+
const associationsPath = `${workspaceDir}/${safeApi}_Associations.csv`;
|
|
122
|
+
const mappingPath = `${workspaceDir}/${safeApi}_RuleKeyMapping.json`;
|
|
123
|
+
await fs.writeFile(cmlPath, cmlModel.generateCml(), 'utf8');
|
|
124
|
+
await fs.writeFile(associationsPath, generateCsvForAssociations(safeApi, cmlModel.associations), 'utf8');
|
|
125
|
+
await fs.writeFile(mappingPath, JSON.stringify(ruleKeyMapping, null, 2), 'utf8');
|
|
126
|
+
this.log(`\nCML written to: ${cmlPath}`);
|
|
127
|
+
this.log(`Associations written to: ${associationsPath}`);
|
|
128
|
+
this.log(`Rule key mapping written to: ${mappingPath}`);
|
|
129
|
+
this.log(`\nConverted ${ruleKeyMapping.length} ${this.recordLabel} rules to CML`);
|
|
130
|
+
this.log('\nNext steps:');
|
|
131
|
+
this.log(' 1. Review the generated .cml file');
|
|
132
|
+
this.log(` 2. Import: sf cml import as-expression-set --cml-api ${api} --context-definition <CD_NAME> --target-org <org>`);
|
|
133
|
+
this.log(' 3. Update records with RuleKey from mapping file');
|
|
134
|
+
return { cmlFile: cmlPath, associationsFile: associationsPath, ruleKeyMapping };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function collectRootProductIds(ruleDefs) {
|
|
138
|
+
const productIds = new Set();
|
|
139
|
+
for (const { record } of ruleDefs) {
|
|
140
|
+
productIds.add(record.ProductPath.split('/')[0]);
|
|
141
|
+
}
|
|
142
|
+
return productIds;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=insurance-rule-convert-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insurance-rule-convert-command.js","sourceRoot":"","sources":["../../../src/shared/insurance/insurance-rule-convert-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CmlModel } from '../types/types.js';
|
|
2
|
+
import { ParsedRuleDefinition, RuleCriteria, RuleKeyEntry, RuleRecord, UnderwritingRuleGroup } from './models.js';
|
|
3
|
+
export declare function sanitizeName(name: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Decodes the common HTML entities that can appear in a RuleDefinition / DynamicRuleDefinition
|
|
6
|
+
* field when the JSON was persisted HTML-escaped. `&` is decoded last so already-decoded
|
|
7
|
+
* ampersands are not double-processed.
|
|
8
|
+
*/
|
|
9
|
+
export declare function decodeHtmlEntities(value: string): string;
|
|
10
|
+
export declare function buildStageTransition(ruleGroup?: UnderwritingRuleGroup): string | undefined;
|
|
11
|
+
export declare function generateRuleKey(prefix: string, productCode: string, apiName: string, stageTransition?: string): string;
|
|
12
|
+
export declare function buildConstraintDeclaration(ruleDef: {
|
|
13
|
+
ruleCriteria?: RuleCriteria[];
|
|
14
|
+
}): string;
|
|
15
|
+
export declare function collectAttributes(ruleDefs: Array<{
|
|
16
|
+
ruleDef: {
|
|
17
|
+
ruleCriteria?: RuleCriteria[];
|
|
18
|
+
};
|
|
19
|
+
}>): Set<string>;
|
|
20
|
+
export declare function buildCmlModel(ruleDefs: Array<{
|
|
21
|
+
record: RuleRecord;
|
|
22
|
+
ruleDef: ParsedRuleDefinition;
|
|
23
|
+
}>, productIdToCode: Map<string, string>, keyPrefix: string, constraintLabel: string): {
|
|
24
|
+
cmlModel: CmlModel;
|
|
25
|
+
ruleKeyMapping: RuleKeyEntry[];
|
|
26
|
+
};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { ASSOCIATION_TYPES, CML_DATA_TYPES, CONSTRAINT_TYPES } from '../constants/constants.js';
|
|
17
|
+
import { Association, CmlAttribute, CmlConstraint, CmlModel, CmlType } from '../types/types.js';
|
|
18
|
+
import { convertToCmlExpression, isKnownOperator, operatorRequiresValues } from '../cml-operators.js';
|
|
19
|
+
function dataTypeToCml(dataType) {
|
|
20
|
+
const types = {
|
|
21
|
+
Number: CML_DATA_TYPES.INTEGER,
|
|
22
|
+
Integer: CML_DATA_TYPES.INTEGER,
|
|
23
|
+
Percent: CML_DATA_TYPES.DECIMAL,
|
|
24
|
+
Currency: CML_DATA_TYPES.DECIMAL,
|
|
25
|
+
Boolean: CML_DATA_TYPES.BOOLEAN,
|
|
26
|
+
Date: CML_DATA_TYPES.DATE,
|
|
27
|
+
DateTime: CML_DATA_TYPES.DATE,
|
|
28
|
+
};
|
|
29
|
+
return (dataType && types[dataType]) ?? CML_DATA_TYPES.STRING;
|
|
30
|
+
}
|
|
31
|
+
export function sanitizeName(name) {
|
|
32
|
+
return name.replace(/[^a-zA-Z0-9]/g, '_');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Decodes the common HTML entities that can appear in a RuleDefinition / DynamicRuleDefinition
|
|
36
|
+
* field when the JSON was persisted HTML-escaped. `&` is decoded last so already-decoded
|
|
37
|
+
* ampersands are not double-processed.
|
|
38
|
+
*/
|
|
39
|
+
export function decodeHtmlEntities(value) {
|
|
40
|
+
return value
|
|
41
|
+
.replace(/"/g, '"')
|
|
42
|
+
.replace(/'/g, "'")
|
|
43
|
+
.replace(/'/g, "'")
|
|
44
|
+
.replace(/</g, '<')
|
|
45
|
+
.replace(/>/g, '>')
|
|
46
|
+
.replace(/&/g, '&');
|
|
47
|
+
}
|
|
48
|
+
function stripSpaces(stage) {
|
|
49
|
+
return stage.replace(/\s+/g, '');
|
|
50
|
+
}
|
|
51
|
+
export function buildStageTransition(ruleGroup) {
|
|
52
|
+
if (!ruleGroup?.fromStage || !ruleGroup?.toStage)
|
|
53
|
+
return undefined;
|
|
54
|
+
return `${stripSpaces(ruleGroup.fromStage)}To${stripSpaces(ruleGroup.toStage)}`;
|
|
55
|
+
}
|
|
56
|
+
export function generateRuleKey(prefix, productCode, apiName, stageTransition) {
|
|
57
|
+
const parts = [prefix, sanitizeName(productCode)];
|
|
58
|
+
if (stageTransition)
|
|
59
|
+
parts.push(stageTransition);
|
|
60
|
+
parts.push(sanitizeName(apiName));
|
|
61
|
+
return parts.join('__');
|
|
62
|
+
}
|
|
63
|
+
function buildConditionExpression(condition) {
|
|
64
|
+
if (!isKnownOperator(condition.operator))
|
|
65
|
+
return null;
|
|
66
|
+
const op = condition.operator;
|
|
67
|
+
if (operatorRequiresValues(op) && (!condition.values || condition.values.length === 0)) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const attrName = sanitizeName(condition.attributeName ?? condition.contextTagName ?? 'unknown');
|
|
71
|
+
const cmlDataType = dataTypeToCml(condition.dataType);
|
|
72
|
+
return convertToCmlExpression(attrName, op, condition.values, cmlDataType);
|
|
73
|
+
}
|
|
74
|
+
function buildCriteriaExpression(criteria) {
|
|
75
|
+
const parts = [];
|
|
76
|
+
if (criteria.conditions) {
|
|
77
|
+
for (const condition of criteria.conditions) {
|
|
78
|
+
const expr = buildConditionExpression(condition);
|
|
79
|
+
if (expr)
|
|
80
|
+
parts.push(expr);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return parts.length > 0 ? parts.join(' && ') : null;
|
|
84
|
+
}
|
|
85
|
+
export function buildConstraintDeclaration(ruleDef) {
|
|
86
|
+
if (!ruleDef.ruleCriteria || ruleDef.ruleCriteria.length === 0) {
|
|
87
|
+
return 'true';
|
|
88
|
+
}
|
|
89
|
+
const expressions = ruleDef.ruleCriteria.map(buildCriteriaExpression).filter((e) => e !== null);
|
|
90
|
+
if (expressions.length === 0)
|
|
91
|
+
return 'true';
|
|
92
|
+
if (expressions.length === 1)
|
|
93
|
+
return expressions[0];
|
|
94
|
+
return expressions.map((e) => `(${e})`).join(' || ');
|
|
95
|
+
}
|
|
96
|
+
export function collectAttributes(ruleDefs) {
|
|
97
|
+
const attrs = new Set();
|
|
98
|
+
for (const { ruleDef } of ruleDefs) {
|
|
99
|
+
for (const criteria of ruleDef.ruleCriteria ?? []) {
|
|
100
|
+
for (const cond of criteria.conditions ?? []) {
|
|
101
|
+
const name = cond.attributeName ?? cond.contextTagName;
|
|
102
|
+
if (name)
|
|
103
|
+
attrs.add(name);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return attrs;
|
|
108
|
+
}
|
|
109
|
+
export function buildCmlModel(ruleDefs, productIdToCode, keyPrefix, constraintLabel) {
|
|
110
|
+
const cmlModel = new CmlModel();
|
|
111
|
+
const rulesByProduct = new Map();
|
|
112
|
+
for (const entry of ruleDefs) {
|
|
113
|
+
const rootProductId = entry.record.ProductPath.split('/')[0];
|
|
114
|
+
if (!rulesByProduct.has(rootProductId)) {
|
|
115
|
+
rulesByProduct.set(rootProductId, []);
|
|
116
|
+
}
|
|
117
|
+
rulesByProduct.get(rootProductId).push(entry);
|
|
118
|
+
}
|
|
119
|
+
const ruleKeyMapping = [];
|
|
120
|
+
for (const [rootProductId, productRules] of rulesByProduct) {
|
|
121
|
+
const productCode = productIdToCode.get(rootProductId) ?? rootProductId;
|
|
122
|
+
const typeName = sanitizeName(productCode);
|
|
123
|
+
const productType = new CmlType(typeName, undefined, undefined);
|
|
124
|
+
const attrs = collectAttributes(productRules);
|
|
125
|
+
for (const attrName of attrs) {
|
|
126
|
+
productType.addAttribute(new CmlAttribute(null, sanitizeName(attrName), CML_DATA_TYPES.STRING));
|
|
127
|
+
}
|
|
128
|
+
for (const { record, ruleDef } of productRules) {
|
|
129
|
+
const apiName = ruleDef.apiName ?? record.Name;
|
|
130
|
+
const stageTransition = buildStageTransition(ruleDef.underwritingRuleGroup);
|
|
131
|
+
const ruleKey = generateRuleKey(keyPrefix, productCode, apiName, stageTransition);
|
|
132
|
+
const constraint = new CmlConstraint(CONSTRAINT_TYPES.CONSTRAINT, buildConstraintDeclaration(ruleDef), `"${constraintLabel}: ${record.Name}"`);
|
|
133
|
+
// Mirror generateRuleKey: include the stage transition so two rules that share an
|
|
134
|
+
// apiName under the same product (gated on different transitions) don't collide.
|
|
135
|
+
constraint.name = sanitizeName(stageTransition ? `${apiName}_${stageTransition}` : apiName);
|
|
136
|
+
productType.addConstraint(constraint);
|
|
137
|
+
ruleKeyMapping.push({ recordId: record.Id, name: record.Name, ruleKey });
|
|
138
|
+
}
|
|
139
|
+
cmlModel.addType(productType);
|
|
140
|
+
cmlModel.addAssociation(new Association(null, typeName, ASSOCIATION_TYPES.TYPE, rootProductId, 'Product2', productCode));
|
|
141
|
+
}
|
|
142
|
+
return { cmlModel, ruleKeyMapping };
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=insurance-rule-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insurance-rule-generator.js","sourceRoot":"","sources":["../../../src/shared/insurance/insurance-rule-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type RuleCondition = {
|
|
2
|
+
contextTagName?: string;
|
|
3
|
+
operator: string;
|
|
4
|
+
conditionIndex?: number;
|
|
5
|
+
attributeName?: string;
|
|
6
|
+
attributePicklistValueId?: string;
|
|
7
|
+
attributeId?: string;
|
|
8
|
+
dataType?: string;
|
|
9
|
+
type?: string;
|
|
10
|
+
values?: string[];
|
|
11
|
+
};
|
|
12
|
+
export type RuleCriteria = {
|
|
13
|
+
rootObjectId: string;
|
|
14
|
+
criteriaIndex?: number;
|
|
15
|
+
sourceContextTagName?: string;
|
|
16
|
+
sourceOperator?: string;
|
|
17
|
+
sourceDataType?: string;
|
|
18
|
+
sourceValues?: string[];
|
|
19
|
+
conditions?: RuleCondition[];
|
|
20
|
+
};
|
|
21
|
+
export type UnderwritingRuleGroup = {
|
|
22
|
+
fromStage?: string;
|
|
23
|
+
toStage?: string;
|
|
24
|
+
stageTransitionName?: string;
|
|
25
|
+
};
|
|
26
|
+
export type ParsedRuleDefinition = {
|
|
27
|
+
name: string;
|
|
28
|
+
apiName: string;
|
|
29
|
+
productPath: string;
|
|
30
|
+
status?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
ruleCriteria?: RuleCriteria[];
|
|
33
|
+
underwritingRuleGroup?: UnderwritingRuleGroup;
|
|
34
|
+
};
|
|
35
|
+
export type RuleRecord = {
|
|
36
|
+
Id: string;
|
|
37
|
+
Name: string;
|
|
38
|
+
ProductPath: string;
|
|
39
|
+
};
|
|
40
|
+
export type RuleKeyEntry = {
|
|
41
|
+
recordId: string;
|
|
42
|
+
name: string;
|
|
43
|
+
ruleKey: string;
|
|
44
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/shared/insurance/models.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# flags.cml-api.summary
|
|
2
|
+
|
|
3
|
+
CML API Name. If omitted, auto-discovers an existing CML associated with the same root products.
|
|
4
|
+
|
|
5
|
+
# flags.workspace-dir.summary
|
|
6
|
+
|
|
7
|
+
Directory where output files will be written.
|
|
8
|
+
|
|
9
|
+
# flags.update-records.summary
|
|
10
|
+
|
|
11
|
+
Update source records in the org with RuleEngineType=ConstraintEngine.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Converts BRE-based Product Surcharge dynamic rules to CML eligibility constraints.
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
Reads ProductSurcharge records from the org (or a JSON file), parses their RuleDefinition, and generates CML constraints that evaluate surcharge eligibility. Each surcharge rule becomes a named constraint that returns true/false. The command outputs a .cml file with the constraint model, an \_Associations.csv file for ExpressionSetConstraintObj records, and a \_RuleKeyMapping.json with the ProductSurcharge ID to RuleKey mapping for updating records.
|
|
8
|
+
|
|
9
|
+
# examples
|
|
10
|
+
|
|
11
|
+
- <%= config.bin %> <%= command.id %> --cml-api SURCHARGE_CML --target-org myOrg
|
|
12
|
+
|
|
13
|
+
- <%= config.bin %> <%= command.id %> --cml-api SURCHARGE_CML --surcharge-file path/to/surcharges.json --workspace-dir data --target-org myOrg
|
|
14
|
+
|
|
15
|
+
# flags.surcharge-file.summary
|
|
16
|
+
|
|
17
|
+
Optional JSON file with pre-exported ProductSurcharge records. If omitted, records are queried from the org.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Converts BRE-based Insurance Underwriting dynamic rules to CML eligibility constraints.
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
Reads UnderwritingRule records from the org (or a JSON file), parses their DynamicRuleDefinition, and generates CML constraints that evaluate underwriting eligibility. Each rule becomes a named constraint that returns true/false. The command outputs a .cml file with the constraint model, an \_Associations.csv file for ExpressionSetConstraintObj records, and a \_RuleKeyMapping.json with the UnderwritingRule ID to RuleKey mapping for updating records.
|
|
8
|
+
|
|
9
|
+
# examples
|
|
10
|
+
|
|
11
|
+
- <%= config.bin %> <%= command.id %> --cml-api UW_CML --target-org myOrg
|
|
12
|
+
|
|
13
|
+
- <%= config.bin %> <%= command.id %> --cml-api UW_CML --uw-file data/underwriting.json --workspace-dir data --target-org myOrg
|
|
14
|
+
|
|
15
|
+
# flags.uw-file.summary
|
|
16
|
+
|
|
17
|
+
Optional JSON file with pre-exported UnderwritingRule records. If omitted, records are queried from the org.
|