lwc-convert 1.8.1 → 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 +332 -229
- 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({
|
|
@@ -9633,6 +9699,8 @@ var init_grader = __esm({
|
|
|
9633
9699
|
Grader = class {
|
|
9634
9700
|
auraGrader;
|
|
9635
9701
|
vfGrader;
|
|
9702
|
+
/** Cache of grading results keyed by resolved file path */
|
|
9703
|
+
gradeCache = /* @__PURE__ */ new Map();
|
|
9636
9704
|
constructor() {
|
|
9637
9705
|
this.auraGrader = new AuraGrader();
|
|
9638
9706
|
this.vfGrader = new VfGrader();
|
|
@@ -9681,7 +9749,8 @@ var init_grader = __esm({
|
|
|
9681
9749
|
}
|
|
9682
9750
|
}
|
|
9683
9751
|
}
|
|
9684
|
-
} catch {
|
|
9752
|
+
} catch (error) {
|
|
9753
|
+
logger.debug(`Error scanning ${dirPath}: ${error.message}`);
|
|
9685
9754
|
}
|
|
9686
9755
|
};
|
|
9687
9756
|
await searchDir(basePath);
|
|
@@ -9697,29 +9766,48 @@ var init_grader = __esm({
|
|
|
9697
9766
|
if (grade2) results.push(grade2);
|
|
9698
9767
|
} else {
|
|
9699
9768
|
const searchPaths = options.targetPath ? [options.targetPath] : await this.getStandardPaths(options.type);
|
|
9769
|
+
const allFiles = [];
|
|
9700
9770
|
for (const searchPath of searchPaths) {
|
|
9701
9771
|
const found = await this.scanDirectory(searchPath, options.type);
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
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}`);
|
|
9708
9780
|
}
|
|
9709
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");
|
|
9710
9791
|
}
|
|
9711
9792
|
}
|
|
9712
9793
|
return results;
|
|
9713
9794
|
}
|
|
9714
9795
|
async gradeSingle(filePath, type) {
|
|
9796
|
+
const resolvedPath = path11.resolve(filePath);
|
|
9797
|
+
const cached = this.gradeCache.get(resolvedPath);
|
|
9798
|
+
if (cached) return cached;
|
|
9715
9799
|
const resolvedType = type === "both" ? this.detectType(filePath) : type;
|
|
9800
|
+
let result = null;
|
|
9716
9801
|
if (resolvedType === "aura") {
|
|
9717
9802
|
const bundlePath = filePath.endsWith(".cmp") ? path11.dirname(filePath) : filePath;
|
|
9718
|
-
|
|
9803
|
+
result = await this.auraGrader.grade(bundlePath);
|
|
9719
9804
|
} else if (resolvedType === "vf") {
|
|
9720
|
-
|
|
9805
|
+
result = await this.vfGrader.grade(filePath);
|
|
9721
9806
|
}
|
|
9722
|
-
|
|
9807
|
+
if (result) {
|
|
9808
|
+
this.gradeCache.set(resolvedPath, result);
|
|
9809
|
+
}
|
|
9810
|
+
return result;
|
|
9723
9811
|
}
|
|
9724
9812
|
detectType(filePath) {
|
|
9725
9813
|
if (filePath.endsWith(".cmp") || filePath.includes("/aura/") || filePath.includes("\\aura\\")) return "aura";
|
|
@@ -10010,7 +10098,7 @@ var init_vf_controller_resolver = __esm({
|
|
|
10010
10098
|
|
|
10011
10099
|
// src/utils/first-time.ts
|
|
10012
10100
|
import fs14 from "fs-extra";
|
|
10013
|
-
import
|
|
10101
|
+
import path16 from "path";
|
|
10014
10102
|
import os4 from "os";
|
|
10015
10103
|
function isFirstTimeSync() {
|
|
10016
10104
|
try {
|
|
@@ -10059,8 +10147,8 @@ var init_first_time = __esm({
|
|
|
10059
10147
|
"src/utils/first-time.ts"() {
|
|
10060
10148
|
"use strict";
|
|
10061
10149
|
init_esm_shims();
|
|
10062
|
-
CONFIG_DIR =
|
|
10063
|
-
FIRST_RUN_FILE =
|
|
10150
|
+
CONFIG_DIR = path16.join(os4.homedir(), ".lwc-convert");
|
|
10151
|
+
FIRST_RUN_FILE = path16.join(CONFIG_DIR, ".first-run-complete");
|
|
10064
10152
|
}
|
|
10065
10153
|
});
|
|
10066
10154
|
|
|
@@ -10070,7 +10158,7 @@ __export(interactive_exports, {
|
|
|
10070
10158
|
runInteractiveTui: () => runInteractiveTui
|
|
10071
10159
|
});
|
|
10072
10160
|
import * as p from "@clack/prompts";
|
|
10073
|
-
import * as
|
|
10161
|
+
import * as path17 from "path";
|
|
10074
10162
|
import fs15 from "fs-extra";
|
|
10075
10163
|
function showBreadcrumbs(currentStep, conversionType) {
|
|
10076
10164
|
const breadcrumb = STEPS.map((step, i) => {
|
|
@@ -10098,16 +10186,16 @@ async function findAuraComponents() {
|
|
|
10098
10186
|
const components3 = [];
|
|
10099
10187
|
const cwd = process.cwd();
|
|
10100
10188
|
for (const searchPath of searchPaths) {
|
|
10101
|
-
const fullPath =
|
|
10189
|
+
const fullPath = path17.join(cwd, searchPath);
|
|
10102
10190
|
if (await fs15.pathExists(fullPath)) {
|
|
10103
10191
|
try {
|
|
10104
10192
|
const entries = await fs15.readdir(fullPath, { withFileTypes: true });
|
|
10105
10193
|
for (const entry of entries) {
|
|
10106
10194
|
if (entry.isDirectory()) {
|
|
10107
|
-
const cmpFile =
|
|
10195
|
+
const cmpFile = path17.join(fullPath, entry.name, `${entry.name}.cmp`);
|
|
10108
10196
|
if (await fs15.pathExists(cmpFile)) {
|
|
10109
10197
|
components3.push({
|
|
10110
|
-
value:
|
|
10198
|
+
value: path17.join(searchPath, entry.name),
|
|
10111
10199
|
label: `\u26A1 ${entry.name}`,
|
|
10112
10200
|
hint: searchPath
|
|
10113
10201
|
});
|
|
@@ -10129,14 +10217,14 @@ async function findVfPages() {
|
|
|
10129
10217
|
const pages = [];
|
|
10130
10218
|
const cwd = process.cwd();
|
|
10131
10219
|
for (const searchPath of searchPaths) {
|
|
10132
|
-
const fullPath =
|
|
10220
|
+
const fullPath = path17.join(cwd, searchPath);
|
|
10133
10221
|
if (await fs15.pathExists(fullPath)) {
|
|
10134
10222
|
try {
|
|
10135
10223
|
const entries = await fs15.readdir(fullPath, { withFileTypes: true });
|
|
10136
10224
|
for (const entry of entries) {
|
|
10137
10225
|
if (entry.isFile() && entry.name.endsWith(".page")) {
|
|
10138
10226
|
pages.push({
|
|
10139
|
-
value:
|
|
10227
|
+
value: path17.join(searchPath, entry.name),
|
|
10140
10228
|
label: `\u{1F4C4} ${entry.name.replace(".page", "")}`,
|
|
10141
10229
|
hint: searchPath
|
|
10142
10230
|
});
|
|
@@ -10157,14 +10245,14 @@ async function findApexControllers() {
|
|
|
10157
10245
|
const controllers = [];
|
|
10158
10246
|
const cwd = process.cwd();
|
|
10159
10247
|
for (const searchPath of searchPaths) {
|
|
10160
|
-
const fullPath =
|
|
10248
|
+
const fullPath = path17.join(cwd, searchPath);
|
|
10161
10249
|
if (await fs15.pathExists(fullPath)) {
|
|
10162
10250
|
try {
|
|
10163
10251
|
const entries = await fs15.readdir(fullPath, { withFileTypes: true });
|
|
10164
10252
|
for (const entry of entries) {
|
|
10165
10253
|
if (entry.isFile() && entry.name.endsWith(".cls")) {
|
|
10166
10254
|
controllers.push({
|
|
10167
|
-
value:
|
|
10255
|
+
value: path17.join(searchPath, entry.name),
|
|
10168
10256
|
label: `\u{1F4CB} ${entry.name.replace(".cls", "")}`
|
|
10169
10257
|
});
|
|
10170
10258
|
}
|
|
@@ -10418,7 +10506,7 @@ async function runInteractiveTui() {
|
|
|
10418
10506
|
}
|
|
10419
10507
|
while (currentStep === 2 && conversionType === "vf" && componentPath && action !== "grade") {
|
|
10420
10508
|
showBreadcrumbs(currentStep, conversionType);
|
|
10421
|
-
const resolvedPagePath =
|
|
10509
|
+
const resolvedPagePath = path17.resolve(componentPath);
|
|
10422
10510
|
if (await fs15.pathExists(resolvedPagePath)) {
|
|
10423
10511
|
const s = p.spinner();
|
|
10424
10512
|
s.start("Analyzing page for controller references...");
|
|
@@ -10472,7 +10560,7 @@ async function runInteractiveTui() {
|
|
|
10472
10560
|
if (addMore) {
|
|
10473
10561
|
const allControllers = await findApexControllers();
|
|
10474
10562
|
const availableControllers = allControllers.filter(
|
|
10475
|
-
(c) => !controllerPaths.includes(
|
|
10563
|
+
(c) => !controllerPaths.includes(path17.resolve(c.value))
|
|
10476
10564
|
);
|
|
10477
10565
|
if (availableControllers.length > 0) {
|
|
10478
10566
|
const additional = await p.multiselect({
|
|
@@ -10481,7 +10569,7 @@ async function runInteractiveTui() {
|
|
|
10481
10569
|
required: false
|
|
10482
10570
|
});
|
|
10483
10571
|
if (!isCancel2(additional)) {
|
|
10484
|
-
controllerPaths.push(...additional.map((c) =>
|
|
10572
|
+
controllerPaths.push(...additional.map((c) => path17.resolve(c)));
|
|
10485
10573
|
}
|
|
10486
10574
|
}
|
|
10487
10575
|
}
|
|
@@ -10508,7 +10596,7 @@ async function runInteractiveTui() {
|
|
|
10508
10596
|
continue wizardLoop;
|
|
10509
10597
|
}
|
|
10510
10598
|
controllerPath = selected;
|
|
10511
|
-
controllerPaths = [
|
|
10599
|
+
controllerPaths = [path17.resolve(controllerPath)];
|
|
10512
10600
|
}
|
|
10513
10601
|
}
|
|
10514
10602
|
}
|
|
@@ -10615,7 +10703,7 @@ async function runInteractiveTui() {
|
|
|
10615
10703
|
if (controllerPaths.length > 0) {
|
|
10616
10704
|
summaryLines.push(`${import_picocolors.default.dim("Controllers:")} ${controllerPaths.length} selected`);
|
|
10617
10705
|
controllerPaths.forEach((cp) => {
|
|
10618
|
-
summaryLines.push(` ${import_picocolors.default.dim("\u2022")} ${
|
|
10706
|
+
summaryLines.push(` ${import_picocolors.default.dim("\u2022")} ${path17.basename(cp)}`);
|
|
10619
10707
|
});
|
|
10620
10708
|
}
|
|
10621
10709
|
summaryLines.push(`${import_picocolors.default.dim("Mode:")} ${conversionMode === "full" ? "\u26A1 Full" : "\u{1F4DD} Scaffolding"}`);
|
|
@@ -10685,7 +10773,7 @@ var init_types = __esm({
|
|
|
10685
10773
|
|
|
10686
10774
|
// src/tui/store/persistence.ts
|
|
10687
10775
|
import fs16 from "fs-extra";
|
|
10688
|
-
import
|
|
10776
|
+
import path18 from "path";
|
|
10689
10777
|
import os5 from "os";
|
|
10690
10778
|
async function savePreferences(prefs) {
|
|
10691
10779
|
try {
|
|
@@ -10713,8 +10801,8 @@ var init_persistence = __esm({
|
|
|
10713
10801
|
"use strict";
|
|
10714
10802
|
init_esm_shims();
|
|
10715
10803
|
init_types();
|
|
10716
|
-
CONFIG_DIR2 =
|
|
10717
|
-
PREFS_PATH =
|
|
10804
|
+
CONFIG_DIR2 = path18.join(os5.homedir(), ".lwc-convert");
|
|
10805
|
+
PREFS_PATH = path18.join(CONFIG_DIR2, "preferences.json");
|
|
10718
10806
|
}
|
|
10719
10807
|
});
|
|
10720
10808
|
|
|
@@ -10724,7 +10812,7 @@ __export(discovery_exports, {
|
|
|
10724
10812
|
discoverComponents: () => discoverComponents
|
|
10725
10813
|
});
|
|
10726
10814
|
import fs17 from "fs-extra";
|
|
10727
|
-
import
|
|
10815
|
+
import path19 from "path";
|
|
10728
10816
|
async function discoverComponents(projectPath) {
|
|
10729
10817
|
const auraComponents = [];
|
|
10730
10818
|
const vfComponents = [];
|
|
@@ -10737,7 +10825,7 @@ async function discoverComponents(projectPath) {
|
|
|
10737
10825
|
"pages"
|
|
10738
10826
|
];
|
|
10739
10827
|
for (const searchPath of searchPaths) {
|
|
10740
|
-
const fullPath =
|
|
10828
|
+
const fullPath = path19.join(projectPath, searchPath);
|
|
10741
10829
|
if (await fs17.pathExists(fullPath)) {
|
|
10742
10830
|
if (searchPath.includes("aura")) {
|
|
10743
10831
|
const components3 = await discoverAuraComponents(fullPath);
|
|
@@ -10754,7 +10842,7 @@ async function discoverComponents(projectPath) {
|
|
|
10754
10842
|
"components"
|
|
10755
10843
|
];
|
|
10756
10844
|
for (const searchPath of vfComponentPaths) {
|
|
10757
|
-
const fullPath =
|
|
10845
|
+
const fullPath = path19.join(projectPath, searchPath);
|
|
10758
10846
|
if (await fs17.pathExists(fullPath)) {
|
|
10759
10847
|
const components3 = await discoverVfComponents(fullPath);
|
|
10760
10848
|
vfComponents.push(...components3);
|
|
@@ -10778,7 +10866,7 @@ async function discoverAuraComponents(auraPath) {
|
|
|
10778
10866
|
const entries = await fs17.readdir(auraPath, { withFileTypes: true });
|
|
10779
10867
|
for (const entry of entries) {
|
|
10780
10868
|
if (entry.isDirectory()) {
|
|
10781
|
-
const componentPath =
|
|
10869
|
+
const componentPath = path19.join(auraPath, entry.name);
|
|
10782
10870
|
const files = await fs17.readdir(componentPath);
|
|
10783
10871
|
const cmpFile = files.find((f) => f.endsWith(".cmp"));
|
|
10784
10872
|
if (cmpFile) {
|
|
@@ -10807,10 +10895,10 @@ async function discoverVfPages(pagesPath) {
|
|
|
10807
10895
|
for (const entry of entries) {
|
|
10808
10896
|
if (entry.isFile() && entry.name.endsWith(".page")) {
|
|
10809
10897
|
const name = entry.name.replace(".page", "");
|
|
10810
|
-
const pagePath =
|
|
10898
|
+
const pagePath = path19.join(pagesPath, entry.name);
|
|
10811
10899
|
const relatedFiles = [entry.name];
|
|
10812
10900
|
const metaFile = `${entry.name}-meta.xml`;
|
|
10813
|
-
if (await fs17.pathExists(
|
|
10901
|
+
if (await fs17.pathExists(path19.join(pagesPath, metaFile))) {
|
|
10814
10902
|
relatedFiles.push(metaFile);
|
|
10815
10903
|
}
|
|
10816
10904
|
pages.push({
|
|
@@ -10836,7 +10924,7 @@ async function discoverVfComponents(componentsPath) {
|
|
|
10836
10924
|
for (const entry of entries) {
|
|
10837
10925
|
if (entry.isFile() && entry.name.endsWith(".component")) {
|
|
10838
10926
|
const name = entry.name.replace(".component", "");
|
|
10839
|
-
const componentPath =
|
|
10927
|
+
const componentPath = path19.join(componentsPath, entry.name);
|
|
10840
10928
|
components3.push({
|
|
10841
10929
|
id: `vf-component-${name}`,
|
|
10842
10930
|
name,
|
|
@@ -11071,8 +11159,8 @@ var init_store = __esm({
|
|
|
11071
11159
|
}
|
|
11072
11160
|
},
|
|
11073
11161
|
// Project actions
|
|
11074
|
-
setProjectPath: (
|
|
11075
|
-
set({ projectPath:
|
|
11162
|
+
setProjectPath: (path20) => {
|
|
11163
|
+
set({ projectPath: path20 });
|
|
11076
11164
|
},
|
|
11077
11165
|
setComponents: (aura, vf) => {
|
|
11078
11166
|
set({ auraComponents: aura, vfComponents: vf });
|
|
@@ -14296,7 +14384,7 @@ function ConversionWizard() {
|
|
|
14296
14384
|
setSelectedComponentIndex(0);
|
|
14297
14385
|
setComponentListScrollOffset(0);
|
|
14298
14386
|
},
|
|
14299
|
-
onSourcePathChange: (
|
|
14387
|
+
onSourcePathChange: (path20) => updateWizardState({ sourcePath: path20 }),
|
|
14300
14388
|
onComponentSelect: (component) => {
|
|
14301
14389
|
updateWizardState({ sourcePath: component.path });
|
|
14302
14390
|
},
|
|
@@ -14786,7 +14874,7 @@ function ExportModal() {
|
|
|
14786
14874
|
{
|
|
14787
14875
|
label: "Output Path",
|
|
14788
14876
|
value: options.outputPath,
|
|
14789
|
-
onChange: (
|
|
14877
|
+
onChange: (path20) => setOptions((o) => ({ ...o, outputPath: path20 })),
|
|
14790
14878
|
focus: focusedField === 4
|
|
14791
14879
|
}
|
|
14792
14880
|
) }),
|
|
@@ -15137,9 +15225,14 @@ async function fetchLatestVersion() {
|
|
|
15137
15225
|
}
|
|
15138
15226
|
}
|
|
15139
15227
|
function parseVersion(version) {
|
|
15140
|
-
|
|
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/, ""));
|
|
15141
15233
|
}
|
|
15142
15234
|
function isNewerVersion(latest, current) {
|
|
15235
|
+
if (isPreRelease(latest)) return false;
|
|
15143
15236
|
const latestParts = parseVersion(latest);
|
|
15144
15237
|
const currentParts = parseVersion(current);
|
|
15145
15238
|
for (let i = 0; i < Math.max(latestParts.length, currentParts.length); i++) {
|
|
@@ -15190,10 +15283,15 @@ async function checkForUpdates() {
|
|
|
15190
15283
|
}
|
|
15191
15284
|
function formatUpdateMessage(latestVersion, currentVersion) {
|
|
15192
15285
|
const versionText = `${currentVersion} \u2192 ${latestVersion}`;
|
|
15193
|
-
|
|
15194
|
-
|
|
15195
|
-
|
|
15196
|
-
|
|
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`;
|
|
15197
15295
|
}
|
|
15198
15296
|
|
|
15199
15297
|
// src/cli/commands/grade.ts
|
|
@@ -15201,6 +15299,7 @@ init_esm_shims();
|
|
|
15201
15299
|
init_logger();
|
|
15202
15300
|
init_grader();
|
|
15203
15301
|
init_path_resolver();
|
|
15302
|
+
import * as path12 from "path";
|
|
15204
15303
|
import fs9 from "fs-extra";
|
|
15205
15304
|
|
|
15206
15305
|
// src/cli/tui/grade-tui.ts
|
|
@@ -15499,7 +15598,7 @@ async function launchGradeTui(components3, summary) {
|
|
|
15499
15598
|
process.stdin.setRawMode(true);
|
|
15500
15599
|
hideCursor();
|
|
15501
15600
|
render(state);
|
|
15502
|
-
return new Promise((
|
|
15601
|
+
return new Promise((resolve10) => {
|
|
15503
15602
|
const handleKeypress = (str, key) => {
|
|
15504
15603
|
if (!key) return;
|
|
15505
15604
|
if (state.isSearching) {
|
|
@@ -15522,7 +15621,7 @@ async function launchGradeTui(components3, summary) {
|
|
|
15522
15621
|
showCursor();
|
|
15523
15622
|
clearScreen();
|
|
15524
15623
|
process.stdin.setRawMode(false);
|
|
15525
|
-
|
|
15624
|
+
resolve10();
|
|
15526
15625
|
return;
|
|
15527
15626
|
}
|
|
15528
15627
|
if (state.viewMode === "detail") {
|
|
@@ -15674,6 +15773,7 @@ async function grade(target, options) {
|
|
|
15674
15773
|
if (options.format === "json") {
|
|
15675
15774
|
const output = { summary, components: filteredResults };
|
|
15676
15775
|
if (options.output) {
|
|
15776
|
+
await fs9.ensureDir(path12.dirname(path12.resolve(options.output)));
|
|
15677
15777
|
await fs9.writeJson(options.output, output, { spaces: 2 });
|
|
15678
15778
|
logger.success(`Results written to ${options.output}`);
|
|
15679
15779
|
} else {
|
|
@@ -15682,6 +15782,7 @@ async function grade(target, options) {
|
|
|
15682
15782
|
} else if (options.format === "csv") {
|
|
15683
15783
|
const csvContent = generateCsvReport(filteredResults, summary);
|
|
15684
15784
|
if (options.output) {
|
|
15785
|
+
await fs9.ensureDir(path12.dirname(path12.resolve(options.output)));
|
|
15685
15786
|
await fs9.writeFile(options.output, csvContent);
|
|
15686
15787
|
logger.success(`CSV report written to ${options.output}`);
|
|
15687
15788
|
} else {
|
|
@@ -15728,11 +15829,19 @@ function filterResults(results, filter) {
|
|
|
15728
15829
|
if (filter.startsWith("score:")) {
|
|
15729
15830
|
const condition = filter.substring(6);
|
|
15730
15831
|
if (condition.startsWith("<")) {
|
|
15731
|
-
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
|
+
}
|
|
15732
15837
|
return results.filter((r) => r.overallScore < val);
|
|
15733
15838
|
}
|
|
15734
15839
|
if (condition.startsWith(">")) {
|
|
15735
|
-
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
|
+
}
|
|
15736
15845
|
return results.filter((r) => r.overallScore > val);
|
|
15737
15846
|
}
|
|
15738
15847
|
}
|
|
@@ -15828,7 +15937,7 @@ function generateCsvReport(results, summary) {
|
|
|
15828
15937
|
init_esm_shims();
|
|
15829
15938
|
init_logger();
|
|
15830
15939
|
import fs12 from "fs-extra";
|
|
15831
|
-
import * as
|
|
15940
|
+
import * as path15 from "path";
|
|
15832
15941
|
|
|
15833
15942
|
// src/dependency-graph/analyzer.ts
|
|
15834
15943
|
init_esm_shims();
|
|
@@ -15838,7 +15947,7 @@ init_logger();
|
|
|
15838
15947
|
init_esm_shims();
|
|
15839
15948
|
init_logger();
|
|
15840
15949
|
import fs10 from "fs-extra";
|
|
15841
|
-
import * as
|
|
15950
|
+
import * as path13 from "path";
|
|
15842
15951
|
import * as htmlparser23 from "htmlparser2";
|
|
15843
15952
|
import { DomHandler as DomHandler3 } from "domhandler";
|
|
15844
15953
|
function extractMarkupDependencies(markup, includeBaseComponents) {
|
|
@@ -16016,7 +16125,7 @@ async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
|
|
|
16016
16125
|
logger.debug(`Not a directory: ${bundlePath}`);
|
|
16017
16126
|
return null;
|
|
16018
16127
|
}
|
|
16019
|
-
const componentName =
|
|
16128
|
+
const componentName = path13.basename(bundlePath);
|
|
16020
16129
|
const files = await fs10.readdir(bundlePath);
|
|
16021
16130
|
const cmpFile = files.find((f) => f.endsWith(".cmp"));
|
|
16022
16131
|
if (!cmpFile) {
|
|
@@ -16026,18 +16135,18 @@ async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
|
|
|
16026
16135
|
const context = {
|
|
16027
16136
|
markup: ""
|
|
16028
16137
|
};
|
|
16029
|
-
context.markup = await fs10.readFile(
|
|
16138
|
+
context.markup = await fs10.readFile(path13.join(bundlePath, cmpFile), "utf-8");
|
|
16030
16139
|
const controllerFile = files.find((f) => f.endsWith("Controller.js"));
|
|
16031
16140
|
if (controllerFile) {
|
|
16032
16141
|
context.controllerJs = await fs10.readFile(
|
|
16033
|
-
|
|
16142
|
+
path13.join(bundlePath, controllerFile),
|
|
16034
16143
|
"utf-8"
|
|
16035
16144
|
);
|
|
16036
16145
|
}
|
|
16037
16146
|
const helperFile = files.find((f) => f.endsWith("Helper.js"));
|
|
16038
16147
|
if (helperFile) {
|
|
16039
16148
|
context.helperJs = await fs10.readFile(
|
|
16040
|
-
|
|
16149
|
+
path13.join(bundlePath, helperFile),
|
|
16041
16150
|
"utf-8"
|
|
16042
16151
|
);
|
|
16043
16152
|
}
|
|
@@ -16062,13 +16171,13 @@ async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
|
|
|
16062
16171
|
}
|
|
16063
16172
|
}
|
|
16064
16173
|
async function getPackageDirectories(rootPath) {
|
|
16065
|
-
const sfdxProjectPath =
|
|
16174
|
+
const sfdxProjectPath = path13.join(rootPath, "sfdx-project.json");
|
|
16066
16175
|
if (await fs10.pathExists(sfdxProjectPath)) {
|
|
16067
16176
|
try {
|
|
16068
16177
|
const projectConfig = await fs10.readJson(sfdxProjectPath);
|
|
16069
16178
|
if (projectConfig.packageDirectories && Array.isArray(projectConfig.packageDirectories)) {
|
|
16070
16179
|
return projectConfig.packageDirectories.map(
|
|
16071
|
-
(pkg) =>
|
|
16180
|
+
(pkg) => path13.join(rootPath, pkg.path)
|
|
16072
16181
|
);
|
|
16073
16182
|
}
|
|
16074
16183
|
} catch (error) {
|
|
@@ -16085,7 +16194,7 @@ async function findAuraDirectories(basePath) {
|
|
|
16085
16194
|
const entries = await fs10.readdir(dirPath, { withFileTypes: true });
|
|
16086
16195
|
for (const entry of entries) {
|
|
16087
16196
|
if (entry.isDirectory()) {
|
|
16088
|
-
const fullPath =
|
|
16197
|
+
const fullPath = path13.join(dirPath, entry.name);
|
|
16089
16198
|
if (entry.name === "aura") {
|
|
16090
16199
|
auraDirectories.push(fullPath);
|
|
16091
16200
|
} else if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
@@ -16111,9 +16220,9 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
|
|
|
16111
16220
|
logger.debug(`Found aura directories from sfdx-project.json: ${searchPaths.join(", ")}`);
|
|
16112
16221
|
}
|
|
16113
16222
|
const fallbackPaths = [
|
|
16114
|
-
|
|
16115
|
-
|
|
16116
|
-
|
|
16223
|
+
path13.join(rootPath, "force-app/main/default/aura"),
|
|
16224
|
+
path13.join(rootPath, "src/aura"),
|
|
16225
|
+
path13.join(rootPath, "aura")
|
|
16117
16226
|
];
|
|
16118
16227
|
for (const fallback of fallbackPaths) {
|
|
16119
16228
|
if (!searchPaths.includes(fallback)) {
|
|
@@ -16142,7 +16251,7 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
|
|
|
16142
16251
|
}
|
|
16143
16252
|
} else {
|
|
16144
16253
|
for (const item of files) {
|
|
16145
|
-
const itemPath =
|
|
16254
|
+
const itemPath = path13.join(searchPath, item);
|
|
16146
16255
|
const itemStat = await fs10.stat(itemPath);
|
|
16147
16256
|
if (itemStat.isDirectory()) {
|
|
16148
16257
|
const result = await analyzeAuraComponent(itemPath, includeBaseComponents);
|
|
@@ -16167,7 +16276,7 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
|
|
|
16167
16276
|
init_esm_shims();
|
|
16168
16277
|
init_logger();
|
|
16169
16278
|
import fs11 from "fs-extra";
|
|
16170
|
-
import * as
|
|
16279
|
+
import * as path14 from "path";
|
|
16171
16280
|
import * as htmlparser24 from "htmlparser2";
|
|
16172
16281
|
import { DomHandler as DomHandler4 } from "domhandler";
|
|
16173
16282
|
function extractVfDependencies(markup) {
|
|
@@ -16355,7 +16464,7 @@ async function analyzeVfPage(pagePath) {
|
|
|
16355
16464
|
const files = await fs11.readdir(pagePath);
|
|
16356
16465
|
const pageFile = files.find((f) => f.endsWith(".page"));
|
|
16357
16466
|
if (pageFile) {
|
|
16358
|
-
actualPath =
|
|
16467
|
+
actualPath = path14.join(pagePath, pageFile);
|
|
16359
16468
|
} else {
|
|
16360
16469
|
return null;
|
|
16361
16470
|
}
|
|
@@ -16367,7 +16476,7 @@ async function analyzeVfPage(pagePath) {
|
|
|
16367
16476
|
return null;
|
|
16368
16477
|
}
|
|
16369
16478
|
const markup = await fs11.readFile(actualPath, "utf-8");
|
|
16370
|
-
const pageName =
|
|
16479
|
+
const pageName = path14.basename(actualPath, ".page");
|
|
16371
16480
|
const dependencies = extractVfDependencies(markup);
|
|
16372
16481
|
return {
|
|
16373
16482
|
id: `vf:${pageName}`,
|
|
@@ -16391,7 +16500,7 @@ async function analyzeVfComponent(componentPath) {
|
|
|
16391
16500
|
const files = await fs11.readdir(componentPath);
|
|
16392
16501
|
const componentFile = files.find((f) => f.endsWith(".component"));
|
|
16393
16502
|
if (componentFile) {
|
|
16394
|
-
actualPath =
|
|
16503
|
+
actualPath = path14.join(componentPath, componentFile);
|
|
16395
16504
|
} else {
|
|
16396
16505
|
return null;
|
|
16397
16506
|
}
|
|
@@ -16403,7 +16512,7 @@ async function analyzeVfComponent(componentPath) {
|
|
|
16403
16512
|
return null;
|
|
16404
16513
|
}
|
|
16405
16514
|
const markup = await fs11.readFile(actualPath, "utf-8");
|
|
16406
|
-
const componentName =
|
|
16515
|
+
const componentName = path14.basename(actualPath, ".component");
|
|
16407
16516
|
const dependencies = extractVfDependencies(markup);
|
|
16408
16517
|
return {
|
|
16409
16518
|
id: `vf:${componentName}`,
|
|
@@ -16418,13 +16527,13 @@ async function analyzeVfComponent(componentPath) {
|
|
|
16418
16527
|
}
|
|
16419
16528
|
}
|
|
16420
16529
|
async function getPackageDirectories2(rootPath) {
|
|
16421
|
-
const sfdxProjectPath =
|
|
16530
|
+
const sfdxProjectPath = path14.join(rootPath, "sfdx-project.json");
|
|
16422
16531
|
if (await fs11.pathExists(sfdxProjectPath)) {
|
|
16423
16532
|
try {
|
|
16424
16533
|
const projectConfig = await fs11.readJson(sfdxProjectPath);
|
|
16425
16534
|
if (projectConfig.packageDirectories && Array.isArray(projectConfig.packageDirectories)) {
|
|
16426
16535
|
return projectConfig.packageDirectories.map(
|
|
16427
|
-
(pkg) =>
|
|
16536
|
+
(pkg) => path14.join(rootPath, pkg.path)
|
|
16428
16537
|
);
|
|
16429
16538
|
}
|
|
16430
16539
|
} catch (error) {
|
|
@@ -16442,7 +16551,7 @@ async function findVfDirectories(basePath) {
|
|
|
16442
16551
|
const entries = await fs11.readdir(dirPath, { withFileTypes: true });
|
|
16443
16552
|
for (const entry of entries) {
|
|
16444
16553
|
if (entry.isDirectory()) {
|
|
16445
|
-
const fullPath =
|
|
16554
|
+
const fullPath = path14.join(dirPath, entry.name);
|
|
16446
16555
|
if (entry.name === "pages") {
|
|
16447
16556
|
pagesDirectories.push(fullPath);
|
|
16448
16557
|
} else if (entry.name === "components") {
|
|
@@ -16473,9 +16582,9 @@ async function scanVfPages(rootPath) {
|
|
|
16473
16582
|
logger.debug(`Found components directories from sfdx-project.json: ${componentSearchPaths.join(", ")}`);
|
|
16474
16583
|
}
|
|
16475
16584
|
const fallbackPagePaths = [
|
|
16476
|
-
|
|
16477
|
-
|
|
16478
|
-
|
|
16585
|
+
path14.join(rootPath, "force-app/main/default/pages"),
|
|
16586
|
+
path14.join(rootPath, "src/pages"),
|
|
16587
|
+
path14.join(rootPath, "pages")
|
|
16479
16588
|
];
|
|
16480
16589
|
for (const fallback of fallbackPagePaths) {
|
|
16481
16590
|
if (!pageSearchPaths.includes(fallback)) {
|
|
@@ -16483,9 +16592,9 @@ async function scanVfPages(rootPath) {
|
|
|
16483
16592
|
}
|
|
16484
16593
|
}
|
|
16485
16594
|
const fallbackComponentPaths = [
|
|
16486
|
-
|
|
16487
|
-
|
|
16488
|
-
|
|
16595
|
+
path14.join(rootPath, "force-app/main/default/components"),
|
|
16596
|
+
path14.join(rootPath, "src/components"),
|
|
16597
|
+
path14.join(rootPath, "components")
|
|
16489
16598
|
];
|
|
16490
16599
|
for (const fallback of fallbackComponentPaths) {
|
|
16491
16600
|
if (!componentSearchPaths.includes(fallback)) {
|
|
@@ -16522,7 +16631,7 @@ async function scanVfPages(rootPath) {
|
|
|
16522
16631
|
const files = await fs11.readdir(searchPath);
|
|
16523
16632
|
for (const file of files) {
|
|
16524
16633
|
if (file.endsWith(".page")) {
|
|
16525
|
-
const result = await analyzeVfPage(
|
|
16634
|
+
const result = await analyzeVfPage(path14.join(searchPath, file));
|
|
16526
16635
|
if (result) {
|
|
16527
16636
|
results.push(result);
|
|
16528
16637
|
}
|
|
@@ -16543,7 +16652,7 @@ async function scanVfPages(rootPath) {
|
|
|
16543
16652
|
const files = await fs11.readdir(searchPath);
|
|
16544
16653
|
for (const file of files) {
|
|
16545
16654
|
if (file.endsWith(".component")) {
|
|
16546
|
-
const result = await analyzeVfComponent(
|
|
16655
|
+
const result = await analyzeVfComponent(path14.join(searchPath, file));
|
|
16547
16656
|
if (result) {
|
|
16548
16657
|
results.push(result);
|
|
16549
16658
|
}
|
|
@@ -17550,7 +17659,7 @@ function formatSimpleMermaidOutput(graph, maxNodes = 30) {
|
|
|
17550
17659
|
// src/cli/commands/deps.ts
|
|
17551
17660
|
async function analyzeDeps(target, options) {
|
|
17552
17661
|
logger.setVerbose(options.verbose);
|
|
17553
|
-
const targetPath = target ?
|
|
17662
|
+
const targetPath = target ? path15.resolve(target) : process.cwd();
|
|
17554
17663
|
logger.banner();
|
|
17555
17664
|
logger.header("Dependency Graph Analysis");
|
|
17556
17665
|
logger.info(`Analyzing: ${targetPath}`);
|
|
@@ -17600,14 +17709,6 @@ async function analyzeDeps(target, options) {
|
|
|
17600
17709
|
console.log(output);
|
|
17601
17710
|
}
|
|
17602
17711
|
break;
|
|
17603
|
-
case "html":
|
|
17604
|
-
logger.warn("HTML format not yet implemented. Using console output.");
|
|
17605
|
-
formatConsoleOutput(graph, conversionOrder, options.showOrphans);
|
|
17606
|
-
break;
|
|
17607
|
-
case "dot":
|
|
17608
|
-
logger.warn("DOT format not yet implemented. Using console output.");
|
|
17609
|
-
formatConsoleOutput(graph, conversionOrder, options.showOrphans);
|
|
17610
|
-
break;
|
|
17611
17712
|
case "console":
|
|
17612
17713
|
default:
|
|
17613
17714
|
formatConsoleOutput(graph, conversionOrder, options.showOrphans);
|
|
@@ -17626,8 +17727,8 @@ async function analyzeDeps(target, options) {
|
|
|
17626
17727
|
}
|
|
17627
17728
|
}
|
|
17628
17729
|
async function writeOutput(filePath, content) {
|
|
17629
|
-
const outputPath =
|
|
17630
|
-
const outputDir =
|
|
17730
|
+
const outputPath = path15.resolve(filePath);
|
|
17731
|
+
const outputDir = path15.dirname(outputPath);
|
|
17631
17732
|
await fs12.ensureDir(outputDir);
|
|
17632
17733
|
await fs12.writeFile(outputPath, content, "utf-8");
|
|
17633
17734
|
}
|
|
@@ -17645,7 +17746,7 @@ program.name(CLI_NAME).description(CLI_DESCRIPTION).version(CLI_VERSION).hook("p
|
|
|
17645
17746
|
} catch {
|
|
17646
17747
|
}
|
|
17647
17748
|
});
|
|
17648
|
-
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) => {
|
|
17649
17750
|
logger.setVerbose(options.verbose);
|
|
17650
17751
|
await convertAura(bundlePath, {
|
|
17651
17752
|
output: options.output,
|
|
@@ -17653,10 +17754,11 @@ program.command("aura <path>").description("Convert an Aura component bundle to
|
|
|
17653
17754
|
dryRun: options.dryRun,
|
|
17654
17755
|
verbose: options.verbose,
|
|
17655
17756
|
open: options.open,
|
|
17656
|
-
preview: options.preview
|
|
17757
|
+
preview: options.preview,
|
|
17758
|
+
apiVersion: options.apiVersion
|
|
17657
17759
|
});
|
|
17658
17760
|
});
|
|
17659
|
-
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) => {
|
|
17660
17762
|
logger.setVerbose(options.verbose);
|
|
17661
17763
|
await convertVf(pagePath, {
|
|
17662
17764
|
output: options.output,
|
|
@@ -17665,7 +17767,8 @@ program.command("vf <path>").description("Convert a Visualforce page to LWC").op
|
|
|
17665
17767
|
verbose: options.verbose,
|
|
17666
17768
|
controller: options.controller,
|
|
17667
17769
|
open: options.open,
|
|
17668
|
-
preview: options.preview
|
|
17770
|
+
preview: options.preview,
|
|
17771
|
+
apiVersion: options.apiVersion
|
|
17669
17772
|
});
|
|
17670
17773
|
});
|
|
17671
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) => {
|