lwc-convert 1.8.0 → 1.8.2
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/dist/index.js +376 -238
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -51,8 +51,8 @@ var init_esm_shims = __esm({
|
|
|
51
51
|
import { readFileSync } from "fs";
|
|
52
52
|
import { join } from "path";
|
|
53
53
|
function getPackageVersion() {
|
|
54
|
-
if ("1.8.
|
|
55
|
-
return "1.8.
|
|
54
|
+
if ("1.8.2") {
|
|
55
|
+
return "1.8.2";
|
|
56
56
|
}
|
|
57
57
|
try {
|
|
58
58
|
const possiblePaths = [
|
|
@@ -76,11 +76,12 @@ function getPackageVersion() {
|
|
|
76
76
|
return "0.0.0";
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
var DEFAULT_OUTPUT_DIR, CLI_VERSION, CLI_NAME, CLI_DESCRIPTION;
|
|
79
|
+
var DEFAULT_API_VERSION, DEFAULT_OUTPUT_DIR, CLI_VERSION, CLI_NAME, CLI_DESCRIPTION;
|
|
80
80
|
var init_options = __esm({
|
|
81
81
|
"src/cli/options.ts"() {
|
|
82
82
|
"use strict";
|
|
83
83
|
init_esm_shims();
|
|
84
|
+
DEFAULT_API_VERSION = "62.0";
|
|
84
85
|
DEFAULT_OUTPUT_DIR = "./lwc-output";
|
|
85
86
|
CLI_VERSION = getPackageVersion();
|
|
86
87
|
CLI_NAME = "lwc-convert";
|
|
@@ -516,7 +517,16 @@ async function writeFile(filePath, content, dryRun = false) {
|
|
|
516
517
|
logger.file("CREATE", filePath);
|
|
517
518
|
}
|
|
518
519
|
function toLwcName(name) {
|
|
519
|
-
|
|
520
|
+
let result = name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
521
|
+
result = result.replace(/[^a-z0-9-]/g, "-");
|
|
522
|
+
result = result.replace(/-{2,}/g, "-");
|
|
523
|
+
result = result.replace(/^[^a-z]+/, "");
|
|
524
|
+
result = result.replace(/-+$/, "");
|
|
525
|
+
if (!result) {
|
|
526
|
+
result = "component";
|
|
527
|
+
logger.warn(`Component name "${name}" could not be converted to a valid LWC name. Using "${result}" as fallback.`);
|
|
528
|
+
}
|
|
529
|
+
return result;
|
|
520
530
|
}
|
|
521
531
|
function toPascalCase(name) {
|
|
522
532
|
return name.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
@@ -770,13 +780,13 @@ function extractFunctionBody(node, source) {
|
|
|
770
780
|
}
|
|
771
781
|
return "";
|
|
772
782
|
}
|
|
773
|
-
function parseAttributeAccess(
|
|
774
|
-
const callee =
|
|
783
|
+
function parseAttributeAccess(path20) {
|
|
784
|
+
const callee = path20.node.callee;
|
|
775
785
|
if (!t.isMemberExpression(callee)) return null;
|
|
776
786
|
const property = callee.property;
|
|
777
787
|
if (!t.isIdentifier(property)) return null;
|
|
778
788
|
if (property.name !== "get" && property.name !== "set") return null;
|
|
779
|
-
const args2 =
|
|
789
|
+
const args2 = path20.node.arguments;
|
|
780
790
|
if (args2.length === 0) return null;
|
|
781
791
|
const firstArg = args2[0];
|
|
782
792
|
if (!t.isStringLiteral(firstArg)) return null;
|
|
@@ -789,8 +799,8 @@ function parseAttributeAccess(path19) {
|
|
|
789
799
|
operation
|
|
790
800
|
};
|
|
791
801
|
}
|
|
792
|
-
function parseServerCall(
|
|
793
|
-
const callee =
|
|
802
|
+
function parseServerCall(path20, _source) {
|
|
803
|
+
const callee = path20.node.callee;
|
|
794
804
|
if (t.isMemberExpression(callee) && t.isIdentifier(callee.object, { name: "$A" }) && t.isIdentifier(callee.property, { name: "enqueueAction" })) {
|
|
795
805
|
return {
|
|
796
806
|
actionName: "enqueueAction",
|
|
@@ -800,7 +810,7 @@ function parseServerCall(path19, _source) {
|
|
|
800
810
|
if (t.isMemberExpression(callee)) {
|
|
801
811
|
const property = callee.property;
|
|
802
812
|
if (t.isIdentifier(property, { name: "get" })) {
|
|
803
|
-
const args2 =
|
|
813
|
+
const args2 = path20.node.arguments;
|
|
804
814
|
if (args2.length > 0 && t.isStringLiteral(args2[0])) {
|
|
805
815
|
const value = args2[0].value;
|
|
806
816
|
if (value.startsWith("c.")) {
|
|
@@ -815,17 +825,17 @@ function parseServerCall(path19, _source) {
|
|
|
815
825
|
}
|
|
816
826
|
return null;
|
|
817
827
|
}
|
|
818
|
-
function parseHelperCall(
|
|
819
|
-
const callee =
|
|
828
|
+
function parseHelperCall(path20) {
|
|
829
|
+
const callee = path20.node.callee;
|
|
820
830
|
if (t.isMemberExpression(callee) && t.isIdentifier(callee.object, { name: "helper" }) && t.isIdentifier(callee.property)) {
|
|
821
831
|
return callee.property.name;
|
|
822
832
|
}
|
|
823
833
|
return null;
|
|
824
834
|
}
|
|
825
|
-
function parseEventFire(
|
|
826
|
-
const callee =
|
|
835
|
+
function parseEventFire(path20) {
|
|
836
|
+
const callee = path20.node.callee;
|
|
827
837
|
if (t.isMemberExpression(callee) && t.isIdentifier(callee.object, { name: "$A" }) && t.isIdentifier(callee.property, { name: "get" })) {
|
|
828
|
-
const args2 =
|
|
838
|
+
const args2 = path20.node.arguments;
|
|
829
839
|
if (args2.length > 0 && t.isStringLiteral(args2[0])) {
|
|
830
840
|
const value = args2[0].value;
|
|
831
841
|
if (value.startsWith("e.")) {
|
|
@@ -834,7 +844,7 @@ function parseEventFire(path19) {
|
|
|
834
844
|
}
|
|
835
845
|
}
|
|
836
846
|
if (t.isMemberExpression(callee) && t.isIdentifier(callee.property, { name: "getEvent" })) {
|
|
837
|
-
const args2 =
|
|
847
|
+
const args2 = path20.node.arguments;
|
|
838
848
|
if (args2.length > 0 && t.isStringLiteral(args2[0])) {
|
|
839
849
|
return args2[0].value;
|
|
840
850
|
}
|
|
@@ -865,11 +875,11 @@ function parseAuraController(source) {
|
|
|
865
875
|
return result;
|
|
866
876
|
}
|
|
867
877
|
traverse(ast, {
|
|
868
|
-
ObjectExpression(
|
|
869
|
-
if (
|
|
878
|
+
ObjectExpression(path20) {
|
|
879
|
+
if (path20.parent.type === "VariableDeclarator" && t.isIdentifier(path20.parent.id, {
|
|
870
880
|
name: "__auraController"
|
|
871
881
|
})) {
|
|
872
|
-
for (const prop of
|
|
882
|
+
for (const prop of path20.node.properties) {
|
|
873
883
|
if (t.isObjectProperty(prop) && t.isIdentifier(prop.key) && t.isFunctionExpression(prop.value)) {
|
|
874
884
|
const funcName = prop.key.name;
|
|
875
885
|
const funcExpr = prop.value;
|
|
@@ -893,7 +903,7 @@ function parseAuraController(source) {
|
|
|
893
903
|
(p2) => p2 === "event" || p2 === "evt"
|
|
894
904
|
);
|
|
895
905
|
funcDef.hasHelper = funcDef.params.some((p2) => p2 === "helper");
|
|
896
|
-
const funcPath =
|
|
906
|
+
const funcPath = path20.get("properties").find((propPath) => {
|
|
897
907
|
const propNode = propPath.node;
|
|
898
908
|
return t.isObjectProperty(propNode) && t.isIdentifier(propNode.key, { name: funcName });
|
|
899
909
|
});
|
|
@@ -977,11 +987,11 @@ function parseAuraHelper(source) {
|
|
|
977
987
|
}
|
|
978
988
|
const helperFunctionNames = /* @__PURE__ */ new Set();
|
|
979
989
|
traverse2(ast, {
|
|
980
|
-
ObjectExpression(
|
|
981
|
-
if (
|
|
990
|
+
ObjectExpression(path20) {
|
|
991
|
+
if (path20.parent.type === "VariableDeclarator" && t2.isIdentifier(path20.parent.id, {
|
|
982
992
|
name: "__auraHelper"
|
|
983
993
|
})) {
|
|
984
|
-
for (const prop of
|
|
994
|
+
for (const prop of path20.node.properties) {
|
|
985
995
|
if (t2.isObjectProperty(prop) && t2.isIdentifier(prop.key)) {
|
|
986
996
|
helperFunctionNames.add(prop.key.name);
|
|
987
997
|
}
|
|
@@ -990,11 +1000,11 @@ function parseAuraHelper(source) {
|
|
|
990
1000
|
}
|
|
991
1001
|
});
|
|
992
1002
|
traverse2(ast, {
|
|
993
|
-
ObjectExpression(
|
|
994
|
-
if (
|
|
1003
|
+
ObjectExpression(path20) {
|
|
1004
|
+
if (path20.parent.type === "VariableDeclarator" && t2.isIdentifier(path20.parent.id, {
|
|
995
1005
|
name: "__auraHelper"
|
|
996
1006
|
})) {
|
|
997
|
-
for (const prop of
|
|
1007
|
+
for (const prop of path20.node.properties) {
|
|
998
1008
|
if (t2.isObjectProperty(prop) && t2.isIdentifier(prop.key) && t2.isFunctionExpression(prop.value)) {
|
|
999
1009
|
const funcName = prop.key.name;
|
|
1000
1010
|
const funcExpr = prop.value;
|
|
@@ -1010,7 +1020,7 @@ function parseAuraHelper(source) {
|
|
|
1010
1020
|
funcDef.hasComponent = funcDef.params.some(
|
|
1011
1021
|
(p2) => p2 === "component" || p2 === "cmp"
|
|
1012
1022
|
);
|
|
1013
|
-
const funcPath =
|
|
1023
|
+
const funcPath = path20.get("properties").find((propPath) => {
|
|
1014
1024
|
const propNode = propPath.node;
|
|
1015
1025
|
return t2.isObjectProperty(propNode) && t2.isIdentifier(propNode.key, { name: funcName });
|
|
1016
1026
|
});
|
|
@@ -4394,11 +4404,23 @@ function convertFunctionBody(body, _func, allHelperFunctions) {
|
|
|
4394
4404
|
/(?:component|cmp)\.get\s*\(\s*["']v\.(\w+)["']\s*\)/g,
|
|
4395
4405
|
"this.$1"
|
|
4396
4406
|
);
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4407
|
+
const setPattern = /(?:component|cmp)\.set\s*\(\s*["']v\.(\w+)["']\s*,\s*/g;
|
|
4408
|
+
let setMatch;
|
|
4409
|
+
while ((setMatch = setPattern.exec(converted)) !== null) {
|
|
4410
|
+
const propName = setMatch[1];
|
|
4411
|
+
const valueStart = setMatch.index + setMatch[0].length;
|
|
4412
|
+
let depth = 1;
|
|
4413
|
+
let i = valueStart;
|
|
4414
|
+
while (i < converted.length && depth > 0) {
|
|
4415
|
+
if (converted[i] === "(") depth++;
|
|
4416
|
+
else if (converted[i] === ")") depth--;
|
|
4417
|
+
i++;
|
|
4418
|
+
}
|
|
4419
|
+
const value = converted.substring(valueStart, i - 1).trim();
|
|
4420
|
+
const replacement = `this.${propName} = ${value}`;
|
|
4421
|
+
converted = converted.substring(0, setMatch.index) + replacement + converted.substring(i);
|
|
4422
|
+
setPattern.lastIndex = setMatch.index + replacement.length;
|
|
4423
|
+
}
|
|
4402
4424
|
if (allHelperFunctions) {
|
|
4403
4425
|
for (const helperFunc of allHelperFunctions) {
|
|
4404
4426
|
const helperRegex = new RegExp(
|
|
@@ -4410,10 +4432,21 @@ function convertFunctionBody(body, _func, allHelperFunctions) {
|
|
|
4410
4432
|
}
|
|
4411
4433
|
if (converted.includes("$A.enqueueAction")) {
|
|
4412
4434
|
warnings.push("Server action ($A.enqueueAction) found - convert to imperative Apex call");
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4435
|
+
const enqueuePattern = /\$A\.enqueueAction\s*\(/g;
|
|
4436
|
+
let enqueueMatch;
|
|
4437
|
+
while ((enqueueMatch = enqueuePattern.exec(converted)) !== null) {
|
|
4438
|
+
const callStart = enqueueMatch.index;
|
|
4439
|
+
let depth = 1;
|
|
4440
|
+
let j = callStart + enqueueMatch[0].length;
|
|
4441
|
+
while (j < converted.length && depth > 0) {
|
|
4442
|
+
if (converted[j] === "(") depth++;
|
|
4443
|
+
else if (converted[j] === ")") depth--;
|
|
4444
|
+
j++;
|
|
4445
|
+
}
|
|
4446
|
+
const replacement = "/* TODO: Convert to imperative Apex call */";
|
|
4447
|
+
converted = converted.substring(0, callStart) + replacement + converted.substring(j);
|
|
4448
|
+
enqueuePattern.lastIndex = callStart + replacement.length;
|
|
4449
|
+
}
|
|
4417
4450
|
}
|
|
4418
4451
|
if (converted.includes('.get("c.') || converted.includes(".get('c.")) {
|
|
4419
4452
|
warnings.push("Server action reference found - import Apex method and call imperatively");
|
|
@@ -6095,7 +6128,7 @@ var init_confidence_scorer = __esm({
|
|
|
6095
6128
|
// src/generators/full-conversion.ts
|
|
6096
6129
|
function generateMetaXml2(_componentName, options) {
|
|
6097
6130
|
const {
|
|
6098
|
-
apiVersion =
|
|
6131
|
+
apiVersion = DEFAULT_API_VERSION,
|
|
6099
6132
|
isExposed = true,
|
|
6100
6133
|
targets = ["lightning__RecordPage", "lightning__AppPage", "lightning__HomePage"],
|
|
6101
6134
|
description,
|
|
@@ -6661,6 +6694,7 @@ var init_full_conversion = __esm({
|
|
|
6661
6694
|
init_test_generator();
|
|
6662
6695
|
init_file_io();
|
|
6663
6696
|
init_logger();
|
|
6697
|
+
init_options();
|
|
6664
6698
|
init_confidence_scorer();
|
|
6665
6699
|
}
|
|
6666
6700
|
});
|
|
@@ -6715,40 +6749,53 @@ var init_project_detector = __esm({
|
|
|
6715
6749
|
}
|
|
6716
6750
|
});
|
|
6717
6751
|
|
|
6752
|
+
// src/utils/constants.ts
|
|
6753
|
+
var AURA_SEARCH_PATHS, VF_PAGE_SEARCH_PATHS, VF_COMPONENT_SEARCH_PATHS, APEX_SEARCH_PATHS;
|
|
6754
|
+
var init_constants = __esm({
|
|
6755
|
+
"src/utils/constants.ts"() {
|
|
6756
|
+
"use strict";
|
|
6757
|
+
init_esm_shims();
|
|
6758
|
+
AURA_SEARCH_PATHS = [
|
|
6759
|
+
"force-app/main/default/aura",
|
|
6760
|
+
"src/aura",
|
|
6761
|
+
"aura",
|
|
6762
|
+
"force-app/main/aura"
|
|
6763
|
+
];
|
|
6764
|
+
VF_PAGE_SEARCH_PATHS = [
|
|
6765
|
+
"force-app/main/default/pages",
|
|
6766
|
+
"src/pages",
|
|
6767
|
+
"pages",
|
|
6768
|
+
"force-app/main/pages"
|
|
6769
|
+
];
|
|
6770
|
+
VF_COMPONENT_SEARCH_PATHS = [
|
|
6771
|
+
"force-app/main/default/components",
|
|
6772
|
+
"src/components",
|
|
6773
|
+
"components",
|
|
6774
|
+
"force-app/main/components"
|
|
6775
|
+
];
|
|
6776
|
+
APEX_SEARCH_PATHS = [
|
|
6777
|
+
"force-app/main/default/classes",
|
|
6778
|
+
"src/classes",
|
|
6779
|
+
"classes",
|
|
6780
|
+
"force-app/main/classes"
|
|
6781
|
+
];
|
|
6782
|
+
}
|
|
6783
|
+
});
|
|
6784
|
+
|
|
6718
6785
|
// src/utils/fuzzy-suggest.ts
|
|
6719
6786
|
import Fuse from "fuse.js";
|
|
6720
6787
|
import * as path4 from "path";
|
|
6721
6788
|
import fs3 from "fs-extra";
|
|
6722
6789
|
async function suggestAuraComponents(input, maxResults = 3) {
|
|
6723
|
-
const
|
|
6724
|
-
"force-app/main/default/aura",
|
|
6725
|
-
"src/aura",
|
|
6726
|
-
"aura",
|
|
6727
|
-
"force-app/main/aura"
|
|
6728
|
-
];
|
|
6729
|
-
const components3 = await scanDirectories(searchPaths, ".cmp");
|
|
6790
|
+
const components3 = await scanDirectories(AURA_SEARCH_PATHS, ".cmp");
|
|
6730
6791
|
return fuzzyMatch(input, components3, maxResults);
|
|
6731
6792
|
}
|
|
6732
6793
|
async function suggestVfPages(input, maxResults = 3) {
|
|
6733
|
-
const
|
|
6734
|
-
"force-app/main/default/pages",
|
|
6735
|
-
"force-app/main/default/components",
|
|
6736
|
-
"src/pages",
|
|
6737
|
-
"src/components",
|
|
6738
|
-
"pages",
|
|
6739
|
-
"components"
|
|
6740
|
-
];
|
|
6741
|
-
const pages = await scanDirectories(searchPaths, ".page", ".component");
|
|
6794
|
+
const pages = await scanDirectories([...VF_PAGE_SEARCH_PATHS, ...VF_COMPONENT_SEARCH_PATHS], ".page", ".component");
|
|
6742
6795
|
return fuzzyMatch(input, pages, maxResults);
|
|
6743
6796
|
}
|
|
6744
6797
|
async function suggestApexControllers(input, maxResults = 3) {
|
|
6745
|
-
const
|
|
6746
|
-
"force-app/main/default/classes",
|
|
6747
|
-
"src/classes",
|
|
6748
|
-
"classes",
|
|
6749
|
-
"force-app/main/classes"
|
|
6750
|
-
];
|
|
6751
|
-
const controllers = await scanDirectories(searchPaths, ".cls");
|
|
6798
|
+
const controllers = await scanDirectories(APEX_SEARCH_PATHS, ".cls");
|
|
6752
6799
|
return fuzzyMatch(input, controllers, maxResults);
|
|
6753
6800
|
}
|
|
6754
6801
|
async function scanDirectories(searchPaths, ...extensions) {
|
|
@@ -6837,6 +6884,7 @@ var init_fuzzy_suggest = __esm({
|
|
|
6837
6884
|
"use strict";
|
|
6838
6885
|
init_esm_shims();
|
|
6839
6886
|
init_project_detector();
|
|
6887
|
+
init_constants();
|
|
6840
6888
|
FUSE_OPTIONS = {
|
|
6841
6889
|
keys: ["name"],
|
|
6842
6890
|
threshold: 0.4,
|
|
@@ -6994,7 +7042,8 @@ async function resolveApexPath(input) {
|
|
|
6994
7042
|
contextualHelp
|
|
6995
7043
|
};
|
|
6996
7044
|
}
|
|
6997
|
-
async function searchForComponent(baseDir, componentName, extension) {
|
|
7045
|
+
async function searchForComponent(baseDir, componentName, extension, currentDepth = 0, maxDepth = 5) {
|
|
7046
|
+
if (currentDepth >= maxDepth) return null;
|
|
6998
7047
|
try {
|
|
6999
7048
|
const entries = await fs4.readdir(baseDir, { withFileTypes: true });
|
|
7000
7049
|
for (const entry of entries) {
|
|
@@ -7009,51 +7058,31 @@ async function searchForComponent(baseDir, componentName, extension) {
|
|
|
7009
7058
|
const subResult = await searchForComponent(
|
|
7010
7059
|
path5.join(baseDir, entry.name),
|
|
7011
7060
|
componentName,
|
|
7012
|
-
extension
|
|
7061
|
+
extension,
|
|
7062
|
+
currentDepth + 1,
|
|
7063
|
+
maxDepth
|
|
7013
7064
|
);
|
|
7014
7065
|
if (subResult) {
|
|
7015
7066
|
return subResult;
|
|
7016
7067
|
}
|
|
7017
7068
|
}
|
|
7018
7069
|
}
|
|
7019
|
-
} catch {
|
|
7070
|
+
} catch (error) {
|
|
7071
|
+
logger.debug(`Error searching ${baseDir}: ${error.message}`);
|
|
7020
7072
|
}
|
|
7021
7073
|
return null;
|
|
7022
7074
|
}
|
|
7023
7075
|
function formatSearchLocations(locations, cwd) {
|
|
7024
7076
|
return locations.map((loc) => ` - ${path5.relative(cwd, loc) || loc}`).join("\n");
|
|
7025
7077
|
}
|
|
7026
|
-
var AURA_SEARCH_PATHS, VF_PAGE_SEARCH_PATHS, VF_COMPONENT_SEARCH_PATHS, APEX_SEARCH_PATHS;
|
|
7027
7078
|
var init_path_resolver = __esm({
|
|
7028
7079
|
"src/utils/path-resolver.ts"() {
|
|
7029
7080
|
"use strict";
|
|
7030
7081
|
init_esm_shims();
|
|
7031
7082
|
init_project_detector();
|
|
7083
|
+
init_logger();
|
|
7032
7084
|
init_fuzzy_suggest();
|
|
7033
|
-
|
|
7034
|
-
"force-app/main/default/aura",
|
|
7035
|
-
"src/aura",
|
|
7036
|
-
"aura",
|
|
7037
|
-
"force-app/main/aura"
|
|
7038
|
-
];
|
|
7039
|
-
VF_PAGE_SEARCH_PATHS = [
|
|
7040
|
-
"force-app/main/default/pages",
|
|
7041
|
-
"src/pages",
|
|
7042
|
-
"pages",
|
|
7043
|
-
"force-app/main/pages"
|
|
7044
|
-
];
|
|
7045
|
-
VF_COMPONENT_SEARCH_PATHS = [
|
|
7046
|
-
"force-app/main/default/components",
|
|
7047
|
-
"src/components",
|
|
7048
|
-
"components",
|
|
7049
|
-
"force-app/main/components"
|
|
7050
|
-
];
|
|
7051
|
-
APEX_SEARCH_PATHS = [
|
|
7052
|
-
"force-app/main/default/classes",
|
|
7053
|
-
"src/classes",
|
|
7054
|
-
"classes",
|
|
7055
|
-
"force-app/main/classes"
|
|
7056
|
-
];
|
|
7085
|
+
init_constants();
|
|
7057
7086
|
}
|
|
7058
7087
|
});
|
|
7059
7088
|
|
|
@@ -7061,7 +7090,7 @@ var init_path_resolver = __esm({
|
|
|
7061
7090
|
import * as fs5 from "fs";
|
|
7062
7091
|
import * as path6 from "path";
|
|
7063
7092
|
import * as os from "os";
|
|
7064
|
-
var SESSIONS_BASE_DIR, ACTIVE_SESSION_FILE, SESSION_EXPIRY_MS, SessionStore, sessionStore;
|
|
7093
|
+
var SESSIONS_BASE_DIR, ACTIVE_SESSION_FILE, SESSION_EXPIRY_MS, MAX_PATTERN_LIBRARY_SIZE, SessionStore, sessionStore;
|
|
7065
7094
|
var init_session_store = __esm({
|
|
7066
7095
|
"src/utils/session-store.ts"() {
|
|
7067
7096
|
"use strict";
|
|
@@ -7070,12 +7099,15 @@ var init_session_store = __esm({
|
|
|
7070
7099
|
SESSIONS_BASE_DIR = path6.join(os.tmpdir(), "lwc-convert-sessions");
|
|
7071
7100
|
ACTIVE_SESSION_FILE = path6.join(SESSIONS_BASE_DIR, "active-session.json");
|
|
7072
7101
|
SESSION_EXPIRY_MS = 4 * 60 * 60 * 1e3;
|
|
7102
|
+
MAX_PATTERN_LIBRARY_SIZE = 1e3;
|
|
7073
7103
|
SessionStore = class {
|
|
7074
7104
|
sessionId = "";
|
|
7075
7105
|
sessionDir = "";
|
|
7076
7106
|
conversions = [];
|
|
7107
|
+
conversionIndex = /* @__PURE__ */ new Map();
|
|
7077
7108
|
patternLibrary = /* @__PURE__ */ new Map();
|
|
7078
7109
|
initialized = false;
|
|
7110
|
+
initPromise = null;
|
|
7079
7111
|
startedAt = /* @__PURE__ */ new Date();
|
|
7080
7112
|
constructor() {
|
|
7081
7113
|
}
|
|
@@ -7130,6 +7162,7 @@ var init_session_store = __esm({
|
|
|
7130
7162
|
const record = JSON.parse(content);
|
|
7131
7163
|
record.timestamp = new Date(record.timestamp);
|
|
7132
7164
|
this.conversions.push(record);
|
|
7165
|
+
this.conversionIndex.set(record.id, record);
|
|
7133
7166
|
for (const pattern of record.patterns) {
|
|
7134
7167
|
this.updatePatternLibrary([pattern]);
|
|
7135
7168
|
}
|
|
@@ -7183,17 +7216,22 @@ var init_session_store = __esm({
|
|
|
7183
7216
|
*/
|
|
7184
7217
|
async init() {
|
|
7185
7218
|
if (this.initialized) return;
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
await this.
|
|
7219
|
+
if (this.initPromise) return this.initPromise;
|
|
7220
|
+
this.initPromise = (async () => {
|
|
7221
|
+
try {
|
|
7222
|
+
const loaded = await this.tryLoadExistingSession();
|
|
7223
|
+
if (!loaded) {
|
|
7224
|
+
await this.createNewSession();
|
|
7225
|
+
}
|
|
7226
|
+
await this.updateActiveSessionFile();
|
|
7227
|
+
this.initialized = true;
|
|
7228
|
+
logger.debug(`Session store initialized: ${this.sessionDir}`);
|
|
7229
|
+
} catch (error) {
|
|
7230
|
+
logger.debug(`Failed to initialize session store: ${error.message}`);
|
|
7231
|
+
this.initPromise = null;
|
|
7190
7232
|
}
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
logger.debug(`Session store initialized: ${this.sessionDir}`);
|
|
7194
|
-
} catch (error) {
|
|
7195
|
-
logger.debug(`Failed to initialize session store: ${error.message}`);
|
|
7196
|
-
}
|
|
7233
|
+
})();
|
|
7234
|
+
return this.initPromise;
|
|
7197
7235
|
}
|
|
7198
7236
|
/**
|
|
7199
7237
|
* Get the session directory path
|
|
@@ -7233,6 +7271,7 @@ var init_session_store = __esm({
|
|
|
7233
7271
|
success: true
|
|
7234
7272
|
};
|
|
7235
7273
|
this.conversions.push(record);
|
|
7274
|
+
this.conversionIndex.set(record.id, record);
|
|
7236
7275
|
this.updatePatternLibrary(record.patterns);
|
|
7237
7276
|
try {
|
|
7238
7277
|
const conversionFile = path6.join(this.sessionDir, "conversions", `${record.id}.json`);
|
|
@@ -7296,7 +7335,15 @@ var init_session_store = __esm({
|
|
|
7296
7335
|
if (existing) {
|
|
7297
7336
|
existing.frequency++;
|
|
7298
7337
|
existing.successRate = (existing.successRate * (existing.frequency - 1) + pattern.successRate) / existing.frequency;
|
|
7338
|
+
this.patternLibrary.delete(key);
|
|
7339
|
+
this.patternLibrary.set(key, existing);
|
|
7299
7340
|
} else {
|
|
7341
|
+
if (this.patternLibrary.size >= MAX_PATTERN_LIBRARY_SIZE) {
|
|
7342
|
+
const firstKey = this.patternLibrary.keys().next().value;
|
|
7343
|
+
if (firstKey !== void 0) {
|
|
7344
|
+
this.patternLibrary.delete(firstKey);
|
|
7345
|
+
}
|
|
7346
|
+
}
|
|
7300
7347
|
this.patternLibrary.set(key, { ...pattern });
|
|
7301
7348
|
}
|
|
7302
7349
|
}
|
|
@@ -7333,13 +7380,13 @@ var init_session_store = __esm({
|
|
|
7333
7380
|
* Get conversion by ID
|
|
7334
7381
|
*/
|
|
7335
7382
|
getConversion(id) {
|
|
7336
|
-
return this.
|
|
7383
|
+
return this.conversionIndex.get(id);
|
|
7337
7384
|
}
|
|
7338
7385
|
/**
|
|
7339
7386
|
* Update test results for a conversion
|
|
7340
7387
|
*/
|
|
7341
7388
|
async updateTestResults(conversionId, results) {
|
|
7342
|
-
const conversion = this.
|
|
7389
|
+
const conversion = this.conversionIndex.get(conversionId);
|
|
7343
7390
|
if (!conversion) return;
|
|
7344
7391
|
conversion.testResults = results;
|
|
7345
7392
|
conversion.success = results.failed === 0;
|
|
@@ -7471,8 +7518,10 @@ All session data is stored in:
|
|
|
7471
7518
|
await fs5.promises.unlink(ACTIVE_SESSION_FILE);
|
|
7472
7519
|
}
|
|
7473
7520
|
this.conversions = [];
|
|
7521
|
+
this.conversionIndex.clear();
|
|
7474
7522
|
this.patternLibrary.clear();
|
|
7475
7523
|
this.initialized = false;
|
|
7524
|
+
this.initPromise = null;
|
|
7476
7525
|
logger.debug(`Cleaned up session: ${this.sessionId}`);
|
|
7477
7526
|
} catch (error) {
|
|
7478
7527
|
logger.debug(`Failed to cleanup session: ${error.message}`);
|
|
@@ -7513,6 +7562,13 @@ All session data is stored in:
|
|
|
7513
7562
|
// src/utils/preview-generator.ts
|
|
7514
7563
|
import fs6 from "fs-extra";
|
|
7515
7564
|
import * as path7 from "path";
|
|
7565
|
+
import { execFile, spawn } from "child_process";
|
|
7566
|
+
function escapeHtml(str) {
|
|
7567
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
7568
|
+
}
|
|
7569
|
+
function escapeCssContent(css) {
|
|
7570
|
+
return css.replace(/<\/style/gi, "<\\/style");
|
|
7571
|
+
}
|
|
7516
7572
|
function parseAttributes(tagContent) {
|
|
7517
7573
|
const attrs = {};
|
|
7518
7574
|
const attrRegex = /(\S+?)(?:=(?:"([^"]*)"|{([^}]*)})|(?=\s|>|$))/g;
|
|
@@ -7611,12 +7667,14 @@ function transformLwcToPreviewHtml(lwcHtml) {
|
|
|
7611
7667
|
function generatePreviewHtml(bundle, componentCss) {
|
|
7612
7668
|
const previewContent = transformLwcToPreviewHtml(bundle.html);
|
|
7613
7669
|
const css = componentCss ?? bundle.css;
|
|
7670
|
+
const safeName = escapeHtml(bundle.name);
|
|
7671
|
+
const safeCss = css ? escapeCssContent(css) : "";
|
|
7614
7672
|
return `<!DOCTYPE html>
|
|
7615
7673
|
<html lang="en">
|
|
7616
7674
|
<head>
|
|
7617
7675
|
<meta charset="UTF-8">
|
|
7618
7676
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7619
|
-
<title>LWC Preview: ${
|
|
7677
|
+
<title>LWC Preview: ${safeName}</title>
|
|
7620
7678
|
|
|
7621
7679
|
<!-- Salesforce Lightning Design System -->
|
|
7622
7680
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/design-system/2.24.2/styles/salesforce-lightning-design-system.min.css">
|
|
@@ -7778,7 +7836,7 @@ function generatePreviewHtml(bundle, componentCss) {
|
|
|
7778
7836
|
}
|
|
7779
7837
|
|
|
7780
7838
|
/* Component-specific CSS from conversion */
|
|
7781
|
-
${
|
|
7839
|
+
${safeCss || "/* No component CSS */"}
|
|
7782
7840
|
|
|
7783
7841
|
/* Legend */
|
|
7784
7842
|
.preview-legend {
|
|
@@ -7836,7 +7894,7 @@ function generatePreviewHtml(bundle, componentCss) {
|
|
|
7836
7894
|
<body>
|
|
7837
7895
|
<div class="preview-container">
|
|
7838
7896
|
<div class="preview-header">
|
|
7839
|
-
<h1>${
|
|
7897
|
+
<h1>${safeName}</h1>
|
|
7840
7898
|
<div class="meta">LWC Preview • Generated by lwc-convert</div>
|
|
7841
7899
|
</div>
|
|
7842
7900
|
|
|
@@ -7911,20 +7969,21 @@ async function writePreviewFile(outputDir, bundle, dryRun = false) {
|
|
|
7911
7969
|
return previewPath;
|
|
7912
7970
|
}
|
|
7913
7971
|
async function openPreview(previewPath) {
|
|
7914
|
-
const { exec: exec2 } = await import("child_process");
|
|
7915
|
-
const { promisify } = await import("util");
|
|
7916
|
-
const execAsync = promisify(exec2);
|
|
7917
7972
|
const platform3 = process.platform;
|
|
7918
|
-
let command;
|
|
7919
|
-
if (platform3 === "win32") {
|
|
7920
|
-
command = `start "" "${previewPath}"`;
|
|
7921
|
-
} else if (platform3 === "darwin") {
|
|
7922
|
-
command = `open "${previewPath}"`;
|
|
7923
|
-
} else {
|
|
7924
|
-
command = `xdg-open "${previewPath}"`;
|
|
7925
|
-
}
|
|
7926
7973
|
try {
|
|
7927
|
-
|
|
7974
|
+
if (platform3 === "win32") {
|
|
7975
|
+
execFile("explorer", [previewPath], () => {
|
|
7976
|
+
});
|
|
7977
|
+
} else if (platform3 === "darwin") {
|
|
7978
|
+
execFile("open", [previewPath], () => {
|
|
7979
|
+
});
|
|
7980
|
+
} else {
|
|
7981
|
+
const child = spawn("xdg-open", [previewPath], {
|
|
7982
|
+
detached: true,
|
|
7983
|
+
stdio: "ignore"
|
|
7984
|
+
});
|
|
7985
|
+
child.unref();
|
|
7986
|
+
}
|
|
7928
7987
|
logger.success("Opened preview in default browser");
|
|
7929
7988
|
} catch (error) {
|
|
7930
7989
|
logger.warn(`Could not open preview automatically: ${error.message}`);
|
|
@@ -8288,31 +8347,38 @@ var open_folder_exports = {};
|
|
|
8288
8347
|
__export(open_folder_exports, {
|
|
8289
8348
|
openFolder: () => openFolder
|
|
8290
8349
|
});
|
|
8291
|
-
import {
|
|
8350
|
+
import { execFile as execFile2, spawn as spawn2 } from "child_process";
|
|
8292
8351
|
import * as os2 from "os";
|
|
8293
8352
|
function openFolder(folderPath) {
|
|
8294
|
-
return new Promise((
|
|
8353
|
+
return new Promise((resolve10) => {
|
|
8295
8354
|
const platform3 = os2.platform();
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
resolve8();
|
|
8355
|
+
try {
|
|
8356
|
+
if (platform3 === "win32") {
|
|
8357
|
+
execFile2("explorer", [folderPath], (error) => {
|
|
8358
|
+
if (error) {
|
|
8359
|
+
logger.warn(`Could not open folder: ${error.message}`);
|
|
8360
|
+
}
|
|
8361
|
+
resolve10();
|
|
8362
|
+
});
|
|
8363
|
+
} else if (platform3 === "darwin") {
|
|
8364
|
+
execFile2("open", [folderPath], (error) => {
|
|
8365
|
+
if (error) {
|
|
8366
|
+
logger.warn(`Could not open folder: ${error.message}`);
|
|
8367
|
+
}
|
|
8368
|
+
resolve10();
|
|
8369
|
+
});
|
|
8312
8370
|
} else {
|
|
8313
|
-
|
|
8371
|
+
const child = spawn2("xdg-open", [folderPath], {
|
|
8372
|
+
detached: true,
|
|
8373
|
+
stdio: "ignore"
|
|
8374
|
+
});
|
|
8375
|
+
child.unref();
|
|
8376
|
+
resolve10();
|
|
8314
8377
|
}
|
|
8315
|
-
})
|
|
8378
|
+
} catch (error) {
|
|
8379
|
+
logger.warn(`Could not open folder: ${error.message}`);
|
|
8380
|
+
resolve10();
|
|
8381
|
+
}
|
|
8316
8382
|
});
|
|
8317
8383
|
}
|
|
8318
8384
|
var init_open_folder = __esm({
|
|
@@ -8417,18 +8483,19 @@ ${resolved.contextualHelp}` : "";
|
|
|
8417
8483
|
if (result.notes.length > 0) {
|
|
8418
8484
|
await writeConversionNotes(outputDir, result.bundle.name, result.notes, options.dryRun);
|
|
8419
8485
|
}
|
|
8420
|
-
|
|
8486
|
+
const shouldGenerateTests = options.generateTests !== false;
|
|
8487
|
+
if (result.tests && shouldGenerateTests) {
|
|
8421
8488
|
const testDir = path8.join(outputDir, result.bundle.name, "__tests__");
|
|
8422
8489
|
const testFilePath = path8.join(testDir, result.tests.filename);
|
|
8423
8490
|
const { writeFile: writeFile2 } = await Promise.resolve().then(() => (init_file_io(), file_io_exports));
|
|
8424
8491
|
await writeFile2(testFilePath, result.tests.content, options.dryRun);
|
|
8425
8492
|
}
|
|
8426
|
-
if (result.behaviorSpec) {
|
|
8493
|
+
if (result.behaviorSpec && shouldGenerateTests) {
|
|
8427
8494
|
const specFilePath = path8.join(outputDir, result.bundle.name, `${result.bundle.name}-behavior-spec.md`);
|
|
8428
8495
|
const { writeFile: writeFile2 } = await Promise.resolve().then(() => (init_file_io(), file_io_exports));
|
|
8429
8496
|
await writeFile2(specFilePath, result.behaviorSpec, options.dryRun);
|
|
8430
8497
|
}
|
|
8431
|
-
if (result.testComparison) {
|
|
8498
|
+
if (result.testComparison && shouldGenerateTests) {
|
|
8432
8499
|
const { writeFile: writeFile2 } = await Promise.resolve().then(() => (init_file_io(), file_io_exports));
|
|
8433
8500
|
const testDir = path8.join(outputDir, result.bundle.name, "__tests__");
|
|
8434
8501
|
const beforeTestPath = path8.join(testDir, `${result.bundle.name}.before.spec.js`);
|
|
@@ -8439,7 +8506,7 @@ ${resolved.contextualHelp}` : "";
|
|
|
8439
8506
|
await writeFile2(comparisonReportPath, result.testComparison.comparisonReport, options.dryRun);
|
|
8440
8507
|
}
|
|
8441
8508
|
logger.divider();
|
|
8442
|
-
if (result.testComparison) {
|
|
8509
|
+
if (result.testComparison && shouldGenerateTests) {
|
|
8443
8510
|
const conversionRecord = await sessionStore.storeConversion(
|
|
8444
8511
|
"aura",
|
|
8445
8512
|
bundle.name,
|
|
@@ -8452,9 +8519,9 @@ ${resolved.contextualHelp}` : "";
|
|
|
8452
8519
|
logger.debug(`Session stored: ${conversionRecord.id}`);
|
|
8453
8520
|
}
|
|
8454
8521
|
let totalFiles = writtenFiles.length + 1;
|
|
8455
|
-
if (result.tests) totalFiles++;
|
|
8456
|
-
if (result.behaviorSpec) totalFiles++;
|
|
8457
|
-
if (result.testComparison) totalFiles += 3;
|
|
8522
|
+
if (result.tests && shouldGenerateTests) totalFiles++;
|
|
8523
|
+
if (result.behaviorSpec && shouldGenerateTests) totalFiles++;
|
|
8524
|
+
if (result.testComparison && shouldGenerateTests) totalFiles += 3;
|
|
8458
8525
|
logger.successToast(
|
|
8459
8526
|
"Conversion Complete",
|
|
8460
8527
|
[
|
|
@@ -8464,9 +8531,11 @@ ${resolved.contextualHelp}` : "";
|
|
|
8464
8531
|
path8.join(outputDir, result.bundle.name)
|
|
8465
8532
|
);
|
|
8466
8533
|
const sessionSummary = sessionStore.getSessionSummary();
|
|
8534
|
+
const jestTestsValue = !shouldGenerateTests ? "Skipped" : result.tests ? `${result.bundle.name}.test.js` : "None";
|
|
8467
8535
|
logger.summaryBox("Conversion Summary", [
|
|
8468
8536
|
{ label: "Component", value: `${bundle.name} \u2192 ${result.bundle.name}`, type: "success" },
|
|
8469
8537
|
{ label: "Files created", value: `${totalFiles}`, type: "info" },
|
|
8538
|
+
{ label: "Jest Tests", value: jestTestsValue, type: shouldGenerateTests && result.tests ? "success" : "warn" },
|
|
8470
8539
|
{ label: "Behaviors mapped", value: `${result.testComparison?.behaviorTests.length || 0}`, type: "info" },
|
|
8471
8540
|
{ label: "Warnings", value: `${result.warnings.length}`, type: result.warnings.length > 0 ? "warn" : "success" },
|
|
8472
8541
|
{ label: "Output", value: path8.join(outputDir, result.bundle.name), type: "info" }
|
|
@@ -9630,6 +9699,8 @@ var init_grader = __esm({
|
|
|
9630
9699
|
Grader = class {
|
|
9631
9700
|
auraGrader;
|
|
9632
9701
|
vfGrader;
|
|
9702
|
+
/** Cache of grading results keyed by resolved file path */
|
|
9703
|
+
gradeCache = /* @__PURE__ */ new Map();
|
|
9633
9704
|
constructor() {
|
|
9634
9705
|
this.auraGrader = new AuraGrader();
|
|
9635
9706
|
this.vfGrader = new VfGrader();
|
|
@@ -9678,7 +9749,8 @@ var init_grader = __esm({
|
|
|
9678
9749
|
}
|
|
9679
9750
|
}
|
|
9680
9751
|
}
|
|
9681
|
-
} catch {
|
|
9752
|
+
} catch (error) {
|
|
9753
|
+
logger.debug(`Error scanning ${dirPath}: ${error.message}`);
|
|
9682
9754
|
}
|
|
9683
9755
|
};
|
|
9684
9756
|
await searchDir(basePath);
|
|
@@ -9694,29 +9766,48 @@ var init_grader = __esm({
|
|
|
9694
9766
|
if (grade2) results.push(grade2);
|
|
9695
9767
|
} else {
|
|
9696
9768
|
const searchPaths = options.targetPath ? [options.targetPath] : await this.getStandardPaths(options.type);
|
|
9769
|
+
const allFiles = [];
|
|
9697
9770
|
for (const searchPath of searchPaths) {
|
|
9698
9771
|
const found = await this.scanDirectory(searchPath, options.type);
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9772
|
+
allFiles.push(...found);
|
|
9773
|
+
}
|
|
9774
|
+
for (let idx = 0; idx < allFiles.length; idx++) {
|
|
9775
|
+
const file = allFiles[idx];
|
|
9776
|
+
if (allFiles.length > 5) {
|
|
9777
|
+
logger.debug(`Grading ${idx + 1}/${allFiles.length}: ${path11.basename(file)}`);
|
|
9778
|
+
if ((idx + 1) % 10 === 0 || idx === allFiles.length - 1) {
|
|
9779
|
+
process.stdout.write(`\r Grading components... ${idx + 1}/${allFiles.length}`);
|
|
9705
9780
|
}
|
|
9706
9781
|
}
|
|
9782
|
+
try {
|
|
9783
|
+
const grade2 = await this.gradeSingle(file, options.type === "both" ? this.detectType(file) : options.type);
|
|
9784
|
+
if (grade2) results.push(grade2);
|
|
9785
|
+
} catch (err) {
|
|
9786
|
+
logger.error(`Failed to grade ${file}: ${err.message}`);
|
|
9787
|
+
}
|
|
9788
|
+
}
|
|
9789
|
+
if (allFiles.length > 5) {
|
|
9790
|
+
process.stdout.write("\r" + " ".repeat(60) + "\r");
|
|
9707
9791
|
}
|
|
9708
9792
|
}
|
|
9709
9793
|
return results;
|
|
9710
9794
|
}
|
|
9711
9795
|
async gradeSingle(filePath, type) {
|
|
9796
|
+
const resolvedPath = path11.resolve(filePath);
|
|
9797
|
+
const cached = this.gradeCache.get(resolvedPath);
|
|
9798
|
+
if (cached) return cached;
|
|
9712
9799
|
const resolvedType = type === "both" ? this.detectType(filePath) : type;
|
|
9800
|
+
let result = null;
|
|
9713
9801
|
if (resolvedType === "aura") {
|
|
9714
9802
|
const bundlePath = filePath.endsWith(".cmp") ? path11.dirname(filePath) : filePath;
|
|
9715
|
-
|
|
9803
|
+
result = await this.auraGrader.grade(bundlePath);
|
|
9716
9804
|
} else if (resolvedType === "vf") {
|
|
9717
|
-
|
|
9805
|
+
result = await this.vfGrader.grade(filePath);
|
|
9718
9806
|
}
|
|
9719
|
-
|
|
9807
|
+
if (result) {
|
|
9808
|
+
this.gradeCache.set(resolvedPath, result);
|
|
9809
|
+
}
|
|
9810
|
+
return result;
|
|
9720
9811
|
}
|
|
9721
9812
|
detectType(filePath) {
|
|
9722
9813
|
if (filePath.endsWith(".cmp") || filePath.includes("/aura/") || filePath.includes("\\aura\\")) return "aura";
|
|
@@ -10007,7 +10098,7 @@ var init_vf_controller_resolver = __esm({
|
|
|
10007
10098
|
|
|
10008
10099
|
// src/utils/first-time.ts
|
|
10009
10100
|
import fs14 from "fs-extra";
|
|
10010
|
-
import
|
|
10101
|
+
import path16 from "path";
|
|
10011
10102
|
import os4 from "os";
|
|
10012
10103
|
function isFirstTimeSync() {
|
|
10013
10104
|
try {
|
|
@@ -10056,8 +10147,8 @@ var init_first_time = __esm({
|
|
|
10056
10147
|
"src/utils/first-time.ts"() {
|
|
10057
10148
|
"use strict";
|
|
10058
10149
|
init_esm_shims();
|
|
10059
|
-
CONFIG_DIR =
|
|
10060
|
-
FIRST_RUN_FILE =
|
|
10150
|
+
CONFIG_DIR = path16.join(os4.homedir(), ".lwc-convert");
|
|
10151
|
+
FIRST_RUN_FILE = path16.join(CONFIG_DIR, ".first-run-complete");
|
|
10061
10152
|
}
|
|
10062
10153
|
});
|
|
10063
10154
|
|
|
@@ -10067,7 +10158,7 @@ __export(interactive_exports, {
|
|
|
10067
10158
|
runInteractiveTui: () => runInteractiveTui
|
|
10068
10159
|
});
|
|
10069
10160
|
import * as p from "@clack/prompts";
|
|
10070
|
-
import * as
|
|
10161
|
+
import * as path17 from "path";
|
|
10071
10162
|
import fs15 from "fs-extra";
|
|
10072
10163
|
function showBreadcrumbs(currentStep, conversionType) {
|
|
10073
10164
|
const breadcrumb = STEPS.map((step, i) => {
|
|
@@ -10095,16 +10186,16 @@ async function findAuraComponents() {
|
|
|
10095
10186
|
const components3 = [];
|
|
10096
10187
|
const cwd = process.cwd();
|
|
10097
10188
|
for (const searchPath of searchPaths) {
|
|
10098
|
-
const fullPath =
|
|
10189
|
+
const fullPath = path17.join(cwd, searchPath);
|
|
10099
10190
|
if (await fs15.pathExists(fullPath)) {
|
|
10100
10191
|
try {
|
|
10101
10192
|
const entries = await fs15.readdir(fullPath, { withFileTypes: true });
|
|
10102
10193
|
for (const entry of entries) {
|
|
10103
10194
|
if (entry.isDirectory()) {
|
|
10104
|
-
const cmpFile =
|
|
10195
|
+
const cmpFile = path17.join(fullPath, entry.name, `${entry.name}.cmp`);
|
|
10105
10196
|
if (await fs15.pathExists(cmpFile)) {
|
|
10106
10197
|
components3.push({
|
|
10107
|
-
value:
|
|
10198
|
+
value: path17.join(searchPath, entry.name),
|
|
10108
10199
|
label: `\u26A1 ${entry.name}`,
|
|
10109
10200
|
hint: searchPath
|
|
10110
10201
|
});
|
|
@@ -10126,14 +10217,14 @@ async function findVfPages() {
|
|
|
10126
10217
|
const pages = [];
|
|
10127
10218
|
const cwd = process.cwd();
|
|
10128
10219
|
for (const searchPath of searchPaths) {
|
|
10129
|
-
const fullPath =
|
|
10220
|
+
const fullPath = path17.join(cwd, searchPath);
|
|
10130
10221
|
if (await fs15.pathExists(fullPath)) {
|
|
10131
10222
|
try {
|
|
10132
10223
|
const entries = await fs15.readdir(fullPath, { withFileTypes: true });
|
|
10133
10224
|
for (const entry of entries) {
|
|
10134
10225
|
if (entry.isFile() && entry.name.endsWith(".page")) {
|
|
10135
10226
|
pages.push({
|
|
10136
|
-
value:
|
|
10227
|
+
value: path17.join(searchPath, entry.name),
|
|
10137
10228
|
label: `\u{1F4C4} ${entry.name.replace(".page", "")}`,
|
|
10138
10229
|
hint: searchPath
|
|
10139
10230
|
});
|
|
@@ -10154,14 +10245,14 @@ async function findApexControllers() {
|
|
|
10154
10245
|
const controllers = [];
|
|
10155
10246
|
const cwd = process.cwd();
|
|
10156
10247
|
for (const searchPath of searchPaths) {
|
|
10157
|
-
const fullPath =
|
|
10248
|
+
const fullPath = path17.join(cwd, searchPath);
|
|
10158
10249
|
if (await fs15.pathExists(fullPath)) {
|
|
10159
10250
|
try {
|
|
10160
10251
|
const entries = await fs15.readdir(fullPath, { withFileTypes: true });
|
|
10161
10252
|
for (const entry of entries) {
|
|
10162
10253
|
if (entry.isFile() && entry.name.endsWith(".cls")) {
|
|
10163
10254
|
controllers.push({
|
|
10164
|
-
value:
|
|
10255
|
+
value: path17.join(searchPath, entry.name),
|
|
10165
10256
|
label: `\u{1F4CB} ${entry.name.replace(".cls", "")}`
|
|
10166
10257
|
});
|
|
10167
10258
|
}
|
|
@@ -10415,7 +10506,7 @@ async function runInteractiveTui() {
|
|
|
10415
10506
|
}
|
|
10416
10507
|
while (currentStep === 2 && conversionType === "vf" && componentPath && action !== "grade") {
|
|
10417
10508
|
showBreadcrumbs(currentStep, conversionType);
|
|
10418
|
-
const resolvedPagePath =
|
|
10509
|
+
const resolvedPagePath = path17.resolve(componentPath);
|
|
10419
10510
|
if (await fs15.pathExists(resolvedPagePath)) {
|
|
10420
10511
|
const s = p.spinner();
|
|
10421
10512
|
s.start("Analyzing page for controller references...");
|
|
@@ -10469,7 +10560,7 @@ async function runInteractiveTui() {
|
|
|
10469
10560
|
if (addMore) {
|
|
10470
10561
|
const allControllers = await findApexControllers();
|
|
10471
10562
|
const availableControllers = allControllers.filter(
|
|
10472
|
-
(c) => !controllerPaths.includes(
|
|
10563
|
+
(c) => !controllerPaths.includes(path17.resolve(c.value))
|
|
10473
10564
|
);
|
|
10474
10565
|
if (availableControllers.length > 0) {
|
|
10475
10566
|
const additional = await p.multiselect({
|
|
@@ -10478,7 +10569,7 @@ async function runInteractiveTui() {
|
|
|
10478
10569
|
required: false
|
|
10479
10570
|
});
|
|
10480
10571
|
if (!isCancel2(additional)) {
|
|
10481
|
-
controllerPaths.push(...additional.map((c) =>
|
|
10572
|
+
controllerPaths.push(...additional.map((c) => path17.resolve(c)));
|
|
10482
10573
|
}
|
|
10483
10574
|
}
|
|
10484
10575
|
}
|
|
@@ -10505,7 +10596,7 @@ async function runInteractiveTui() {
|
|
|
10505
10596
|
continue wizardLoop;
|
|
10506
10597
|
}
|
|
10507
10598
|
controllerPath = selected;
|
|
10508
|
-
controllerPaths = [
|
|
10599
|
+
controllerPaths = [path17.resolve(controllerPath)];
|
|
10509
10600
|
}
|
|
10510
10601
|
}
|
|
10511
10602
|
}
|
|
@@ -10612,7 +10703,7 @@ async function runInteractiveTui() {
|
|
|
10612
10703
|
if (controllerPaths.length > 0) {
|
|
10613
10704
|
summaryLines.push(`${import_picocolors.default.dim("Controllers:")} ${controllerPaths.length} selected`);
|
|
10614
10705
|
controllerPaths.forEach((cp) => {
|
|
10615
|
-
summaryLines.push(` ${import_picocolors.default.dim("\u2022")} ${
|
|
10706
|
+
summaryLines.push(` ${import_picocolors.default.dim("\u2022")} ${path17.basename(cp)}`);
|
|
10616
10707
|
});
|
|
10617
10708
|
}
|
|
10618
10709
|
summaryLines.push(`${import_picocolors.default.dim("Mode:")} ${conversionMode === "full" ? "\u26A1 Full" : "\u{1F4DD} Scaffolding"}`);
|
|
@@ -10682,7 +10773,7 @@ var init_types = __esm({
|
|
|
10682
10773
|
|
|
10683
10774
|
// src/tui/store/persistence.ts
|
|
10684
10775
|
import fs16 from "fs-extra";
|
|
10685
|
-
import
|
|
10776
|
+
import path18 from "path";
|
|
10686
10777
|
import os5 from "os";
|
|
10687
10778
|
async function savePreferences(prefs) {
|
|
10688
10779
|
try {
|
|
@@ -10710,8 +10801,8 @@ var init_persistence = __esm({
|
|
|
10710
10801
|
"use strict";
|
|
10711
10802
|
init_esm_shims();
|
|
10712
10803
|
init_types();
|
|
10713
|
-
CONFIG_DIR2 =
|
|
10714
|
-
PREFS_PATH =
|
|
10804
|
+
CONFIG_DIR2 = path18.join(os5.homedir(), ".lwc-convert");
|
|
10805
|
+
PREFS_PATH = path18.join(CONFIG_DIR2, "preferences.json");
|
|
10715
10806
|
}
|
|
10716
10807
|
});
|
|
10717
10808
|
|
|
@@ -10721,7 +10812,7 @@ __export(discovery_exports, {
|
|
|
10721
10812
|
discoverComponents: () => discoverComponents
|
|
10722
10813
|
});
|
|
10723
10814
|
import fs17 from "fs-extra";
|
|
10724
|
-
import
|
|
10815
|
+
import path19 from "path";
|
|
10725
10816
|
async function discoverComponents(projectPath) {
|
|
10726
10817
|
const auraComponents = [];
|
|
10727
10818
|
const vfComponents = [];
|
|
@@ -10734,7 +10825,7 @@ async function discoverComponents(projectPath) {
|
|
|
10734
10825
|
"pages"
|
|
10735
10826
|
];
|
|
10736
10827
|
for (const searchPath of searchPaths) {
|
|
10737
|
-
const fullPath =
|
|
10828
|
+
const fullPath = path19.join(projectPath, searchPath);
|
|
10738
10829
|
if (await fs17.pathExists(fullPath)) {
|
|
10739
10830
|
if (searchPath.includes("aura")) {
|
|
10740
10831
|
const components3 = await discoverAuraComponents(fullPath);
|
|
@@ -10751,7 +10842,7 @@ async function discoverComponents(projectPath) {
|
|
|
10751
10842
|
"components"
|
|
10752
10843
|
];
|
|
10753
10844
|
for (const searchPath of vfComponentPaths) {
|
|
10754
|
-
const fullPath =
|
|
10845
|
+
const fullPath = path19.join(projectPath, searchPath);
|
|
10755
10846
|
if (await fs17.pathExists(fullPath)) {
|
|
10756
10847
|
const components3 = await discoverVfComponents(fullPath);
|
|
10757
10848
|
vfComponents.push(...components3);
|
|
@@ -10775,7 +10866,7 @@ async function discoverAuraComponents(auraPath) {
|
|
|
10775
10866
|
const entries = await fs17.readdir(auraPath, { withFileTypes: true });
|
|
10776
10867
|
for (const entry of entries) {
|
|
10777
10868
|
if (entry.isDirectory()) {
|
|
10778
|
-
const componentPath =
|
|
10869
|
+
const componentPath = path19.join(auraPath, entry.name);
|
|
10779
10870
|
const files = await fs17.readdir(componentPath);
|
|
10780
10871
|
const cmpFile = files.find((f) => f.endsWith(".cmp"));
|
|
10781
10872
|
if (cmpFile) {
|
|
@@ -10804,10 +10895,10 @@ async function discoverVfPages(pagesPath) {
|
|
|
10804
10895
|
for (const entry of entries) {
|
|
10805
10896
|
if (entry.isFile() && entry.name.endsWith(".page")) {
|
|
10806
10897
|
const name = entry.name.replace(".page", "");
|
|
10807
|
-
const pagePath =
|
|
10898
|
+
const pagePath = path19.join(pagesPath, entry.name);
|
|
10808
10899
|
const relatedFiles = [entry.name];
|
|
10809
10900
|
const metaFile = `${entry.name}-meta.xml`;
|
|
10810
|
-
if (await fs17.pathExists(
|
|
10901
|
+
if (await fs17.pathExists(path19.join(pagesPath, metaFile))) {
|
|
10811
10902
|
relatedFiles.push(metaFile);
|
|
10812
10903
|
}
|
|
10813
10904
|
pages.push({
|
|
@@ -10833,7 +10924,7 @@ async function discoverVfComponents(componentsPath) {
|
|
|
10833
10924
|
for (const entry of entries) {
|
|
10834
10925
|
if (entry.isFile() && entry.name.endsWith(".component")) {
|
|
10835
10926
|
const name = entry.name.replace(".component", "");
|
|
10836
|
-
const componentPath =
|
|
10927
|
+
const componentPath = path19.join(componentsPath, entry.name);
|
|
10837
10928
|
components3.push({
|
|
10838
10929
|
id: `vf-component-${name}`,
|
|
10839
10930
|
name,
|
|
@@ -11068,8 +11159,8 @@ var init_store = __esm({
|
|
|
11068
11159
|
}
|
|
11069
11160
|
},
|
|
11070
11161
|
// Project actions
|
|
11071
|
-
setProjectPath: (
|
|
11072
|
-
set({ projectPath:
|
|
11162
|
+
setProjectPath: (path20) => {
|
|
11163
|
+
set({ projectPath: path20 });
|
|
11073
11164
|
},
|
|
11074
11165
|
setComponents: (aura, vf) => {
|
|
11075
11166
|
set({ auraComponents: aura, vfComponents: vf });
|
|
@@ -14095,6 +14186,10 @@ function ConversionWizard() {
|
|
|
14095
14186
|
}
|
|
14096
14187
|
} else if (wizard.currentStep === 1 && focusedField === 0) {
|
|
14097
14188
|
handleNext();
|
|
14189
|
+
} else if (wizard.currentStep === 2 && focusedField === 1) {
|
|
14190
|
+
updateWizardState({ generatePreview: !wizard.generatePreview });
|
|
14191
|
+
} else if (wizard.currentStep === 2 && focusedField === 2) {
|
|
14192
|
+
updateWizardState({ generateTests: !wizard.generateTests });
|
|
14098
14193
|
} else if (canGoNext()) {
|
|
14099
14194
|
handleNext();
|
|
14100
14195
|
}
|
|
@@ -14118,6 +14213,7 @@ function ConversionWizard() {
|
|
|
14118
14213
|
output: wizard.outputDir,
|
|
14119
14214
|
full: wizard.conversionMode === "full",
|
|
14120
14215
|
preview: wizard.generatePreview,
|
|
14216
|
+
generateTests: wizard.generateTests,
|
|
14121
14217
|
dryRun: false,
|
|
14122
14218
|
verbose: false,
|
|
14123
14219
|
open: false
|
|
@@ -14288,7 +14384,7 @@ function ConversionWizard() {
|
|
|
14288
14384
|
setSelectedComponentIndex(0);
|
|
14289
14385
|
setComponentListScrollOffset(0);
|
|
14290
14386
|
},
|
|
14291
|
-
onSourcePathChange: (
|
|
14387
|
+
onSourcePathChange: (path20) => updateWizardState({ sourcePath: path20 }),
|
|
14292
14388
|
onComponentSelect: (component) => {
|
|
14293
14389
|
updateWizardState({ sourcePath: component.path });
|
|
14294
14390
|
},
|
|
@@ -14462,7 +14558,9 @@ function OptionsStep({
|
|
|
14462
14558
|
generatePreview,
|
|
14463
14559
|
generateTests,
|
|
14464
14560
|
focusedField,
|
|
14465
|
-
onOutputDirChange
|
|
14561
|
+
onOutputDirChange,
|
|
14562
|
+
onPreviewChange,
|
|
14563
|
+
onTestsChange
|
|
14466
14564
|
}) {
|
|
14467
14565
|
const preferences = useStore((state) => state.preferences);
|
|
14468
14566
|
const theme = getTheme(preferences.theme);
|
|
@@ -14478,7 +14576,32 @@ function OptionsStep({
|
|
|
14478
14576
|
focus: focusedField === 0
|
|
14479
14577
|
}
|
|
14480
14578
|
) }),
|
|
14481
|
-
/* @__PURE__ */
|
|
14579
|
+
/* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
14580
|
+
/* @__PURE__ */ jsxs22(Text24, { color: theme.text, bold: true, children: [
|
|
14581
|
+
"Generation Options ",
|
|
14582
|
+
focusedField === 1 || focusedField === 2 ? /* @__PURE__ */ jsx22(Text24, { color: theme.accent, children: "(Enter to toggle)" }) : ""
|
|
14583
|
+
] }),
|
|
14584
|
+
/* @__PURE__ */ jsxs22(Box21, { marginTop: 1, flexDirection: "column", children: [
|
|
14585
|
+
/* @__PURE__ */ jsx22(
|
|
14586
|
+
Checkbox,
|
|
14587
|
+
{
|
|
14588
|
+
label: "Generate UI Preview",
|
|
14589
|
+
checked: generatePreview,
|
|
14590
|
+
onChange: onPreviewChange,
|
|
14591
|
+
isFocused: focusedField === 1
|
|
14592
|
+
}
|
|
14593
|
+
),
|
|
14594
|
+
/* @__PURE__ */ jsx22(
|
|
14595
|
+
Checkbox,
|
|
14596
|
+
{
|
|
14597
|
+
label: "Generate Jest Tests",
|
|
14598
|
+
checked: generateTests,
|
|
14599
|
+
onChange: onTestsChange,
|
|
14600
|
+
isFocused: focusedField === 2
|
|
14601
|
+
}
|
|
14602
|
+
)
|
|
14603
|
+
] })
|
|
14604
|
+
] })
|
|
14482
14605
|
] });
|
|
14483
14606
|
}
|
|
14484
14607
|
function ReviewStep({ wizard }) {
|
|
@@ -14751,7 +14874,7 @@ function ExportModal() {
|
|
|
14751
14874
|
{
|
|
14752
14875
|
label: "Output Path",
|
|
14753
14876
|
value: options.outputPath,
|
|
14754
|
-
onChange: (
|
|
14877
|
+
onChange: (path20) => setOptions((o) => ({ ...o, outputPath: path20 })),
|
|
14755
14878
|
focus: focusedField === 4
|
|
14756
14879
|
}
|
|
14757
14880
|
) }),
|
|
@@ -15102,9 +15225,14 @@ async function fetchLatestVersion() {
|
|
|
15102
15225
|
}
|
|
15103
15226
|
}
|
|
15104
15227
|
function parseVersion(version) {
|
|
15105
|
-
|
|
15228
|
+
const cleaned = version.replace(/^v/, "").replace(/[-+].*$/, "");
|
|
15229
|
+
return cleaned.split(".").map((n) => parseInt(n, 10) || 0);
|
|
15230
|
+
}
|
|
15231
|
+
function isPreRelease(version) {
|
|
15232
|
+
return /[-]/.test(version.replace(/^v/, ""));
|
|
15106
15233
|
}
|
|
15107
15234
|
function isNewerVersion(latest, current) {
|
|
15235
|
+
if (isPreRelease(latest)) return false;
|
|
15108
15236
|
const latestParts = parseVersion(latest);
|
|
15109
15237
|
const currentParts = parseVersion(current);
|
|
15110
15238
|
for (let i = 0; i < Math.max(latestParts.length, currentParts.length); i++) {
|
|
@@ -15155,10 +15283,15 @@ async function checkForUpdates() {
|
|
|
15155
15283
|
}
|
|
15156
15284
|
function formatUpdateMessage(latestVersion, currentVersion) {
|
|
15157
15285
|
const versionText = `${currentVersion} \u2192 ${latestVersion}`;
|
|
15158
|
-
|
|
15159
|
-
|
|
15160
|
-
|
|
15161
|
-
|
|
15286
|
+
const updateCmd = `npm i -g ${CLI_NAME}`;
|
|
15287
|
+
const line1Content = ` Update available: ${versionText} `;
|
|
15288
|
+
const line2Content = ` Run ${updateCmd} to update `;
|
|
15289
|
+
const innerWidth = Math.max(line1Content.length, line2Content.length);
|
|
15290
|
+
const border = "\u2500".repeat(innerWidth);
|
|
15291
|
+
return `\x1B[33m \u256D${border}\u256E
|
|
15292
|
+
\u2502${line1Content.padEnd(innerWidth)}\u2502
|
|
15293
|
+
\u2502 Run \x1B[36m${updateCmd}\x1B[33m to update${" ".repeat(innerWidth - line2Content.length)} \u2502
|
|
15294
|
+
\u2570${border}\u256F\x1B[0m`;
|
|
15162
15295
|
}
|
|
15163
15296
|
|
|
15164
15297
|
// src/cli/commands/grade.ts
|
|
@@ -15166,6 +15299,7 @@ init_esm_shims();
|
|
|
15166
15299
|
init_logger();
|
|
15167
15300
|
init_grader();
|
|
15168
15301
|
init_path_resolver();
|
|
15302
|
+
import * as path12 from "path";
|
|
15169
15303
|
import fs9 from "fs-extra";
|
|
15170
15304
|
|
|
15171
15305
|
// src/cli/tui/grade-tui.ts
|
|
@@ -15464,7 +15598,7 @@ async function launchGradeTui(components3, summary) {
|
|
|
15464
15598
|
process.stdin.setRawMode(true);
|
|
15465
15599
|
hideCursor();
|
|
15466
15600
|
render(state);
|
|
15467
|
-
return new Promise((
|
|
15601
|
+
return new Promise((resolve10) => {
|
|
15468
15602
|
const handleKeypress = (str, key) => {
|
|
15469
15603
|
if (!key) return;
|
|
15470
15604
|
if (state.isSearching) {
|
|
@@ -15487,7 +15621,7 @@ async function launchGradeTui(components3, summary) {
|
|
|
15487
15621
|
showCursor();
|
|
15488
15622
|
clearScreen();
|
|
15489
15623
|
process.stdin.setRawMode(false);
|
|
15490
|
-
|
|
15624
|
+
resolve10();
|
|
15491
15625
|
return;
|
|
15492
15626
|
}
|
|
15493
15627
|
if (state.viewMode === "detail") {
|
|
@@ -15639,6 +15773,7 @@ async function grade(target, options) {
|
|
|
15639
15773
|
if (options.format === "json") {
|
|
15640
15774
|
const output = { summary, components: filteredResults };
|
|
15641
15775
|
if (options.output) {
|
|
15776
|
+
await fs9.ensureDir(path12.dirname(path12.resolve(options.output)));
|
|
15642
15777
|
await fs9.writeJson(options.output, output, { spaces: 2 });
|
|
15643
15778
|
logger.success(`Results written to ${options.output}`);
|
|
15644
15779
|
} else {
|
|
@@ -15647,6 +15782,7 @@ async function grade(target, options) {
|
|
|
15647
15782
|
} else if (options.format === "csv") {
|
|
15648
15783
|
const csvContent = generateCsvReport(filteredResults, summary);
|
|
15649
15784
|
if (options.output) {
|
|
15785
|
+
await fs9.ensureDir(path12.dirname(path12.resolve(options.output)));
|
|
15650
15786
|
await fs9.writeFile(options.output, csvContent);
|
|
15651
15787
|
logger.success(`CSV report written to ${options.output}`);
|
|
15652
15788
|
} else {
|
|
@@ -15693,11 +15829,19 @@ function filterResults(results, filter) {
|
|
|
15693
15829
|
if (filter.startsWith("score:")) {
|
|
15694
15830
|
const condition = filter.substring(6);
|
|
15695
15831
|
if (condition.startsWith("<")) {
|
|
15696
|
-
const val = parseInt(condition.substring(1));
|
|
15832
|
+
const val = parseInt(condition.substring(1), 10);
|
|
15833
|
+
if (isNaN(val)) {
|
|
15834
|
+
logger.warn(`Invalid score filter value: "${condition.substring(1)}". Expected a number.`);
|
|
15835
|
+
return results;
|
|
15836
|
+
}
|
|
15697
15837
|
return results.filter((r) => r.overallScore < val);
|
|
15698
15838
|
}
|
|
15699
15839
|
if (condition.startsWith(">")) {
|
|
15700
|
-
const val = parseInt(condition.substring(1));
|
|
15840
|
+
const val = parseInt(condition.substring(1), 10);
|
|
15841
|
+
if (isNaN(val)) {
|
|
15842
|
+
logger.warn(`Invalid score filter value: "${condition.substring(1)}". Expected a number.`);
|
|
15843
|
+
return results;
|
|
15844
|
+
}
|
|
15701
15845
|
return results.filter((r) => r.overallScore > val);
|
|
15702
15846
|
}
|
|
15703
15847
|
}
|
|
@@ -15793,7 +15937,7 @@ function generateCsvReport(results, summary) {
|
|
|
15793
15937
|
init_esm_shims();
|
|
15794
15938
|
init_logger();
|
|
15795
15939
|
import fs12 from "fs-extra";
|
|
15796
|
-
import * as
|
|
15940
|
+
import * as path15 from "path";
|
|
15797
15941
|
|
|
15798
15942
|
// src/dependency-graph/analyzer.ts
|
|
15799
15943
|
init_esm_shims();
|
|
@@ -15803,7 +15947,7 @@ init_logger();
|
|
|
15803
15947
|
init_esm_shims();
|
|
15804
15948
|
init_logger();
|
|
15805
15949
|
import fs10 from "fs-extra";
|
|
15806
|
-
import * as
|
|
15950
|
+
import * as path13 from "path";
|
|
15807
15951
|
import * as htmlparser23 from "htmlparser2";
|
|
15808
15952
|
import { DomHandler as DomHandler3 } from "domhandler";
|
|
15809
15953
|
function extractMarkupDependencies(markup, includeBaseComponents) {
|
|
@@ -15981,7 +16125,7 @@ async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
|
|
|
15981
16125
|
logger.debug(`Not a directory: ${bundlePath}`);
|
|
15982
16126
|
return null;
|
|
15983
16127
|
}
|
|
15984
|
-
const componentName =
|
|
16128
|
+
const componentName = path13.basename(bundlePath);
|
|
15985
16129
|
const files = await fs10.readdir(bundlePath);
|
|
15986
16130
|
const cmpFile = files.find((f) => f.endsWith(".cmp"));
|
|
15987
16131
|
if (!cmpFile) {
|
|
@@ -15991,18 +16135,18 @@ async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
|
|
|
15991
16135
|
const context = {
|
|
15992
16136
|
markup: ""
|
|
15993
16137
|
};
|
|
15994
|
-
context.markup = await fs10.readFile(
|
|
16138
|
+
context.markup = await fs10.readFile(path13.join(bundlePath, cmpFile), "utf-8");
|
|
15995
16139
|
const controllerFile = files.find((f) => f.endsWith("Controller.js"));
|
|
15996
16140
|
if (controllerFile) {
|
|
15997
16141
|
context.controllerJs = await fs10.readFile(
|
|
15998
|
-
|
|
16142
|
+
path13.join(bundlePath, controllerFile),
|
|
15999
16143
|
"utf-8"
|
|
16000
16144
|
);
|
|
16001
16145
|
}
|
|
16002
16146
|
const helperFile = files.find((f) => f.endsWith("Helper.js"));
|
|
16003
16147
|
if (helperFile) {
|
|
16004
16148
|
context.helperJs = await fs10.readFile(
|
|
16005
|
-
|
|
16149
|
+
path13.join(bundlePath, helperFile),
|
|
16006
16150
|
"utf-8"
|
|
16007
16151
|
);
|
|
16008
16152
|
}
|
|
@@ -16027,13 +16171,13 @@ async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
|
|
|
16027
16171
|
}
|
|
16028
16172
|
}
|
|
16029
16173
|
async function getPackageDirectories(rootPath) {
|
|
16030
|
-
const sfdxProjectPath =
|
|
16174
|
+
const sfdxProjectPath = path13.join(rootPath, "sfdx-project.json");
|
|
16031
16175
|
if (await fs10.pathExists(sfdxProjectPath)) {
|
|
16032
16176
|
try {
|
|
16033
16177
|
const projectConfig = await fs10.readJson(sfdxProjectPath);
|
|
16034
16178
|
if (projectConfig.packageDirectories && Array.isArray(projectConfig.packageDirectories)) {
|
|
16035
16179
|
return projectConfig.packageDirectories.map(
|
|
16036
|
-
(pkg) =>
|
|
16180
|
+
(pkg) => path13.join(rootPath, pkg.path)
|
|
16037
16181
|
);
|
|
16038
16182
|
}
|
|
16039
16183
|
} catch (error) {
|
|
@@ -16050,7 +16194,7 @@ async function findAuraDirectories(basePath) {
|
|
|
16050
16194
|
const entries = await fs10.readdir(dirPath, { withFileTypes: true });
|
|
16051
16195
|
for (const entry of entries) {
|
|
16052
16196
|
if (entry.isDirectory()) {
|
|
16053
|
-
const fullPath =
|
|
16197
|
+
const fullPath = path13.join(dirPath, entry.name);
|
|
16054
16198
|
if (entry.name === "aura") {
|
|
16055
16199
|
auraDirectories.push(fullPath);
|
|
16056
16200
|
} else if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
@@ -16076,9 +16220,9 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
|
|
|
16076
16220
|
logger.debug(`Found aura directories from sfdx-project.json: ${searchPaths.join(", ")}`);
|
|
16077
16221
|
}
|
|
16078
16222
|
const fallbackPaths = [
|
|
16079
|
-
|
|
16080
|
-
|
|
16081
|
-
|
|
16223
|
+
path13.join(rootPath, "force-app/main/default/aura"),
|
|
16224
|
+
path13.join(rootPath, "src/aura"),
|
|
16225
|
+
path13.join(rootPath, "aura")
|
|
16082
16226
|
];
|
|
16083
16227
|
for (const fallback of fallbackPaths) {
|
|
16084
16228
|
if (!searchPaths.includes(fallback)) {
|
|
@@ -16107,7 +16251,7 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
|
|
|
16107
16251
|
}
|
|
16108
16252
|
} else {
|
|
16109
16253
|
for (const item of files) {
|
|
16110
|
-
const itemPath =
|
|
16254
|
+
const itemPath = path13.join(searchPath, item);
|
|
16111
16255
|
const itemStat = await fs10.stat(itemPath);
|
|
16112
16256
|
if (itemStat.isDirectory()) {
|
|
16113
16257
|
const result = await analyzeAuraComponent(itemPath, includeBaseComponents);
|
|
@@ -16132,7 +16276,7 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
|
|
|
16132
16276
|
init_esm_shims();
|
|
16133
16277
|
init_logger();
|
|
16134
16278
|
import fs11 from "fs-extra";
|
|
16135
|
-
import * as
|
|
16279
|
+
import * as path14 from "path";
|
|
16136
16280
|
import * as htmlparser24 from "htmlparser2";
|
|
16137
16281
|
import { DomHandler as DomHandler4 } from "domhandler";
|
|
16138
16282
|
function extractVfDependencies(markup) {
|
|
@@ -16320,7 +16464,7 @@ async function analyzeVfPage(pagePath) {
|
|
|
16320
16464
|
const files = await fs11.readdir(pagePath);
|
|
16321
16465
|
const pageFile = files.find((f) => f.endsWith(".page"));
|
|
16322
16466
|
if (pageFile) {
|
|
16323
|
-
actualPath =
|
|
16467
|
+
actualPath = path14.join(pagePath, pageFile);
|
|
16324
16468
|
} else {
|
|
16325
16469
|
return null;
|
|
16326
16470
|
}
|
|
@@ -16332,7 +16476,7 @@ async function analyzeVfPage(pagePath) {
|
|
|
16332
16476
|
return null;
|
|
16333
16477
|
}
|
|
16334
16478
|
const markup = await fs11.readFile(actualPath, "utf-8");
|
|
16335
|
-
const pageName =
|
|
16479
|
+
const pageName = path14.basename(actualPath, ".page");
|
|
16336
16480
|
const dependencies = extractVfDependencies(markup);
|
|
16337
16481
|
return {
|
|
16338
16482
|
id: `vf:${pageName}`,
|
|
@@ -16356,7 +16500,7 @@ async function analyzeVfComponent(componentPath) {
|
|
|
16356
16500
|
const files = await fs11.readdir(componentPath);
|
|
16357
16501
|
const componentFile = files.find((f) => f.endsWith(".component"));
|
|
16358
16502
|
if (componentFile) {
|
|
16359
|
-
actualPath =
|
|
16503
|
+
actualPath = path14.join(componentPath, componentFile);
|
|
16360
16504
|
} else {
|
|
16361
16505
|
return null;
|
|
16362
16506
|
}
|
|
@@ -16368,7 +16512,7 @@ async function analyzeVfComponent(componentPath) {
|
|
|
16368
16512
|
return null;
|
|
16369
16513
|
}
|
|
16370
16514
|
const markup = await fs11.readFile(actualPath, "utf-8");
|
|
16371
|
-
const componentName =
|
|
16515
|
+
const componentName = path14.basename(actualPath, ".component");
|
|
16372
16516
|
const dependencies = extractVfDependencies(markup);
|
|
16373
16517
|
return {
|
|
16374
16518
|
id: `vf:${componentName}`,
|
|
@@ -16383,13 +16527,13 @@ async function analyzeVfComponent(componentPath) {
|
|
|
16383
16527
|
}
|
|
16384
16528
|
}
|
|
16385
16529
|
async function getPackageDirectories2(rootPath) {
|
|
16386
|
-
const sfdxProjectPath =
|
|
16530
|
+
const sfdxProjectPath = path14.join(rootPath, "sfdx-project.json");
|
|
16387
16531
|
if (await fs11.pathExists(sfdxProjectPath)) {
|
|
16388
16532
|
try {
|
|
16389
16533
|
const projectConfig = await fs11.readJson(sfdxProjectPath);
|
|
16390
16534
|
if (projectConfig.packageDirectories && Array.isArray(projectConfig.packageDirectories)) {
|
|
16391
16535
|
return projectConfig.packageDirectories.map(
|
|
16392
|
-
(pkg) =>
|
|
16536
|
+
(pkg) => path14.join(rootPath, pkg.path)
|
|
16393
16537
|
);
|
|
16394
16538
|
}
|
|
16395
16539
|
} catch (error) {
|
|
@@ -16407,7 +16551,7 @@ async function findVfDirectories(basePath) {
|
|
|
16407
16551
|
const entries = await fs11.readdir(dirPath, { withFileTypes: true });
|
|
16408
16552
|
for (const entry of entries) {
|
|
16409
16553
|
if (entry.isDirectory()) {
|
|
16410
|
-
const fullPath =
|
|
16554
|
+
const fullPath = path14.join(dirPath, entry.name);
|
|
16411
16555
|
if (entry.name === "pages") {
|
|
16412
16556
|
pagesDirectories.push(fullPath);
|
|
16413
16557
|
} else if (entry.name === "components") {
|
|
@@ -16438,9 +16582,9 @@ async function scanVfPages(rootPath) {
|
|
|
16438
16582
|
logger.debug(`Found components directories from sfdx-project.json: ${componentSearchPaths.join(", ")}`);
|
|
16439
16583
|
}
|
|
16440
16584
|
const fallbackPagePaths = [
|
|
16441
|
-
|
|
16442
|
-
|
|
16443
|
-
|
|
16585
|
+
path14.join(rootPath, "force-app/main/default/pages"),
|
|
16586
|
+
path14.join(rootPath, "src/pages"),
|
|
16587
|
+
path14.join(rootPath, "pages")
|
|
16444
16588
|
];
|
|
16445
16589
|
for (const fallback of fallbackPagePaths) {
|
|
16446
16590
|
if (!pageSearchPaths.includes(fallback)) {
|
|
@@ -16448,9 +16592,9 @@ async function scanVfPages(rootPath) {
|
|
|
16448
16592
|
}
|
|
16449
16593
|
}
|
|
16450
16594
|
const fallbackComponentPaths = [
|
|
16451
|
-
|
|
16452
|
-
|
|
16453
|
-
|
|
16595
|
+
path14.join(rootPath, "force-app/main/default/components"),
|
|
16596
|
+
path14.join(rootPath, "src/components"),
|
|
16597
|
+
path14.join(rootPath, "components")
|
|
16454
16598
|
];
|
|
16455
16599
|
for (const fallback of fallbackComponentPaths) {
|
|
16456
16600
|
if (!componentSearchPaths.includes(fallback)) {
|
|
@@ -16487,7 +16631,7 @@ async function scanVfPages(rootPath) {
|
|
|
16487
16631
|
const files = await fs11.readdir(searchPath);
|
|
16488
16632
|
for (const file of files) {
|
|
16489
16633
|
if (file.endsWith(".page")) {
|
|
16490
|
-
const result = await analyzeVfPage(
|
|
16634
|
+
const result = await analyzeVfPage(path14.join(searchPath, file));
|
|
16491
16635
|
if (result) {
|
|
16492
16636
|
results.push(result);
|
|
16493
16637
|
}
|
|
@@ -16508,7 +16652,7 @@ async function scanVfPages(rootPath) {
|
|
|
16508
16652
|
const files = await fs11.readdir(searchPath);
|
|
16509
16653
|
for (const file of files) {
|
|
16510
16654
|
if (file.endsWith(".component")) {
|
|
16511
|
-
const result = await analyzeVfComponent(
|
|
16655
|
+
const result = await analyzeVfComponent(path14.join(searchPath, file));
|
|
16512
16656
|
if (result) {
|
|
16513
16657
|
results.push(result);
|
|
16514
16658
|
}
|
|
@@ -17515,7 +17659,7 @@ function formatSimpleMermaidOutput(graph, maxNodes = 30) {
|
|
|
17515
17659
|
// src/cli/commands/deps.ts
|
|
17516
17660
|
async function analyzeDeps(target, options) {
|
|
17517
17661
|
logger.setVerbose(options.verbose);
|
|
17518
|
-
const targetPath = target ?
|
|
17662
|
+
const targetPath = target ? path15.resolve(target) : process.cwd();
|
|
17519
17663
|
logger.banner();
|
|
17520
17664
|
logger.header("Dependency Graph Analysis");
|
|
17521
17665
|
logger.info(`Analyzing: ${targetPath}`);
|
|
@@ -17565,14 +17709,6 @@ async function analyzeDeps(target, options) {
|
|
|
17565
17709
|
console.log(output);
|
|
17566
17710
|
}
|
|
17567
17711
|
break;
|
|
17568
|
-
case "html":
|
|
17569
|
-
logger.warn("HTML format not yet implemented. Using console output.");
|
|
17570
|
-
formatConsoleOutput(graph, conversionOrder, options.showOrphans);
|
|
17571
|
-
break;
|
|
17572
|
-
case "dot":
|
|
17573
|
-
logger.warn("DOT format not yet implemented. Using console output.");
|
|
17574
|
-
formatConsoleOutput(graph, conversionOrder, options.showOrphans);
|
|
17575
|
-
break;
|
|
17576
17712
|
case "console":
|
|
17577
17713
|
default:
|
|
17578
17714
|
formatConsoleOutput(graph, conversionOrder, options.showOrphans);
|
|
@@ -17591,8 +17727,8 @@ async function analyzeDeps(target, options) {
|
|
|
17591
17727
|
}
|
|
17592
17728
|
}
|
|
17593
17729
|
async function writeOutput(filePath, content) {
|
|
17594
|
-
const outputPath =
|
|
17595
|
-
const outputDir =
|
|
17730
|
+
const outputPath = path15.resolve(filePath);
|
|
17731
|
+
const outputDir = path15.dirname(outputPath);
|
|
17596
17732
|
await fs12.ensureDir(outputDir);
|
|
17597
17733
|
await fs12.writeFile(outputPath, content, "utf-8");
|
|
17598
17734
|
}
|
|
@@ -17610,7 +17746,7 @@ program.name(CLI_NAME).description(CLI_DESCRIPTION).version(CLI_VERSION).hook("p
|
|
|
17610
17746
|
} catch {
|
|
17611
17747
|
}
|
|
17612
17748
|
});
|
|
17613
|
-
program.command("aura <path>").description("Convert an Aura component bundle to LWC").option("--full", "Run full automated conversion (default: scaffolding only)", false).option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("--open", "Open output folder in file explorer after conversion", false).option("--preview", "Generate and open HTML preview of converted component", false).option("--dry-run", "Preview conversion without writing files", false).option("--verbose", "Show detailed conversion logs", false).action(async (bundlePath, options) => {
|
|
17749
|
+
program.command("aura <path>").description("Convert an Aura component bundle to LWC").option("--full", "Run full automated conversion (default: scaffolding only)", false).option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("--api-version <version>", "Salesforce API version for meta.xml", DEFAULT_API_VERSION).option("--open", "Open output folder in file explorer after conversion", false).option("--preview", "Generate and open HTML preview of converted component", false).option("--dry-run", "Preview conversion without writing files", false).option("--verbose", "Show detailed conversion logs", false).action(async (bundlePath, options) => {
|
|
17614
17750
|
logger.setVerbose(options.verbose);
|
|
17615
17751
|
await convertAura(bundlePath, {
|
|
17616
17752
|
output: options.output,
|
|
@@ -17618,10 +17754,11 @@ program.command("aura <path>").description("Convert an Aura component bundle to
|
|
|
17618
17754
|
dryRun: options.dryRun,
|
|
17619
17755
|
verbose: options.verbose,
|
|
17620
17756
|
open: options.open,
|
|
17621
|
-
preview: options.preview
|
|
17757
|
+
preview: options.preview,
|
|
17758
|
+
apiVersion: options.apiVersion
|
|
17622
17759
|
});
|
|
17623
17760
|
});
|
|
17624
|
-
program.command("vf <path>").description("Convert a Visualforce page to LWC").option("--full", "Run full automated conversion (default: scaffolding only)", false).option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("--controller <path>", "Include Apex controller file for analysis").option("--open", "Open output folder in file explorer after conversion", false).option("--preview", "Generate and open HTML preview of converted component", false).option("--dry-run", "Preview conversion without writing files", false).option("--verbose", "Show detailed conversion logs", false).action(async (pagePath, options) => {
|
|
17761
|
+
program.command("vf <path>").description("Convert a Visualforce page to LWC").option("--full", "Run full automated conversion (default: scaffolding only)", false).option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("--api-version <version>", "Salesforce API version for meta.xml", DEFAULT_API_VERSION).option("--controller <path>", "Include Apex controller file for analysis").option("--open", "Open output folder in file explorer after conversion", false).option("--preview", "Generate and open HTML preview of converted component", false).option("--dry-run", "Preview conversion without writing files", false).option("--verbose", "Show detailed conversion logs", false).action(async (pagePath, options) => {
|
|
17625
17762
|
logger.setVerbose(options.verbose);
|
|
17626
17763
|
await convertVf(pagePath, {
|
|
17627
17764
|
output: options.output,
|
|
@@ -17630,7 +17767,8 @@ program.command("vf <path>").description("Convert a Visualforce page to LWC").op
|
|
|
17630
17767
|
verbose: options.verbose,
|
|
17631
17768
|
controller: options.controller,
|
|
17632
17769
|
open: options.open,
|
|
17633
|
-
preview: options.preview
|
|
17770
|
+
preview: options.preview,
|
|
17771
|
+
apiVersion: options.apiVersion
|
|
17634
17772
|
});
|
|
17635
17773
|
});
|
|
17636
17774
|
program.command("grade [target]").description("Assess conversion complexity of components").option("-t, --type <type>", "Component type (aura, vf, both)", "both").option("-o, --output <file>", "Output file for report").option("--format <format>", "Output format (json, csv, console)", "console").option("--detailed", "Show detailed breakdown", false).option("--sort-by <field>", "Sort by (score, complexity, name)").option("--filter <filter>", 'Filter results (e.g., "grade:D,F")').option("--dry-run", "Run without writing files", false).option("--verbose", "Show detailed logs", false).action(async (target, options) => {
|