@salesforce/plugin-omnistudio-migration-tool 2.0.0-rc.6 → 2.0.0-rc.61
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 +165 -73
- package/lib/commands/omnistudio/migration/assess.d.ts +23 -15
- package/lib/commands/omnistudio/migration/assess.js +250 -89
- package/lib/commands/omnistudio/migration/assess.js.map +1 -1
- package/lib/commands/omnistudio/migration/clean.d.ts +13 -0
- package/lib/commands/omnistudio/migration/clean.js +162 -0
- package/lib/commands/omnistudio/migration/clean.js.map +1 -0
- package/lib/commands/omnistudio/migration/info.d.ts +10 -16
- package/lib/commands/omnistudio/migration/info.js +53 -35
- package/lib/commands/omnistudio/migration/info.js.map +1 -1
- package/lib/commands/omnistudio/migration/migrate.d.ts +78 -18
- package/lib/commands/omnistudio/migration/migrate.js +461 -175
- package/lib/commands/omnistudio/migration/migrate.js.map +1 -1
- package/lib/error/deploymentErrors.d.ts +15 -0
- package/lib/error/deploymentErrors.js +35 -0
- package/lib/error/deploymentErrors.js.map +1 -0
- package/lib/error/errorInterfaces.d.ts +5 -0
- package/lib/error/errorInterfaces.js +9 -1
- package/lib/error/errorInterfaces.js.map +1 -1
- package/lib/javascripts/reportGeneratorUtility.js +585 -22
- package/lib/migration/ApexNamespaceRegistry.d.ts +49 -0
- package/lib/migration/ApexNamespaceRegistry.js +130 -0
- package/lib/migration/ApexNamespaceRegistry.js.map +1 -0
- package/lib/migration/CustomCssRegistry.d.ts +117 -0
- package/lib/migration/CustomCssRegistry.js +234 -0
- package/lib/migration/CustomCssRegistry.js.map +1 -0
- package/lib/migration/NameMappingRegistry.d.ts +134 -0
- package/lib/migration/NameMappingRegistry.js +411 -0
- package/lib/migration/NameMappingRegistry.js.map +1 -0
- package/lib/migration/base.d.ts +8 -6
- package/lib/migration/base.js +25 -8
- package/lib/migration/base.js.map +1 -1
- package/lib/migration/customLabels.d.ts +70 -0
- package/lib/migration/customLabels.js +177 -0
- package/lib/migration/customLabels.js.map +1 -0
- package/lib/migration/dataraptor.d.ts +13 -0
- package/lib/migration/dataraptor.js +205 -80
- package/lib/migration/dataraptor.js.map +1 -1
- package/lib/migration/deployer.d.ts +14 -0
- package/lib/migration/deployer.js +105 -0
- package/lib/migration/deployer.js.map +1 -0
- package/lib/migration/flexcard.d.ts +256 -6
- package/lib/migration/flexcard.js +1808 -268
- package/lib/migration/flexcard.js.map +1 -1
- package/lib/migration/globalautonumber.d.ts +8 -8
- package/lib/migration/globalautonumber.js +49 -24
- package/lib/migration/globalautonumber.js.map +1 -1
- package/lib/migration/interfaces.d.ts +14 -0
- package/lib/migration/interfaces.js.map +1 -1
- package/lib/migration/metadataobjnamecheck.js.map +1 -1
- package/lib/migration/omniscript.d.ts +218 -4
- package/lib/migration/omniscript.js +1709 -247
- package/lib/migration/omniscript.js.map +1 -1
- package/lib/migration/omniscriptInstance.d.ts +90 -0
- package/lib/migration/omniscriptInstance.js +755 -0
- package/lib/migration/omniscriptInstance.js.map +1 -0
- package/lib/migration/postMigrate.d.ts +20 -4
- package/lib/migration/postMigrate.js +199 -12
- package/lib/migration/postMigrate.js.map +1 -1
- package/lib/migration/premigrate.d.ts +51 -0
- package/lib/migration/premigrate.js +325 -0
- package/lib/migration/premigrate.js.map +1 -0
- package/lib/migration/related/ApexMigration.d.ts +3 -0
- package/lib/migration/related/ApexMigration.js +222 -56
- package/lib/migration/related/ApexMigration.js.map +1 -1
- package/lib/migration/related/ExperienceSiteMigration.d.ts +30 -5
- package/lib/migration/related/ExperienceSiteMigration.js +263 -73
- package/lib/migration/related/ExperienceSiteMigration.js.map +1 -1
- package/lib/migration/related/FlexipageMigration.d.ts +5 -5
- package/lib/migration/related/FlexipageMigration.js +60 -38
- package/lib/migration/related/FlexipageMigration.js.map +1 -1
- package/lib/migration/related/LwcMigration.js +45 -26
- package/lib/migration/related/LwcMigration.js.map +1 -1
- package/lib/migration/related/OmnistudioRelatedObjectMigrationFacade.js +48 -32
- package/lib/migration/related/OmnistudioRelatedObjectMigrationFacade.js.map +1 -1
- package/lib/styles/reportGenerator.css +241 -16
- package/lib/templates/assessmentReport.template +78 -8
- package/lib/templates/dashboard.template +86 -57
- package/lib/templates/migrationReport.template +151 -0
- package/lib/utils/OmnistudioSettingsPrefManager.d.ts +14 -0
- package/lib/utils/OmnistudioSettingsPrefManager.js +112 -0
- package/lib/utils/OmnistudioSettingsPrefManager.js.map +1 -0
- package/lib/utils/XMLUtil.js +2 -1
- package/lib/utils/XMLUtil.js.map +1 -1
- package/lib/utils/apex/executor/AnonymousApexRunner.d.ts +1 -1
- package/lib/utils/apex/parser/apexparser.d.ts +8 -1
- package/lib/utils/apex/parser/apexparser.js +79 -13
- package/lib/utils/apex/parser/apexparser.js.map +1 -1
- package/lib/utils/config/ExistingRecordCleanupService.d.ts +30 -0
- package/lib/utils/config/ExistingRecordCleanupService.js +266 -0
- package/lib/utils/config/ExistingRecordCleanupService.js.map +1 -0
- package/lib/utils/config/OmniStudioMetadataCleanupService.d.ts +36 -0
- package/lib/utils/config/OmniStudioMetadataCleanupService.js +123 -0
- package/lib/utils/config/OmniStudioMetadataCleanupService.js.map +1 -0
- package/lib/utils/config/SpecialCharacterRecordCleanupService.d.ts +17 -0
- package/lib/utils/config/SpecialCharacterRecordCleanupService.js +186 -0
- package/lib/utils/config/SpecialCharacterRecordCleanupService.js.map +1 -0
- package/lib/utils/constants/documentRegistry.d.ts +9 -17
- package/lib/utils/constants/documentRegistry.js +9 -17
- package/lib/utils/constants/documentRegistry.js.map +1 -1
- package/lib/utils/constants/stringContants.d.ts +78 -0
- package/lib/utils/constants/stringContants.js +91 -4
- package/lib/utils/constants/stringContants.js.map +1 -1
- package/lib/utils/customLabels.d.ts +35 -0
- package/lib/utils/customLabels.js +100 -0
- package/lib/utils/customLabels.js.map +1 -0
- package/lib/utils/dataModelService.d.ts +18 -0
- package/lib/utils/dataModelService.js +72 -0
- package/lib/utils/dataModelService.js.map +1 -0
- package/lib/utils/file/fileUtil.d.ts +3 -1
- package/lib/utils/file/fileUtil.js +30 -13
- package/lib/utils/file/fileUtil.js.map +1 -1
- package/lib/utils/flexipage/flexiPageTransformer.js +119 -23
- package/lib/utils/flexipage/flexiPageTransformer.js.map +1 -1
- package/lib/utils/formula/FormulaUtil.d.ts +1 -1
- package/lib/utils/formula/FormulaUtil.js +17 -9
- package/lib/utils/formula/FormulaUtil.js.map +1 -1
- package/lib/utils/formula/Stack.js.map +1 -1
- package/lib/utils/generatePackageXml.d.ts +6 -2
- package/lib/utils/generatePackageXml.js +73 -33
- package/lib/utils/generatePackageXml.js.map +1 -1
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +1 -0
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/interfaces.d.ts +69 -8
- package/lib/utils/json/jsonutil.js.map +1 -1
- package/lib/utils/logger/fileLogger.js +17 -7
- package/lib/utils/logger/fileLogger.js.map +1 -1
- package/lib/utils/logger.d.ts +3 -3
- package/lib/utils/logger.js +10 -6
- package/lib/utils/logger.js.map +1 -1
- package/lib/utils/logging/debugtimer.js.map +1 -1
- package/lib/utils/lwcparser/fileutils/FileDiffUtil.js +30 -22
- package/lib/utils/lwcparser/fileutils/FileDiffUtil.js.map +1 -1
- package/lib/utils/lwcparser/fileutils/FileProcessorFactory.js.map +1 -1
- package/lib/utils/lwcparser/fileutils/HtmlFileProcessor.js.map +1 -1
- package/lib/utils/lwcparser/fileutils/JavascriptFileProcessor.js.map +1 -1
- package/lib/utils/lwcparser/fileutils/XmlFileProcessor.js.map +1 -1
- package/lib/utils/lwcparser/htmlParser/HTMLParser.js +29 -10
- package/lib/utils/lwcparser/htmlParser/HTMLParser.js.map +1 -1
- package/lib/utils/lwcparser/jsParser/JavaScriptParser.js +29 -11
- package/lib/utils/lwcparser/jsParser/JavaScriptParser.js.map +1 -1
- package/lib/utils/lwcparser/xmlParser/XmlParser.js +19 -8
- package/lib/utils/lwcparser/xmlParser/XmlParser.js.map +1 -1
- package/lib/utils/net/index.d.ts +5 -0
- package/lib/utils/net/index.js +40 -2
- package/lib/utils/net/index.js.map +1 -1
- package/lib/utils/omniscriptPackageManager.d.ts +31 -0
- package/lib/utils/omniscriptPackageManager.js +215 -0
- package/lib/utils/omniscriptPackageManager.js.map +1 -0
- package/lib/utils/orgPreferences.d.ts +25 -0
- package/lib/utils/orgPreferences.js +124 -8
- package/lib/utils/orgPreferences.js.map +1 -1
- package/lib/utils/orgUtils/index.d.ts +12 -5
- package/lib/utils/orgUtils/index.js +52 -22
- package/lib/utils/orgUtils/index.js.map +1 -1
- package/lib/utils/projectPathUtil.d.ts +1 -1
- package/lib/utils/projectPathUtil.js +27 -10
- package/lib/utils/projectPathUtil.js.map +1 -1
- package/lib/utils/promptUtil.d.ts +11 -1
- package/lib/utils/promptUtil.js +92 -0
- package/lib/utils/promptUtil.js.map +1 -1
- package/lib/utils/query/index.d.ts +1 -0
- package/lib/utils/query/index.js +18 -1
- package/lib/utils/query/index.js.map +1 -1
- package/lib/utils/recordPrioritization.d.ts +44 -0
- package/lib/utils/recordPrioritization.js +69 -0
- package/lib/utils/recordPrioritization.js.map +1 -0
- package/lib/utils/reportGenerator/reportInterfaces.d.ts +12 -0
- package/lib/utils/reportGenerator/reportUtil.d.ts +6 -1
- package/lib/utils/reportGenerator/reportUtil.js +22 -7
- package/lib/utils/reportGenerator/reportUtil.js.map +1 -1
- package/lib/utils/resultsbuilder/ApexAssessmentReporter.d.ts +1 -0
- package/lib/utils/resultsbuilder/ApexAssessmentReporter.js +40 -17
- package/lib/utils/resultsbuilder/ApexAssessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/CustomLabelAssessmentReporter.d.ts +13 -0
- package/lib/utils/resultsbuilder/CustomLabelAssessmentReporter.js +179 -0
- package/lib/utils/resultsbuilder/CustomLabelAssessmentReporter.js.map +1 -0
- package/lib/utils/resultsbuilder/CustomLabelMigrationReporter.d.ts +27 -0
- package/lib/utils/resultsbuilder/CustomLabelMigrationReporter.js +262 -0
- package/lib/utils/resultsbuilder/CustomLabelMigrationReporter.js.map +1 -0
- package/lib/utils/resultsbuilder/DRAssessmentReporter.js +38 -70
- package/lib/utils/resultsbuilder/DRAssessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/ExperienceSiteAssessmentReporter.d.ts +14 -0
- package/lib/utils/resultsbuilder/ExperienceSiteAssessmentReporter.js +143 -0
- package/lib/utils/resultsbuilder/ExperienceSiteAssessmentReporter.js.map +1 -0
- package/lib/utils/resultsbuilder/FlexcardAssessmentReporter.js +46 -85
- package/lib/utils/resultsbuilder/FlexcardAssessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/FlexipageAssessmentReporter.d.ts +1 -0
- package/lib/utils/resultsbuilder/FlexipageAssessmentReporter.js +37 -19
- package/lib/utils/resultsbuilder/FlexipageAssessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/GlobalAutoNumberAssessmentReporter.js +22 -14
- package/lib/utils/resultsbuilder/GlobalAutoNumberAssessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/IPAssessmentReporter.js +38 -71
- package/lib/utils/resultsbuilder/IPAssessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/LWCAssessmentReporter.d.ts +14 -0
- package/lib/utils/resultsbuilder/LWCAssessmentReporter.js +143 -139
- package/lib/utils/resultsbuilder/LWCAssessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/OSAssessmentReporter.js +41 -88
- package/lib/utils/resultsbuilder/OSAssessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/SaveForLaterAssessmentReporter.d.ts +12 -0
- package/lib/utils/resultsbuilder/SaveForLaterAssessmentReporter.js +109 -0
- package/lib/utils/resultsbuilder/SaveForLaterAssessmentReporter.js.map +1 -0
- package/lib/utils/resultsbuilder/assessmentReporter.d.ts +16 -6
- package/lib/utils/resultsbuilder/assessmentReporter.js +96 -152
- package/lib/utils/resultsbuilder/assessmentReporter.js.map +1 -1
- package/lib/utils/resultsbuilder/helpers/AssessmentReportHelper.d.ts +104 -0
- package/lib/utils/resultsbuilder/helpers/AssessmentReportHelper.js +380 -0
- package/lib/utils/resultsbuilder/helpers/AssessmentReportHelper.js.map +1 -0
- package/lib/utils/resultsbuilder/index.d.ts +37 -1
- package/lib/utils/resultsbuilder/index.js +582 -151
- package/lib/utils/resultsbuilder/index.js.map +1 -1
- package/lib/utils/resultsbuilder/reportingHelper.d.ts +2 -7
- package/lib/utils/resultsbuilder/reportingHelper.js +0 -43
- package/lib/utils/resultsbuilder/reportingHelper.js.map +1 -1
- package/lib/utils/sfcli/project/sfProject.d.ts +29 -0
- package/lib/utils/sfcli/project/sfProject.js +220 -2
- package/lib/utils/sfcli/project/sfProject.js.map +1 -1
- package/lib/utils/shell/cli.js +20 -14
- package/lib/utils/shell/cli.js.map +1 -1
- package/lib/utils/storageUtil.d.ts +14 -1
- package/lib/utils/storageUtil.js +31 -1
- package/lib/utils/storageUtil.js.map +1 -1
- package/lib/utils/stringUtils.d.ts +24 -0
- package/lib/utils/stringUtils.js +76 -9
- package/lib/utils/stringUtils.js.map +1 -1
- package/lib/utils/templateParser/__tests__/test.js +1 -2
- package/lib/utils/templateParser/__tests__/test.js.map +1 -1
- package/lib/utils/templateParser/generate.d.ts +1 -1
- package/lib/utils/templateParser/generate.js.map +1 -1
- package/lib/utils/templateParser/model/elementNode.d.ts +2 -2
- package/lib/utils/templateParser/model/elementNode.js +11 -2
- package/lib/utils/templateParser/model/elementNode.js.map +1 -1
- package/lib/utils/templateParser/model/nodeTypes.js +1 -1
- package/lib/utils/templateParser/model/nodeTypes.js.map +1 -1
- package/lib/utils/templateParser/util.d.ts +2 -2
- package/lib/utils/templateParser/util.js.map +1 -1
- package/lib/utils/validatorService.d.ts +14 -0
- package/lib/utils/validatorService.js +136 -0
- package/lib/utils/validatorService.js.map +1 -0
- package/messages/assess.json +220 -103
- package/messages/clean.json +40 -0
- package/messages/info.json +2 -1
- package/messages/migrate.json +314 -102
- package/oclif.manifest.json +1 -1
- package/package.json +49 -13
- package/lib/commands/basecommand.d.ts +0 -8
- package/lib/commands/basecommand.js +0 -13
- package/lib/commands/basecommand.js.map +0 -1
- package/lib/utils/OmniGlobalAutoNumberPrefManager.d.ts +0 -40
- package/lib/utils/OmniGlobalAutoNumberPrefManager.js +0 -65
- package/lib/utils/OmniGlobalAutoNumberPrefManager.js.map +0 -1
|
@@ -8,22 +8,30 @@ const VlocityCard_1 = __importDefault(require("../mappings/VlocityCard"));
|
|
|
8
8
|
const utils_1 = require("../utils");
|
|
9
9
|
const net_1 = require("../utils/net");
|
|
10
10
|
const base_1 = require("./base");
|
|
11
|
+
const CustomCssRegistry_1 = require("./CustomCssRegistry");
|
|
11
12
|
const interfaces_1 = require("./interfaces");
|
|
12
13
|
const logger_1 = require("../utils/logger");
|
|
13
14
|
const base_2 = require("./base");
|
|
14
15
|
const stringContants_1 = require("../utils/constants/stringContants");
|
|
15
16
|
const storageUtil_1 = require("../utils/storageUtil");
|
|
17
|
+
const stringUtils_1 = require("../utils/stringUtils");
|
|
18
|
+
const dataModelService_1 = require("../utils/dataModelService");
|
|
19
|
+
const recordPrioritization_1 = require("../utils/recordPrioritization");
|
|
20
|
+
const ApexNamespaceRegistry_1 = require("./ApexNamespaceRegistry");
|
|
16
21
|
class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
17
22
|
constructor(namespace, connection, logger, messages, ux, allVersions) {
|
|
18
23
|
super(namespace, connection, logger, messages, ux);
|
|
24
|
+
this.apexNamespaceRegistry = ApexNamespaceRegistry_1.ApexNamespaceRegistry.getInstance();
|
|
25
|
+
this.IS_STANDARD_DATA_MODEL = (0, dataModelService_1.isStandardDataModel)();
|
|
19
26
|
this.allVersions = allVersions;
|
|
27
|
+
CustomCssRegistry_1.CustomCssRegistry.getInstance().init(connection, namespace, messages);
|
|
20
28
|
}
|
|
21
29
|
getName() {
|
|
22
|
-
return '
|
|
30
|
+
return 'Flexcards';
|
|
23
31
|
}
|
|
24
32
|
getRecordName(record) {
|
|
25
33
|
return this.allVersions
|
|
26
|
-
? `${record['Name']}_${record[this.
|
|
34
|
+
? `${record['Name']}_${record[this.getFieldKey(CardMigrationTool.VERSION_PROP)]}`
|
|
27
35
|
: record['Name'];
|
|
28
36
|
}
|
|
29
37
|
getMappings() {
|
|
@@ -36,6 +44,10 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
36
44
|
}
|
|
37
45
|
// Perform Delete of OmniUiCard Records to start migration from scratch
|
|
38
46
|
async truncate() {
|
|
47
|
+
if (this.IS_STANDARD_DATA_MODEL) {
|
|
48
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('skippingTruncation'));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
39
51
|
const objectName = CardMigrationTool.OMNIUICARD_NAME;
|
|
40
52
|
utils_1.DebugTimer.getInstance().lap('Truncating ' + objectName);
|
|
41
53
|
const ids = await utils_1.QueryTools.queryIds(this.connection, objectName);
|
|
@@ -57,19 +69,53 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
57
69
|
}
|
|
58
70
|
// Perform Records Migration from VlocityCard__c to OmniUiCard
|
|
59
71
|
async migrate() {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
const allCards = await this.getAllCards();
|
|
73
|
+
if ((0, dataModelService_1.isStandardDataModelWithMetadataAPIEnabled)()) {
|
|
74
|
+
return this.handleMigrationForStdDataModelOrgsWithMetadataAPIEnabled(allCards);
|
|
75
|
+
}
|
|
76
|
+
logger_1.Logger.log(this.messages.getMessage('foundFlexCardsToMigrate', [allCards.length]));
|
|
77
|
+
// Filter out FlexCards with Angular OmniScript dependencies
|
|
78
|
+
const cards = [];
|
|
79
|
+
const skippedCards = new Map();
|
|
80
|
+
for (const card of allCards) {
|
|
81
|
+
if (this.hasAngularOmniScriptDependencies(card)) {
|
|
82
|
+
// Skip FlexCard with Angular dependencies
|
|
83
|
+
logger_1.Logger.logVerbose(`${this.messages.getMessage('skipFlexcardAngularOmniScriptDependencyWarning', [card['Name']])}`);
|
|
84
|
+
skippedCards.set(card['Id'], {
|
|
85
|
+
referenceId: card['Id'],
|
|
86
|
+
id: '',
|
|
87
|
+
success: false,
|
|
88
|
+
hasErrors: false,
|
|
89
|
+
errors: [],
|
|
90
|
+
warnings: [this.messages.getMessage('flexCardWithAngularOmniScriptWarning')],
|
|
91
|
+
newName: '',
|
|
92
|
+
skipped: true,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
cards.push(card);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (this.IS_STANDARD_DATA_MODEL) {
|
|
100
|
+
logger_1.Logger.log(`${this.messages.getMessage('flexCardMigrationProcessingMessage', [cards.length])}`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
logger_1.Logger.log(`${this.messages.getMessage('flexCardMigrationProcessingMessage', [cards.length])} ${this.messages.getMessage('skippingAsAngularDependencies', [skippedCards.size])}`);
|
|
104
|
+
}
|
|
105
|
+
const progressBar = (0, base_2.createProgressBar)('Migrating', 'Flexcards');
|
|
64
106
|
// Save the Vlocity Cards in OmniUiCard
|
|
65
107
|
const cardUploadResponse = await this.uploadAllCards(cards, progressBar);
|
|
108
|
+
// Add skipped cards to the response
|
|
109
|
+
for (const [cardId, skippedResult] of skippedCards.entries()) {
|
|
110
|
+
cardUploadResponse.set(cardId, skippedResult);
|
|
111
|
+
}
|
|
66
112
|
const records = new Map();
|
|
67
|
-
for (let i = 0; i <
|
|
68
|
-
records.set(
|
|
113
|
+
for (let i = 0; i < allCards.length; i++) {
|
|
114
|
+
records.set(allCards[i]['Id'], allCards[i]);
|
|
69
115
|
}
|
|
70
116
|
return [
|
|
71
117
|
{
|
|
72
|
-
name: '
|
|
118
|
+
name: 'Flexcards',
|
|
73
119
|
records: records,
|
|
74
120
|
results: cardUploadResponse,
|
|
75
121
|
},
|
|
@@ -77,10 +123,14 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
77
123
|
}
|
|
78
124
|
async assess() {
|
|
79
125
|
try {
|
|
126
|
+
const flexCards = await this.getAllCards();
|
|
127
|
+
if ((0, dataModelService_1.isStandardDataModelWithMetadataAPIEnabled)()) {
|
|
128
|
+
return this.handleAssessmentForStdDataModelOrgsWithMetadataAPIEnabled(flexCards);
|
|
129
|
+
}
|
|
80
130
|
logger_1.Logger.log(this.messages.getMessage('startingFlexCardAssessment'));
|
|
81
|
-
const flexCards = await this.getAllActiveCards();
|
|
82
131
|
logger_1.Logger.log(this.messages.getMessage('foundFlexCardsToAssess', [flexCards.length]));
|
|
83
|
-
const flexCardsAssessmentInfos = this.processCardComponents(flexCards);
|
|
132
|
+
const flexCardsAssessmentInfos = await this.processCardComponents(flexCards);
|
|
133
|
+
this.prepareAssessmentStorageForFlexcards(flexCardsAssessmentInfos);
|
|
84
134
|
return flexCardsAssessmentInfos;
|
|
85
135
|
}
|
|
86
136
|
catch (err) {
|
|
@@ -93,13 +143,14 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
93
143
|
async processCardComponents(flexCards) {
|
|
94
144
|
const flexCardAssessmentInfos = [];
|
|
95
145
|
let progressCounter = 0;
|
|
96
|
-
const progressBar = (0, base_2.createProgressBar)('Assessing', '
|
|
146
|
+
const progressBar = (0, base_2.createProgressBar)('Assessing', 'Flexcards');
|
|
97
147
|
progressBar.start(flexCards.length, progressCounter);
|
|
98
148
|
const uniqueNames = new Set();
|
|
149
|
+
const dupFlexCardNames = new Map();
|
|
99
150
|
// Now process each OmniScript and its elements
|
|
100
151
|
for (const flexCard of flexCards) {
|
|
101
152
|
try {
|
|
102
|
-
const flexCardAssessmentInfo = await this.processFlexCard(flexCard, uniqueNames);
|
|
153
|
+
const flexCardAssessmentInfo = await this.processFlexCard(flexCard, uniqueNames, dupFlexCardNames);
|
|
103
154
|
flexCardAssessmentInfos.push(flexCardAssessmentInfo);
|
|
104
155
|
}
|
|
105
156
|
catch (e) {
|
|
@@ -113,6 +164,7 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
113
164
|
dependenciesOS: [],
|
|
114
165
|
dependenciesLWC: [],
|
|
115
166
|
dependenciesApexRemoteAction: [],
|
|
167
|
+
dependenciesVlocityAction: [],
|
|
116
168
|
infos: [],
|
|
117
169
|
warnings: [],
|
|
118
170
|
errors: [this.messages.getMessage('unexpectedError')],
|
|
@@ -126,10 +178,10 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
126
178
|
progressBar.stop();
|
|
127
179
|
return flexCardAssessmentInfos;
|
|
128
180
|
}
|
|
129
|
-
async processFlexCard(flexCard, uniqueNames) {
|
|
181
|
+
async processFlexCard(flexCard, uniqueNames, dupFlexCardNames) {
|
|
130
182
|
const flexCardName = flexCard['Name'];
|
|
131
183
|
logger_1.Logger.info(this.messages.getMessage('processingFlexCard', [flexCardName]));
|
|
132
|
-
const version = flexCard[this.
|
|
184
|
+
const version = flexCard[this.getFieldKey(CardMigrationTool.VERSION_PROP)];
|
|
133
185
|
const flexCardAssessmentInfo = {
|
|
134
186
|
name: this.allVersions ? `${flexCardName}_${version}` : flexCardName,
|
|
135
187
|
oldName: this.allVersions ? `${flexCardName}_${version}` : flexCardName,
|
|
@@ -140,101 +192,196 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
140
192
|
dependenciesFC: [],
|
|
141
193
|
dependenciesLWC: [],
|
|
142
194
|
dependenciesApexRemoteAction: [],
|
|
195
|
+
dependenciesVlocityAction: [],
|
|
143
196
|
infos: [],
|
|
144
197
|
warnings: [],
|
|
145
198
|
errors: [],
|
|
146
|
-
migrationStatus: '',
|
|
199
|
+
migrationStatus: 'Ready for migration',
|
|
147
200
|
};
|
|
148
201
|
// Check for name changes due to API naming requirements
|
|
149
202
|
const originalName = flexCardName;
|
|
150
203
|
const cleanedName = this.cleanName(originalName);
|
|
151
|
-
let assessmentStatus = '
|
|
204
|
+
let assessmentStatus = 'Ready for migration';
|
|
152
205
|
flexCardAssessmentInfo.name = this.allVersions ? `${cleanedName}_${version}` : cleanedName;
|
|
153
206
|
if (cleanedName !== originalName) {
|
|
154
207
|
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('cardNameChangeMessage', [originalName, cleanedName]));
|
|
155
|
-
assessmentStatus = '
|
|
208
|
+
assessmentStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(assessmentStatus, 'Warnings');
|
|
209
|
+
}
|
|
210
|
+
// Check for duplicate names (include version when allVersions is true)
|
|
211
|
+
const uniqueCleanedName = this.allVersions ? `${cleanedName}_${version}` : cleanedName;
|
|
212
|
+
// Check for exact duplicate (same name + same version)
|
|
213
|
+
if (uniqueNames.has(uniqueCleanedName)) {
|
|
214
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('duplicateCardNameMessage', [uniqueCleanedName]));
|
|
215
|
+
assessmentStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(assessmentStatus, 'Needs manual intervention');
|
|
216
|
+
}
|
|
217
|
+
// Check for naming conflict: different original names cleaning to same name
|
|
218
|
+
else if (this.allVersions && dupFlexCardNames.has(cleanedName)) {
|
|
219
|
+
const existingOriginalName = dupFlexCardNames.get(cleanedName);
|
|
220
|
+
// Only flag if the original names are different (indicates a naming conflict)
|
|
221
|
+
if (existingOriginalName !== originalName) {
|
|
222
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('lowerVersionDuplicateCardNameMessage', [uniqueCleanedName]));
|
|
223
|
+
assessmentStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(assessmentStatus, 'Needs manual intervention');
|
|
224
|
+
}
|
|
156
225
|
}
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
226
|
+
// Add to tracking structures
|
|
227
|
+
uniqueNames.add(uniqueCleanedName);
|
|
228
|
+
if (this.allVersions && !dupFlexCardNames.has(cleanedName)) {
|
|
229
|
+
dupFlexCardNames.set(cleanedName, originalName);
|
|
161
230
|
}
|
|
162
|
-
uniqueNames.add(cleanedName);
|
|
163
|
-
this.addToAssessmentStorage(originalName, cleanedName);
|
|
164
231
|
// Check for author name changes
|
|
165
|
-
const originalAuthor = flexCard[this.
|
|
232
|
+
const originalAuthor = flexCard[this.getFieldKey('Author__c')];
|
|
166
233
|
if (originalAuthor) {
|
|
167
234
|
const cleanedAuthor = this.cleanName(originalAuthor);
|
|
168
235
|
if (cleanedAuthor !== originalAuthor) {
|
|
169
236
|
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('authordNameChangeMessage', [originalAuthor, cleanedAuthor]));
|
|
170
|
-
assessmentStatus = '
|
|
237
|
+
assessmentStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(assessmentStatus, 'Warnings');
|
|
171
238
|
}
|
|
172
239
|
}
|
|
240
|
+
flexCardAssessmentInfo.nameMapping = {
|
|
241
|
+
oldName: flexCardName,
|
|
242
|
+
newName: cleanedName,
|
|
243
|
+
};
|
|
173
244
|
flexCardAssessmentInfo.migrationStatus = assessmentStatus;
|
|
174
245
|
this.updateDependencies(flexCard, flexCardAssessmentInfo);
|
|
246
|
+
// Scan custom CSS (both StaticResource-backed and inline) for managed-package
|
|
247
|
+
// namespace references. The helper updates `migrationStatus` itself via
|
|
248
|
+
// `getUpdatedAssessmentStatus`, so it never downgrades a stricter status.
|
|
249
|
+
await this.collectStylesheetNamespaceDependencies(flexCard, flexCardAssessmentInfo);
|
|
250
|
+
if (flexCardAssessmentInfo.errors.length > 0) {
|
|
251
|
+
flexCardAssessmentInfo.migrationStatus = 'Needs manual intervention';
|
|
252
|
+
}
|
|
253
|
+
else if (flexCardAssessmentInfo.warnings.length > 0 &&
|
|
254
|
+
flexCardAssessmentInfo.migrationStatus === 'Ready for migration') {
|
|
255
|
+
flexCardAssessmentInfo.migrationStatus = 'Warnings';
|
|
256
|
+
}
|
|
257
|
+
// Deduplicate all dependency arrays to ensure no duplicates
|
|
258
|
+
flexCardAssessmentInfo.dependenciesIP = [...new Set(flexCardAssessmentInfo.dependenciesIP)];
|
|
259
|
+
flexCardAssessmentInfo.dependenciesDR = [...new Set(flexCardAssessmentInfo.dependenciesDR)];
|
|
260
|
+
flexCardAssessmentInfo.dependenciesFC = [...new Set(flexCardAssessmentInfo.dependenciesFC)];
|
|
261
|
+
flexCardAssessmentInfo.dependenciesOS = [...new Set(flexCardAssessmentInfo.dependenciesOS)];
|
|
262
|
+
flexCardAssessmentInfo.dependenciesLWC = [...new Set(flexCardAssessmentInfo.dependenciesLWC)];
|
|
263
|
+
flexCardAssessmentInfo.dependenciesApexRemoteAction = [
|
|
264
|
+
...new Set(flexCardAssessmentInfo.dependenciesApexRemoteAction),
|
|
265
|
+
];
|
|
266
|
+
flexCardAssessmentInfo.dependenciesVlocityAction = [...new Set(flexCardAssessmentInfo.dependenciesVlocityAction)];
|
|
175
267
|
return flexCardAssessmentInfo;
|
|
176
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Scan a FlexCard for two distinct kinds of namespace-bound custom CSS:
|
|
271
|
+
*
|
|
272
|
+
* 1. **StaticResource-backed stylesheet** — `Definition__c.customStyleSheet`
|
|
273
|
+
* stores the *Name* of a Static Resource. We look it up, fetch its body,
|
|
274
|
+
* and substring-check for the org's managed-package namespace. Same flow
|
|
275
|
+
* and same warning message as the OmniScript implementation; resource
|
|
276
|
+
* scans are cached by name in {@link CustomCssRegistry}, so a stylesheet
|
|
277
|
+
* shared between OmniScripts and FlexCards is only fetched once per run.
|
|
278
|
+
*
|
|
279
|
+
* 2. **Inline CSS** — `Styles__c.customStyles` stores raw CSS text. We
|
|
280
|
+
* substring-check the namespace directly against that string. No
|
|
281
|
+
* SOQL/REST traffic and no caching (the CSS is per-FlexCard and not
|
|
282
|
+
* shared across records).
|
|
283
|
+
*
|
|
284
|
+
* Both checks emit a warning into `flexCardAssessmentInfo.warnings` and bump
|
|
285
|
+
* `migrationStatus` to 'Needs manual intervention' (via
|
|
286
|
+
* `getUpdatedAssessmentStatus`, which never downgrades a stricter status).
|
|
287
|
+
*/
|
|
288
|
+
async collectStylesheetNamespaceDependencies(flexCard, flexCardAssessmentInfo) {
|
|
289
|
+
const registry = CustomCssRegistry_1.CustomCssRegistry.getInstance();
|
|
290
|
+
if (!registry.isEnabled()) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
// ---- 1. Definition__c.customStyleSheet (StaticResource name) ----
|
|
294
|
+
const definitionRaw = flexCard[this.getFieldKey('Definition__c')];
|
|
295
|
+
if (definitionRaw) {
|
|
296
|
+
let definition;
|
|
297
|
+
try {
|
|
298
|
+
definition = JSON.parse(definitionRaw);
|
|
299
|
+
}
|
|
300
|
+
catch (ex) {
|
|
301
|
+
logger_1.Logger.error(`Failed to parse Definition__c for stylesheet scan: ${flexCard['Name']}`);
|
|
302
|
+
definition = null;
|
|
303
|
+
}
|
|
304
|
+
const resourceName = ((definition === null || definition === void 0 ? void 0 : definition.customStyleSheet) || '').toString().trim();
|
|
305
|
+
if (resourceName) {
|
|
306
|
+
const verdict = await registry.scanResource(resourceName);
|
|
307
|
+
if (verdict === 'namespaceFound') {
|
|
308
|
+
const message = registry.buildFlexCardNamespaceWarning(resourceName);
|
|
309
|
+
if (message) {
|
|
310
|
+
flexCardAssessmentInfo.warnings.push(message);
|
|
311
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Needs manual intervention');
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// ---- 2. Styles__c.customStyles (raw inline CSS) ----
|
|
317
|
+
const stylesRaw = flexCard[this.getFieldKey('Styles__c')];
|
|
318
|
+
if (stylesRaw) {
|
|
319
|
+
let styles;
|
|
320
|
+
try {
|
|
321
|
+
styles = JSON.parse(stylesRaw);
|
|
322
|
+
}
|
|
323
|
+
catch (ex) {
|
|
324
|
+
logger_1.Logger.error(`Failed to parse Styles__c for stylesheet scan: ${flexCard['Name']}`);
|
|
325
|
+
styles = null;
|
|
326
|
+
}
|
|
327
|
+
const inlineCss = styles === null || styles === void 0 ? void 0 : styles.customStyles;
|
|
328
|
+
if (registry.containsNamespaceInText(inlineCss)) {
|
|
329
|
+
const message = registry.buildInlineCssNamespaceWarning();
|
|
330
|
+
if (message) {
|
|
331
|
+
flexCardAssessmentInfo.warnings.push(message);
|
|
332
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Needs manual intervention');
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
177
337
|
updateDependencies(flexCard, flexCardAssessmentInfo) {
|
|
178
338
|
var _a, _b, _c, _d;
|
|
179
|
-
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const originalBundle = (_a = dataSource.value) === null || _a === void 0 ? void 0 : _a.bundle;
|
|
190
|
-
if (originalBundle) {
|
|
191
|
-
const cleanedBundle = this.cleanName(originalBundle);
|
|
192
|
-
flexCardAssessmentInfo.dependenciesDR.push(cleanedBundle);
|
|
193
|
-
// Add warning if DataRaptor name will change
|
|
194
|
-
if (originalBundle !== cleanedBundle) {
|
|
195
|
-
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('dataRaptorNameChangeMessage', [originalBundle, cleanedBundle]));
|
|
196
|
-
flexCardAssessmentInfo.migrationStatus = 'Has Warnings';
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
else if (dataSource.type === stringContants_1.Constants.IntegrationProcedurePluralName) {
|
|
201
|
-
const originalIpMethod = (_b = dataSource.value) === null || _b === void 0 ? void 0 : _b.ipMethod;
|
|
202
|
-
if (originalIpMethod) {
|
|
203
|
-
const parts = originalIpMethod.split('_');
|
|
204
|
-
const cleanedParts = parts.map((p) => this.cleanName(p, true));
|
|
205
|
-
const cleanedIpMethod = cleanedParts.join('_');
|
|
206
|
-
flexCardAssessmentInfo.dependenciesIP.push(cleanedIpMethod);
|
|
207
|
-
// Add warning if IP name will change
|
|
208
|
-
if (originalIpMethod !== cleanedIpMethod) {
|
|
209
|
-
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('integrationProcedureNameChangeMessage', [originalIpMethod, cleanedIpMethod]));
|
|
210
|
-
flexCardAssessmentInfo.migrationStatus = 'Has Warnings';
|
|
211
|
-
}
|
|
212
|
-
// Add warning for IP references with more than 2 parts (which potentially need manual updates)
|
|
213
|
-
if (parts.length > 2) {
|
|
214
|
-
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('integrationProcedureManualUpdateMessage', [originalIpMethod]));
|
|
215
|
-
flexCardAssessmentInfo.migrationStatus = 'Need Manual Intervention';
|
|
339
|
+
const dataSourceConfig = JSON.parse(flexCard[this.getFieldKey('Datasource__c')] || '{}');
|
|
340
|
+
// Collect all data sources - any nested object with a 'type' property is a data source
|
|
341
|
+
// This handles: dataSource, datasource, event-0_0, event-1_0, etc.
|
|
342
|
+
const dataSources = Object.values(dataSourceConfig).filter((value) => value && typeof value === 'object' && value.type);
|
|
343
|
+
for (const ds of dataSources) {
|
|
344
|
+
// Check if it's a DataRaptor source
|
|
345
|
+
if (ds.type === stringContants_1.Constants.DataRaptorComponentName) {
|
|
346
|
+
const originalBundle = (_a = ds.value) === null || _a === void 0 ? void 0 : _a.bundle;
|
|
347
|
+
if (originalBundle) {
|
|
348
|
+
this.addDataRaptorDependency(originalBundle, flexCardAssessmentInfo);
|
|
216
349
|
}
|
|
217
350
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if (
|
|
225
|
-
|
|
351
|
+
else if (ds.type === stringContants_1.Constants.IntegrationProcedurePluralName) {
|
|
352
|
+
const originalIpMethod = (_b = ds.value) === null || _b === void 0 ? void 0 : _b.ipMethod;
|
|
353
|
+
if (originalIpMethod) {
|
|
354
|
+
this.addIntegrationProcedureDependency(originalIpMethod, flexCardAssessmentInfo);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else if (ds.type === stringContants_1.Constants.ApexRemoteComponentName) {
|
|
358
|
+
const remoteClass = (_c = ds.value) === null || _c === void 0 ? void 0 : _c.remoteClass;
|
|
359
|
+
const remoteMethod = (_d = ds.value) === null || _d === void 0 ? void 0 : _d.remoteMethod;
|
|
360
|
+
if (remoteClass && remoteMethod) {
|
|
361
|
+
const status = this.apexNamespaceRegistry.resolveStatus(remoteClass);
|
|
362
|
+
const qualifiedClass = this.apexNamespaceRegistry.getQualifiedClassName(remoteClass);
|
|
363
|
+
const qualifiedEntry = `${qualifiedClass}.${remoteMethod}`;
|
|
364
|
+
if (!flexCardAssessmentInfo.dependenciesApexRemoteAction.includes(qualifiedEntry)) {
|
|
365
|
+
flexCardAssessmentInfo.dependenciesApexRemoteAction.push(qualifiedEntry);
|
|
366
|
+
}
|
|
367
|
+
if (status === ApexNamespaceRegistry_1.ApexResolveStatus.NAMESPACED) {
|
|
368
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('apexRemoteDatasourceNamespaceWarning', [remoteClass, qualifiedClass]));
|
|
369
|
+
}
|
|
370
|
+
else if (status === ApexNamespaceRegistry_1.ApexResolveStatus.NOT_FOUND) {
|
|
371
|
+
flexCardAssessmentInfo.errors.push(this.messages.getMessage('apexClassNotFound', [remoteClass, flexCardAssessmentInfo.name]));
|
|
372
|
+
}
|
|
373
|
+
}
|
|
226
374
|
}
|
|
227
375
|
}
|
|
228
|
-
// Check for
|
|
376
|
+
// Check for Omniscript dependencies in the card's definition
|
|
229
377
|
try {
|
|
230
|
-
const definition = JSON.parse(flexCard[this.
|
|
378
|
+
const definition = JSON.parse(flexCard[this.getFieldKey('Definition__c')] || '{}');
|
|
231
379
|
if (definition && definition.states) {
|
|
232
380
|
for (const state of definition.states) {
|
|
233
381
|
if (state.omniscripts && Array.isArray(state.omniscripts)) {
|
|
234
382
|
for (const os of state.omniscripts) {
|
|
235
383
|
if (os.type && os.subtype) {
|
|
236
|
-
|
|
237
|
-
flexCardAssessmentInfo.dependenciesOS.push(osRef);
|
|
384
|
+
this.addOmniScriptDependencyFromParts(os.type, os.subtype, os.language, flexCardAssessmentInfo);
|
|
238
385
|
}
|
|
239
386
|
}
|
|
240
387
|
}
|
|
@@ -250,16 +397,281 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
250
397
|
}
|
|
251
398
|
}
|
|
252
399
|
let childCards = this.readChildCardsFromDefinition(flexCard);
|
|
253
|
-
|
|
400
|
+
// Add warnings for child card name changes
|
|
401
|
+
for (const childCardName of childCards) {
|
|
402
|
+
this.addFlexCardDependency(childCardName, flexCardAssessmentInfo);
|
|
403
|
+
}
|
|
404
|
+
// Check for dependencies in events[] array
|
|
405
|
+
if (definition.events && Array.isArray(definition.events)) {
|
|
406
|
+
this.checkEventsForDependencies(definition.events, flexCardAssessmentInfo);
|
|
407
|
+
}
|
|
254
408
|
}
|
|
255
409
|
catch (err) {
|
|
256
410
|
// Log the error but continue processing
|
|
257
411
|
logger_1.Logger.error(`Error parsing definition for card ${flexCard.Name}: ${err.message}`);
|
|
258
412
|
}
|
|
259
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Check events array for dependencies (Assessment)
|
|
416
|
+
* Handles: events[].actionList[].stateAction references
|
|
417
|
+
*/
|
|
418
|
+
checkEventsForDependencies(events, flexCardAssessmentInfo) {
|
|
419
|
+
for (const event of events) {
|
|
420
|
+
if (!event.actionList || !Array.isArray(event.actionList)) {
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
for (const action of event.actionList) {
|
|
424
|
+
if (!action.stateAction) {
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
const stateAction = action.stateAction;
|
|
428
|
+
// Detect Vlocity Action (not supported in standard runtime FlexCards)
|
|
429
|
+
if (stateAction.type === stringContants_1.Constants.VlocityAction) {
|
|
430
|
+
this.addVlocityActionDependency(stateAction, flexCardAssessmentInfo);
|
|
431
|
+
}
|
|
432
|
+
// 1-2. Handle message.value.bundle (DataRaptor) and message.value.ipMethod (Integration Procedure)
|
|
433
|
+
this.processStateActionMessageForDependencies(stateAction, flexCardAssessmentInfo);
|
|
434
|
+
// 3. Handle cardName (FlexCard - Flyout childCard)
|
|
435
|
+
if (stateAction.cardName) {
|
|
436
|
+
this.addFlexCardDependency(stateAction.cardName, flexCardAssessmentInfo);
|
|
437
|
+
}
|
|
438
|
+
// 4. Handle flyoutLwc - FlexCard child cards
|
|
439
|
+
if (this.hasFlexCardFlyoutDependency(stateAction)) {
|
|
440
|
+
this.addFlexCardDependency(stateAction.flyoutLwc, flexCardAssessmentInfo);
|
|
441
|
+
}
|
|
442
|
+
// Handle flyoutLwc - CustomLwc with potential "cf" prefix for FlexCard reference
|
|
443
|
+
else if (this.hasCustomLwcFlyoutDependency(stateAction)) {
|
|
444
|
+
this.addCfPrefixedFlexCardDependency(stateAction.flyoutLwc, flexCardAssessmentInfo);
|
|
445
|
+
}
|
|
446
|
+
// 5. Handle osName
|
|
447
|
+
else if (this.hasOmniscriptFlyoutDependency(stateAction)) {
|
|
448
|
+
this.addOmniScriptDependency(stateAction.osName, flexCardAssessmentInfo);
|
|
449
|
+
}
|
|
450
|
+
// 6. Handle omniType.Name (OmniScript)
|
|
451
|
+
if (stateAction.omniType && stateAction.omniType.Name) {
|
|
452
|
+
this.addOmniScriptDependency(stateAction.omniType.Name, flexCardAssessmentInfo);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Shared helper to check if a "cf" prefixed LWC name references a FlexCard and add dependency (assessment phase)
|
|
459
|
+
* @param cfPrefixedLwcName LWC name with "cf" prefix (e.g., "cfMyFlexCard")
|
|
460
|
+
* @param flexCardAssessmentInfo Assessment info to add dependencies and warnings
|
|
461
|
+
*/
|
|
462
|
+
addCfPrefixedFlexCardDependency(cfPrefixedLwcName, flexCardAssessmentInfo) {
|
|
463
|
+
if (cfPrefixedLwcName.startsWith('cf')) {
|
|
464
|
+
// Remove "cf" prefix to get the original FlexCard name
|
|
465
|
+
const originalFlexCardName = cfPrefixedLwcName.substring(2);
|
|
466
|
+
// Check if the FlexCard name will change and add warning
|
|
467
|
+
const cleanedFlexCardName = this.cleanName(originalFlexCardName);
|
|
468
|
+
this.addFlexCardDependency(originalFlexCardName, flexCardAssessmentInfo);
|
|
469
|
+
if (originalFlexCardName !== cleanedFlexCardName) {
|
|
470
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('cardLWCNameChangeMessage', [originalFlexCardName, cleanedFlexCardName]));
|
|
471
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Warnings');
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Shared helper to update a "cf" prefixed LWC name with registry (migration phase)
|
|
477
|
+
* @param cfPrefixedLwcName LWC name with "cf" prefix (e.g., "cfMyFlexCard")
|
|
478
|
+
* @returns Updated LWC name with "cf" prefix
|
|
479
|
+
*/
|
|
480
|
+
updateCfPrefixedFlexCardName(cfPrefixedLwcName) {
|
|
481
|
+
if (cfPrefixedLwcName.startsWith('cf')) {
|
|
482
|
+
// Remove "cf" prefix to get the original FlexCard name
|
|
483
|
+
const originalFlexCardName = cfPrefixedLwcName.substring(2);
|
|
484
|
+
// Look up the cleaned name from registry
|
|
485
|
+
let cleanedFlexCardName;
|
|
486
|
+
if (this.nameRegistry.hasFlexCardMapping(originalFlexCardName)) {
|
|
487
|
+
cleanedFlexCardName = this.nameRegistry.getFlexCardCleanedName(originalFlexCardName);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['Flexcard', originalFlexCardName])}`);
|
|
491
|
+
cleanedFlexCardName = this.cleanName(originalFlexCardName);
|
|
492
|
+
}
|
|
493
|
+
return `cf${cleanedFlexCardName}`;
|
|
494
|
+
}
|
|
495
|
+
return cfPrefixedLwcName;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Shared helper to check Custom LWC component for FlexCard dependencies (assessment phase)
|
|
499
|
+
* Handles customlwcname with "cf" prefix indicating FlexCard reference
|
|
500
|
+
*/
|
|
501
|
+
checkCustomLwcForDependencies(component, flexCardAssessmentInfo) {
|
|
502
|
+
if (component.element === stringContants_1.Constants.CustomLwc && component.property) {
|
|
503
|
+
if (component.property.customlwcname) {
|
|
504
|
+
const customLwcName = component.property.customlwcname;
|
|
505
|
+
logger_1.Logger.info(`Custom LWC name: ${customLwcName}`);
|
|
506
|
+
// Check if this is a FlexCard reference (starts with "cf" prefix)
|
|
507
|
+
this.addCfPrefixedFlexCardDependency(customLwcName, flexCardAssessmentInfo);
|
|
508
|
+
// Add to LWC dependencies for tracking (avoid duplicates)
|
|
509
|
+
if (!flexCardAssessmentInfo.dependenciesLWC.includes(customLwcName)) {
|
|
510
|
+
flexCardAssessmentInfo.dependenciesLWC.push(customLwcName);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
// "action" is a reserved keyword in the core runtime; flag any Custom LWC
|
|
514
|
+
// that defines it as a property so the user removes/renames it pre-migration.
|
|
515
|
+
if (Object.prototype.hasOwnProperty.call(component.property, 'action')) {
|
|
516
|
+
const lwcLabel = component.property.customlwcname || component.elementLabel || stringContants_1.Constants.CustomLwc;
|
|
517
|
+
const reservedActionMessage = this.messages.getMessage('customLwcReservedActionKey', [lwcLabel]);
|
|
518
|
+
flexCardAssessmentInfo.errors.push(reservedActionMessage);
|
|
519
|
+
flexCardAssessmentInfo.warnings.push(reservedActionMessage);
|
|
520
|
+
flexCardAssessmentInfo.migrationStatus = 'Needs manual intervention';
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Shared helper to update Custom LWC component with registry (migration phase)
|
|
526
|
+
* Handles customlwcname with "cf" prefix indicating FlexCard reference
|
|
527
|
+
*/
|
|
528
|
+
updateCustomLwcWithRegistry(component) {
|
|
529
|
+
if (component.element === stringContants_1.Constants.CustomLwc && component.property) {
|
|
530
|
+
if (component.property.customlwcname) {
|
|
531
|
+
const customLwcName = component.property.customlwcname;
|
|
532
|
+
// Check if this is a FlexCard reference (starts with "cf" prefix) and update it
|
|
533
|
+
if (customLwcName === null || customLwcName === void 0 ? void 0 : customLwcName.startsWith('cf')) {
|
|
534
|
+
const updatedLwcName = this.updateCfPrefixedFlexCardName(customLwcName);
|
|
535
|
+
component.property.customlwcname = updatedLwcName;
|
|
536
|
+
if (customLwcName !== updatedLwcName) {
|
|
537
|
+
const cleanedFlexCardName = updatedLwcName.substring(2);
|
|
538
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('customLWCFlexCardReferenceUpdated', [customLwcName, cleanedFlexCardName]));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
// Note: Other custom LWC names (not starting with "cf") typically don't need cleaning
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Shared helper to update flyoutLwc value with registry (migration phase)
|
|
547
|
+
* Handles FlexCard child cards references
|
|
548
|
+
*/
|
|
549
|
+
updateFlyoutLwcValue(stateAction) {
|
|
550
|
+
if (stateAction.flyoutLwc) {
|
|
551
|
+
if (stateAction.flyoutType === stringContants_1.Constants.ChildCard) {
|
|
552
|
+
// flyoutLwc is a direct FlexCard name reference
|
|
553
|
+
const lwcName = stateAction.flyoutLwc;
|
|
554
|
+
if (this.nameRegistry.hasFlexCardMapping(lwcName)) {
|
|
555
|
+
stateAction.flyoutLwc = this.nameRegistry.getFlexCardCleanedName(lwcName);
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['Flexcard', lwcName])}`);
|
|
559
|
+
stateAction.flyoutLwc = this.cleanName(lwcName);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
else if (stateAction.flyoutType === stringContants_1.Constants.CustomLwc) {
|
|
563
|
+
// flyoutType is customLwc - update if it's a FlexCard reference with "cf" prefix
|
|
564
|
+
stateAction.flyoutLwc = this.updateCfPrefixedFlexCardName(stateAction.flyoutLwc);
|
|
565
|
+
// Note: Non-"cf" prefixed names are returned unchanged by the helper
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Shared helper to process stateAction.message JSON for dependencies
|
|
571
|
+
* Handles DataRaptor bundle and Integration Procedure ipMethod references
|
|
572
|
+
*/
|
|
573
|
+
processStateActionMessageForDependencies(stateAction, flexCardAssessmentInfo) {
|
|
574
|
+
// Only parse message for DataAction or cardAction types
|
|
575
|
+
if (stateAction.message &&
|
|
576
|
+
typeof stateAction.message === 'string' &&
|
|
577
|
+
stateAction.message.trim().length > 0 &&
|
|
578
|
+
(stateAction.type === stringContants_1.Constants.DataAction || stateAction.type === stringContants_1.Constants.CardAction)) {
|
|
579
|
+
try {
|
|
580
|
+
const messageObj = JSON.parse(stateAction.message);
|
|
581
|
+
if (messageObj.value) {
|
|
582
|
+
// DataRaptor bundle
|
|
583
|
+
if (messageObj.value.bundle) {
|
|
584
|
+
this.addDataRaptorDependency(messageObj.value.bundle, flexCardAssessmentInfo);
|
|
585
|
+
}
|
|
586
|
+
// Integration Procedure ipMethod
|
|
587
|
+
if (messageObj.value.ipMethod) {
|
|
588
|
+
this.addIntegrationProcedureDependency(messageObj.value.ipMethod, flexCardAssessmentInfo);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
catch (e) {
|
|
593
|
+
// message is not valid JSON, skip
|
|
594
|
+
logger_1.Logger.error(`Failed to parse stateAction.message as JSON: ${e.message}`);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Shared helper to process stateAction.message JSON with registry updates
|
|
600
|
+
* Handles DataRaptor bundle and Integration Procedure ipMethod references
|
|
601
|
+
*/
|
|
602
|
+
processStateActionMessageWithRegistry(stateAction, invalidIpNames) {
|
|
603
|
+
// Only parse message for DataAction or cardAction types
|
|
604
|
+
if (stateAction.message &&
|
|
605
|
+
typeof stateAction.message === 'string' &&
|
|
606
|
+
stateAction.message.trim().length > 0 &&
|
|
607
|
+
(stateAction.type === stringContants_1.Constants.DataAction || stateAction.type === stringContants_1.Constants.CardAction)) {
|
|
608
|
+
try {
|
|
609
|
+
const messageObj = JSON.parse(stateAction.message);
|
|
610
|
+
let messageUpdated = false;
|
|
611
|
+
if (messageObj.value) {
|
|
612
|
+
// DataRaptor bundle
|
|
613
|
+
if (messageObj.value.bundle) {
|
|
614
|
+
const originalBundle = messageObj.value.bundle;
|
|
615
|
+
if (this.nameRegistry.hasDataMapperMapping(originalBundle)) {
|
|
616
|
+
messageObj.value.bundle = this.nameRegistry.getDataMapperCleanedName(originalBundle);
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['DataMapper', originalBundle])}`);
|
|
620
|
+
messageObj.value.bundle = this.cleanName(originalBundle);
|
|
621
|
+
}
|
|
622
|
+
messageUpdated = true;
|
|
623
|
+
}
|
|
624
|
+
// Integration Procedure ipMethod
|
|
625
|
+
if (messageObj.value.ipMethod) {
|
|
626
|
+
const ipMethod = messageObj.value.ipMethod;
|
|
627
|
+
if (this.nameRegistry.hasIntegrationProcedureMapping(ipMethod)) {
|
|
628
|
+
messageObj.value.ipMethod = this.nameRegistry.getIntegrationProcedureCleanedName(ipMethod);
|
|
629
|
+
}
|
|
630
|
+
else {
|
|
631
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['IntegrationProcedure', ipMethod])}`);
|
|
632
|
+
const parts = ipMethod.split('_');
|
|
633
|
+
messageObj.value.ipMethod = parts.map((p) => this.cleanName(p, true)).join('_');
|
|
634
|
+
if (parts.length > 2 && invalidIpNames) {
|
|
635
|
+
invalidIpNames.set(`event.actionList.stateAction.message`, ipMethod);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
messageUpdated = true;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
if (messageUpdated) {
|
|
642
|
+
stateAction.message = JSON.stringify(messageObj);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
catch (e) {
|
|
646
|
+
// message is not valid JSON, skip
|
|
647
|
+
logger_1.Logger.error(`Failed to parse stateAction.message as JSON: ${e.message}`);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
handleAssessmentForStdDataModelOrgsWithMetadataAPIEnabled(flexCards) {
|
|
652
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('preparingStorageForMetadataEnabledOrg', [stringContants_1.Constants.Flexcard]));
|
|
653
|
+
let storage = storageUtil_1.StorageUtil.getOmnistudioAssessmentStorage();
|
|
654
|
+
this.prepareStorageForRelatedObjectsWhenMetadataAPIEnabled(storage, flexCards);
|
|
655
|
+
storageUtil_1.StorageUtil.printAssessmentStorage();
|
|
656
|
+
return [];
|
|
657
|
+
}
|
|
658
|
+
handleMigrationForStdDataModelOrgsWithMetadataAPIEnabled(flexcards) {
|
|
659
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('preparingStorageForMetadataEnabledOrg', [stringContants_1.Constants.Flexcard]));
|
|
660
|
+
let storage = storageUtil_1.StorageUtil.getOmnistudioMigrationStorage();
|
|
661
|
+
this.prepareStorageForRelatedObjectsWhenMetadataAPIEnabled(storage, flexcards);
|
|
662
|
+
storageUtil_1.StorageUtil.printAssessmentStorage();
|
|
663
|
+
// Return empty result structure for report generation
|
|
664
|
+
return [
|
|
665
|
+
{
|
|
666
|
+
name: this.getName(),
|
|
667
|
+
results: new Map(),
|
|
668
|
+
records: new Map(),
|
|
669
|
+
},
|
|
670
|
+
];
|
|
671
|
+
}
|
|
260
672
|
readChildCardsFromDefinition(card) {
|
|
261
673
|
let childs = [];
|
|
262
|
-
const definition = JSON.parse(card[this.
|
|
674
|
+
const definition = JSON.parse(card[this.getFieldKey('Definition__c')]);
|
|
263
675
|
if (!definition)
|
|
264
676
|
return childs;
|
|
265
677
|
for (let state of definition.states || []) {
|
|
@@ -269,105 +681,205 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
269
681
|
}
|
|
270
682
|
return childs;
|
|
271
683
|
}
|
|
272
|
-
checkComponentForDependencies(component, flexCardAssessmentInfo) {
|
|
684
|
+
checkComponentForDependencies(component, flexCardAssessmentInfo, omniScriptNavigateURLWarningKeys = new Set()) {
|
|
273
685
|
// Check if this component is an action element
|
|
274
686
|
if (component.element === 'action' && component.property && component.property.actionList) {
|
|
275
687
|
// Process each action in the actionList
|
|
276
688
|
for (const action of component.property.actionList) {
|
|
277
689
|
if (action.stateAction) {
|
|
690
|
+
// Detect Vlocity Action (not supported in standard runtime FlexCards)
|
|
691
|
+
if (action.stateAction.type === stringContants_1.Constants.VlocityAction) {
|
|
692
|
+
this.addVlocityActionDependency(action.stateAction, flexCardAssessmentInfo);
|
|
693
|
+
}
|
|
694
|
+
// Handle message field (contains DataRaptor/IP references as JSON string)
|
|
695
|
+
this.processStateActionMessageForDependencies(action.stateAction, flexCardAssessmentInfo);
|
|
278
696
|
// Case 1: Direct OmniScript reference
|
|
279
697
|
if (action.stateAction.type === stringContants_1.Constants.OmniScriptComponentName && action.stateAction.omniType) {
|
|
280
698
|
const omniType = action.stateAction.omniType;
|
|
281
699
|
if (omniType.Name && typeof omniType.Name === 'string') {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('omniScriptNameChangeMessage', [parts[i], cleanedParts[i]]));
|
|
293
|
-
flexCardAssessmentInfo.migrationStatus = 'Has Warnings';
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
700
|
+
this.addOmniScriptDependency(omniType.Name, flexCardAssessmentInfo);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
// MISSING PATTERN FIXED: Case 1b: Direct OmniScript reference without type check (for test compatibility)
|
|
704
|
+
else if (action.stateAction.omniType && !action.stateAction.type) {
|
|
705
|
+
const omniType = action.stateAction.omniType;
|
|
706
|
+
// Handle both string omniType and object with Name property
|
|
707
|
+
let omniTypeName;
|
|
708
|
+
if (typeof omniType === 'string') {
|
|
709
|
+
omniTypeName = omniType;
|
|
297
710
|
}
|
|
711
|
+
else if (omniType.Name && typeof omniType.Name === 'string') {
|
|
712
|
+
omniTypeName = omniType.Name;
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
continue; // Skip if we can't extract the name
|
|
716
|
+
}
|
|
717
|
+
this.addOmniScriptDependency(omniTypeName, flexCardAssessmentInfo);
|
|
298
718
|
}
|
|
299
719
|
// Case 2: Flyout OmniScript reference
|
|
300
|
-
else if (action.stateAction
|
|
301
|
-
action.stateAction.flyoutType === stringContants_1.Constants.OmniScriptPluralName &&
|
|
302
|
-
action.stateAction.osName) {
|
|
720
|
+
else if (this.hasOmniscriptFlyoutDependency(action.stateAction)) {
|
|
303
721
|
const osName = action.stateAction.osName;
|
|
304
722
|
if (typeof osName === 'string') {
|
|
305
|
-
|
|
306
|
-
const originalName = osName;
|
|
307
|
-
const parts = originalName.split('/');
|
|
308
|
-
if (parts.length >= 2) {
|
|
309
|
-
// Check for name changes in each part
|
|
310
|
-
const cleanedParts = parts.map((p) => this.cleanName(p));
|
|
311
|
-
const cleanedName = cleanedParts.join('_');
|
|
312
|
-
flexCardAssessmentInfo.dependenciesOS.push(cleanedName);
|
|
313
|
-
// Add warning if any part of the name will change
|
|
314
|
-
for (let i = 0; i < parts.length; i++) {
|
|
315
|
-
if (parts[i] !== cleanedParts[i]) {
|
|
316
|
-
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('omniScriptNameChangeMessage', [parts[i], cleanedParts[i]]));
|
|
317
|
-
flexCardAssessmentInfo.migrationStatus = 'Has Warnings';
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
723
|
+
this.addOmniScriptDependency(osName, flexCardAssessmentInfo);
|
|
321
724
|
}
|
|
322
725
|
}
|
|
726
|
+
// Case 3: Flyout childCard reference - flyoutLwc is a direct FlexCard name
|
|
727
|
+
else if (this.hasFlexCardFlyoutDependency(action.stateAction)) {
|
|
728
|
+
this.addFlexCardDependency(action.stateAction.flyoutLwc, flexCardAssessmentInfo);
|
|
729
|
+
}
|
|
730
|
+
// Case 4: Flyout CustomLwc reference - check for FlexCard reference with "cf" prefix
|
|
731
|
+
else if (this.hasCustomLwcFlyoutDependency(action.stateAction)) {
|
|
732
|
+
this.addCfPrefixedFlexCardDependency(action.stateAction.flyoutLwc, flexCardAssessmentInfo);
|
|
733
|
+
}
|
|
734
|
+
else if (this.isCustomWebPageAction(action.stateAction)) {
|
|
735
|
+
this.addOmniScriptNavigateURLAssessmentWarning(action.stateAction, flexCardAssessmentInfo, omniScriptNavigateURLWarningKeys);
|
|
736
|
+
}
|
|
323
737
|
}
|
|
324
738
|
}
|
|
325
739
|
}
|
|
326
740
|
// Check for Custom LWC component
|
|
327
|
-
|
|
328
|
-
// Check customlwcname property first
|
|
329
|
-
if (component.property.customlwcname) {
|
|
330
|
-
const customLwcName = component.property.customlwcname;
|
|
331
|
-
logger_1.Logger.info(`Custom LWC name: ${customLwcName}`);
|
|
332
|
-
// Avoid duplicates
|
|
333
|
-
if (!flexCardAssessmentInfo.dependenciesLWC.includes(customLwcName)) {
|
|
334
|
-
flexCardAssessmentInfo.dependenciesLWC.push(customLwcName);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
741
|
+
this.checkCustomLwcForDependencies(component, flexCardAssessmentInfo);
|
|
338
742
|
// Check standard component actions if they exist
|
|
339
743
|
if (component.actions && Array.isArray(component.actions)) {
|
|
340
744
|
for (const action of component.actions) {
|
|
341
745
|
if (action.stateAction && action.stateAction.omniType) {
|
|
342
746
|
const omniType = action.stateAction.omniType;
|
|
343
747
|
if (omniType.Name && typeof omniType.Name === 'string') {
|
|
344
|
-
|
|
345
|
-
if (parts.length >= 2) {
|
|
346
|
-
const osRef = parts.join('_');
|
|
347
|
-
flexCardAssessmentInfo.dependenciesOS.push(osRef);
|
|
348
|
-
}
|
|
748
|
+
this.addOmniScriptDependency(omniType.Name, flexCardAssessmentInfo);
|
|
349
749
|
}
|
|
350
750
|
}
|
|
351
751
|
}
|
|
352
752
|
}
|
|
753
|
+
// MISSING PATTERN FIXED: Handle direct stateAction on component property
|
|
754
|
+
if (component.property && component.property.stateAction) {
|
|
755
|
+
// Case 1: Direct OmniScript reference on component property
|
|
756
|
+
if (component.property.stateAction.omniType) {
|
|
757
|
+
const omniType = component.property.stateAction.omniType;
|
|
758
|
+
if (omniType.Name && typeof omniType.Name === 'string') {
|
|
759
|
+
this.addOmniScriptDependency(omniType.Name, flexCardAssessmentInfo);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
// Case 2: Flyout OmniScript reference on component property
|
|
763
|
+
if (this.hasOmniscriptFlyoutDependency(component.property.stateAction)) {
|
|
764
|
+
const osName = component.property.stateAction.osName;
|
|
765
|
+
if (typeof osName === 'string') {
|
|
766
|
+
this.addOmniScriptDependency(osName, flexCardAssessmentInfo);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
// Case 3: Flyout childCard reference on component property - flyoutLwc is a direct FlexCard name
|
|
770
|
+
if (this.hasFlexCardFlyoutDependency(component.property.stateAction)) {
|
|
771
|
+
this.addFlexCardDependency(component.property.stateAction.flyoutLwc, flexCardAssessmentInfo);
|
|
772
|
+
}
|
|
773
|
+
// Case 4: Flyout CustomLwc reference on component property - check for FlexCard reference with "cf" prefix
|
|
774
|
+
if (this.hasCustomLwcFlyoutDependency(component.property.stateAction)) {
|
|
775
|
+
this.addCfPrefixedFlexCardDependency(component.property.stateAction.flyoutLwc, flexCardAssessmentInfo);
|
|
776
|
+
}
|
|
777
|
+
else if (this.isCustomWebPageAction(component.property.stateAction)) {
|
|
778
|
+
this.addOmniScriptNavigateURLAssessmentWarning(component.property.stateAction, flexCardAssessmentInfo, omniScriptNavigateURLWarningKeys);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
// MISSING PATTERN FIXED: Handle omni-flyout elements (from tests)
|
|
782
|
+
if (component.element === stringContants_1.Constants.OmniFlyout && component.property && component.property.flyoutOmniScript) {
|
|
783
|
+
if (component.property.flyoutOmniScript.osName) {
|
|
784
|
+
const osName = component.property.flyoutOmniScript.osName;
|
|
785
|
+
if (typeof osName === 'string') {
|
|
786
|
+
this.addOmniScriptDependency(osName, flexCardAssessmentInfo);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
// MISSING PATTERN FIXED: Handle childCardPreview elements with cardName property
|
|
791
|
+
if (component.element === stringContants_1.Constants.ChildCardPreview && component.property && component.property.cardName) {
|
|
792
|
+
this.addFlexCardDependency(component.property.cardName, flexCardAssessmentInfo);
|
|
793
|
+
}
|
|
353
794
|
// Check child components recursively
|
|
354
795
|
if (component.children && Array.isArray(component.children)) {
|
|
355
|
-
for (
|
|
356
|
-
|
|
796
|
+
for (let childIndex = 0; childIndex < component.children.length; childIndex++) {
|
|
797
|
+
const child = component.children[childIndex];
|
|
798
|
+
this.checkComponentForDependencies(child, flexCardAssessmentInfo, omniScriptNavigateURLWarningKeys);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
addOmniScriptNavigateURLAssessmentWarning(stateAction, flexCardAssessmentInfo, warningKeys) {
|
|
803
|
+
if (this.IS_STANDARD_DATA_MODEL) {
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
const rewrite = this.getOmniScriptURLRewrite(stateAction);
|
|
807
|
+
if (!rewrite) {
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
const { targetName, updatedURL, malformedTokens } = rewrite;
|
|
811
|
+
const summary = this.formatURLRewriteSummary(targetName, updatedURL);
|
|
812
|
+
if (warningKeys.has(summary)) {
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
warningKeys.add(summary);
|
|
816
|
+
// Emit a single warning per URL: when fragment tokens are malformed, the
|
|
817
|
+
// dedicated malformed-token warning is the authoritative one (it already
|
|
818
|
+
// contains both the original URL and the "will get replaced with" line,
|
|
819
|
+
// PLUS the malformed-token list and the verify instruction). For clean
|
|
820
|
+
// URLs we fall back to the plain rewrite warning. Defense-in-depth: if
|
|
821
|
+
// the malformed formatter unexpectedly returns empty, fall back to the
|
|
822
|
+
// plain rewrite warning so the customer still sees something.
|
|
823
|
+
const hasMalformedTokens = Array.isArray(malformedTokens) && malformedTokens.length > 0;
|
|
824
|
+
let warningText = '';
|
|
825
|
+
if (hasMalformedTokens) {
|
|
826
|
+
warningText = this.formatMalformedFragmentTokenWarning(targetName, updatedURL, malformedTokens);
|
|
827
|
+
}
|
|
828
|
+
if (!warningText) {
|
|
829
|
+
warningText = this.messages.getMessage('webPageOmniScriptNavigationDetected', [
|
|
830
|
+
this.toReadableURL(targetName),
|
|
831
|
+
this.toReadableURL(updatedURL),
|
|
832
|
+
]);
|
|
833
|
+
}
|
|
834
|
+
flexCardAssessmentInfo.warnings.push(warningText);
|
|
835
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Warnings');
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Build the customer-facing warning shown when a Web Page action URL contains
|
|
839
|
+
* fragment tokens that decodeURIComponent couldn't parse. Centralised here so
|
|
840
|
+
* the assessment and migration paths emit byte-identical text.
|
|
841
|
+
*
|
|
842
|
+
* Returns an empty string when the helper is called with no malformed tokens
|
|
843
|
+
* (defense in depth: callers already guard, but a future caller that forgets
|
|
844
|
+
* shouldn't be able to produce a degenerate warning with an empty bracket).
|
|
845
|
+
* Non-string entries are coerced via String() so a misbehaving caller can't
|
|
846
|
+
* surface "undefined" / "[object Object]" to customers; duplicates are
|
|
847
|
+
* suppressed so a fragment like `#/Foo%/Bar/Foo%/Baz` doesn't render as
|
|
848
|
+
* `["Foo%", "Foo%"]`.
|
|
849
|
+
*/
|
|
850
|
+
formatMalformedFragmentTokenWarning(targetName, updatedURL, malformedTokens) {
|
|
851
|
+
if (!Array.isArray(malformedTokens) || malformedTokens.length === 0) {
|
|
852
|
+
return '';
|
|
853
|
+
}
|
|
854
|
+
const seen = new Set();
|
|
855
|
+
const uniqueTokens = [];
|
|
856
|
+
for (const raw of malformedTokens) {
|
|
857
|
+
const t = typeof raw === 'string' ? raw : String(raw);
|
|
858
|
+
if (!seen.has(t)) {
|
|
859
|
+
seen.add(t);
|
|
860
|
+
uniqueTokens.push(t);
|
|
357
861
|
}
|
|
358
862
|
}
|
|
863
|
+
const tokenList = uniqueTokens.map((t) => `"${t}"`).join(', ');
|
|
864
|
+
return this.messages.getMessage('webPageOmniScriptUrlMalformedToken', [
|
|
865
|
+
tokenList,
|
|
866
|
+
this.toReadableURL(targetName),
|
|
867
|
+
this.toReadableURL(updatedURL),
|
|
868
|
+
]);
|
|
359
869
|
}
|
|
360
|
-
|
|
361
|
-
async getAllActiveCards() {
|
|
870
|
+
async getAllCards() {
|
|
362
871
|
//DebugTimer.getInstance().lap('Query Vlocity Cards');
|
|
363
872
|
const filters = new Map();
|
|
364
|
-
|
|
873
|
+
if (!this.IS_STANDARD_DATA_MODEL) {
|
|
874
|
+
filters.set(this.namespacePrefix + 'CardType__c', 'flex');
|
|
875
|
+
}
|
|
876
|
+
let flexCards;
|
|
365
877
|
if (this.allVersions) {
|
|
366
878
|
const sortFields = [
|
|
367
879
|
{ field: 'Name', direction: utils_1.SortDirection.ASC },
|
|
368
|
-
{ field: this.
|
|
880
|
+
{ field: this.getFieldKey('Version__c'), direction: utils_1.SortDirection.ASC },
|
|
369
881
|
];
|
|
370
|
-
|
|
882
|
+
flexCards = await utils_1.QueryTools.queryWithFilterAndSort(this.connection, this.getQueryNamespace(), this.getCardObjectName(), this.getCardFields(), filters, sortFields).catch((err) => {
|
|
371
883
|
if (err.errorCode === 'INVALID_TYPE') {
|
|
372
884
|
throw new interfaces_1.InvalidEntityTypeError(`${CardMigrationTool.VLOCITYCARD_NAME} type is not found under this namespace`);
|
|
373
885
|
}
|
|
@@ -375,37 +887,44 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
375
887
|
});
|
|
376
888
|
}
|
|
377
889
|
else {
|
|
378
|
-
filters.set(this.
|
|
379
|
-
|
|
890
|
+
filters.set(this.getFieldKey('Active__c'), true);
|
|
891
|
+
flexCards = await utils_1.QueryTools.queryWithFilter(this.connection, this.getQueryNamespace(), this.getCardObjectName(), this.getCardFields(), filters).catch((err) => {
|
|
380
892
|
if (err.errorCode === 'INVALID_TYPE') {
|
|
381
|
-
throw new interfaces_1.InvalidEntityTypeError(`${
|
|
893
|
+
throw new interfaces_1.InvalidEntityTypeError(`${this.getCardObjectName()} type is not found under this namespace`);
|
|
382
894
|
}
|
|
383
895
|
throw err;
|
|
384
896
|
});
|
|
385
897
|
}
|
|
898
|
+
// Apply prioritization only for standard data model
|
|
899
|
+
if (this.IS_STANDARD_DATA_MODEL) {
|
|
900
|
+
return this.prioritizeFlexCardsWithoutSpecialCharacters(flexCards);
|
|
901
|
+
}
|
|
902
|
+
return flexCards;
|
|
386
903
|
}
|
|
387
|
-
// Upload All the VlocityCard__c records to OmniUiCard
|
|
904
|
+
// Upload All the VlocityCard__c records to OmniUiCard for custom model and update references for standard
|
|
388
905
|
async uploadAllCards(cards, progressBar) {
|
|
389
906
|
const cardsUploadInfo = new Map();
|
|
390
907
|
const originalRecords = new Map();
|
|
391
908
|
const uniqueNames = new Set();
|
|
909
|
+
// Map to track cleanedName -> originalName for duplicate detection
|
|
910
|
+
const dupFlexCardNames = new Map();
|
|
392
911
|
let progressCounter = 0;
|
|
393
912
|
progressBar.start(cards.length, progressCounter);
|
|
394
913
|
for (let card of cards) {
|
|
395
|
-
await this.uploadCard(cards, card, cardsUploadInfo, originalRecords, uniqueNames);
|
|
914
|
+
await this.uploadCard(cards, card, cardsUploadInfo, originalRecords, uniqueNames, dupFlexCardNames);
|
|
396
915
|
progressBar.update(++progressCounter);
|
|
397
916
|
}
|
|
398
917
|
this.prepareStorageForFlexcards(cardsUploadInfo, originalRecords);
|
|
399
918
|
progressBar.stop();
|
|
400
919
|
return cardsUploadInfo;
|
|
401
920
|
}
|
|
402
|
-
async uploadCard(allCards, card, cardsUploadInfo, originalRecords, uniqueNames) {
|
|
921
|
+
async uploadCard(allCards, card, cardsUploadInfo, originalRecords, uniqueNames, dupFlexCardNames) {
|
|
403
922
|
const recordId = card['Id'];
|
|
404
923
|
// If we already uploaded this card, skip
|
|
405
924
|
if (cardsUploadInfo.has(recordId)) {
|
|
406
925
|
return;
|
|
407
926
|
}
|
|
408
|
-
const isCardActive = card[
|
|
927
|
+
const isCardActive = card[this.getFieldKey('Active__c')];
|
|
409
928
|
try {
|
|
410
929
|
const childCards = this.getChildCards(card);
|
|
411
930
|
if (childCards.length > 0) {
|
|
@@ -413,14 +932,19 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
413
932
|
// Upload child cards
|
|
414
933
|
const childCard = allCards.find((c) => c['Name'] === childCardName);
|
|
415
934
|
if (childCard) {
|
|
416
|
-
await this.uploadCard(allCards, childCard, cardsUploadInfo, originalRecords, uniqueNames);
|
|
935
|
+
await this.uploadCard(allCards, childCard, cardsUploadInfo, originalRecords, uniqueNames, dupFlexCardNames);
|
|
417
936
|
}
|
|
418
937
|
}
|
|
419
938
|
this.updateChildCards(card);
|
|
420
939
|
}
|
|
421
940
|
// Perform the transformation
|
|
422
941
|
const invalidIpNames = new Map();
|
|
423
|
-
const
|
|
942
|
+
const urlUpdateSummaries = new Set();
|
|
943
|
+
// Map keyed by rewrite summary so the emission step below can subtract
|
|
944
|
+
// malformed URLs from the aggregate "Updated URLs:" locations message.
|
|
945
|
+
// Same key for two actions on the same card => one entry (deduped).
|
|
946
|
+
const malformedFragmentWarnings = new Map();
|
|
947
|
+
const transformedCard = this.mapVlocityCardRecord(card, cardsUploadInfo, invalidIpNames, urlUpdateSummaries, malformedFragmentWarnings); // This only has the card structure, card definition is not there
|
|
424
948
|
// Verify duplicated names
|
|
425
949
|
let transformedCardName;
|
|
426
950
|
if (this.allVersions) {
|
|
@@ -430,17 +954,50 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
430
954
|
transformedCardName = transformedCard['Name'];
|
|
431
955
|
}
|
|
432
956
|
const transformedCardAuthorName = transformedCard['AuthorName'];
|
|
433
|
-
|
|
434
|
-
|
|
957
|
+
// Check for duplicates using version-aware name when allVersions is true
|
|
958
|
+
const uniqueCheckName = this.allVersions
|
|
959
|
+
? `${transformedCard['Name']}_${transformedCard['VersionNumber']}`
|
|
960
|
+
: transformedCard['Name'];
|
|
961
|
+
const originalCardName = card['Name'];
|
|
962
|
+
const cleanedCardName = transformedCard['Name'];
|
|
963
|
+
// Check for exact duplicate (same name + same version)
|
|
964
|
+
if (uniqueNames.has(uniqueCheckName)) {
|
|
965
|
+
this.setRecordErrors(card, this.messages.getMessage('duplicatedCardName', [uniqueCheckName]));
|
|
435
966
|
originalRecords.set(recordId, card);
|
|
436
967
|
return;
|
|
437
968
|
}
|
|
438
|
-
//
|
|
439
|
-
|
|
969
|
+
// Check for naming conflict: different original names cleaning to same name
|
|
970
|
+
else if (this.allVersions && dupFlexCardNames.has(cleanedCardName)) {
|
|
971
|
+
const existingOriginalName = dupFlexCardNames.get(cleanedCardName);
|
|
972
|
+
// Only flag if the original names are different (indicates a naming conflict)
|
|
973
|
+
if (existingOriginalName !== originalCardName) {
|
|
974
|
+
this.setRecordErrors(card, this.messages.getMessage('lowerVersionDuplicateCardName', [uniqueCheckName]));
|
|
975
|
+
originalRecords.set(recordId, card);
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
// Add to tracking structures
|
|
980
|
+
uniqueNames.add(uniqueCheckName);
|
|
981
|
+
if (this.allVersions && !dupFlexCardNames.has(cleanedCardName)) {
|
|
982
|
+
dupFlexCardNames.set(cleanedCardName, originalCardName);
|
|
983
|
+
}
|
|
440
984
|
// Create a map of the original records
|
|
441
985
|
originalRecords.set(recordId, card);
|
|
442
986
|
// Create card
|
|
443
|
-
|
|
987
|
+
let uploadResult;
|
|
988
|
+
if (!this.IS_STANDARD_DATA_MODEL) {
|
|
989
|
+
uploadResult = await net_1.NetUtils.createOne(this.connection, CardMigrationTool.OMNIUICARD_NAME, recordId, transformedCard);
|
|
990
|
+
}
|
|
991
|
+
else {
|
|
992
|
+
const standardId = transformedCard['Id'];
|
|
993
|
+
delete transformedCard['Id'];
|
|
994
|
+
const deactivationResult = await net_1.NetUtils.updateOne(this.connection, CardMigrationTool.OMNIUICARD_NAME, standardId, standardId, {
|
|
995
|
+
['IsActive']: false,
|
|
996
|
+
});
|
|
997
|
+
logger_1.Logger.logVerbose(JSON.stringify(deactivationResult)); // TODO - Add checks here
|
|
998
|
+
uploadResult = await net_1.NetUtils.updateOne(this.connection, CardMigrationTool.OMNIUICARD_NAME, recordId, recordId, transformedCard);
|
|
999
|
+
uploadResult['id'] = standardId;
|
|
1000
|
+
}
|
|
444
1001
|
if (uploadResult) {
|
|
445
1002
|
// Fix errors
|
|
446
1003
|
uploadResult.errors = uploadResult.errors || [];
|
|
@@ -449,13 +1006,33 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
449
1006
|
}
|
|
450
1007
|
// If name has been changed, add a warning message
|
|
451
1008
|
uploadResult.warnings = uploadResult.warnings || [];
|
|
452
|
-
if (transformedCardAuthorName !== card[this.
|
|
1009
|
+
if (transformedCardAuthorName !== card[this.getFieldKey('Author__c')]) {
|
|
453
1010
|
uploadResult.warnings.unshift(this.messages.getMessage('cardAuthorNameChangeMessage', [transformedCardAuthorName]));
|
|
454
1011
|
}
|
|
455
1012
|
uploadResult.newName = transformedCardName;
|
|
1013
|
+
uploadResult.actualName = transformedCard['Name']; // This is required as storage needs name without version, for replacement in other references
|
|
456
1014
|
if (transformedCard['Name'] !== card['Name']) {
|
|
457
1015
|
uploadResult.warnings.unshift(this.messages.getMessage('cardNameChangeMessage', [transformedCardName]));
|
|
458
1016
|
}
|
|
1017
|
+
// The count summary describes ONLY URLs that were converted cleanly
|
|
1018
|
+
// to the standard URL format. Malformed URLs were rewritten with
|
|
1019
|
+
// their bad tokens kept as-is -- claiming they were "updated to
|
|
1020
|
+
// standard URL format" alongside their own malformed warning would
|
|
1021
|
+
// contradict that warning and confuse the customer. Each malformed
|
|
1022
|
+
// URL is surfaced via its own dedicated bullet below which already
|
|
1023
|
+
// names the original URL, the rewritten URL, and the verify
|
|
1024
|
+
// instruction.
|
|
1025
|
+
const cleanRewriteSummaries = Array.from(urlUpdateSummaries).filter((summary) => !malformedFragmentWarnings.has(summary));
|
|
1026
|
+
if (cleanRewriteSummaries.length > 0) {
|
|
1027
|
+
uploadResult.warnings.unshift(this.messages.getMessage('flexCardOmniScriptNavigateURLUpdated', [String(cleanRewriteSummaries.length)]));
|
|
1028
|
+
}
|
|
1029
|
+
// Surface malformed-fragment-token warnings (one per affected URL).
|
|
1030
|
+
// These are intentionally emitted *instead of* the count bullet
|
|
1031
|
+
// above so the customer sees a single, actionable bullet per
|
|
1032
|
+
// malformed URL: original URL, rewrite, verify instruction.
|
|
1033
|
+
for (const malformedWarning of malformedFragmentWarnings.values()) {
|
|
1034
|
+
uploadResult.warnings.push(malformedWarning);
|
|
1035
|
+
}
|
|
459
1036
|
if (uploadResult.id && invalidIpNames.size > 0) {
|
|
460
1037
|
const val = Array.from(invalidIpNames.entries())
|
|
461
1038
|
.map((e) => e[0])
|
|
@@ -485,50 +1062,120 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
485
1062
|
});
|
|
486
1063
|
}
|
|
487
1064
|
}
|
|
488
|
-
|
|
1065
|
+
prepareStorageForRelatedObjectsWhenMetadataAPIEnabled(storage, flexcards) {
|
|
1066
|
+
for (const flexcard of flexcards) {
|
|
1067
|
+
const originalName = flexcard[this.getFieldKey('Name')];
|
|
1068
|
+
let value = {
|
|
1069
|
+
name: originalName,
|
|
1070
|
+
isDuplicate: false,
|
|
1071
|
+
originalName: originalName,
|
|
1072
|
+
migrationSuccess: true, // When metadata API is enabled, assume migration is successful
|
|
1073
|
+
};
|
|
1074
|
+
this.addKeyToStorage(originalName, value, storage);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
prepareAssessmentStorageForFlexcards(flexcardAssessmentInfos) {
|
|
489
1078
|
let storage = storageUtil_1.StorageUtil.getOmnistudioAssessmentStorage();
|
|
490
|
-
|
|
491
|
-
|
|
1079
|
+
for (let flexCardAssessmentInfo of flexcardAssessmentInfos) {
|
|
1080
|
+
try {
|
|
1081
|
+
if (!(flexCardAssessmentInfo === null || flexCardAssessmentInfo === void 0 ? void 0 : flexCardAssessmentInfo.nameMapping)) {
|
|
1082
|
+
logger_1.Logger.error(this.messages.getMessage('missingInfo'));
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
const originalName = flexCardAssessmentInfo.nameMapping.oldName;
|
|
1086
|
+
let value = {
|
|
1087
|
+
name: flexCardAssessmentInfo.nameMapping.newName,
|
|
1088
|
+
isDuplicate: false,
|
|
1089
|
+
originalName: originalName,
|
|
1090
|
+
};
|
|
1091
|
+
if (flexCardAssessmentInfo.errors && flexCardAssessmentInfo.errors.length > 0) {
|
|
1092
|
+
value.error = flexCardAssessmentInfo.errors;
|
|
1093
|
+
value.migrationSuccess = false;
|
|
1094
|
+
}
|
|
1095
|
+
else if (flexCardAssessmentInfo.migrationStatus === 'Needs manual intervention') {
|
|
1096
|
+
// Duplicate name and other critical warnings
|
|
1097
|
+
value.error = flexCardAssessmentInfo.warnings;
|
|
1098
|
+
value.migrationSuccess = false;
|
|
1099
|
+
}
|
|
1100
|
+
else {
|
|
1101
|
+
value.migrationSuccess = true;
|
|
1102
|
+
}
|
|
1103
|
+
this.addKeyToStorage(originalName, value, storage);
|
|
1104
|
+
}
|
|
1105
|
+
catch (error) {
|
|
1106
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('errorWhileProcessingFlexcardStorage'));
|
|
1107
|
+
logger_1.Logger.error(error);
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
storageUtil_1.StorageUtil.printAssessmentStorage();
|
|
1111
|
+
}
|
|
1112
|
+
addKeyToStorage(originalName, value, storage) {
|
|
1113
|
+
let finalKey = `${originalName}`;
|
|
1114
|
+
finalKey = finalKey.toLowerCase();
|
|
1115
|
+
if (storage.fcStorage.has(finalKey)) {
|
|
1116
|
+
if (this.allVersions) {
|
|
1117
|
+
const storedValue = storage.fcStorage.get(finalKey);
|
|
1118
|
+
if (this.isDifferentFlexcard(storedValue, originalName)) {
|
|
1119
|
+
this.markDuplicateKeyInStorage(value, finalKey, storage);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
this.markDuplicateKeyInStorage(value, finalKey, storage);
|
|
1124
|
+
}
|
|
492
1125
|
}
|
|
493
1126
|
else {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
1127
|
+
// Key doesn't exist - safe to set
|
|
1128
|
+
storage.fcStorage.set(finalKey, value);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
markDuplicateKeyInStorage(value, finalKey, storage) {
|
|
1132
|
+
// Key already exists - handle accordingly
|
|
1133
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('keyAlreadyInStorage', ['Flexcard', finalKey]));
|
|
1134
|
+
value.isDuplicate = true;
|
|
1135
|
+
storage.fcStorage.set(finalKey, value);
|
|
1136
|
+
}
|
|
1137
|
+
isDifferentFlexcard(storedValue, originalName) {
|
|
1138
|
+
if (storedValue.originalName === originalName) {
|
|
1139
|
+
return false;
|
|
498
1140
|
}
|
|
1141
|
+
return true;
|
|
499
1142
|
}
|
|
500
1143
|
prepareStorageForFlexcards(cardsUploadInfo, originalRecords) {
|
|
501
|
-
logger_1.Logger.logVerbose('
|
|
1144
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('flexcardStorageProcessingStarted'));
|
|
502
1145
|
let storage = storageUtil_1.StorageUtil.getOmnistudioMigrationStorage();
|
|
503
1146
|
for (let key of Array.from(originalRecords.keys())) {
|
|
504
1147
|
try {
|
|
505
1148
|
let oldrecord = originalRecords.get(key);
|
|
506
1149
|
let newrecord = cardsUploadInfo.get(key);
|
|
1150
|
+
const originalName = oldrecord['Name'];
|
|
507
1151
|
let value = {
|
|
508
|
-
name: newrecord
|
|
1152
|
+
name: newrecord === null || newrecord === void 0 ? void 0 : newrecord.actualName,
|
|
509
1153
|
isDuplicate: false,
|
|
1154
|
+
originalName: originalName,
|
|
510
1155
|
};
|
|
511
|
-
if (newrecord
|
|
512
|
-
|
|
1156
|
+
if (newrecord === undefined) {
|
|
1157
|
+
// Card was not migrated - check if original record has error details
|
|
1158
|
+
if (oldrecord['errors'] && Array.isArray(oldrecord['errors'])) {
|
|
1159
|
+
value.error = oldrecord['errors'];
|
|
1160
|
+
}
|
|
1161
|
+
else {
|
|
1162
|
+
value.error = ['Migration Failed'];
|
|
1163
|
+
}
|
|
513
1164
|
value.migrationSuccess = false;
|
|
514
1165
|
}
|
|
515
1166
|
else {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
storage.fcStorage.set(finalKey, value);
|
|
524
|
-
}
|
|
525
|
-
else {
|
|
526
|
-
// Key doesn't exist - safe to set
|
|
527
|
-
storage.fcStorage.set(finalKey, value);
|
|
1167
|
+
if (newrecord.hasErrors) {
|
|
1168
|
+
value.error = newrecord.errors;
|
|
1169
|
+
value.migrationSuccess = false;
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
value.migrationSuccess = true;
|
|
1173
|
+
}
|
|
528
1174
|
}
|
|
1175
|
+
this.addKeyToStorage(originalName, value, storage);
|
|
529
1176
|
}
|
|
530
1177
|
catch (error) {
|
|
531
|
-
logger_1.Logger.logVerbose('
|
|
1178
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('errorWhileProcessingFlexcardStorage'));
|
|
532
1179
|
logger_1.Logger.error(error);
|
|
533
1180
|
}
|
|
534
1181
|
storageUtil_1.StorageUtil.printMigrationStorage();
|
|
@@ -536,7 +1183,7 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
536
1183
|
}
|
|
537
1184
|
getChildCards(card) {
|
|
538
1185
|
let childs = [];
|
|
539
|
-
const definition = JSON.parse(card[this.
|
|
1186
|
+
const definition = JSON.parse(card[this.getFieldKey('Definition__c')]);
|
|
540
1187
|
if (!definition)
|
|
541
1188
|
return childs;
|
|
542
1189
|
for (let state of definition.states || []) {
|
|
@@ -549,137 +1196,1030 @@ class CardMigrationTool extends base_1.BaseMigrationTool {
|
|
|
549
1196
|
return childs;
|
|
550
1197
|
}
|
|
551
1198
|
updateChildCards(card) {
|
|
552
|
-
const definition = JSON.parse(card[this.
|
|
1199
|
+
const definition = JSON.parse(card[this.getFieldKey('Definition__c')]);
|
|
553
1200
|
if (!definition)
|
|
554
1201
|
return;
|
|
555
1202
|
for (let state of definition.states || []) {
|
|
556
1203
|
if (state.childCards && Array.isArray(state.childCards)) {
|
|
1204
|
+
const originalChildCards = [...state.childCards];
|
|
557
1205
|
state.childCards = state.childCards.map((c) => this.cleanName(c));
|
|
1206
|
+
// Check if any child card name was changed
|
|
1207
|
+
for (let i = 0; i < originalChildCards.length; i++) {
|
|
1208
|
+
if (originalChildCards[i] !== state.childCards[i]) {
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
558
1211
|
}
|
|
559
1212
|
}
|
|
560
|
-
card[this.
|
|
1213
|
+
card[this.getFieldKey('Definition__c')] = JSON.stringify(definition);
|
|
561
1214
|
}
|
|
562
1215
|
// Maps an indivitdual VlocityCard__c record to an OmniUiCard record.
|
|
563
|
-
mapVlocityCardRecord(cardRecord, cardsUploadInfo, invalidIpNames) {
|
|
1216
|
+
mapVlocityCardRecord(cardRecord, cardsUploadInfo, invalidIpNames, urlUpdateSummaries, malformedFragmentWarnings) {
|
|
1217
|
+
var _a, _b;
|
|
564
1218
|
// Transformed object
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
1219
|
+
let mappedObject = {};
|
|
1220
|
+
if (!this.IS_STANDARD_DATA_MODEL) {
|
|
1221
|
+
// Get the fields of the record
|
|
1222
|
+
const recordFields = Object.keys(cardRecord);
|
|
1223
|
+
// Map individual fields
|
|
1224
|
+
recordFields.forEach((recordField) => {
|
|
1225
|
+
const cleanFieldName = this.getCleanFieldName(recordField);
|
|
1226
|
+
if (VlocityCard_1.default.hasOwnProperty(cleanFieldName) && cleanFieldName !== 'IsChildCard__c') {
|
|
1227
|
+
mappedObject[VlocityCard_1.default[cleanFieldName]] = cardRecord[recordField];
|
|
1228
|
+
// Transform ParentId__c to ClonedFromOmniUiCardKey field from uploaded response map
|
|
1229
|
+
if (cleanFieldName === 'ParentID__c' && cardsUploadInfo.has(cardRecord[this.getFieldKey('ParentID__c')])) {
|
|
1230
|
+
mappedObject[VlocityCard_1.default[cleanFieldName]] = cardsUploadInfo.get(cardRecord[this.getFieldKey('ParentID__c')]).id;
|
|
1231
|
+
}
|
|
1232
|
+
// CardType__c and OmniUiCardType have different picklist values
|
|
1233
|
+
if (cleanFieldName === 'CardType__c') {
|
|
1234
|
+
let ischildCard = cardRecord[this.getFieldKey('IsChildCard__c')];
|
|
1235
|
+
mappedObject['OmniUiCardType'] = ischildCard ? 'Child' : 'Parent';
|
|
1236
|
+
}
|
|
1237
|
+
// Child Cards don't have version, so assigning 1
|
|
1238
|
+
if (cleanFieldName === 'Version__c') {
|
|
1239
|
+
let versionNumber = cardRecord[this.getFieldKey('Version__c')];
|
|
1240
|
+
mappedObject['VersionNumber'] = versionNumber ? versionNumber : 1;
|
|
1241
|
+
}
|
|
586
1242
|
}
|
|
587
|
-
}
|
|
588
|
-
}
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
else {
|
|
1246
|
+
mappedObject = { ...cardRecord };
|
|
1247
|
+
}
|
|
589
1248
|
// Clean the name
|
|
590
1249
|
mappedObject['Name'] = this.cleanName(mappedObject['Name']);
|
|
591
1250
|
mappedObject[VlocityCard_1.default.Author__c] = this.cleanName(mappedObject[VlocityCard_1.default.Author__c]);
|
|
592
1251
|
mappedObject[VlocityCard_1.default.Active__c] = false;
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
const parts = ipMethod.split('_');
|
|
603
|
-
const newKey = parts.map((p) => this.cleanName(p, true)).join('_');
|
|
604
|
-
datasource.dataSource.value.ipMethod = newKey;
|
|
605
|
-
if (parts.length > 2) {
|
|
606
|
-
invalidIpNames.set('DataSource', ipMethod);
|
|
607
|
-
}
|
|
1252
|
+
if (this.IS_STANDARD_DATA_MODEL) {
|
|
1253
|
+
if (mappedObject['OmniUiCardKey']) {
|
|
1254
|
+
mappedObject['OmniUiCardKey'] =
|
|
1255
|
+
mappedObject['Name'] +
|
|
1256
|
+
'/' +
|
|
1257
|
+
mappedObject[VlocityCard_1.default.Author__c] +
|
|
1258
|
+
'/' +
|
|
1259
|
+
mappedObject[VlocityCard_1.default.Version__c] +
|
|
1260
|
+
'.0';
|
|
608
1261
|
}
|
|
609
|
-
mappedObject[VlocityCard_1.default.Datasource__c] = JSON.stringify(datasource);
|
|
610
1262
|
}
|
|
611
|
-
// Update the
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
1263
|
+
// Update the datasource - process any nested object with a 'type' property
|
|
1264
|
+
const datasource = JSON.parse(mappedObject[VlocityCard_1.default.Datasource__c] || '{}');
|
|
1265
|
+
let updated = false;
|
|
1266
|
+
// Process all keys that have objects with type property
|
|
1267
|
+
for (const key of Object.keys(datasource)) {
|
|
1268
|
+
const ds = datasource[key];
|
|
1269
|
+
if (!ds || typeof ds !== 'object' || !ds.type)
|
|
1270
|
+
continue;
|
|
1271
|
+
if (ds.type === stringContants_1.Constants.DataRaptorComponentName && ((_a = ds.value) === null || _a === void 0 ? void 0 : _a.bundle)) {
|
|
1272
|
+
ds.value.bundle = this.nameRegistry.hasDataMapperMapping(ds.value.bundle)
|
|
1273
|
+
? this.nameRegistry.getDataMapperCleanedName(ds.value.bundle)
|
|
1274
|
+
: this.cleanName(ds.value.bundle);
|
|
1275
|
+
updated = true;
|
|
1276
|
+
}
|
|
1277
|
+
else if (ds.type === stringContants_1.Constants.IntegrationProcedurePluralName && ((_b = ds.value) === null || _b === void 0 ? void 0 : _b.ipMethod)) {
|
|
1278
|
+
const ipMethod = ds.value.ipMethod;
|
|
1279
|
+
if (this.nameRegistry.hasIntegrationProcedureMapping(ipMethod)) {
|
|
1280
|
+
ds.value.ipMethod = this.nameRegistry.getIntegrationProcedureCleanedName(ipMethod);
|
|
618
1281
|
}
|
|
619
|
-
else
|
|
620
|
-
const ipMethod = propertySet.dataSource.value.ipMethod || '';
|
|
1282
|
+
else {
|
|
621
1283
|
const parts = ipMethod.split('_');
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
invalidIpNames.set('DataSource', ipMethod);
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
// update the states for child cards
|
|
630
|
-
for (let i = 0; i < (propertySet.states || []).length; i++) {
|
|
631
|
-
const state = propertySet.states[i];
|
|
632
|
-
// Clean childCards property
|
|
633
|
-
if (state.childCards && Array.isArray(state.childCards)) {
|
|
634
|
-
state.childCards = state.childCards.map((c) => this.cleanName(c));
|
|
635
|
-
}
|
|
636
|
-
// Fix the "components" for child cards
|
|
637
|
-
for (let componentKey in state.components) {
|
|
638
|
-
if (state.components.hasOwnProperty(componentKey)) {
|
|
639
|
-
const component = state.components[componentKey];
|
|
640
|
-
if (component.children && Array.isArray(component.children)) {
|
|
641
|
-
this.fixChildren(component.children);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
if (state.omniscripts && Array.isArray(state.omniscripts)) {
|
|
646
|
-
for (let osIdx = 0; osIdx < state.omniscripts.length; osIdx++) {
|
|
647
|
-
state.omniscripts[osIdx].type = this.cleanName(state.omniscripts[osIdx].type);
|
|
648
|
-
state.omniscripts[osIdx].subtype = this.cleanName(state.omniscripts[osIdx].subtype);
|
|
649
|
-
}
|
|
1284
|
+
ds.value.ipMethod = parts.map((p) => this.cleanName(p, true)).join('_');
|
|
1285
|
+
if (parts.length > 2)
|
|
1286
|
+
invalidIpNames.set(key, ipMethod);
|
|
650
1287
|
}
|
|
1288
|
+
updated = true;
|
|
651
1289
|
}
|
|
652
|
-
mappedObject[VlocityCard_1.default.Definition__c] = JSON.stringify(propertySet);
|
|
653
1290
|
}
|
|
1291
|
+
if (updated)
|
|
1292
|
+
mappedObject[VlocityCard_1.default.Datasource__c] = JSON.stringify(datasource);
|
|
1293
|
+
const isCardActive = cardRecord[this.getFieldKey('Active__c')];
|
|
1294
|
+
this.ensureCommunityTargets(mappedObject, isCardActive);
|
|
1295
|
+
// Update all dependencies comprehensively
|
|
1296
|
+
this.updateAllDependenciesWithRegistry(mappedObject, invalidIpNames, urlUpdateSummaries, malformedFragmentWarnings);
|
|
654
1297
|
mappedObject['attributes'] = {
|
|
655
1298
|
type: CardMigrationTool.OMNIUICARD_NAME,
|
|
656
1299
|
referenceId: cardRecord['Id'],
|
|
657
1300
|
};
|
|
658
1301
|
return mappedObject;
|
|
659
1302
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
1303
|
+
/**
|
|
1304
|
+
* Comprehensive dependency update using NameMappingRegistry - mirrors assessment logic
|
|
1305
|
+
*/
|
|
1306
|
+
updateAllDependenciesWithRegistry(mappedObject, invalidIpNames, urlUpdateSummaries, malformedFragmentWarnings) {
|
|
1307
|
+
// Handle propertySet (Definition) - update all dependency references
|
|
1308
|
+
const propertySet = JSON.parse(mappedObject[VlocityCard_1.default.Definition__c] || '{}');
|
|
1309
|
+
if (propertySet) {
|
|
1310
|
+
// Handle dataSource in propertySet
|
|
1311
|
+
if (propertySet.dataSource) {
|
|
1312
|
+
this.updateDataSourceWithRegistry(propertySet.dataSource, invalidIpNames, 'PropertySet');
|
|
665
1313
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
1314
|
+
// Handle states comprehensively
|
|
1315
|
+
if (propertySet.states && Array.isArray(propertySet.states)) {
|
|
1316
|
+
for (let i = 0; i < propertySet.states.length; i++) {
|
|
1317
|
+
const state = propertySet.states[i];
|
|
1318
|
+
// Handle child cards using registry
|
|
1319
|
+
if (state.childCards && Array.isArray(state.childCards)) {
|
|
1320
|
+
state.childCards = state.childCards.map((c) => {
|
|
1321
|
+
if (c && this.nameRegistry.hasFlexCardMapping(c)) {
|
|
1322
|
+
return this.nameRegistry.getFlexCardCleanedName(c);
|
|
1323
|
+
}
|
|
1324
|
+
else {
|
|
1325
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['Flexcard', c])}`);
|
|
1326
|
+
return this.cleanName(c);
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
// Handle omniscripts using registry
|
|
1331
|
+
if (state.omniscripts && Array.isArray(state.omniscripts)) {
|
|
1332
|
+
for (let osIdx = 0; osIdx < state.omniscripts.length; osIdx++) {
|
|
1333
|
+
this.updateOmniScriptReferenceWithRegistry(state.omniscripts[osIdx]);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
// Handle components comprehensively using registry
|
|
1337
|
+
if (state.components) {
|
|
1338
|
+
for (const componentKey in state.components) {
|
|
1339
|
+
if (state.components.hasOwnProperty(componentKey)) {
|
|
1340
|
+
const component = state.components[componentKey];
|
|
1341
|
+
this.updateComponentDependenciesWithRegistry(component, urlUpdateSummaries, malformedFragmentWarnings);
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
671
1346
|
}
|
|
672
|
-
|
|
673
|
-
|
|
1347
|
+
// Handle events[] array references (Migration)
|
|
1348
|
+
if (propertySet.events && Array.isArray(propertySet.events)) {
|
|
1349
|
+
this.updateEventsWithRegistry(propertySet.events, invalidIpNames);
|
|
674
1350
|
}
|
|
1351
|
+
mappedObject[VlocityCard_1.default.Definition__c] = JSON.stringify(propertySet);
|
|
675
1352
|
}
|
|
676
1353
|
}
|
|
1354
|
+
/**
|
|
1355
|
+
* Update events array references (Migration)
|
|
1356
|
+
* Handles: events[].actionList[].stateAction references
|
|
1357
|
+
*/
|
|
1358
|
+
updateEventsWithRegistry(events, invalidIpNames) {
|
|
1359
|
+
for (const event of events) {
|
|
1360
|
+
if (!event.actionList || !Array.isArray(event.actionList)) {
|
|
1361
|
+
continue;
|
|
1362
|
+
}
|
|
1363
|
+
for (const action of event.actionList) {
|
|
1364
|
+
if (!action.stateAction) {
|
|
1365
|
+
continue;
|
|
1366
|
+
}
|
|
1367
|
+
const stateAction = action.stateAction;
|
|
1368
|
+
// 1-2. Handle message.value.bundle (DataRaptor) and message.value.ipMethod (Integration Procedure)
|
|
1369
|
+
this.processStateActionMessageWithRegistry(stateAction, invalidIpNames);
|
|
1370
|
+
// 3. Handle cardName (FlexCard - Flyout childCard)
|
|
1371
|
+
if (stateAction.cardName) {
|
|
1372
|
+
const originalCardName = stateAction.cardName;
|
|
1373
|
+
if (this.nameRegistry.hasFlexCardMapping(originalCardName)) {
|
|
1374
|
+
stateAction.cardName = this.nameRegistry.getFlexCardCleanedName(originalCardName);
|
|
1375
|
+
}
|
|
1376
|
+
else {
|
|
1377
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['Flexcard', originalCardName])}`);
|
|
1378
|
+
stateAction.cardName = this.cleanName(originalCardName);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
// 4. Handle flyoutLwc (FlexCard child card and custom LWC references)
|
|
1382
|
+
this.updateFlyoutLwcValue(stateAction);
|
|
1383
|
+
if (this.hasOmniscriptFlyoutDependency(stateAction)) {
|
|
1384
|
+
this.updateOsNameWithRegistry(stateAction, 'osName');
|
|
1385
|
+
}
|
|
1386
|
+
// 6. Handle omniType.Name (OmniScript)
|
|
1387
|
+
if (stateAction.omniType && stateAction.omniType.Name) {
|
|
1388
|
+
this.updateOmniTypeNameWithRegistry(stateAction.omniType);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Update dataSource (DataRaptor, Integration Procedures, Apex Remote) using registry
|
|
1395
|
+
*/
|
|
1396
|
+
updateDataSourceWithRegistry(dataSource, invalidIpNames, context) {
|
|
1397
|
+
var _a, _b, _c;
|
|
1398
|
+
const type = dataSource.type;
|
|
1399
|
+
if (type === stringContants_1.Constants.DataRaptorComponentName) {
|
|
1400
|
+
// Handle DataRaptor using registry
|
|
1401
|
+
const originalBundle = ((_a = dataSource.value) === null || _a === void 0 ? void 0 : _a.bundle) || '';
|
|
1402
|
+
if (originalBundle && this.nameRegistry.hasDataMapperMapping(originalBundle)) {
|
|
1403
|
+
dataSource.value.bundle = this.nameRegistry.getDataMapperCleanedName(originalBundle);
|
|
1404
|
+
}
|
|
1405
|
+
else {
|
|
1406
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['DataMapper', originalBundle])}`);
|
|
1407
|
+
dataSource.value.bundle = this.cleanName(originalBundle);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
else if (type === stringContants_1.Constants.IntegrationProcedurePluralName) {
|
|
1411
|
+
// Handle Integration Procedures using registry
|
|
1412
|
+
const ipMethod = ((_b = dataSource.value) === null || _b === void 0 ? void 0 : _b.ipMethod) || '';
|
|
1413
|
+
const hasRegistryMapping = this.nameRegistry.hasIntegrationProcedureMapping(ipMethod);
|
|
1414
|
+
if (hasRegistryMapping) {
|
|
1415
|
+
const cleanedIpName = this.nameRegistry.getIntegrationProcedureCleanedName(ipMethod);
|
|
1416
|
+
dataSource.value.ipMethod = cleanedIpName;
|
|
1417
|
+
}
|
|
1418
|
+
else {
|
|
1419
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['IntegrationProcedure', ipMethod])}`);
|
|
1420
|
+
const parts = ipMethod.split('_');
|
|
1421
|
+
const newKey = parts.map((p) => this.cleanName(p, true)).join('_');
|
|
1422
|
+
dataSource.value.ipMethod = newKey;
|
|
1423
|
+
if (parts.length > 2) {
|
|
1424
|
+
invalidIpNames.set(context, ipMethod);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
else if (type === stringContants_1.Constants.ApexRemoteComponentName) {
|
|
1429
|
+
if ((_c = dataSource.value) === null || _c === void 0 ? void 0 : _c.remoteClass) {
|
|
1430
|
+
dataSource.value.remoteClass = this.apexNamespaceRegistry.getQualifiedClassName(dataSource.value.remoteClass);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Update OmniScript reference using registry
|
|
1436
|
+
*/
|
|
1437
|
+
updateOmniScriptReferenceWithRegistry(omniscriptRef) {
|
|
1438
|
+
const originalType = omniscriptRef.type;
|
|
1439
|
+
const originalSubtype = omniscriptRef.subtype;
|
|
1440
|
+
const language = omniscriptRef.language || 'English';
|
|
1441
|
+
// Construct full OmniScript name to check registry
|
|
1442
|
+
const fullOmniScriptName = `${originalType}_${originalSubtype}_${language}`;
|
|
1443
|
+
if (this.nameRegistry.hasOmniScriptMapping(fullOmniScriptName)) {
|
|
1444
|
+
// Registry has mapping for this OmniScript - extract cleaned parts
|
|
1445
|
+
const cleanedFullName = this.nameRegistry.getCleanedName(fullOmniScriptName, 'OmniScript');
|
|
1446
|
+
const parts = cleanedFullName.split('_');
|
|
1447
|
+
if (parts.length >= 2) {
|
|
1448
|
+
omniscriptRef.type = parts[0];
|
|
1449
|
+
omniscriptRef.subtype = parts[1];
|
|
1450
|
+
// Language doesn't typically change, but update if provided
|
|
1451
|
+
if (parts.length >= 3) {
|
|
1452
|
+
omniscriptRef.language = parts[2];
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
else {
|
|
1457
|
+
// No registry mapping - use original fallback approach
|
|
1458
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['Omniscript', fullOmniScriptName])}`);
|
|
1459
|
+
omniscriptRef.type = this.cleanName(originalType);
|
|
1460
|
+
omniscriptRef.subtype = this.cleanName(originalSubtype);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Update component dependencies comprehensively
|
|
1465
|
+
*/
|
|
1466
|
+
updateComponentDependenciesWithRegistry(component, urlUpdateSummaries, malformedFragmentWarnings) {
|
|
1467
|
+
// Handle action elements with actionList (like assessment)
|
|
1468
|
+
if (component.element === 'action' && component.property && component.property.actionList) {
|
|
1469
|
+
for (const action of component.property.actionList) {
|
|
1470
|
+
if (action.stateAction) {
|
|
1471
|
+
// Handle message field (contains DataRaptor/IP references as JSON string)
|
|
1472
|
+
this.processStateActionMessageWithRegistry(action.stateAction);
|
|
1473
|
+
// Case 1: Direct OmniScript reference
|
|
1474
|
+
if (action.stateAction.type === stringContants_1.Constants.OmniScriptComponentName && action.stateAction.omniType) {
|
|
1475
|
+
this.updateOmniTypeNameWithRegistry(action.stateAction.omniType);
|
|
1476
|
+
}
|
|
1477
|
+
// Case 2: Flyout OmniScript reference
|
|
1478
|
+
else if (this.hasOmniscriptFlyoutDependency(action.stateAction)) {
|
|
1479
|
+
this.updateOsNameWithRegistry(action.stateAction, 'osName');
|
|
1480
|
+
}
|
|
1481
|
+
// Case 3: Flyout with flyoutLwc (ChildCard or CustomLwc)
|
|
1482
|
+
else if (this.hasFlyoutLwc(action.stateAction)) {
|
|
1483
|
+
this.updateFlyoutLwcValue(action.stateAction);
|
|
1484
|
+
}
|
|
1485
|
+
// Case A: Custom Web Page action referencing OmniScript Universal Page
|
|
1486
|
+
else if (this.isCustomWebPageAction(action.stateAction)) {
|
|
1487
|
+
this.applyOmniScriptURLRewrite(action.stateAction, urlUpdateSummaries, malformedFragmentWarnings);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
// Handle Custom LWC components - special case for FlexCard references
|
|
1493
|
+
this.updateCustomLwcWithRegistry(component);
|
|
1494
|
+
// Handle standard component actions (like assessment)
|
|
1495
|
+
if (component.actions && Array.isArray(component.actions)) {
|
|
1496
|
+
for (const action of component.actions) {
|
|
1497
|
+
if (action.stateAction && action.stateAction.omniType) {
|
|
1498
|
+
this.updateOmniTypeNameWithRegistry(action.stateAction.omniType);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
// Handle direct stateAction on component property (existing logic)
|
|
1503
|
+
if (component.property && component.property.stateAction) {
|
|
1504
|
+
if (component.property.stateAction.omniType) {
|
|
1505
|
+
this.updateOmniTypeNameWithRegistry(component.property.stateAction.omniType);
|
|
1506
|
+
}
|
|
1507
|
+
if (this.hasOmniscriptFlyoutDependency(component.property.stateAction)) {
|
|
1508
|
+
this.updateOsNameWithRegistry(component.property.stateAction, 'osName');
|
|
1509
|
+
}
|
|
1510
|
+
// Handle Flyout with flyoutLwc (ChildCard or CustomLwc)
|
|
1511
|
+
if (this.hasFlyoutLwc(component.property.stateAction)) {
|
|
1512
|
+
this.updateFlyoutLwcValue(component.property.stateAction);
|
|
1513
|
+
}
|
|
1514
|
+
if (this.isCustomWebPageAction(component.property.stateAction)) {
|
|
1515
|
+
this.applyOmniScriptURLRewrite(component.property.stateAction, urlUpdateSummaries, malformedFragmentWarnings);
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
// Handle childCardPreview elements (from old fixChildren method)
|
|
1519
|
+
if (component.element === stringContants_1.Constants.ChildCardPreview && component.property) {
|
|
1520
|
+
if (component.property.cardName) {
|
|
1521
|
+
const originalCardName = component.property.cardName;
|
|
1522
|
+
if (this.nameRegistry.hasFlexCardMapping(originalCardName)) {
|
|
1523
|
+
component.property.cardName = this.nameRegistry.getFlexCardCleanedName(originalCardName);
|
|
1524
|
+
}
|
|
1525
|
+
else {
|
|
1526
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['Flexcard', originalCardName])}`);
|
|
1527
|
+
component.property.cardName = this.cleanName(originalCardName);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
// Handle omni-flyout elements (missing from migration logic)
|
|
1532
|
+
if (component.element === stringContants_1.Constants.OmniFlyout && component.property && component.property.flyoutOmniScript) {
|
|
1533
|
+
if (component.property.flyoutOmniScript.osName) {
|
|
1534
|
+
const osName = component.property.flyoutOmniScript.osName;
|
|
1535
|
+
if (typeof osName === 'string') {
|
|
1536
|
+
const parts = osName.split('/');
|
|
1537
|
+
if (parts.length >= 2) {
|
|
1538
|
+
// Construct full OmniScript name: Type_SubType_Language
|
|
1539
|
+
const originalOsRef = parts.join('_');
|
|
1540
|
+
if (this.nameRegistry.hasOmniScriptMapping(originalOsRef)) {
|
|
1541
|
+
// Registry has mapping - extract cleaned parts and convert back to / format
|
|
1542
|
+
const cleanedFullName = this.nameRegistry.getCleanedName(originalOsRef, 'OmniScript');
|
|
1543
|
+
const cleanedParts = cleanedFullName.split('_');
|
|
1544
|
+
if (cleanedParts.length >= 2) {
|
|
1545
|
+
component.property.flyoutOmniScript.osName = cleanedParts.join('/');
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
else {
|
|
1549
|
+
// No registry mapping - use original fallback approach
|
|
1550
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['Omniscript', originalOsRef])}`);
|
|
1551
|
+
component.property.flyoutOmniScript.osName =
|
|
1552
|
+
parts.length >= 3
|
|
1553
|
+
? `${this.cleanName(parts[0])}/${this.cleanName(parts[1])}/${parts[2]}`
|
|
1554
|
+
: parts.map((p) => this.cleanName(p)).join('/');
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
// Check child components recursively
|
|
1561
|
+
if (component.children && Array.isArray(component.children)) {
|
|
1562
|
+
for (const child of component.children) {
|
|
1563
|
+
this.updateComponentDependenciesWithRegistry(child, urlUpdateSummaries, malformedFragmentWarnings);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
applyOmniScriptURLRewrite(stateAction, urlUpdateSummaries, malformedFragmentWarnings) {
|
|
1568
|
+
if (this.IS_STANDARD_DATA_MODEL) {
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
const rewrite = this.getOmniScriptURLRewrite(stateAction);
|
|
1572
|
+
if (!rewrite) {
|
|
1573
|
+
return;
|
|
1574
|
+
}
|
|
1575
|
+
const { targetName, updatedURL, malformedTokens } = rewrite;
|
|
1576
|
+
stateAction[stringContants_1.Constants.WebPageTargetType].targetName = updatedURL;
|
|
1577
|
+
const summary = this.formatURLRewriteSummary(targetName, updatedURL);
|
|
1578
|
+
urlUpdateSummaries.add(summary);
|
|
1579
|
+
// Per-card collector is optional so internal/test callers can omit it
|
|
1580
|
+
// without forcing a signature update. The Map is keyed by the rewrite
|
|
1581
|
+
// summary so the emission step can later subtract malformed URLs from
|
|
1582
|
+
// the aggregate "Updated URLs: ..." locations message -- each malformed
|
|
1583
|
+
// entry already carries the original URL, the rewritten URL, and the
|
|
1584
|
+
// verify instruction inside its own warning, so listing it twice would
|
|
1585
|
+
// be redundant. Same key for two actions on the same card => one entry.
|
|
1586
|
+
// Defense-in-depth: skip if the formatter returns an empty string so we
|
|
1587
|
+
// never store a blank warning under a real summary key.
|
|
1588
|
+
if (malformedFragmentWarnings && Array.isArray(malformedTokens) && malformedTokens.length > 0) {
|
|
1589
|
+
const malformedWarning = this.formatMalformedFragmentTokenWarning(targetName, updatedURL, malformedTokens);
|
|
1590
|
+
if (malformedWarning) {
|
|
1591
|
+
malformedFragmentWarnings.set(summary, malformedWarning);
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
/** Build a human-readable "before -> after" string for warning messages only. */
|
|
1596
|
+
formatURLRewriteSummary(originalURL, updatedURL) {
|
|
1597
|
+
return `${this.toReadableURL(originalURL)} -> ${this.toReadableURL(updatedURL)}`;
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* Decode a URL for DISPLAY purposes only (warning/log messages). The output
|
|
1601
|
+
* is lossy with respect to URL parsing semantics (e.g. an encoded `%26`
|
|
1602
|
+
* becomes a literal `&`) and must NOT be re-fed into a URL parser. Falls
|
|
1603
|
+
* back to the raw input on malformed percent sequences.
|
|
1604
|
+
*/
|
|
1605
|
+
toReadableURL(url) {
|
|
1606
|
+
try {
|
|
1607
|
+
return decodeURIComponent(url);
|
|
1608
|
+
}
|
|
1609
|
+
catch {
|
|
1610
|
+
return url;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
getOmniScriptURLRewrite(stateAction) {
|
|
1614
|
+
var _a;
|
|
1615
|
+
const targetName = (_a = stateAction[stringContants_1.Constants.WebPageTargetType]) === null || _a === void 0 ? void 0 : _a.targetName;
|
|
1616
|
+
if (typeof targetName !== 'string') {
|
|
1617
|
+
return undefined;
|
|
1618
|
+
}
|
|
1619
|
+
// Fast reject: if the raw text doesn't even mention the universal-page
|
|
1620
|
+
// path or token, skip URL parsing entirely. This is a substring screen,
|
|
1621
|
+
// not a security check; the strict structural validation happens after
|
|
1622
|
+
// parsing in isValidOmniScriptNavigationURL.
|
|
1623
|
+
if (!targetName.includes(stringContants_1.Constants.OmniScriptUniversalPagePath) ||
|
|
1624
|
+
!targetName.includes(stringContants_1.Constants.OmniScriptUniversalPageToken)) {
|
|
1625
|
+
return undefined;
|
|
1626
|
+
}
|
|
1627
|
+
const parsedURL = this.tryParseURL(targetName);
|
|
1628
|
+
if (!parsedURL || !this.isValidOmniScriptNavigationURL(parsedURL)) {
|
|
1629
|
+
return undefined;
|
|
1630
|
+
}
|
|
1631
|
+
const updatedURL = this.convertToStandardOmniScriptURL(parsedURL);
|
|
1632
|
+
// Re-parse the fragment once more here purely to capture malformed-token
|
|
1633
|
+
// diagnostics for the caller. Cheap (single split + map over a short
|
|
1634
|
+
// string) and keeps `convertToStandardOmniScriptURL` focused on rewriting.
|
|
1635
|
+
const { malformedTokens } = this.parseSlashFragmentParams(parsedURL.hash);
|
|
1636
|
+
return { targetName, updatedURL, malformedTokens };
|
|
1637
|
+
}
|
|
1638
|
+
isCustomWebPageAction(stateAction) {
|
|
1639
|
+
return (stateAction === null || stateAction === void 0 ? void 0 : stateAction.type) === stringContants_1.Constants.CustomActionType && (stateAction === null || stateAction === void 0 ? void 0 : stateAction.targetType) === stringContants_1.Constants.WebPageTargetType;
|
|
1640
|
+
}
|
|
1641
|
+
/**
|
|
1642
|
+
* Parse a URL string without throwing. Returns the parsed URL on success or
|
|
1643
|
+
* undefined for:
|
|
1644
|
+
* - syntactically invalid input (e.g. `https://[bad`, raw spaces in host,
|
|
1645
|
+
* `http:///` with no host), or
|
|
1646
|
+
* - URLs whose scheme is not `http:` or `https:` (e.g. `javascript:`,
|
|
1647
|
+
* `data:`, `file:`, `mailto:`).
|
|
1648
|
+
*
|
|
1649
|
+
* See URL_PARSE_BASE for why a synthetic base is supplied.
|
|
1650
|
+
*/
|
|
1651
|
+
tryParseURL(input) {
|
|
1652
|
+
let parsed;
|
|
1653
|
+
try {
|
|
1654
|
+
parsed = new URL(input, CardMigrationTool.URL_PARSE_BASE);
|
|
1655
|
+
}
|
|
1656
|
+
catch {
|
|
1657
|
+
return undefined;
|
|
1658
|
+
}
|
|
1659
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
1660
|
+
return undefined;
|
|
1661
|
+
}
|
|
1662
|
+
return parsed;
|
|
1663
|
+
}
|
|
1664
|
+
/**
|
|
1665
|
+
* Verify a parsed URL has the OmniScript Navigate shape. We validate against
|
|
1666
|
+
* the parsed components (pathname / searchParams / hash) rather than doing
|
|
1667
|
+
* substring matches on the raw input so callers cannot smuggle the required
|
|
1668
|
+
* tokens in unrelated positions (e.g. inside another query value).
|
|
1669
|
+
*
|
|
1670
|
+
* The pathname must START WITH `/apex/` and contain the universal-page
|
|
1671
|
+
* token. Anchoring to the prefix rejects non-http(s) schemes such as
|
|
1672
|
+
* `javascript:alert(1)//apex/...` whose parsed pathname does not begin
|
|
1673
|
+
* with `/` (it begins with the opaque body of the scheme).
|
|
1674
|
+
*
|
|
1675
|
+
* Two legitimate shapes are accepted:
|
|
1676
|
+
* 1. Path + query: /apex/<ns>__OmniScriptUniversalPage?OmniScriptType=...&OmniScriptSubType=...&OmniScriptLang=...
|
|
1677
|
+
* 2. Path + fragment: /apex/<ns>__OmniScriptUniversalPage?...#/OmniScriptType/.../OmniScriptSubType/.../OmniScriptLang/...
|
|
1678
|
+
*/
|
|
1679
|
+
isValidOmniScriptNavigationURL(parsedURL) {
|
|
1680
|
+
if (!parsedURL.pathname.startsWith(`${stringContants_1.Constants.OmniScriptUniversalPagePath}/`)) {
|
|
1681
|
+
return false;
|
|
1682
|
+
}
|
|
1683
|
+
if (!parsedURL.pathname.includes(stringContants_1.Constants.OmniScriptUniversalPageToken)) {
|
|
1684
|
+
return false;
|
|
1685
|
+
}
|
|
1686
|
+
const fragmentKeys = new Set(this.parseSlashFragmentParams(parsedURL.hash).pairs.map(([key]) => key));
|
|
1687
|
+
const hasParam = (key) => parsedURL.searchParams.has(key) || fragmentKeys.has(key);
|
|
1688
|
+
return (hasParam(stringContants_1.Constants.OmniScriptTypeParam) &&
|
|
1689
|
+
hasParam(stringContants_1.Constants.OmniScriptSubTypeParam) &&
|
|
1690
|
+
hasParam(stringContants_1.Constants.OmniScriptLangParam));
|
|
1691
|
+
}
|
|
1692
|
+
convertToStandardOmniScriptURL(parsedURL) {
|
|
1693
|
+
var _a;
|
|
1694
|
+
const paramRenames = {
|
|
1695
|
+
[stringContants_1.Constants.OmniScriptTypeParam]: stringContants_1.Constants.OmniScriptStandardTypeParam,
|
|
1696
|
+
[stringContants_1.Constants.OmniScriptSubTypeParam]: stringContants_1.Constants.OmniScriptStandardSubTypeParam,
|
|
1697
|
+
[stringContants_1.Constants.OmniScriptLangParam]: stringContants_1.Constants.OmniScriptStandardLanguageParam,
|
|
1698
|
+
[stringContants_1.Constants.OmniScriptLayoutParam]: stringContants_1.Constants.OmniScriptStandardThemeParam,
|
|
1699
|
+
};
|
|
1700
|
+
const paramsToClean = new Set([stringContants_1.Constants.OmniScriptTypeParam, stringContants_1.Constants.OmniScriptSubTypeParam]);
|
|
1701
|
+
// Merge query-string params with fragment params. Query-string entries win on conflict.
|
|
1702
|
+
const mergedEntries = [];
|
|
1703
|
+
const seenKeys = new Set();
|
|
1704
|
+
parsedURL.searchParams.forEach((value, key) => {
|
|
1705
|
+
mergedEntries.push([key, value]);
|
|
1706
|
+
seenKeys.add(key);
|
|
1707
|
+
});
|
|
1708
|
+
for (const [key, value] of this.parseSlashFragmentParams(parsedURL.hash).pairs) {
|
|
1709
|
+
if (!seenKeys.has(key)) {
|
|
1710
|
+
mergedEntries.push([key, value]);
|
|
1711
|
+
seenKeys.add(key);
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
const newSearchParams = new URLSearchParams();
|
|
1715
|
+
for (const [key, value] of mergedEntries) {
|
|
1716
|
+
const newKey = (_a = paramRenames[key]) !== null && _a !== void 0 ? _a : key;
|
|
1717
|
+
const newValue = paramsToClean.has(key) ? this.cleanName(value) : value;
|
|
1718
|
+
newSearchParams.append(newKey, newValue);
|
|
1719
|
+
}
|
|
1720
|
+
return `${stringContants_1.Constants.OmniScriptStandardPagePath}?${newSearchParams.toString()}`;
|
|
1721
|
+
}
|
|
1722
|
+
/**
|
|
1723
|
+
* Parse a slash-separated OmniScript fragment of the form
|
|
1724
|
+
* #/Key1/Value1/Key2/Value2/...
|
|
1725
|
+
* into [key, value] pairs. Tolerates leading `#`, leading `/`, empty values
|
|
1726
|
+
* (consecutive slashes), and a trailing orphan token (which is dropped).
|
|
1727
|
+
*
|
|
1728
|
+
* Tokens with malformed percent sequences (e.g. `Foo%`, `Bar%E2`) are kept
|
|
1729
|
+
* as-is rather than throwing; decodeURIComponent raises URIError on invalid
|
|
1730
|
+
* escape sequences and we don't want one bad token to crash the whole
|
|
1731
|
+
* FlexCard's URL rewrite. The raw (still-encoded) tokens are also returned
|
|
1732
|
+
* via `malformedTokens` so callers can surface them to customers as a
|
|
1733
|
+
* "please verify" warning rather than silently shipping a best-effort guess.
|
|
1734
|
+
*/
|
|
1735
|
+
parseSlashFragmentParams(hash) {
|
|
1736
|
+
if (!hash) {
|
|
1737
|
+
return { pairs: [], malformedTokens: [] };
|
|
1738
|
+
}
|
|
1739
|
+
const trimmed = hash.replace(/^#\/?/, '');
|
|
1740
|
+
if (!trimmed) {
|
|
1741
|
+
return { pairs: [], malformedTokens: [] };
|
|
1742
|
+
}
|
|
1743
|
+
const malformedTokens = [];
|
|
1744
|
+
const tokens = trimmed.split('/').map((t) => {
|
|
1745
|
+
try {
|
|
1746
|
+
return decodeURIComponent(t);
|
|
1747
|
+
}
|
|
1748
|
+
catch {
|
|
1749
|
+
malformedTokens.push(t);
|
|
1750
|
+
return t;
|
|
1751
|
+
}
|
|
1752
|
+
});
|
|
1753
|
+
const pairs = [];
|
|
1754
|
+
for (let i = 0; i + 1 < tokens.length; i += 2) {
|
|
1755
|
+
pairs.push([tokens[i], tokens[i + 1]]);
|
|
1756
|
+
}
|
|
1757
|
+
return { pairs, malformedTokens };
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* Update omniType.Name using registry (handles Type/SubType/Language format)
|
|
1761
|
+
*/
|
|
1762
|
+
updateOmniTypeNameWithRegistry(omniType) {
|
|
1763
|
+
const originalName = omniType.Name || '';
|
|
1764
|
+
const parts = originalName.split('/');
|
|
1765
|
+
if (parts.length >= 3) {
|
|
1766
|
+
// Construct full OmniScript name: Type_SubType_Language
|
|
1767
|
+
const fullOmniScriptName = `${parts[0]}_${parts[1]}_${parts[2]}`;
|
|
1768
|
+
if (this.nameRegistry.hasOmniScriptMapping(fullOmniScriptName)) {
|
|
1769
|
+
// Registry has mapping - extract cleaned parts and convert back to / format
|
|
1770
|
+
const cleanedFullName = this.nameRegistry.getCleanedName(fullOmniScriptName, 'OmniScript');
|
|
1771
|
+
const cleanedParts = cleanedFullName.split('_');
|
|
1772
|
+
if (cleanedParts.length >= 3) {
|
|
1773
|
+
omniType.Name = cleanedParts.join('/');
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
else {
|
|
1777
|
+
// No registry mapping - use original fallback approach
|
|
1778
|
+
logger_1.Logger.logVerbose(`\n${this.messages.getMessage('componentMappingNotFound', ['Omniscript', fullOmniScriptName])}`);
|
|
1779
|
+
omniType.Name =
|
|
1780
|
+
parts.length >= 3
|
|
1781
|
+
? `${this.cleanName(parts[0])}/${this.cleanName(parts[1])}/${parts[2]}`
|
|
1782
|
+
: parts.map((p) => this.cleanName(p)).join('/');
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
else {
|
|
1786
|
+
// Fallback for unexpected format
|
|
1787
|
+
omniType.Name = parts.map((p) => this.cleanName(p)).join('/');
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
/**
|
|
1791
|
+
* Update osName using registry (handles Type/SubType/Language format)
|
|
1792
|
+
*/
|
|
1793
|
+
updateOsNameWithRegistry(stateAction, fieldName) {
|
|
1794
|
+
const originalOsName = stateAction[fieldName];
|
|
1795
|
+
const parts = originalOsName.split('/');
|
|
1796
|
+
if (parts.length >= 3) {
|
|
1797
|
+
// Construct full OmniScript name: Type_SubType_Language
|
|
1798
|
+
const fullOmniScriptName = `${parts[0]}_${parts[1]}_${parts[2]}`;
|
|
1799
|
+
if (this.nameRegistry.hasOmniScriptMapping(fullOmniScriptName)) {
|
|
1800
|
+
// Registry has mapping - extract cleaned parts and convert back to / format
|
|
1801
|
+
const cleanedFullName = this.nameRegistry.getCleanedName(fullOmniScriptName, 'OmniScript');
|
|
1802
|
+
const cleanedParts = cleanedFullName.split('_');
|
|
1803
|
+
if (cleanedParts.length >= 3) {
|
|
1804
|
+
stateAction[fieldName] = cleanedParts.join('/');
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
else {
|
|
1808
|
+
// No registry mapping - use original fallback approach
|
|
1809
|
+
logger_1.Logger.logVerbose(this.messages.getMessage('componentMappingNotFound', ['Omniscript', fullOmniScriptName]));
|
|
1810
|
+
stateAction[fieldName] =
|
|
1811
|
+
parts.length >= 3
|
|
1812
|
+
? `${this.cleanName(parts[0])}/${this.cleanName(parts[1])}/${parts[2]}`
|
|
1813
|
+
: parts.map((p) => this.cleanName(p)).join('/');
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
else {
|
|
1817
|
+
// Fallback for unexpected format
|
|
1818
|
+
stateAction[fieldName] = parts.map((p) => this.cleanName(p)).join('/');
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
// ==================== Assessment Helper Methods ====================
|
|
1822
|
+
/**
|
|
1823
|
+
* Helper method to add OmniScript dependency and warnings during assessment
|
|
1824
|
+
* Handles osName in format "Type/SubType/Language" or "Type/SubType"
|
|
1825
|
+
* @param osName - OmniScript name in format "Type/SubType" or "Type/SubType/Language"
|
|
1826
|
+
* @param flexCardAssessmentInfo - Assessment info to update
|
|
1827
|
+
*/
|
|
1828
|
+
addOmniScriptDependency(osName, flexCardAssessmentInfo) {
|
|
1829
|
+
if (!osName || typeof osName !== 'string') {
|
|
1830
|
+
return;
|
|
1831
|
+
}
|
|
1832
|
+
const parts = osName.split('/');
|
|
1833
|
+
if (parts.length < 2) {
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
const originalOsRef = parts.join('_');
|
|
1837
|
+
// Skip if already processed
|
|
1838
|
+
if (flexCardAssessmentInfo.dependenciesOS.includes(originalOsRef)) {
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1841
|
+
// Clean parts - preserve language (3rd part) as-is
|
|
1842
|
+
const cleanedParts = parts.length >= 3
|
|
1843
|
+
? [this.cleanName(parts[0]), this.cleanName(parts[1]), parts[2]]
|
|
1844
|
+
: parts.map((p) => this.cleanName(p));
|
|
1845
|
+
const cleanedOsRef = cleanedParts.join('_');
|
|
1846
|
+
// Add to dependencies
|
|
1847
|
+
flexCardAssessmentInfo.dependenciesOS.push(originalOsRef);
|
|
1848
|
+
// Add warning if name will change
|
|
1849
|
+
if (originalOsRef !== cleanedOsRef) {
|
|
1850
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('omniScriptNameChangeMessage', [originalOsRef, cleanedOsRef]));
|
|
1851
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Warnings');
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
/**
|
|
1855
|
+
* Helper method to add OmniScript dependency from type/subtype/language fields
|
|
1856
|
+
* @param type - OmniScript type
|
|
1857
|
+
* @param subtype - OmniScript subtype
|
|
1858
|
+
* @param language - OmniScript language (defaults to 'English')
|
|
1859
|
+
* @param flexCardAssessmentInfo - Assessment info to update
|
|
1860
|
+
*/
|
|
1861
|
+
addOmniScriptDependencyFromParts(type, subtype, language, flexCardAssessmentInfo) {
|
|
1862
|
+
if (!type || !subtype) {
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
const lang = language || 'English';
|
|
1866
|
+
const originalOsRef = `${type}_${subtype}_${lang}`;
|
|
1867
|
+
// Skip if already processed
|
|
1868
|
+
if (flexCardAssessmentInfo.dependenciesOS.includes(originalOsRef)) {
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
const cleanedOsRef = `${this.cleanName(type)}_${this.cleanName(subtype)}_${lang}`;
|
|
1872
|
+
// Add to dependencies
|
|
1873
|
+
flexCardAssessmentInfo.dependenciesOS.push(originalOsRef);
|
|
1874
|
+
// Add warning if name will change
|
|
1875
|
+
if (originalOsRef !== cleanedOsRef) {
|
|
1876
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('omniScriptNameChangeMessage', [originalOsRef, cleanedOsRef]));
|
|
1877
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Warnings');
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
/**
|
|
1881
|
+
* Helper method to add DataRaptor dependency and warnings during assessment
|
|
1882
|
+
* @param bundle - DataRaptor bundle name
|
|
1883
|
+
* @param flexCardAssessmentInfo - Assessment info to update
|
|
1884
|
+
*/
|
|
1885
|
+
addDataRaptorDependency(bundle, flexCardAssessmentInfo) {
|
|
1886
|
+
if (!bundle || flexCardAssessmentInfo.dependenciesDR.includes(bundle)) {
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
const cleanedBundle = this.cleanName(bundle);
|
|
1890
|
+
flexCardAssessmentInfo.dependenciesDR.push(bundle);
|
|
1891
|
+
if (bundle !== cleanedBundle) {
|
|
1892
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('dataRaptorNameChangeMessage', [bundle, cleanedBundle]));
|
|
1893
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Warnings');
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
/**
|
|
1897
|
+
* Helper method to add Integration Procedure dependency and warnings during assessment
|
|
1898
|
+
* @param ipMethod - Integration Procedure method name (Type_SubType format)
|
|
1899
|
+
* @param flexCardAssessmentInfo - Assessment info to update
|
|
1900
|
+
*/
|
|
1901
|
+
addIntegrationProcedureDependency(ipMethod, flexCardAssessmentInfo) {
|
|
1902
|
+
if (!ipMethod || flexCardAssessmentInfo.dependenciesIP.includes(ipMethod)) {
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
|
+
const parts = ipMethod.split('_');
|
|
1906
|
+
const cleanedParts = parts.map((p) => this.cleanName(p, true));
|
|
1907
|
+
const cleanedIpMethod = cleanedParts.join('_');
|
|
1908
|
+
flexCardAssessmentInfo.dependenciesIP.push(ipMethod);
|
|
1909
|
+
if (ipMethod !== cleanedIpMethod) {
|
|
1910
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('integrationProcedureNameChangeMessage', [ipMethod, cleanedIpMethod]));
|
|
1911
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Warnings');
|
|
1912
|
+
}
|
|
1913
|
+
// Add manual intervention warning if IP has more than 2 parts
|
|
1914
|
+
if (parts.length > 2) {
|
|
1915
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('integrationProcedureManualUpdateMessage', [ipMethod]));
|
|
1916
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Needs manual intervention');
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Helper method to add FlexCard dependency and warnings during assessment
|
|
1921
|
+
* @param cardName - FlexCard name
|
|
1922
|
+
* @param flexCardAssessmentInfo - Assessment info to update
|
|
1923
|
+
*/
|
|
1924
|
+
addFlexCardDependency(cardName, flexCardAssessmentInfo) {
|
|
1925
|
+
if (!cardName || flexCardAssessmentInfo.dependenciesFC.includes(cardName)) {
|
|
1926
|
+
return;
|
|
1927
|
+
}
|
|
1928
|
+
const cleanedCardName = this.cleanName(cardName);
|
|
1929
|
+
flexCardAssessmentInfo.dependenciesFC.push(cardName);
|
|
1930
|
+
if (cardName !== cleanedCardName) {
|
|
1931
|
+
flexCardAssessmentInfo.warnings.push(this.messages.getMessage('cardNameChangeMessage', [cardName, cleanedCardName]));
|
|
1932
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Warnings');
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
/**
|
|
1936
|
+
* Helper method to flag a Vlocity Action dependency during assessment.
|
|
1937
|
+
* Vlocity Actions are not supported in standard runtime FlexCards, so the
|
|
1938
|
+
* FlexCard cannot be auto-migrated and must be manually reimplemented using
|
|
1939
|
+
* the FlexCard Action (cardAction) feature.
|
|
1940
|
+
*/
|
|
1941
|
+
addVlocityActionDependency(stateAction, flexCardAssessmentInfo) {
|
|
1942
|
+
const actionName = stateAction.name || stateAction.displayName || 'Unnamed Vlocity Action';
|
|
1943
|
+
if (!flexCardAssessmentInfo.dependenciesVlocityAction.includes(actionName)) {
|
|
1944
|
+
flexCardAssessmentInfo.dependenciesVlocityAction.push(actionName);
|
|
1945
|
+
}
|
|
1946
|
+
const warning = this.messages.getMessage('vlocityActionNotSupportedMessage', [actionName]);
|
|
1947
|
+
if (!flexCardAssessmentInfo.warnings.includes(warning)) {
|
|
1948
|
+
flexCardAssessmentInfo.warnings.push(warning);
|
|
1949
|
+
}
|
|
1950
|
+
flexCardAssessmentInfo.migrationStatus = (0, stringUtils_1.getUpdatedAssessmentStatus)(flexCardAssessmentInfo.migrationStatus, 'Needs manual intervention');
|
|
1951
|
+
}
|
|
1952
|
+
// ==================== End Assessment Helper Methods ====================
|
|
677
1953
|
getCardFields() {
|
|
678
|
-
return
|
|
1954
|
+
return this.IS_STANDARD_DATA_MODEL
|
|
1955
|
+
? Object.values(VlocityCard_1.default).filter((value) => value !== '')
|
|
1956
|
+
: Object.keys(VlocityCard_1.default);
|
|
1957
|
+
}
|
|
1958
|
+
getFieldKey(fieldName) {
|
|
1959
|
+
return this.IS_STANDARD_DATA_MODEL ? VlocityCard_1.default[fieldName] : this.namespacePrefix + fieldName;
|
|
1960
|
+
}
|
|
1961
|
+
getQueryNamespace() {
|
|
1962
|
+
return this.IS_STANDARD_DATA_MODEL ? '' : this.namespace;
|
|
1963
|
+
}
|
|
1964
|
+
getCardObjectName() {
|
|
1965
|
+
return this.IS_STANDARD_DATA_MODEL ? CardMigrationTool.OMNIUICARD_NAME : CardMigrationTool.VLOCITYCARD_NAME;
|
|
1966
|
+
}
|
|
1967
|
+
/**
|
|
1968
|
+
* Check if a FlexCard has dependencies on Angular OmniScripts
|
|
1969
|
+
*/
|
|
1970
|
+
hasAngularOmniScriptDependencies(card) {
|
|
1971
|
+
try {
|
|
1972
|
+
const definition = JSON.parse(card[this.getFieldKey('Definition__c')] || '{}');
|
|
1973
|
+
if (definition && definition.states) {
|
|
1974
|
+
for (const state of definition.states) {
|
|
1975
|
+
// Check direct OmniScript references in states
|
|
1976
|
+
if (state.omniscripts && Array.isArray(state.omniscripts)) {
|
|
1977
|
+
for (const os of state.omniscripts) {
|
|
1978
|
+
if (os.type && os.subtype) {
|
|
1979
|
+
const osRef = `${os.type}_${os.subtype}_${os.language || 'English'}`;
|
|
1980
|
+
if (this.nameRegistry.isAngularOmniScript(osRef)) {
|
|
1981
|
+
return true;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
// Check OmniScript references in component actions
|
|
1987
|
+
if (state.components) {
|
|
1988
|
+
for (const componentKey in state.components) {
|
|
1989
|
+
if (state.components.hasOwnProperty(componentKey)) {
|
|
1990
|
+
const component = state.components[componentKey];
|
|
1991
|
+
if (this.componentHasAngularOmniScriptDependency(component)) {
|
|
1992
|
+
return true;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
// Check OmniScript references in events[] array
|
|
2000
|
+
if (definition && definition.events && Array.isArray(definition.events)) {
|
|
2001
|
+
if (this.eventsHaveAngularOmniScriptDependency(definition.events)) {
|
|
2002
|
+
return true;
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
catch (err) {
|
|
2007
|
+
logger_1.Logger.error(`Error checking Angular dependencies for card ${card['Name']}: ${err.message}`);
|
|
2008
|
+
}
|
|
2009
|
+
return false;
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Check if events array has Angular OmniScript dependencies
|
|
2013
|
+
*/
|
|
2014
|
+
eventsHaveAngularOmniScriptDependency(events) {
|
|
2015
|
+
for (const event of events) {
|
|
2016
|
+
if (!event.actionList || !Array.isArray(event.actionList)) {
|
|
2017
|
+
continue;
|
|
2018
|
+
}
|
|
2019
|
+
for (const action of event.actionList) {
|
|
2020
|
+
if (!action.stateAction) {
|
|
2021
|
+
continue;
|
|
2022
|
+
}
|
|
2023
|
+
const stateAction = action.stateAction;
|
|
2024
|
+
// Check omniType.Name
|
|
2025
|
+
if (stateAction.omniType) {
|
|
2026
|
+
if (this.checkOmniTypeForAngular(stateAction.omniType)) {
|
|
2027
|
+
return true;
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
if (this.hasOmniscriptFlyoutDependency(stateAction)) {
|
|
2031
|
+
if (this.checkOsNameForAngular(stateAction.osName)) {
|
|
2032
|
+
return true;
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
return false;
|
|
2038
|
+
}
|
|
2039
|
+
hasOmniscriptFlyoutDependency(stateAction) {
|
|
2040
|
+
return (stateAction.type === stringContants_1.Constants.Flyout &&
|
|
2041
|
+
stateAction.flyoutType === stringContants_1.Constants.OmniScriptPluralName &&
|
|
2042
|
+
stateAction.osName);
|
|
2043
|
+
}
|
|
2044
|
+
hasFlexCardFlyoutDependency(stateAction) {
|
|
2045
|
+
return (stateAction.type === stringContants_1.Constants.Flyout && stateAction.flyoutType === stringContants_1.Constants.ChildCard && stateAction.flyoutLwc);
|
|
2046
|
+
}
|
|
2047
|
+
hasCustomLwcFlyoutDependency(stateAction) {
|
|
2048
|
+
return (stateAction.type === stringContants_1.Constants.Flyout && stateAction.flyoutType === stringContants_1.Constants.CustomLwc && stateAction.flyoutLwc);
|
|
2049
|
+
}
|
|
2050
|
+
hasFlyoutLwc(stateAction) {
|
|
2051
|
+
return stateAction.type === stringContants_1.Constants.Flyout && stateAction.flyoutLwc;
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
* Recursively check if a component has Angular Omniscript dependencies
|
|
2055
|
+
*/
|
|
2056
|
+
componentHasAngularOmniScriptDependency(component) {
|
|
2057
|
+
// Pattern 1: Handle action elements with actionList (like migration logic)
|
|
2058
|
+
if (component.element === 'action' && component.property && component.property.actionList) {
|
|
2059
|
+
for (const action of component.property.actionList) {
|
|
2060
|
+
if (action.stateAction) {
|
|
2061
|
+
// Case 1: Direct OmniScript reference with type check
|
|
2062
|
+
if (action.stateAction.type === stringContants_1.Constants.OmniScriptComponentName && action.stateAction.omniType) {
|
|
2063
|
+
if (this.checkOmniTypeForAngular(action.stateAction.omniType)) {
|
|
2064
|
+
return true;
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
// Case 1b: Direct OmniScript reference without type check (for test compatibility)
|
|
2068
|
+
else if (action.stateAction.omniType && !action.stateAction.type) {
|
|
2069
|
+
if (this.checkOmniTypeForAngular(action.stateAction.omniType)) {
|
|
2070
|
+
return true;
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
// Case 2: Flyout OmniScript reference
|
|
2074
|
+
else if (this.hasOmniscriptFlyoutDependency(action.stateAction)) {
|
|
2075
|
+
if (this.checkOsNameForAngular(action.stateAction.osName)) {
|
|
2076
|
+
return true;
|
|
2077
|
+
}
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
// Pattern 2: Handle standard component actions (like migration logic)
|
|
2083
|
+
if (component.actions && Array.isArray(component.actions)) {
|
|
2084
|
+
for (const action of component.actions) {
|
|
2085
|
+
if (action.stateAction && action.stateAction.omniType) {
|
|
2086
|
+
if (this.checkOmniTypeForAngular(action.stateAction.omniType)) {
|
|
2087
|
+
return true;
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
// Pattern 3: Handle direct stateAction on component property (like migration logic)
|
|
2093
|
+
if (component.property && component.property.stateAction) {
|
|
2094
|
+
if (component.property.stateAction.omniType) {
|
|
2095
|
+
if (this.checkOmniTypeForAngular(component.property.stateAction.omniType)) {
|
|
2096
|
+
return true;
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
if (this.hasOmniscriptFlyoutDependency(component.property.stateAction)) {
|
|
2100
|
+
if (this.checkOsNameForAngular(component.property.stateAction.osName)) {
|
|
2101
|
+
return true;
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
// Pattern 4: Handle omni-flyout elements (for test compatibility)
|
|
2106
|
+
if (component.element === stringContants_1.Constants.OmniFlyout && component.property && component.property.flyoutOmniScript) {
|
|
2107
|
+
if (component.property.flyoutOmniScript.osName) {
|
|
2108
|
+
if (this.checkOsNameForAngular(component.property.flyoutOmniScript.osName)) {
|
|
2109
|
+
return true;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
// Recursively check child components
|
|
2114
|
+
if (component.children && Array.isArray(component.children)) {
|
|
2115
|
+
for (const child of component.children) {
|
|
2116
|
+
if (this.componentHasAngularOmniScriptDependency(child)) {
|
|
2117
|
+
return true;
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
return false;
|
|
2122
|
+
}
|
|
2123
|
+
/**
|
|
2124
|
+
* Check if an omniType references an Angular OmniScript
|
|
2125
|
+
* Handles both string format and object with Name property
|
|
2126
|
+
*/
|
|
2127
|
+
checkOmniTypeForAngular(omniType) {
|
|
2128
|
+
if (!omniType) {
|
|
2129
|
+
return false;
|
|
2130
|
+
}
|
|
2131
|
+
// Check if IsWebCompEnabled is explicitly false (Angular OmniScript)
|
|
2132
|
+
if (typeof omniType === 'object' && omniType.IsWebCompEnabled === false) {
|
|
2133
|
+
return true;
|
|
2134
|
+
}
|
|
2135
|
+
let omniTypeName;
|
|
2136
|
+
// Handle both string omniType and object with Name property
|
|
2137
|
+
if (typeof omniType === 'string') {
|
|
2138
|
+
omniTypeName = omniType;
|
|
2139
|
+
}
|
|
2140
|
+
else if (omniType.Name && typeof omniType.Name === 'string') {
|
|
2141
|
+
omniTypeName = omniType.Name;
|
|
2142
|
+
}
|
|
2143
|
+
else {
|
|
2144
|
+
return false;
|
|
2145
|
+
}
|
|
2146
|
+
const parts = omniTypeName.split('/');
|
|
2147
|
+
if (parts.length >= 3) {
|
|
2148
|
+
// Construct full OmniScript name: Type_SubType_Language
|
|
2149
|
+
const fullOmniScriptName = `${parts[0]}_${parts[1]}_${parts[2]}`;
|
|
2150
|
+
return this.nameRegistry.isAngularOmniScript(fullOmniScriptName);
|
|
2151
|
+
}
|
|
2152
|
+
return false;
|
|
2153
|
+
}
|
|
2154
|
+
/**
|
|
2155
|
+
* Check if an osName string references an Angular OmniScript
|
|
2156
|
+
* Handles Type/SubType/Language format in string
|
|
2157
|
+
*/
|
|
2158
|
+
checkOsNameForAngular(osName) {
|
|
2159
|
+
if (!osName || typeof osName !== 'string') {
|
|
2160
|
+
return false;
|
|
2161
|
+
}
|
|
2162
|
+
const parts = osName.split('/');
|
|
2163
|
+
if (parts.length >= 3) {
|
|
2164
|
+
// Construct full OmniScript name: Type_SubType_Language
|
|
2165
|
+
const fullOmniScriptName = `${parts[0]}_${parts[1]}_${parts[2]}`;
|
|
2166
|
+
return this.nameRegistry.isAngularOmniScript(fullOmniScriptName);
|
|
2167
|
+
}
|
|
2168
|
+
return false;
|
|
2169
|
+
}
|
|
2170
|
+
/**
|
|
2171
|
+
* Ensures that the FlexCard Definition includes required Lightning Community targets
|
|
2172
|
+
* Adds "lightningCommunity__Page" and "lightningCommunity__Default" if missing
|
|
2173
|
+
* This is needed as vlocity wrapper can have flexcard which is unpublished but omniwapper needs published card
|
|
2174
|
+
*/
|
|
2175
|
+
ensureCommunityTargets(mappedObject, isCardActive) {
|
|
2176
|
+
if (!isCardActive) {
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
const definition = JSON.parse(mappedObject[VlocityCard_1.default.Definition__c] || '{}');
|
|
2180
|
+
if (!definition || !definition.xmlObject) {
|
|
2181
|
+
return;
|
|
2182
|
+
}
|
|
2183
|
+
// Initialize targets structure if it doesn't exist
|
|
2184
|
+
if (!definition.xmlObject.targets) {
|
|
2185
|
+
definition.xmlObject.targets = { target: [] };
|
|
2186
|
+
}
|
|
2187
|
+
// Ensure target is an array
|
|
2188
|
+
if (!Array.isArray(definition.xmlObject.targets.target)) {
|
|
2189
|
+
definition.xmlObject.targets.target = [];
|
|
2190
|
+
}
|
|
2191
|
+
const requiredTargets = [
|
|
2192
|
+
'lightning__RecordPage',
|
|
2193
|
+
'lightning__AppPage',
|
|
2194
|
+
'lightning__HomePage',
|
|
2195
|
+
'lightningCommunity__Page',
|
|
2196
|
+
'lightningCommunity__Default',
|
|
2197
|
+
];
|
|
2198
|
+
const currentTargets = definition.xmlObject.targets.target;
|
|
2199
|
+
// Add missing community targets
|
|
2200
|
+
for (const requiredTarget of requiredTargets) {
|
|
2201
|
+
if (!currentTargets.includes(requiredTarget)) {
|
|
2202
|
+
currentTargets.push(requiredTarget);
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
logger_1.Logger.logVerbose(`Targets processed`);
|
|
2206
|
+
// Save the updated definition back to the mappedObject
|
|
2207
|
+
mappedObject[VlocityCard_1.default.Definition__c] = JSON.stringify(definition);
|
|
2208
|
+
}
|
|
2209
|
+
/**
|
|
2210
|
+
* Prioritizes FlexCards by name characteristics:
|
|
2211
|
+
* - Clean names (alphanumeric only) are processed first
|
|
2212
|
+
* - Names with special characters are processed after
|
|
2213
|
+
* This avoids naming conflicts during migration when special characters are cleaned
|
|
2214
|
+
*/
|
|
2215
|
+
prioritizeFlexCardsWithoutSpecialCharacters(flexCards) {
|
|
2216
|
+
const nameField = this.getFieldKey('Name');
|
|
2217
|
+
return (0, recordPrioritization_1.prioritizeCleanNamesFirst)(flexCards, nameField);
|
|
679
2218
|
}
|
|
680
2219
|
}
|
|
681
2220
|
exports.CardMigrationTool = CardMigrationTool;
|
|
682
2221
|
CardMigrationTool.VLOCITYCARD_NAME = 'VlocityCard__c';
|
|
683
2222
|
CardMigrationTool.OMNIUICARD_NAME = 'OmniUiCard';
|
|
684
2223
|
CardMigrationTool.VERSION_PROP = 'Version__c';
|
|
2224
|
+
CardMigrationTool.URL_PARSE_BASE = 'https://placeholder.local';
|
|
685
2225
|
//# sourceMappingURL=flexcard.js.map
|