lwc-convert 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +719 -0
- package/dist/cli/commands/aura.d.ts +6 -0
- package/dist/cli/commands/aura.d.ts.map +1 -0
- package/dist/cli/commands/aura.js +225 -0
- package/dist/cli/commands/aura.js.map +1 -0
- package/dist/cli/commands/vf.d.ts +6 -0
- package/dist/cli/commands/vf.d.ts.map +1 -0
- package/dist/cli/commands/vf.js +218 -0
- package/dist/cli/commands/vf.js.map +1 -0
- package/dist/cli/interactive.d.ts +20 -0
- package/dist/cli/interactive.d.ts.map +1 -0
- package/dist/cli/interactive.js +577 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli/options.d.ts +21 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +24 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/generators/full-conversion.d.ts +41 -0
- package/dist/generators/full-conversion.d.ts.map +1 -0
- package/dist/generators/full-conversion.js +538 -0
- package/dist/generators/full-conversion.js.map +1 -0
- package/dist/generators/scaffolding.d.ts +40 -0
- package/dist/generators/scaffolding.d.ts.map +1 -0
- package/dist/generators/scaffolding.js +716 -0
- package/dist/generators/scaffolding.js.map +1 -0
- package/dist/generators/test-comparison.d.ts +47 -0
- package/dist/generators/test-comparison.d.ts.map +1 -0
- package/dist/generators/test-comparison.js +855 -0
- package/dist/generators/test-comparison.js.map +1 -0
- package/dist/generators/test-generator.d.ts +27 -0
- package/dist/generators/test-generator.d.ts.map +1 -0
- package/dist/generators/test-generator.js +385 -0
- package/dist/generators/test-generator.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +226 -0
- package/dist/index.js.map +1 -0
- package/dist/mappings/aura-to-lwc.json +321 -0
- package/dist/mappings/vf-to-lwc.json +354 -0
- package/dist/parsers/aura/controller-parser.d.ts +36 -0
- package/dist/parsers/aura/controller-parser.d.ts.map +1 -0
- package/dist/parsers/aura/controller-parser.js +269 -0
- package/dist/parsers/aura/controller-parser.js.map +1 -0
- package/dist/parsers/aura/helper-parser.d.ts +21 -0
- package/dist/parsers/aura/helper-parser.d.ts.map +1 -0
- package/dist/parsers/aura/helper-parser.js +173 -0
- package/dist/parsers/aura/helper-parser.js.map +1 -0
- package/dist/parsers/aura/markup-parser.d.ts +59 -0
- package/dist/parsers/aura/markup-parser.d.ts.map +1 -0
- package/dist/parsers/aura/markup-parser.js +279 -0
- package/dist/parsers/aura/markup-parser.js.map +1 -0
- package/dist/parsers/aura/style-parser.d.ts +37 -0
- package/dist/parsers/aura/style-parser.d.ts.map +1 -0
- package/dist/parsers/aura/style-parser.js +151 -0
- package/dist/parsers/aura/style-parser.js.map +1 -0
- package/dist/parsers/vf/apex-parser.d.ts +51 -0
- package/dist/parsers/vf/apex-parser.d.ts.map +1 -0
- package/dist/parsers/vf/apex-parser.js +251 -0
- package/dist/parsers/vf/apex-parser.js.map +1 -0
- package/dist/parsers/vf/page-parser.d.ts +61 -0
- package/dist/parsers/vf/page-parser.d.ts.map +1 -0
- package/dist/parsers/vf/page-parser.js +403 -0
- package/dist/parsers/vf/page-parser.js.map +1 -0
- package/dist/transformers/aura-to-lwc/controller.d.ts +36 -0
- package/dist/transformers/aura-to-lwc/controller.d.ts.map +1 -0
- package/dist/transformers/aura-to-lwc/controller.js +372 -0
- package/dist/transformers/aura-to-lwc/controller.js.map +1 -0
- package/dist/transformers/aura-to-lwc/events.d.ts +47 -0
- package/dist/transformers/aura-to-lwc/events.d.ts.map +1 -0
- package/dist/transformers/aura-to-lwc/events.js +262 -0
- package/dist/transformers/aura-to-lwc/events.js.map +1 -0
- package/dist/transformers/aura-to-lwc/markup.d.ts +51 -0
- package/dist/transformers/aura-to-lwc/markup.d.ts.map +1 -0
- package/dist/transformers/aura-to-lwc/markup.js +465 -0
- package/dist/transformers/aura-to-lwc/markup.js.map +1 -0
- package/dist/transformers/vf-to-lwc/components.d.ts +40 -0
- package/dist/transformers/vf-to-lwc/components.d.ts.map +1 -0
- package/dist/transformers/vf-to-lwc/components.js +374 -0
- package/dist/transformers/vf-to-lwc/components.js.map +1 -0
- package/dist/transformers/vf-to-lwc/data-binding.d.ts +53 -0
- package/dist/transformers/vf-to-lwc/data-binding.d.ts.map +1 -0
- package/dist/transformers/vf-to-lwc/data-binding.js +660 -0
- package/dist/transformers/vf-to-lwc/data-binding.js.map +1 -0
- package/dist/transformers/vf-to-lwc/markup.d.ts +44 -0
- package/dist/transformers/vf-to-lwc/markup.d.ts.map +1 -0
- package/dist/transformers/vf-to-lwc/markup.js +816 -0
- package/dist/transformers/vf-to-lwc/markup.js.map +1 -0
- package/dist/utils/confidence-scorer.d.ts +100 -0
- package/dist/utils/confidence-scorer.d.ts.map +1 -0
- package/dist/utils/confidence-scorer.js +358 -0
- package/dist/utils/confidence-scorer.js.map +1 -0
- package/dist/utils/file-io.d.ts +62 -0
- package/dist/utils/file-io.d.ts.map +1 -0
- package/dist/utils/file-io.js +248 -0
- package/dist/utils/file-io.js.map +1 -0
- package/dist/utils/logger.d.ts +34 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +130 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/open-folder.d.ts +9 -0
- package/dist/utils/open-folder.d.ts.map +1 -0
- package/dist/utils/open-folder.js +76 -0
- package/dist/utils/open-folder.js.map +1 -0
- package/dist/utils/path-resolver.d.ts +29 -0
- package/dist/utils/path-resolver.d.ts.map +1 -0
- package/dist/utils/path-resolver.js +240 -0
- package/dist/utils/path-resolver.js.map +1 -0
- package/dist/utils/session-store.d.ts +158 -0
- package/dist/utils/session-store.d.ts.map +1 -0
- package/dist/utils/session-store.js +518 -0
- package/dist/utils/session-store.js.map +1 -0
- package/dist/utils/vf-controller-resolver.d.ts +36 -0
- package/dist/utils/vf-controller-resolver.d.ts.map +1 -0
- package/dist/utils/vf-controller-resolver.js +162 -0
- package/dist/utils/vf-controller-resolver.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,716 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Generate LWC scaffolding with TODO comments from Aura or VF components
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateAuraScaffolding = generateAuraScaffolding;
|
|
7
|
+
exports.generateVfScaffolding = generateVfScaffolding;
|
|
8
|
+
const style_parser_1 = require("../parsers/aura/style-parser");
|
|
9
|
+
const data_binding_1 = require("../transformers/vf-to-lwc/data-binding");
|
|
10
|
+
const test_generator_1 = require("./test-generator");
|
|
11
|
+
const test_comparison_1 = require("./test-comparison");
|
|
12
|
+
const file_io_1 = require("../utils/file-io");
|
|
13
|
+
const logger_1 = require("../utils/logger");
|
|
14
|
+
/**
|
|
15
|
+
* Generate LWC meta XML file content
|
|
16
|
+
*/
|
|
17
|
+
function generateMetaXml(_componentName, options) {
|
|
18
|
+
const { apiVersion = '59.0', isExposed = true, targets = ['lightning__RecordPage', 'lightning__AppPage', 'lightning__HomePage'], description, } = options || {};
|
|
19
|
+
let xml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
20
|
+
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
21
|
+
<apiVersion>${apiVersion}</apiVersion>
|
|
22
|
+
<isExposed>${isExposed}</isExposed>`;
|
|
23
|
+
if (description) {
|
|
24
|
+
xml += `\n <description>${description}</description>`;
|
|
25
|
+
}
|
|
26
|
+
if (targets.length > 0) {
|
|
27
|
+
xml += `\n <targets>`;
|
|
28
|
+
for (const target of targets) {
|
|
29
|
+
xml += `\n <target>${target}</target>`;
|
|
30
|
+
}
|
|
31
|
+
xml += `\n </targets>`;
|
|
32
|
+
}
|
|
33
|
+
xml += `\n</LightningComponentBundle>\n`;
|
|
34
|
+
return xml;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generate scaffolding JS from Aura parsed data
|
|
38
|
+
*/
|
|
39
|
+
function generateAuraScaffoldingJs(markup, transformedMarkup, controller, helper) {
|
|
40
|
+
const warnings = [];
|
|
41
|
+
const className = (0, file_io_1.toPascalCase)(markup.componentName);
|
|
42
|
+
const imports = ['LightningElement'];
|
|
43
|
+
const wireImports = [];
|
|
44
|
+
const lmsImports = [];
|
|
45
|
+
const schemaImports = [];
|
|
46
|
+
const channelImports = [];
|
|
47
|
+
const apiProperties = [];
|
|
48
|
+
const reactiveProperties = [];
|
|
49
|
+
const wireDeclarations = [];
|
|
50
|
+
const methodStubs = [];
|
|
51
|
+
const apexImports = [];
|
|
52
|
+
// Track which attributes are used by force:recordData (these should be private)
|
|
53
|
+
const recordDataBindings = new Set();
|
|
54
|
+
for (const rds of transformedMarkup.recordDataServices) {
|
|
55
|
+
recordDataBindings.add(rds.recordIdBinding);
|
|
56
|
+
if (rds.targetFields)
|
|
57
|
+
recordDataBindings.add(rds.targetFields);
|
|
58
|
+
}
|
|
59
|
+
// Process attributes -> properties
|
|
60
|
+
for (const attr of markup.attributes) {
|
|
61
|
+
// Check if this attribute is used internally by force:recordData or LMS
|
|
62
|
+
const usedByRecordData = recordDataBindings.has(attr.name);
|
|
63
|
+
const isPublic = (!attr.access || attr.access === 'public' || attr.access === 'global') && !usedByRecordData;
|
|
64
|
+
let propCode = '';
|
|
65
|
+
if (attr.description) {
|
|
66
|
+
propCode += ` // ${attr.description}\n`;
|
|
67
|
+
}
|
|
68
|
+
if (isPublic) {
|
|
69
|
+
propCode += ` @api ${attr.name}`;
|
|
70
|
+
if (!imports.includes('api'))
|
|
71
|
+
imports.push('api');
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Private property - don't use @api
|
|
75
|
+
propCode += ` ${attr.name}`;
|
|
76
|
+
}
|
|
77
|
+
// Only add default value if it exists and is not empty
|
|
78
|
+
if (attr.default !== undefined && attr.default !== '' && attr.default.trim() !== '') {
|
|
79
|
+
propCode += ` = ${attr.default}`;
|
|
80
|
+
}
|
|
81
|
+
propCode += ';';
|
|
82
|
+
if (isPublic) {
|
|
83
|
+
apiProperties.push(propCode);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
reactiveProperties.push(propCode);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Generate LMS code from lightning:messageChannel
|
|
90
|
+
if (transformedMarkup.lmsChannels.length > 0) {
|
|
91
|
+
if (!imports.includes('wire'))
|
|
92
|
+
imports.push('wire');
|
|
93
|
+
for (const lms of transformedMarkup.lmsChannels) {
|
|
94
|
+
const channelVar = lms.channelName.replace(/__c$/i, '').toUpperCase() + '_CHANNEL';
|
|
95
|
+
channelImports.push(`import ${channelVar} from '@salesforce/messageChannel/${lms.channelName}';`);
|
|
96
|
+
// Add wire for message context (needed for both publish and subscribe)
|
|
97
|
+
wireDeclarations.push(` @wire(MessageContext)
|
|
98
|
+
messageContext;`);
|
|
99
|
+
// Check if this is publisher-only (no onMessage handler)
|
|
100
|
+
if (lms.isPublisherOnly) {
|
|
101
|
+
// Publisher-only pattern - just need publish(), no subscribe/unsubscribe
|
|
102
|
+
lmsImports.push('publish', 'MessageContext');
|
|
103
|
+
// Add publish method
|
|
104
|
+
methodStubs.push(` // LMS: Publish to ${lms.channelName}
|
|
105
|
+
// Call this method to publish a message, e.g., from an onclick handler
|
|
106
|
+
publishMessage(payload) {
|
|
107
|
+
const message = {
|
|
108
|
+
recordId: payload.recordId,
|
|
109
|
+
// TODO: Add other message fields as needed
|
|
110
|
+
};
|
|
111
|
+
publish(this.messageContext, ${channelVar}, message);
|
|
112
|
+
}`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Subscriber pattern - needs full subscribe/unsubscribe lifecycle
|
|
116
|
+
lmsImports.push('publish', 'subscribe', 'unsubscribe', 'MessageContext');
|
|
117
|
+
// Add subscription property
|
|
118
|
+
reactiveProperties.push(` // LMS subscription reference
|
|
119
|
+
_subscription = null;`);
|
|
120
|
+
// Generate handleMessage with converted controller logic
|
|
121
|
+
let handleMessageBody = '// TODO: Process message payload';
|
|
122
|
+
if (lms.onMessageHandler && controller) {
|
|
123
|
+
const handlerFunc = controller.functions.find(f => f.name === lms.onMessageHandler);
|
|
124
|
+
if (handlerFunc) {
|
|
125
|
+
// Convert Aura controller code to LWC
|
|
126
|
+
handleMessageBody = convertAuraControllerToLwc(handlerFunc, markup);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Add LMS lifecycle methods for subscriber
|
|
130
|
+
methodStubs.push(` // LMS: Subscribe to ${lms.channelName}
|
|
131
|
+
connectedCallback() {
|
|
132
|
+
this.subscribeToMessageChannel();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
disconnectedCallback() {
|
|
136
|
+
this.unsubscribeFromMessageChannel();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
subscribeToMessageChannel() {
|
|
140
|
+
if (!this._subscription) {
|
|
141
|
+
this._subscription = subscribe(
|
|
142
|
+
this.messageContext,
|
|
143
|
+
${channelVar},
|
|
144
|
+
(message) => this.handleMessage(message)
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
unsubscribeFromMessageChannel() {
|
|
150
|
+
unsubscribe(this._subscription);
|
|
151
|
+
this._subscription = null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
handleMessage(message) {
|
|
155
|
+
${handleMessageBody}
|
|
156
|
+
}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Generate @wire(getRecord) from force:recordData
|
|
161
|
+
if (transformedMarkup.recordDataServices.length > 0) {
|
|
162
|
+
wireImports.push('getRecord', 'getFieldValue');
|
|
163
|
+
if (!imports.includes('wire'))
|
|
164
|
+
imports.push('wire');
|
|
165
|
+
for (const rds of transformedMarkup.recordDataServices) {
|
|
166
|
+
const targetProp = rds.targetFields || 'record';
|
|
167
|
+
// Generate field constants and imports (active, not commented)
|
|
168
|
+
const fieldConstants = [];
|
|
169
|
+
const fieldImportStatements = [];
|
|
170
|
+
for (const field of rds.fields) {
|
|
171
|
+
const fieldConst = field.toUpperCase().replace(/[^A-Z0-9_]/g, '_') + '_FIELD';
|
|
172
|
+
// Use Contact as default - can be changed based on context
|
|
173
|
+
fieldImportStatements.push(`import ${fieldConst} from '@salesforce/schema/Contact.${field}';`);
|
|
174
|
+
fieldConstants.push(fieldConst);
|
|
175
|
+
}
|
|
176
|
+
// Add the imports to schema imports
|
|
177
|
+
schemaImports.push(...fieldImportStatements);
|
|
178
|
+
// Generate wire adapter with proper field constants
|
|
179
|
+
const fieldsArray = fieldConstants.join(', ');
|
|
180
|
+
// Generate individual getters for each field (proper LWC pattern)
|
|
181
|
+
const fieldGetters = rds.fields.map((field, index) => {
|
|
182
|
+
const getterName = field.charAt(0).toLowerCase() + field.slice(1).replace(/__c$/i, '');
|
|
183
|
+
const fieldConst = fieldConstants[index];
|
|
184
|
+
return ` get ${getterName}() {
|
|
185
|
+
return this.${targetProp}?.data
|
|
186
|
+
? getFieldValue(this.${targetProp}.data, ${fieldConst})
|
|
187
|
+
: undefined;
|
|
188
|
+
}`;
|
|
189
|
+
}).join('\n\n');
|
|
190
|
+
wireDeclarations.push(` // Converted from force:recordData (aura:id="${rds.auraId}")
|
|
191
|
+
@wire(getRecord, { recordId: '$${rds.recordIdBinding}', fields: [${fieldsArray}] })
|
|
192
|
+
${targetProp};
|
|
193
|
+
|
|
194
|
+
// Error getter for wire errors
|
|
195
|
+
get ${targetProp}Error() {
|
|
196
|
+
return this.${targetProp}?.error;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
${fieldGetters}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Process handlers for lifecycle and event methods
|
|
203
|
+
// Check for LMS subscriber lifecycle (subscriber pattern uses connected/disconnected)
|
|
204
|
+
const hasLmsSubscriberLifecycle = transformedMarkup.lmsChannels.some(lms => !lms.isPublisherOnly);
|
|
205
|
+
const initHandler = markup.handlers.find((h) => h.name === 'init');
|
|
206
|
+
const renderHandler = markup.handlers.find((h) => h.name === 'render' || h.name === 'afterRender');
|
|
207
|
+
const destroyHandler = markup.handlers.find((h) => h.name === 'destroy');
|
|
208
|
+
// Find controller functions referenced by handlers
|
|
209
|
+
const controllerFunctions = new Map();
|
|
210
|
+
if (controller) {
|
|
211
|
+
for (const func of controller.functions) {
|
|
212
|
+
controllerFunctions.set(func.name, func.body);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Check if init handler makes Apex calls - if so, convert to @wire instead of connectedCallback
|
|
216
|
+
let initHandlerHasApexCalls = false;
|
|
217
|
+
let initApexMethods = [];
|
|
218
|
+
if (initHandler && controller) {
|
|
219
|
+
const funcName = initHandler.action.replace('{!c.', '').replace('}', '');
|
|
220
|
+
const initFunc = controller.functions.find(f => f.name === funcName);
|
|
221
|
+
if (initFunc && initFunc.serverCalls.length > 0) {
|
|
222
|
+
initHandlerHasApexCalls = true;
|
|
223
|
+
initApexMethods = initFunc.serverCalls
|
|
224
|
+
.filter(sc => sc.controllerMethod)
|
|
225
|
+
.map(sc => sc.controllerMethod);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// If init handler calls Apex, generate @wire adapter instead of connectedCallback
|
|
229
|
+
if (initHandlerHasApexCalls && initApexMethods.length > 0) {
|
|
230
|
+
for (const apexMethod of initApexMethods) {
|
|
231
|
+
// Generate wire adapter for the Apex call
|
|
232
|
+
const wireProp = apexMethod.charAt(0).toLowerCase() + apexMethod.slice(1) + 'Result';
|
|
233
|
+
const dataProperty = apexMethod.charAt(0).toLowerCase() + apexMethod.slice(1);
|
|
234
|
+
// Add the Apex wire import
|
|
235
|
+
if (markup.controller) {
|
|
236
|
+
apexImports.push(apexMethod);
|
|
237
|
+
}
|
|
238
|
+
wireDeclarations.push(` // Converted from init handler Apex call - data loads automatically
|
|
239
|
+
@wire(${apexMethod})
|
|
240
|
+
${wireProp};
|
|
241
|
+
|
|
242
|
+
// Getter to safely access wire data
|
|
243
|
+
get ${dataProperty}() {
|
|
244
|
+
return this.${wireProp}?.data;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
get ${wireProp}Error() {
|
|
248
|
+
return this.${wireProp}?.error;
|
|
249
|
+
}`);
|
|
250
|
+
}
|
|
251
|
+
warnings.push('Init handler Apex call converted to @wire - data loads automatically, no connectedCallback needed');
|
|
252
|
+
}
|
|
253
|
+
else if (initHandler && !hasLmsSubscriberLifecycle) {
|
|
254
|
+
// Regular init handler without Apex calls - use connectedCallback
|
|
255
|
+
const funcName = initHandler.action.replace('{!c.', '').replace('}', '');
|
|
256
|
+
methodStubs.push(` // TODO: Migrate logic from Aura init handler (${funcName})
|
|
257
|
+
connectedCallback() {
|
|
258
|
+
// Original init handler logic goes here
|
|
259
|
+
${controllerFunctions.has(funcName) ? '// Original body available in controller' : ''}
|
|
260
|
+
}`);
|
|
261
|
+
}
|
|
262
|
+
if (renderHandler) {
|
|
263
|
+
methodStubs.push(` // TODO: Migrate logic from Aura render/afterRender handler
|
|
264
|
+
// WARNING: renderedCallback fires on every render - use flag for one-time logic
|
|
265
|
+
isRendered = false;
|
|
266
|
+
|
|
267
|
+
renderedCallback() {
|
|
268
|
+
if (this.isRendered) return;
|
|
269
|
+
this.isRendered = true;
|
|
270
|
+
// Original render handler logic goes here
|
|
271
|
+
}`);
|
|
272
|
+
warnings.push('Render handler converted - renderedCallback fires on every render, not just initial');
|
|
273
|
+
}
|
|
274
|
+
if (destroyHandler && !hasLmsSubscriberLifecycle) {
|
|
275
|
+
methodStubs.push(` // TODO: Migrate cleanup logic from Aura destroy handler
|
|
276
|
+
disconnectedCallback() {
|
|
277
|
+
// Clean up event listeners, intervals, subscriptions
|
|
278
|
+
}`);
|
|
279
|
+
}
|
|
280
|
+
// Process controller functions as method stubs
|
|
281
|
+
if (controller) {
|
|
282
|
+
// Get names of handlers already processed
|
|
283
|
+
const processedHandlers = new Set();
|
|
284
|
+
if (initHandler)
|
|
285
|
+
processedHandlers.add(initHandler.action.replace('{!c.', '').replace('}', ''));
|
|
286
|
+
if (renderHandler)
|
|
287
|
+
processedHandlers.add(renderHandler.action.replace('{!c.', '').replace('}', ''));
|
|
288
|
+
if (destroyHandler)
|
|
289
|
+
processedHandlers.add(destroyHandler.action.replace('{!c.', '').replace('}', ''));
|
|
290
|
+
for (const lms of transformedMarkup.lmsChannels) {
|
|
291
|
+
if (lms.onMessageHandler)
|
|
292
|
+
processedHandlers.add(lms.onMessageHandler);
|
|
293
|
+
}
|
|
294
|
+
for (const func of controller.functions) {
|
|
295
|
+
// Skip if already handled
|
|
296
|
+
if (processedHandlers.has(func.name)) {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
let paramStr = '';
|
|
300
|
+
if (func.hasEvent) {
|
|
301
|
+
paramStr = 'event';
|
|
302
|
+
}
|
|
303
|
+
methodStubs.push(` // TODO: Implement - converted from controller.${func.name}
|
|
304
|
+
${func.name}(${paramStr}) {
|
|
305
|
+
// Original function accessed: ${func.attributeAccess.map((a) => `v.${a.name}`).join(', ') || 'none'}
|
|
306
|
+
// Helper calls: ${func.helperCalls.join(', ') || 'none'}
|
|
307
|
+
// Server calls: ${func.serverCalls.length > 0 ? 'yes' : 'none'}
|
|
308
|
+
}`);
|
|
309
|
+
// Track server calls
|
|
310
|
+
for (const serverCall of func.serverCalls) {
|
|
311
|
+
if (serverCall.controllerMethod) {
|
|
312
|
+
apexImports.push(serverCall.controllerMethod);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Process helper functions
|
|
318
|
+
if (helper) {
|
|
319
|
+
for (const func of helper.functions) {
|
|
320
|
+
methodStubs.push(` // TODO: Implement - merged from helper.${func.name}
|
|
321
|
+
${func.name}() {
|
|
322
|
+
// This was a helper function, now part of the class
|
|
323
|
+
}`);
|
|
324
|
+
for (const serverCall of func.serverCalls) {
|
|
325
|
+
if (!apexImports.includes(serverCall)) {
|
|
326
|
+
apexImports.push(serverCall);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// Process aura:method declarations
|
|
332
|
+
for (const method of markup.methods) {
|
|
333
|
+
if (!methodStubs.some((m) => m.includes(`${method.name}(`))) {
|
|
334
|
+
if (!imports.includes('api'))
|
|
335
|
+
imports.push('api');
|
|
336
|
+
const params = method.attributes.map((a) => a.name).join(', ');
|
|
337
|
+
methodStubs.push(` // Public method - was aura:method
|
|
338
|
+
@api
|
|
339
|
+
${method.name}(${params}) {
|
|
340
|
+
// TODO: Implement public method
|
|
341
|
+
}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// Build JS file
|
|
345
|
+
let js = `import { ${imports.join(', ')} } from 'lwc';\n`;
|
|
346
|
+
// Add LMS imports
|
|
347
|
+
if (lmsImports.length > 0) {
|
|
348
|
+
// Deduplicate LMS imports
|
|
349
|
+
const uniqueLmsImports = [...new Set(lmsImports)];
|
|
350
|
+
js += `import { ${uniqueLmsImports.join(', ')} } from 'lightning/messageService';\n`;
|
|
351
|
+
for (const channelImport of channelImports) {
|
|
352
|
+
js += `${channelImport}\n`;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// Add wire adapter imports
|
|
356
|
+
if (wireImports.length > 0) {
|
|
357
|
+
// Deduplicate wire imports
|
|
358
|
+
const uniqueWireImports = [...new Set(wireImports)];
|
|
359
|
+
js += `import { ${uniqueWireImports.join(', ')} } from 'lightning/uiRecordApi';\n`;
|
|
360
|
+
}
|
|
361
|
+
// Add schema imports (now active imports for detected fields)
|
|
362
|
+
if (schemaImports.length > 0) {
|
|
363
|
+
js += `\n// Field schema imports (verify object name - defaulting to Contact)\n`;
|
|
364
|
+
for (const schemaImport of schemaImports) {
|
|
365
|
+
js += `${schemaImport}\n`;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// Add Apex import TODOs
|
|
369
|
+
if (apexImports.length > 0 || markup.controller) {
|
|
370
|
+
js += `\n// TODO: Import Apex methods - verify class and method names\n`;
|
|
371
|
+
for (const method of apexImports) {
|
|
372
|
+
js += `// import ${method} from '@salesforce/apex/${markup.controller || 'ControllerName'}.${method}';\n`;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
js += `\nexport default class ${className} extends LightningElement {\n`;
|
|
376
|
+
// Add properties
|
|
377
|
+
if (apiProperties.length > 0) {
|
|
378
|
+
js += ` // Public properties (from aura:attribute)\n`;
|
|
379
|
+
js += apiProperties.join('\n\n') + '\n\n';
|
|
380
|
+
}
|
|
381
|
+
if (reactiveProperties.length > 0) {
|
|
382
|
+
js += ` // Private properties\n`;
|
|
383
|
+
js += reactiveProperties.join('\n\n') + '\n\n';
|
|
384
|
+
}
|
|
385
|
+
// Add wire declarations
|
|
386
|
+
if (wireDeclarations.length > 0) {
|
|
387
|
+
js += wireDeclarations.join('\n\n') + '\n\n';
|
|
388
|
+
}
|
|
389
|
+
// Add methods
|
|
390
|
+
if (methodStubs.length > 0) {
|
|
391
|
+
js += methodStubs.join('\n\n') + '\n';
|
|
392
|
+
}
|
|
393
|
+
js += `}\n`;
|
|
394
|
+
return { js, warnings };
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Convert Aura controller function to LWC method body
|
|
398
|
+
*/
|
|
399
|
+
function convertAuraControllerToLwc(func, _markup) {
|
|
400
|
+
// Parse the original function body and convert patterns
|
|
401
|
+
let body = func.body || '';
|
|
402
|
+
// Convert message.getParam('recordId') -> message.recordId
|
|
403
|
+
body = body.replace(/(\w+)\.getParam\s*\(\s*['"](\w+)['"]\s*\)/g, '$1.$2');
|
|
404
|
+
// Convert component.set('v.propName', value) -> this.propName = value
|
|
405
|
+
body = body.replace(/component\.set\s*\(\s*['"]v\.(\w+)['"]\s*,\s*([^)]+)\)/g, 'this.$1 = $2');
|
|
406
|
+
// Convert component.get('v.propName') -> this.propName
|
|
407
|
+
body = body.replace(/component\.get\s*\(\s*['"]v\.(\w+)['"]\s*\)/g, 'this.$1');
|
|
408
|
+
// Convert component.find('auraId').reloadRecord() -> automatic refresh via reactive property
|
|
409
|
+
// Since we're using @wire with '$contactId', changing contactId will automatically refresh
|
|
410
|
+
if (body.includes('reloadRecord')) {
|
|
411
|
+
body = body.replace(/(\w+)\s*=\s*component\.find\s*\(\s*['"][^'"]+['"]\s*\);?\s*\n?\s*\1\.reloadRecord\s*\(\s*\);?/g, '// Wire will auto-refresh when contactId changes (reactive binding)');
|
|
412
|
+
// Simpler pattern
|
|
413
|
+
body = body.replace(/component\.find\s*\(\s*['"][^'"]+['"]\s*\)\.reloadRecord\s*\(\s*\);?/g, '// Wire will auto-refresh when contactId changes (reactive binding)');
|
|
414
|
+
}
|
|
415
|
+
// Convert component.find('auraId') to this.template.querySelector('[data-id="auraId"]')
|
|
416
|
+
body = body.replace(/component\.find\s*\(\s*['"](\w+)['"]\s*\)/g, "this.template.querySelector('[data-id=\"$1\"]')");
|
|
417
|
+
// If the body has var declarations, suggest let/const
|
|
418
|
+
body = body.replace(/\bvar\s+/g, 'let ');
|
|
419
|
+
// Clean up and format
|
|
420
|
+
const lines = body.split('\n').filter(line => line.trim());
|
|
421
|
+
if (lines.length === 0) {
|
|
422
|
+
return '// TODO: Convert controller logic';
|
|
423
|
+
}
|
|
424
|
+
// Indent properly
|
|
425
|
+
return lines.map(line => line.trim()).join('\n ');
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Extract static resource name from VF expression
|
|
429
|
+
* e.g., "{!URLFOR($Resource.lmsvf, 'lmsvf.css')}" -> { resourceName: 'lmsvf', path: 'lmsvf.css' }
|
|
430
|
+
*/
|
|
431
|
+
function parseStaticResourceExpression(expr) {
|
|
432
|
+
// Match URLFOR($Resource.name, 'path')
|
|
433
|
+
const urlforMatch = expr.match(/URLFOR\s*\(\s*\$Resource\.(\w+)\s*,\s*['"]([^'"]+)['"]\s*\)/i);
|
|
434
|
+
if (urlforMatch) {
|
|
435
|
+
return { resourceName: urlforMatch[1], path: urlforMatch[2] };
|
|
436
|
+
}
|
|
437
|
+
// Match simple $Resource.name
|
|
438
|
+
const simpleMatch = expr.match(/\$Resource\.(\w+)/);
|
|
439
|
+
if (simpleMatch) {
|
|
440
|
+
return { resourceName: simpleMatch[1] };
|
|
441
|
+
}
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Generate scaffolding JS from VF parsed data
|
|
446
|
+
*/
|
|
447
|
+
function generateVfScaffoldingJs(vfPage, apexController) {
|
|
448
|
+
const warnings = [];
|
|
449
|
+
const className = (0, file_io_1.toPascalCase)(vfPage.pageName);
|
|
450
|
+
const dataAccess = (0, data_binding_1.generateDataAccessLayer)(vfPage, apexController);
|
|
451
|
+
warnings.push(...dataAccess.warnings);
|
|
452
|
+
// Build imports
|
|
453
|
+
const baseImports = ['LightningElement'];
|
|
454
|
+
if (dataAccess.wireDeclarations.length > 0) {
|
|
455
|
+
baseImports.push('wire');
|
|
456
|
+
}
|
|
457
|
+
// Check if we need platformResourceLoader for styles/scripts
|
|
458
|
+
const hasStyles = vfPage.includedStyles.length > 0;
|
|
459
|
+
const hasScripts = vfPage.includedScripts.length > 0;
|
|
460
|
+
const needsResourceLoader = hasStyles || hasScripts;
|
|
461
|
+
// Parse static resource references
|
|
462
|
+
const styleResources = [];
|
|
463
|
+
const scriptResources = [];
|
|
464
|
+
for (const style of vfPage.includedStyles) {
|
|
465
|
+
const parsed = parseStaticResourceExpression(style);
|
|
466
|
+
if (parsed) {
|
|
467
|
+
styleResources.push(parsed);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
for (const script of vfPage.includedScripts) {
|
|
471
|
+
const parsed = parseStaticResourceExpression(script);
|
|
472
|
+
if (parsed) {
|
|
473
|
+
scriptResources.push(parsed);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
let js = `import { ${baseImports.join(', ')} } from 'lwc';\n`;
|
|
477
|
+
// Add platformResourceLoader import if needed
|
|
478
|
+
if (needsResourceLoader) {
|
|
479
|
+
const loaderImports = [];
|
|
480
|
+
if (hasStyles)
|
|
481
|
+
loaderImports.push('loadStyle');
|
|
482
|
+
if (hasScripts)
|
|
483
|
+
loaderImports.push('loadScript');
|
|
484
|
+
js += `import { ${loaderImports.join(', ')} } from 'lightning/platformResourceLoader';\n`;
|
|
485
|
+
}
|
|
486
|
+
// Add static resource imports
|
|
487
|
+
const uniqueResources = new Set();
|
|
488
|
+
for (const res of [...styleResources, ...scriptResources]) {
|
|
489
|
+
uniqueResources.add(res.resourceName);
|
|
490
|
+
}
|
|
491
|
+
for (const resourceName of uniqueResources) {
|
|
492
|
+
js += `import ${resourceName}Resource from '@salesforce/resourceUrl/${resourceName}';\n`;
|
|
493
|
+
}
|
|
494
|
+
// Add other imports from data access layer
|
|
495
|
+
for (const imp of dataAccess.imports) {
|
|
496
|
+
js += `${imp}\n`;
|
|
497
|
+
}
|
|
498
|
+
// Add ShowToastEvent import - always needed for handleError method
|
|
499
|
+
js += `import { ShowToastEvent } from 'lightning/platformShowToastEvent';\n`;
|
|
500
|
+
js += `\nexport default class ${className} extends LightningElement {\n`;
|
|
501
|
+
// Add flag for one-time style/script loading
|
|
502
|
+
if (needsResourceLoader) {
|
|
503
|
+
js += ` // Flag to prevent duplicate resource loading\n`;
|
|
504
|
+
js += ` _resourcesLoaded = false;\n\n`;
|
|
505
|
+
}
|
|
506
|
+
// Add properties
|
|
507
|
+
if (dataAccess.properties.length > 0) {
|
|
508
|
+
js += ` // Properties\n`;
|
|
509
|
+
for (const prop of dataAccess.properties) {
|
|
510
|
+
js += ` ${prop}\n\n`;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
// Add wire declarations
|
|
514
|
+
if (dataAccess.wireDeclarations.length > 0) {
|
|
515
|
+
js += ` // Wire adapters\n`;
|
|
516
|
+
for (const wire of dataAccess.wireDeclarations) {
|
|
517
|
+
js += ` ${wire}\n\n`;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// Add loading state for async operations
|
|
521
|
+
if (vfPage.actionFunctions.length > 0 || vfPage.remoteActions.length > 0) {
|
|
522
|
+
js += ` // Loading state\n`;
|
|
523
|
+
js += ` isLoading = false;\n\n`;
|
|
524
|
+
}
|
|
525
|
+
// Add connectedCallback if page had action
|
|
526
|
+
if (vfPage.pageAttributes.action) {
|
|
527
|
+
js += ` // Page action - runs on component load\n`;
|
|
528
|
+
js += ` connectedCallback() {\n`;
|
|
529
|
+
js += ` // TODO: Implement page load action: ${vfPage.pageAttributes.action}\n`;
|
|
530
|
+
js += ` }\n\n`;
|
|
531
|
+
}
|
|
532
|
+
// Add renderedCallback for loading static resources
|
|
533
|
+
if (needsResourceLoader) {
|
|
534
|
+
js += ` // Load static resources (styles/scripts)\n`;
|
|
535
|
+
js += ` renderedCallback() {\n`;
|
|
536
|
+
js += ` if (this._resourcesLoaded) return;\n`;
|
|
537
|
+
js += ` this._resourcesLoaded = true;\n\n`;
|
|
538
|
+
// Generate loadStyle calls
|
|
539
|
+
if (styleResources.length > 0) {
|
|
540
|
+
js += ` // Load stylesheets\n`;
|
|
541
|
+
js += ` Promise.all([\n`;
|
|
542
|
+
for (const res of styleResources) {
|
|
543
|
+
const resourcePath = res.path
|
|
544
|
+
? `${res.resourceName}Resource + '/${res.path}'`
|
|
545
|
+
: `${res.resourceName}Resource`;
|
|
546
|
+
js += ` loadStyle(this, ${resourcePath}),\n`;
|
|
547
|
+
}
|
|
548
|
+
js += ` ])\n`;
|
|
549
|
+
js += ` .then(() => {\n`;
|
|
550
|
+
js += ` // Styles loaded successfully\n`;
|
|
551
|
+
js += ` })\n`;
|
|
552
|
+
js += ` .catch(error => {\n`;
|
|
553
|
+
js += ` console.error('Error loading styles:', error);\n`;
|
|
554
|
+
js += ` });\n`;
|
|
555
|
+
}
|
|
556
|
+
// Generate loadScript calls
|
|
557
|
+
if (scriptResources.length > 0) {
|
|
558
|
+
js += `\n // Load scripts\n`;
|
|
559
|
+
js += ` Promise.all([\n`;
|
|
560
|
+
for (const res of scriptResources) {
|
|
561
|
+
const resourcePath = res.path
|
|
562
|
+
? `${res.resourceName}Resource + '/${res.path}'`
|
|
563
|
+
: `${res.resourceName}Resource`;
|
|
564
|
+
js += ` loadScript(this, ${resourcePath}),\n`;
|
|
565
|
+
}
|
|
566
|
+
js += ` ])\n`;
|
|
567
|
+
js += ` .then(() => {\n`;
|
|
568
|
+
js += ` // Scripts loaded - initialize any external libraries here\n`;
|
|
569
|
+
js += ` })\n`;
|
|
570
|
+
js += ` .catch(error => {\n`;
|
|
571
|
+
js += ` console.error('Error loading scripts:', error);\n`;
|
|
572
|
+
js += ` });\n`;
|
|
573
|
+
}
|
|
574
|
+
js += ` }\n\n`;
|
|
575
|
+
}
|
|
576
|
+
// Add methods
|
|
577
|
+
if (dataAccess.methods.length > 0) {
|
|
578
|
+
js += ` // Methods\n`;
|
|
579
|
+
for (const method of dataAccess.methods) {
|
|
580
|
+
js += ` ${method}\n\n`;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
// Add error handler
|
|
584
|
+
js += ` // Error handler\n`;
|
|
585
|
+
js += ` handleError(error) {\n`;
|
|
586
|
+
js += ` this.dispatchEvent(\n`;
|
|
587
|
+
js += ` new ShowToastEvent({\n`;
|
|
588
|
+
js += ` title: 'Error',\n`;
|
|
589
|
+
js += ` message: error?.body?.message || 'An error occurred',\n`;
|
|
590
|
+
js += ` variant: 'error'\n`;
|
|
591
|
+
js += ` })\n`;
|
|
592
|
+
js += ` );\n`;
|
|
593
|
+
js += ` }\n`;
|
|
594
|
+
js += `}\n`;
|
|
595
|
+
return { js, warnings };
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Generate LWC scaffolding from Aura component
|
|
599
|
+
*/
|
|
600
|
+
function generateAuraScaffolding(markup, transformedMarkup, controller, helper, style) {
|
|
601
|
+
const lwcName = (0, file_io_1.toLwcName)(markup.componentName);
|
|
602
|
+
const allWarnings = [...transformedMarkup.warnings];
|
|
603
|
+
const notes = [];
|
|
604
|
+
// Generate HTML with comments
|
|
605
|
+
let html = transformedMarkup.html;
|
|
606
|
+
// Generate JS scaffolding
|
|
607
|
+
const { js, warnings: jsWarnings } = generateAuraScaffoldingJs(markup, transformedMarkup, controller, helper);
|
|
608
|
+
allWarnings.push(...jsWarnings);
|
|
609
|
+
// Generate CSS
|
|
610
|
+
let css;
|
|
611
|
+
if (style) {
|
|
612
|
+
css = (0, style_parser_1.convertAuraStyleToLwc)(style);
|
|
613
|
+
if (style.usesTokens) {
|
|
614
|
+
notes.push('CSS uses design tokens - may need conversion to SLDS or CSS custom properties');
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
// Generate meta XML
|
|
618
|
+
const meta = generateMetaXml(lwcName, {
|
|
619
|
+
description: `Converted from Aura component: ${markup.componentName}`,
|
|
620
|
+
targets: markup.implements?.includes('flexipage:availableForAllPageTypes')
|
|
621
|
+
? ['lightning__RecordPage', 'lightning__AppPage', 'lightning__HomePage']
|
|
622
|
+
: ['lightning__AppPage'],
|
|
623
|
+
});
|
|
624
|
+
// Generate notes
|
|
625
|
+
if (markup.controller) {
|
|
626
|
+
notes.push(`Original Apex controller: ${markup.controller}`);
|
|
627
|
+
}
|
|
628
|
+
if (markup.implements && markup.implements.length > 0) {
|
|
629
|
+
notes.push(`Original interfaces: ${markup.implements.join(', ')}`);
|
|
630
|
+
}
|
|
631
|
+
if (markup.registeredEvents.length > 0) {
|
|
632
|
+
notes.push(`Registered events to convert: ${markup.registeredEvents.map((e) => e.name).join(', ')}`);
|
|
633
|
+
}
|
|
634
|
+
if (transformedMarkup.usedDirectives.length > 0) {
|
|
635
|
+
notes.push(`LWC directives used: ${transformedMarkup.usedDirectives.join(', ')}`);
|
|
636
|
+
}
|
|
637
|
+
// Add warnings as notes
|
|
638
|
+
for (const warning of allWarnings) {
|
|
639
|
+
notes.push(`WARNING: ${warning}`);
|
|
640
|
+
}
|
|
641
|
+
// Generate Jest tests
|
|
642
|
+
const tests = (0, test_generator_1.generateAuraToLwcTests)(markup, transformedMarkup, controller);
|
|
643
|
+
const behaviorSpec = (0, test_generator_1.generateBehaviorSpecDocument)(markup.componentName, tests.behaviorSpecs);
|
|
644
|
+
// Generate before/after test comparison for behavior verification
|
|
645
|
+
const testComparison = (0, test_comparison_1.generateTestComparison)(markup, transformedMarkup, controller, helper);
|
|
646
|
+
logger_1.logger.debug(`Generated scaffolding for ${lwcName}`);
|
|
647
|
+
logger_1.logger.debug(`Generated ${tests.behaviorSpecs.length} behavior specs`);
|
|
648
|
+
logger_1.logger.debug(`Generated ${testComparison.behaviorTests.length} behavior tests for comparison`);
|
|
649
|
+
return {
|
|
650
|
+
bundle: {
|
|
651
|
+
name: lwcName,
|
|
652
|
+
html,
|
|
653
|
+
js,
|
|
654
|
+
css,
|
|
655
|
+
meta,
|
|
656
|
+
},
|
|
657
|
+
notes,
|
|
658
|
+
warnings: allWarnings,
|
|
659
|
+
tests,
|
|
660
|
+
behaviorSpec,
|
|
661
|
+
testComparison,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Generate LWC scaffolding from VF page
|
|
666
|
+
*/
|
|
667
|
+
function generateVfScaffolding(vfPage, transformedMarkup, apexController) {
|
|
668
|
+
const lwcName = (0, file_io_1.toLwcName)(vfPage.pageName);
|
|
669
|
+
const allWarnings = [...transformedMarkup.warnings];
|
|
670
|
+
const notes = [];
|
|
671
|
+
// Generate JS scaffolding
|
|
672
|
+
const { js, warnings: jsWarnings } = generateVfScaffoldingJs(vfPage, apexController);
|
|
673
|
+
allWarnings.push(...jsWarnings);
|
|
674
|
+
// Generate meta XML
|
|
675
|
+
const targets = [];
|
|
676
|
+
if (vfPage.pageAttributes.standardController) {
|
|
677
|
+
targets.push('lightning__RecordPage');
|
|
678
|
+
}
|
|
679
|
+
targets.push('lightning__AppPage', 'lightning__HomePage');
|
|
680
|
+
const meta = generateMetaXml(lwcName, {
|
|
681
|
+
description: `Converted from Visualforce page: ${vfPage.pageName}`,
|
|
682
|
+
targets,
|
|
683
|
+
});
|
|
684
|
+
// Generate notes
|
|
685
|
+
if (vfPage.pageAttributes.controller) {
|
|
686
|
+
notes.push(`Original controller: ${vfPage.pageAttributes.controller}`);
|
|
687
|
+
}
|
|
688
|
+
if (vfPage.pageAttributes.standardController) {
|
|
689
|
+
notes.push(`Standard controller: ${vfPage.pageAttributes.standardController}`);
|
|
690
|
+
}
|
|
691
|
+
if (vfPage.pageAttributes.extensions && vfPage.pageAttributes.extensions.length > 0) {
|
|
692
|
+
notes.push(`Controller extensions: ${vfPage.pageAttributes.extensions.join(', ')}`);
|
|
693
|
+
}
|
|
694
|
+
if (transformedMarkup.formFields.length > 0) {
|
|
695
|
+
notes.push(`Form fields to implement: ${transformedMarkup.formFields.map((f) => f.name).join(', ')}`);
|
|
696
|
+
}
|
|
697
|
+
if (vfPage.remoteActions.length > 0) {
|
|
698
|
+
notes.push(`Remote actions to convert: ${vfPage.remoteActions.map((ra) => `${ra.controller}.${ra.method}`).join(', ')}`);
|
|
699
|
+
}
|
|
700
|
+
// Add warnings as notes
|
|
701
|
+
for (const warning of allWarnings) {
|
|
702
|
+
notes.push(`WARNING: ${warning}`);
|
|
703
|
+
}
|
|
704
|
+
logger_1.logger.debug(`Generated VF scaffolding for ${lwcName}`);
|
|
705
|
+
return {
|
|
706
|
+
bundle: {
|
|
707
|
+
name: lwcName,
|
|
708
|
+
html: transformedMarkup.html,
|
|
709
|
+
js,
|
|
710
|
+
meta,
|
|
711
|
+
},
|
|
712
|
+
notes,
|
|
713
|
+
warnings: allWarnings,
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
//# sourceMappingURL=scaffolding.js.map
|