lwc-convert 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -55,8 +55,8 @@ var init_esm_shims = __esm({
55
55
  import { readFileSync } from "fs";
56
56
  import { join } from "path";
57
57
  function getPackageVersion() {
58
- if ("1.6.1") {
59
- return "1.6.1";
58
+ if ("1.7.0") {
59
+ return "1.7.0";
60
60
  }
61
61
  try {
62
62
  const possiblePaths = [
@@ -229,6 +229,26 @@ ${COLORS.dim} ${message}${COLORS.reset}`);
229
229
  blank() {
230
230
  console.log("");
231
231
  }
232
+ // Success toast for completed operations
233
+ successToast(title, details, outputPath) {
234
+ console.log("");
235
+ console.log(`${COLORS.green} \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E${COLORS.reset}`);
236
+ console.log(`${COLORS.green} \u2502${COLORS.reset} ${COLORS.green}\u2502${COLORS.reset}`);
237
+ console.log(`${COLORS.green} \u2502${COLORS.reset} ${COLORS.bright}\u2728 Success! \u2728${COLORS.reset} ${COLORS.green}\u2502${COLORS.reset}`);
238
+ console.log(`${COLORS.green} \u2502${COLORS.reset} ${COLORS.green}\u2502${COLORS.reset}`);
239
+ details.forEach((detail) => {
240
+ const padded = detail.padEnd(38);
241
+ console.log(`${COLORS.green} \u2502${COLORS.reset} ${padded} ${COLORS.green}\u2502${COLORS.reset}`);
242
+ });
243
+ if (outputPath) {
244
+ console.log(`${COLORS.green} \u2502${COLORS.reset} ${COLORS.green}\u2502${COLORS.reset}`);
245
+ const pathText = `\u{1F4C1} ${outputPath}`.padEnd(38);
246
+ console.log(`${COLORS.green} \u2502${COLORS.reset} ${pathText} ${COLORS.green}\u2502${COLORS.reset}`);
247
+ }
248
+ console.log(`${COLORS.green} \u2502${COLORS.reset} ${COLORS.green}\u2502${COLORS.reset}`);
249
+ console.log(`${COLORS.green} \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F${COLORS.reset}`);
250
+ console.log("");
251
+ }
232
252
  };
233
253
  logger = new Logger();
234
254
  }
@@ -648,13 +668,13 @@ function extractFunctionBody(node, source) {
648
668
  }
649
669
  return "";
650
670
  }
651
- function parseAttributeAccess(path16) {
652
- const callee = path16.node.callee;
671
+ function parseAttributeAccess(path17) {
672
+ const callee = path17.node.callee;
653
673
  if (!t.isMemberExpression(callee)) return null;
654
674
  const property = callee.property;
655
675
  if (!t.isIdentifier(property)) return null;
656
676
  if (property.name !== "get" && property.name !== "set") return null;
657
- const args2 = path16.node.arguments;
677
+ const args2 = path17.node.arguments;
658
678
  if (args2.length === 0) return null;
659
679
  const firstArg = args2[0];
660
680
  if (!t.isStringLiteral(firstArg)) return null;
@@ -667,8 +687,8 @@ function parseAttributeAccess(path16) {
667
687
  operation
668
688
  };
669
689
  }
670
- function parseServerCall(path16, _source) {
671
- const callee = path16.node.callee;
690
+ function parseServerCall(path17, _source) {
691
+ const callee = path17.node.callee;
672
692
  if (t.isMemberExpression(callee) && t.isIdentifier(callee.object, { name: "$A" }) && t.isIdentifier(callee.property, { name: "enqueueAction" })) {
673
693
  return {
674
694
  actionName: "enqueueAction",
@@ -678,7 +698,7 @@ function parseServerCall(path16, _source) {
678
698
  if (t.isMemberExpression(callee)) {
679
699
  const property = callee.property;
680
700
  if (t.isIdentifier(property, { name: "get" })) {
681
- const args2 = path16.node.arguments;
701
+ const args2 = path17.node.arguments;
682
702
  if (args2.length > 0 && t.isStringLiteral(args2[0])) {
683
703
  const value = args2[0].value;
684
704
  if (value.startsWith("c.")) {
@@ -693,17 +713,17 @@ function parseServerCall(path16, _source) {
693
713
  }
694
714
  return null;
695
715
  }
696
- function parseHelperCall(path16) {
697
- const callee = path16.node.callee;
716
+ function parseHelperCall(path17) {
717
+ const callee = path17.node.callee;
698
718
  if (t.isMemberExpression(callee) && t.isIdentifier(callee.object, { name: "helper" }) && t.isIdentifier(callee.property)) {
699
719
  return callee.property.name;
700
720
  }
701
721
  return null;
702
722
  }
703
- function parseEventFire(path16) {
704
- const callee = path16.node.callee;
723
+ function parseEventFire(path17) {
724
+ const callee = path17.node.callee;
705
725
  if (t.isMemberExpression(callee) && t.isIdentifier(callee.object, { name: "$A" }) && t.isIdentifier(callee.property, { name: "get" })) {
706
- const args2 = path16.node.arguments;
726
+ const args2 = path17.node.arguments;
707
727
  if (args2.length > 0 && t.isStringLiteral(args2[0])) {
708
728
  const value = args2[0].value;
709
729
  if (value.startsWith("e.")) {
@@ -712,7 +732,7 @@ function parseEventFire(path16) {
712
732
  }
713
733
  }
714
734
  if (t.isMemberExpression(callee) && t.isIdentifier(callee.property, { name: "getEvent" })) {
715
- const args2 = path16.node.arguments;
735
+ const args2 = path17.node.arguments;
716
736
  if (args2.length > 0 && t.isStringLiteral(args2[0])) {
717
737
  return args2[0].value;
718
738
  }
@@ -743,11 +763,11 @@ function parseAuraController(source) {
743
763
  return result;
744
764
  }
745
765
  traverse(ast, {
746
- ObjectExpression(path16) {
747
- if (path16.parent.type === "VariableDeclarator" && t.isIdentifier(path16.parent.id, {
766
+ ObjectExpression(path17) {
767
+ if (path17.parent.type === "VariableDeclarator" && t.isIdentifier(path17.parent.id, {
748
768
  name: "__auraController"
749
769
  })) {
750
- for (const prop of path16.node.properties) {
770
+ for (const prop of path17.node.properties) {
751
771
  if (t.isObjectProperty(prop) && t.isIdentifier(prop.key) && t.isFunctionExpression(prop.value)) {
752
772
  const funcName = prop.key.name;
753
773
  const funcExpr = prop.value;
@@ -771,7 +791,7 @@ function parseAuraController(source) {
771
791
  (p2) => p2 === "event" || p2 === "evt"
772
792
  );
773
793
  funcDef.hasHelper = funcDef.params.some((p2) => p2 === "helper");
774
- const funcPath = path16.get("properties").find((propPath) => {
794
+ const funcPath = path17.get("properties").find((propPath) => {
775
795
  const propNode = propPath.node;
776
796
  return t.isObjectProperty(propNode) && t.isIdentifier(propNode.key, { name: funcName });
777
797
  });
@@ -855,11 +875,11 @@ function parseAuraHelper(source) {
855
875
  }
856
876
  const helperFunctionNames = /* @__PURE__ */ new Set();
857
877
  traverse2(ast, {
858
- ObjectExpression(path16) {
859
- if (path16.parent.type === "VariableDeclarator" && t2.isIdentifier(path16.parent.id, {
878
+ ObjectExpression(path17) {
879
+ if (path17.parent.type === "VariableDeclarator" && t2.isIdentifier(path17.parent.id, {
860
880
  name: "__auraHelper"
861
881
  })) {
862
- for (const prop of path16.node.properties) {
882
+ for (const prop of path17.node.properties) {
863
883
  if (t2.isObjectProperty(prop) && t2.isIdentifier(prop.key)) {
864
884
  helperFunctionNames.add(prop.key.name);
865
885
  }
@@ -868,11 +888,11 @@ function parseAuraHelper(source) {
868
888
  }
869
889
  });
870
890
  traverse2(ast, {
871
- ObjectExpression(path16) {
872
- if (path16.parent.type === "VariableDeclarator" && t2.isIdentifier(path16.parent.id, {
891
+ ObjectExpression(path17) {
892
+ if (path17.parent.type === "VariableDeclarator" && t2.isIdentifier(path17.parent.id, {
873
893
  name: "__auraHelper"
874
894
  })) {
875
- for (const prop of path16.node.properties) {
895
+ for (const prop of path17.node.properties) {
876
896
  if (t2.isObjectProperty(prop) && t2.isIdentifier(prop.key) && t2.isFunctionExpression(prop.value)) {
877
897
  const funcName = prop.key.name;
878
898
  const funcExpr = prop.value;
@@ -888,7 +908,7 @@ function parseAuraHelper(source) {
888
908
  funcDef.hasComponent = funcDef.params.some(
889
909
  (p2) => p2 === "component" || p2 === "cmp"
890
910
  );
891
- const funcPath = path16.get("properties").find((propPath) => {
911
+ const funcPath = path17.get("properties").find((propPath) => {
892
912
  const propNode = propPath.node;
893
913
  return t2.isObjectProperty(propNode) && t2.isIdentifier(propNode.key, { name: funcName });
894
914
  });
@@ -6543,29 +6563,80 @@ var init_full_conversion = __esm({
6543
6563
  }
6544
6564
  });
6545
6565
 
6546
- // src/utils/path-resolver.ts
6566
+ // src/utils/project-detector.ts
6547
6567
  import * as path3 from "path";
6548
6568
  import fs2 from "fs-extra";
6569
+ async function findProjectRoot(startDir = process.cwd()) {
6570
+ let currentDir = path3.resolve(startDir);
6571
+ const root = path3.parse(currentDir).root;
6572
+ while (currentDir !== root) {
6573
+ for (const marker of PROJECT_MARKERS) {
6574
+ const markerPath = path3.join(currentDir, marker);
6575
+ if (await fs2.pathExists(markerPath)) {
6576
+ if (marker === "sfdx-project.json") {
6577
+ return currentDir;
6578
+ }
6579
+ if (marker === "force-app") {
6580
+ const sfdxPath = path3.join(currentDir, "sfdx-project.json");
6581
+ if (await fs2.pathExists(sfdxPath)) {
6582
+ return currentDir;
6583
+ }
6584
+ }
6585
+ }
6586
+ }
6587
+ const parentDir = path3.dirname(currentDir);
6588
+ if (parentDir === currentDir) break;
6589
+ currentDir = parentDir;
6590
+ }
6591
+ return null;
6592
+ }
6593
+ async function ensureProjectRoot() {
6594
+ const cwd = process.cwd();
6595
+ const projectRoot = await findProjectRoot(cwd);
6596
+ if (projectRoot && projectRoot !== cwd) {
6597
+ process.chdir(projectRoot);
6598
+ return { root: projectRoot, changed: true };
6599
+ }
6600
+ return { root: cwd, changed: false };
6601
+ }
6602
+ var PROJECT_MARKERS;
6603
+ var init_project_detector = __esm({
6604
+ "src/utils/project-detector.ts"() {
6605
+ "use strict";
6606
+ init_esm_shims();
6607
+ PROJECT_MARKERS = [
6608
+ "sfdx-project.json",
6609
+ "force-app",
6610
+ "package.json"
6611
+ // fallback
6612
+ ];
6613
+ }
6614
+ });
6615
+
6616
+ // src/utils/path-resolver.ts
6617
+ import * as path4 from "path";
6618
+ import fs3 from "fs-extra";
6549
6619
  function isFullPath(inputPath) {
6550
- return inputPath.includes("/") || inputPath.includes("\\") || inputPath.startsWith(".") || path3.isAbsolute(inputPath);
6620
+ return inputPath.includes("/") || inputPath.includes("\\") || inputPath.startsWith(".") || path4.isAbsolute(inputPath);
6551
6621
  }
6552
6622
  async function resolveAuraPath(input) {
6623
+ const projectRoot = await findProjectRoot();
6624
+ const cwd = projectRoot || process.cwd();
6553
6625
  if (isFullPath(input)) {
6554
- const resolved = path3.resolve(input);
6626
+ const resolved = path4.resolve(input);
6555
6627
  return {
6556
- found: await fs2.pathExists(resolved),
6628
+ found: await fs3.pathExists(resolved),
6557
6629
  path: resolved
6558
6630
  };
6559
6631
  }
6560
6632
  const componentName = input;
6561
- const cwd = process.cwd();
6562
6633
  const searchedLocations = [];
6563
6634
  for (const searchPath of AURA_SEARCH_PATHS) {
6564
- const fullPath = path3.join(cwd, searchPath, componentName);
6635
+ const fullPath = path4.join(cwd, searchPath, componentName);
6565
6636
  searchedLocations.push(fullPath);
6566
- if (await fs2.pathExists(fullPath)) {
6567
- const cmpFile = path3.join(fullPath, `${componentName}.cmp`);
6568
- if (await fs2.pathExists(cmpFile)) {
6637
+ if (await fs3.pathExists(fullPath)) {
6638
+ const cmpFile = path4.join(fullPath, `${componentName}.cmp`);
6639
+ if (await fs3.pathExists(cmpFile)) {
6569
6640
  return {
6570
6641
  found: true,
6571
6642
  path: fullPath,
@@ -6575,8 +6646,8 @@ async function resolveAuraPath(input) {
6575
6646
  }
6576
6647
  }
6577
6648
  for (const searchPath of AURA_SEARCH_PATHS) {
6578
- const basePath = path3.join(cwd, searchPath);
6579
- if (await fs2.pathExists(basePath)) {
6649
+ const basePath = path4.join(cwd, searchPath);
6650
+ if (await fs3.pathExists(basePath)) {
6580
6651
  const found = await searchForComponent(basePath, componentName, ".cmp");
6581
6652
  if (found) {
6582
6653
  return {
@@ -6594,46 +6665,47 @@ async function resolveAuraPath(input) {
6594
6665
  };
6595
6666
  }
6596
6667
  async function resolveVfPath(input) {
6668
+ const projectRoot = await findProjectRoot();
6669
+ const cwd = projectRoot || process.cwd();
6597
6670
  if (isFullPath(input)) {
6598
- const resolved = path3.resolve(input);
6671
+ const resolved = path4.resolve(input);
6599
6672
  return {
6600
- found: await fs2.pathExists(resolved),
6673
+ found: await fs3.pathExists(resolved),
6601
6674
  path: resolved
6602
6675
  };
6603
6676
  }
6604
- const cwd = process.cwd();
6605
6677
  const searchedLocations = [];
6606
6678
  const hasPageExtension = input.endsWith(".page");
6607
6679
  const hasComponentExtension = input.endsWith(".component");
6608
6680
  if (hasPageExtension) {
6609
6681
  for (const searchPath of VF_PAGE_SEARCH_PATHS) {
6610
- const fullPath = path3.join(cwd, searchPath, input);
6682
+ const fullPath = path4.join(cwd, searchPath, input);
6611
6683
  searchedLocations.push(fullPath);
6612
- if (await fs2.pathExists(fullPath)) {
6684
+ if (await fs3.pathExists(fullPath)) {
6613
6685
  return { found: true, path: fullPath, searchedLocations };
6614
6686
  }
6615
6687
  }
6616
6688
  } else if (hasComponentExtension) {
6617
6689
  for (const searchPath of VF_COMPONENT_SEARCH_PATHS) {
6618
- const fullPath = path3.join(cwd, searchPath, input);
6690
+ const fullPath = path4.join(cwd, searchPath, input);
6619
6691
  searchedLocations.push(fullPath);
6620
- if (await fs2.pathExists(fullPath)) {
6692
+ if (await fs3.pathExists(fullPath)) {
6621
6693
  return { found: true, path: fullPath, searchedLocations };
6622
6694
  }
6623
6695
  }
6624
6696
  } else {
6625
6697
  const baseName = input;
6626
6698
  for (const searchPath of VF_PAGE_SEARCH_PATHS) {
6627
- const fullPath = path3.join(cwd, searchPath, `${baseName}.page`);
6699
+ const fullPath = path4.join(cwd, searchPath, `${baseName}.page`);
6628
6700
  searchedLocations.push(fullPath);
6629
- if (await fs2.pathExists(fullPath)) {
6701
+ if (await fs3.pathExists(fullPath)) {
6630
6702
  return { found: true, path: fullPath, searchedLocations };
6631
6703
  }
6632
6704
  }
6633
6705
  for (const searchPath of VF_COMPONENT_SEARCH_PATHS) {
6634
- const fullPath = path3.join(cwd, searchPath, `${baseName}.component`);
6706
+ const fullPath = path4.join(cwd, searchPath, `${baseName}.component`);
6635
6707
  searchedLocations.push(fullPath);
6636
- if (await fs2.pathExists(fullPath)) {
6708
+ if (await fs3.pathExists(fullPath)) {
6637
6709
  return { found: true, path: fullPath, searchedLocations };
6638
6710
  }
6639
6711
  }
@@ -6645,10 +6717,12 @@ async function resolveVfPath(input) {
6645
6717
  };
6646
6718
  }
6647
6719
  async function resolveApexPath(input) {
6720
+ const projectRoot = await findProjectRoot();
6721
+ const cwd = projectRoot || process.cwd();
6648
6722
  if (isFullPath(input)) {
6649
- const resolved = path3.resolve(input);
6723
+ const resolved = path4.resolve(input);
6650
6724
  return {
6651
- found: await fs2.pathExists(resolved),
6725
+ found: await fs3.pathExists(resolved),
6652
6726
  path: resolved
6653
6727
  };
6654
6728
  }
@@ -6656,12 +6730,11 @@ async function resolveApexPath(input) {
6656
6730
  if (!className.endsWith(".cls")) {
6657
6731
  className = `${className}.cls`;
6658
6732
  }
6659
- const cwd = process.cwd();
6660
6733
  const searchedLocations = [];
6661
6734
  for (const searchPath of APEX_SEARCH_PATHS) {
6662
- const fullPath = path3.join(cwd, searchPath, className);
6735
+ const fullPath = path4.join(cwd, searchPath, className);
6663
6736
  searchedLocations.push(fullPath);
6664
- if (await fs2.pathExists(fullPath)) {
6737
+ if (await fs3.pathExists(fullPath)) {
6665
6738
  return {
6666
6739
  found: true,
6667
6740
  path: fullPath,
@@ -6677,18 +6750,18 @@ async function resolveApexPath(input) {
6677
6750
  }
6678
6751
  async function searchForComponent(baseDir, componentName, extension) {
6679
6752
  try {
6680
- const entries = await fs2.readdir(baseDir, { withFileTypes: true });
6753
+ const entries = await fs3.readdir(baseDir, { withFileTypes: true });
6681
6754
  for (const entry of entries) {
6682
6755
  if (entry.isDirectory()) {
6683
6756
  if (entry.name === componentName) {
6684
- const componentPath = path3.join(baseDir, entry.name);
6685
- const mainFile = path3.join(componentPath, `${componentName}${extension}`);
6686
- if (await fs2.pathExists(mainFile)) {
6757
+ const componentPath = path4.join(baseDir, entry.name);
6758
+ const mainFile = path4.join(componentPath, `${componentName}${extension}`);
6759
+ if (await fs3.pathExists(mainFile)) {
6687
6760
  return componentPath;
6688
6761
  }
6689
6762
  }
6690
6763
  const subResult = await searchForComponent(
6691
- path3.join(baseDir, entry.name),
6764
+ path4.join(baseDir, entry.name),
6692
6765
  componentName,
6693
6766
  extension
6694
6767
  );
@@ -6702,13 +6775,14 @@ async function searchForComponent(baseDir, componentName, extension) {
6702
6775
  return null;
6703
6776
  }
6704
6777
  function formatSearchLocations(locations, cwd) {
6705
- return locations.map((loc) => ` - ${path3.relative(cwd, loc) || loc}`).join("\n");
6778
+ return locations.map((loc) => ` - ${path4.relative(cwd, loc) || loc}`).join("\n");
6706
6779
  }
6707
6780
  var AURA_SEARCH_PATHS, VF_PAGE_SEARCH_PATHS, VF_COMPONENT_SEARCH_PATHS, APEX_SEARCH_PATHS;
6708
6781
  var init_path_resolver = __esm({
6709
6782
  "src/utils/path-resolver.ts"() {
6710
6783
  "use strict";
6711
6784
  init_esm_shims();
6785
+ init_project_detector();
6712
6786
  AURA_SEARCH_PATHS = [
6713
6787
  "force-app/main/default/aura",
6714
6788
  "src/aura",
@@ -6737,8 +6811,8 @@ var init_path_resolver = __esm({
6737
6811
  });
6738
6812
 
6739
6813
  // src/utils/session-store.ts
6740
- import * as fs3 from "fs";
6741
- import * as path4 from "path";
6814
+ import * as fs4 from "fs";
6815
+ import * as path5 from "path";
6742
6816
  import * as os from "os";
6743
6817
  var SESSIONS_BASE_DIR, ACTIVE_SESSION_FILE, SESSION_EXPIRY_MS, SessionStore, sessionStore;
6744
6818
  var init_session_store = __esm({
@@ -6746,8 +6820,8 @@ var init_session_store = __esm({
6746
6820
  "use strict";
6747
6821
  init_esm_shims();
6748
6822
  init_logger();
6749
- SESSIONS_BASE_DIR = path4.join(os.tmpdir(), "lwc-convert-sessions");
6750
- ACTIVE_SESSION_FILE = path4.join(SESSIONS_BASE_DIR, "active-session.json");
6823
+ SESSIONS_BASE_DIR = path5.join(os.tmpdir(), "lwc-convert-sessions");
6824
+ ACTIVE_SESSION_FILE = path5.join(SESSIONS_BASE_DIR, "active-session.json");
6751
6825
  SESSION_EXPIRY_MS = 4 * 60 * 60 * 1e3;
6752
6826
  SessionStore = class {
6753
6827
  sessionId = "";
@@ -6763,22 +6837,22 @@ var init_session_store = __esm({
6763
6837
  */
6764
6838
  async tryLoadExistingSession() {
6765
6839
  try {
6766
- if (!fs3.existsSync(ACTIVE_SESSION_FILE)) {
6840
+ if (!fs4.existsSync(ACTIVE_SESSION_FILE)) {
6767
6841
  return false;
6768
6842
  }
6769
6843
  const activeInfo = JSON.parse(
6770
- await fs3.promises.readFile(ACTIVE_SESSION_FILE, "utf-8")
6844
+ await fs4.promises.readFile(ACTIVE_SESSION_FILE, "utf-8")
6771
6845
  );
6772
6846
  const lastActivity = new Date(activeInfo.lastActivityAt).getTime();
6773
6847
  if (Date.now() - lastActivity > SESSION_EXPIRY_MS) {
6774
6848
  logger.debug("Previous session expired, starting new session");
6775
6849
  try {
6776
- await fs3.promises.rm(activeInfo.sessionDir, { recursive: true, force: true });
6850
+ await fs4.promises.rm(activeInfo.sessionDir, { recursive: true, force: true });
6777
6851
  } catch {
6778
6852
  }
6779
6853
  return false;
6780
6854
  }
6781
- if (!fs3.existsSync(activeInfo.sessionDir)) {
6855
+ if (!fs4.existsSync(activeInfo.sessionDir)) {
6782
6856
  return false;
6783
6857
  }
6784
6858
  this.sessionId = activeInfo.sessionId;
@@ -6797,13 +6871,13 @@ var init_session_store = __esm({
6797
6871
  */
6798
6872
  async loadConversions() {
6799
6873
  try {
6800
- const conversionsDir = path4.join(this.sessionDir, "conversions");
6801
- if (!fs3.existsSync(conversionsDir)) return;
6802
- const files = await fs3.promises.readdir(conversionsDir);
6874
+ const conversionsDir = path5.join(this.sessionDir, "conversions");
6875
+ if (!fs4.existsSync(conversionsDir)) return;
6876
+ const files = await fs4.promises.readdir(conversionsDir);
6803
6877
  for (const file of files) {
6804
6878
  if (file.endsWith(".json")) {
6805
- const content = await fs3.promises.readFile(
6806
- path4.join(conversionsDir, file),
6879
+ const content = await fs4.promises.readFile(
6880
+ path5.join(conversionsDir, file),
6807
6881
  "utf-8"
6808
6882
  );
6809
6883
  const record = JSON.parse(content);
@@ -6823,20 +6897,20 @@ var init_session_store = __esm({
6823
6897
  */
6824
6898
  async createNewSession() {
6825
6899
  this.sessionId = `lwc-convert-${Date.now()}-${Math.random().toString(36).substring(7)}`;
6826
- this.sessionDir = path4.join(SESSIONS_BASE_DIR, this.sessionId);
6900
+ this.sessionDir = path5.join(SESSIONS_BASE_DIR, this.sessionId);
6827
6901
  this.startedAt = /* @__PURE__ */ new Date();
6828
- await fs3.promises.mkdir(this.sessionDir, { recursive: true });
6829
- await fs3.promises.mkdir(path4.join(this.sessionDir, "conversions"), { recursive: true });
6830
- await fs3.promises.mkdir(path4.join(this.sessionDir, "patterns"), { recursive: true });
6831
- await fs3.promises.mkdir(path4.join(this.sessionDir, "tests"), { recursive: true });
6902
+ await fs4.promises.mkdir(this.sessionDir, { recursive: true });
6903
+ await fs4.promises.mkdir(path5.join(this.sessionDir, "conversions"), { recursive: true });
6904
+ await fs4.promises.mkdir(path5.join(this.sessionDir, "patterns"), { recursive: true });
6905
+ await fs4.promises.mkdir(path5.join(this.sessionDir, "tests"), { recursive: true });
6832
6906
  const sessionInfo = {
6833
6907
  sessionId: this.sessionId,
6834
6908
  startedAt: this.startedAt.toISOString(),
6835
6909
  platform: os.platform(),
6836
6910
  nodeVersion: process.version
6837
6911
  };
6838
- await fs3.promises.writeFile(
6839
- path4.join(this.sessionDir, "session.json"),
6912
+ await fs4.promises.writeFile(
6913
+ path5.join(this.sessionDir, "session.json"),
6840
6914
  JSON.stringify(sessionInfo, null, 2)
6841
6915
  );
6842
6916
  logger.debug(`Created new session: ${this.sessionId}`);
@@ -6851,8 +6925,8 @@ var init_session_store = __esm({
6851
6925
  startedAt: this.startedAt.toISOString(),
6852
6926
  lastActivityAt: (/* @__PURE__ */ new Date()).toISOString()
6853
6927
  };
6854
- await fs3.promises.mkdir(SESSIONS_BASE_DIR, { recursive: true });
6855
- await fs3.promises.writeFile(
6928
+ await fs4.promises.mkdir(SESSIONS_BASE_DIR, { recursive: true });
6929
+ await fs4.promises.writeFile(
6856
6930
  ACTIVE_SESSION_FILE,
6857
6931
  JSON.stringify(activeInfo, null, 2)
6858
6932
  );
@@ -6914,10 +6988,10 @@ var init_session_store = __esm({
6914
6988
  this.conversions.push(record);
6915
6989
  this.updatePatternLibrary(record.patterns);
6916
6990
  try {
6917
- const conversionFile = path4.join(this.sessionDir, "conversions", `${record.id}.json`);
6918
- await fs3.promises.writeFile(conversionFile, JSON.stringify(record, null, 2));
6919
- const testFile = path4.join(this.sessionDir, "tests", `${targetName}-comparison.json`);
6920
- await fs3.promises.writeFile(testFile, JSON.stringify({
6991
+ const conversionFile = path5.join(this.sessionDir, "conversions", `${record.id}.json`);
6992
+ await fs4.promises.writeFile(conversionFile, JSON.stringify(record, null, 2));
6993
+ const testFile = path5.join(this.sessionDir, "tests", `${targetName}-comparison.json`);
6994
+ await fs4.promises.writeFile(testFile, JSON.stringify({
6921
6995
  ...testComparison,
6922
6996
  conversionId: record.id,
6923
6997
  timestamp: record.timestamp
@@ -7031,8 +7105,8 @@ var init_session_store = __esm({
7031
7105
  }
7032
7106
  }
7033
7107
  try {
7034
- const conversionFile = path4.join(this.sessionDir, "conversions", `${conversionId}.json`);
7035
- await fs3.promises.writeFile(conversionFile, JSON.stringify(conversion, null, 2));
7108
+ const conversionFile = path5.join(this.sessionDir, "conversions", `${conversionId}.json`);
7109
+ await fs4.promises.writeFile(conversionFile, JSON.stringify(conversion, null, 2));
7036
7110
  await this.saveSessionSummary();
7037
7111
  } catch (error) {
7038
7112
  logger.debug(`Failed to update conversion: ${error.message}`);
@@ -7063,12 +7137,12 @@ var init_session_store = __esm({
7063
7137
  async saveSessionSummary() {
7064
7138
  const summary = this.getSessionSummary();
7065
7139
  try {
7066
- await fs3.promises.writeFile(
7067
- path4.join(this.sessionDir, "summary.json"),
7140
+ await fs4.promises.writeFile(
7141
+ path5.join(this.sessionDir, "summary.json"),
7068
7142
  JSON.stringify(summary, null, 2)
7069
7143
  );
7070
- await fs3.promises.writeFile(
7071
- path4.join(this.sessionDir, "patterns", "library.json"),
7144
+ await fs4.promises.writeFile(
7145
+ path5.join(this.sessionDir, "patterns", "library.json"),
7072
7146
  JSON.stringify(Array.from(this.patternLibrary.values()), null, 2)
7073
7147
  );
7074
7148
  } catch (error) {
@@ -7144,10 +7218,10 @@ All session data is stored in:
7144
7218
  async cleanup() {
7145
7219
  try {
7146
7220
  if (this.sessionDir) {
7147
- await fs3.promises.rm(this.sessionDir, { recursive: true, force: true });
7221
+ await fs4.promises.rm(this.sessionDir, { recursive: true, force: true });
7148
7222
  }
7149
- if (fs3.existsSync(ACTIVE_SESSION_FILE)) {
7150
- await fs3.promises.unlink(ACTIVE_SESSION_FILE);
7223
+ if (fs4.existsSync(ACTIVE_SESSION_FILE)) {
7224
+ await fs4.promises.unlink(ACTIVE_SESSION_FILE);
7151
7225
  }
7152
7226
  this.conversions = [];
7153
7227
  this.patternLibrary.clear();
@@ -7190,8 +7264,8 @@ All session data is stored in:
7190
7264
  });
7191
7265
 
7192
7266
  // src/utils/preview-generator.ts
7193
- import fs4 from "fs-extra";
7194
- import * as path5 from "path";
7267
+ import fs5 from "fs-extra";
7268
+ import * as path6 from "path";
7195
7269
  function parseAttributes(tagContent) {
7196
7270
  const attrs = {};
7197
7271
  const attrRegex = /(\S+?)(?:=(?:"([^"]*)"|{([^}]*)})|(?=\s|>|$))/g;
@@ -7578,14 +7652,14 @@ function generatePreviewHtml(bundle, componentCss) {
7578
7652
  </html>`;
7579
7653
  }
7580
7654
  async function writePreviewFile(outputDir, bundle, dryRun = false) {
7581
- const previewPath = path5.join(outputDir, bundle.name, `${bundle.name}-preview.html`);
7655
+ const previewPath = path6.join(outputDir, bundle.name, `${bundle.name}-preview.html`);
7582
7656
  const previewHtml = generatePreviewHtml(bundle, bundle.css);
7583
7657
  if (dryRun) {
7584
7658
  logger.info(`[DRY RUN] Would write preview: ${previewPath}`);
7585
7659
  return previewPath;
7586
7660
  }
7587
- await fs4.ensureDir(path5.dirname(previewPath));
7588
- await fs4.writeFile(previewPath, previewHtml, "utf-8");
7661
+ await fs5.ensureDir(path6.dirname(previewPath));
7662
+ await fs5.writeFile(previewPath, previewHtml, "utf-8");
7589
7663
  logger.file("CREATE", previewPath);
7590
7664
  return previewPath;
7591
7665
  }
@@ -7970,7 +8044,7 @@ __export(open_folder_exports, {
7970
8044
  import { exec } from "child_process";
7971
8045
  import * as os2 from "os";
7972
8046
  function openFolder(folderPath) {
7973
- return new Promise((resolve7, _reject) => {
8047
+ return new Promise((resolve8, _reject) => {
7974
8048
  const platform3 = os2.platform();
7975
8049
  let command;
7976
8050
  switch (platform3) {
@@ -7987,9 +8061,9 @@ function openFolder(folderPath) {
7987
8061
  exec(command, (error) => {
7988
8062
  if (error) {
7989
8063
  logger.warn(`Could not open folder: ${error.message}`);
7990
- resolve7();
8064
+ resolve8();
7991
8065
  } else {
7992
- resolve7();
8066
+ resolve8();
7993
8067
  }
7994
8068
  });
7995
8069
  });
@@ -8007,8 +8081,12 @@ var aura_exports = {};
8007
8081
  __export(aura_exports, {
8008
8082
  convertAura: () => convertAura
8009
8083
  });
8010
- import * as path6 from "path";
8084
+ import * as path7 from "path";
8011
8085
  async function convertAura(inputPath, options) {
8086
+ const { root, changed } = await ensureProjectRoot();
8087
+ if (changed) {
8088
+ logger.success(`Found project root: ${root}`);
8089
+ }
8012
8090
  const resolved = await resolveAuraPath(inputPath);
8013
8091
  if (!resolved.found) {
8014
8092
  const searchInfo = resolved.searchedLocations && resolved.searchedLocations.length > 0 ? `
@@ -8084,41 +8162,40 @@ Tip: You can provide just the component name (e.g., "AccountCard") or a full pat
8084
8162
  }
8085
8163
  logger.success(`Generated LWC: ${result.bundle.name}`);
8086
8164
  logger.step(7, "Writing output files...");
8087
- const outputDir = path6.resolve(options.output);
8165
+ const outputDir = path7.resolve(options.output);
8088
8166
  const writtenFiles = await writeLwcBundle(outputDir, result.bundle, options.dryRun);
8089
8167
  if (result.notes.length > 0) {
8090
8168
  await writeConversionNotes(outputDir, result.bundle.name, result.notes, options.dryRun);
8091
8169
  }
8092
8170
  if (result.tests) {
8093
- const testDir = path6.join(outputDir, result.bundle.name, "__tests__");
8094
- const testFilePath = path6.join(testDir, result.tests.filename);
8171
+ const testDir = path7.join(outputDir, result.bundle.name, "__tests__");
8172
+ const testFilePath = path7.join(testDir, result.tests.filename);
8095
8173
  const { writeFile: writeFile2 } = await Promise.resolve().then(() => (init_file_io(), file_io_exports));
8096
8174
  await writeFile2(testFilePath, result.tests.content, options.dryRun);
8097
8175
  }
8098
8176
  if (result.behaviorSpec) {
8099
- const specFilePath = path6.join(outputDir, result.bundle.name, `${result.bundle.name}-behavior-spec.md`);
8177
+ const specFilePath = path7.join(outputDir, result.bundle.name, `${result.bundle.name}-behavior-spec.md`);
8100
8178
  const { writeFile: writeFile2 } = await Promise.resolve().then(() => (init_file_io(), file_io_exports));
8101
8179
  await writeFile2(specFilePath, result.behaviorSpec, options.dryRun);
8102
8180
  }
8103
8181
  if (result.testComparison) {
8104
8182
  const { writeFile: writeFile2 } = await Promise.resolve().then(() => (init_file_io(), file_io_exports));
8105
- const testDir = path6.join(outputDir, result.bundle.name, "__tests__");
8106
- const beforeTestPath = path6.join(testDir, `${result.bundle.name}.before.spec.js`);
8183
+ const testDir = path7.join(outputDir, result.bundle.name, "__tests__");
8184
+ const beforeTestPath = path7.join(testDir, `${result.bundle.name}.before.spec.js`);
8107
8185
  await writeFile2(beforeTestPath, result.testComparison.beforeTestFile, options.dryRun);
8108
- const afterTestPath = path6.join(testDir, `${result.bundle.name}.after.test.js`);
8186
+ const afterTestPath = path7.join(testDir, `${result.bundle.name}.after.test.js`);
8109
8187
  await writeFile2(afterTestPath, result.testComparison.afterTestFile, options.dryRun);
8110
- const comparisonReportPath = path6.join(outputDir, result.bundle.name, `${result.bundle.name}-test-comparison.md`);
8188
+ const comparisonReportPath = path7.join(outputDir, result.bundle.name, `${result.bundle.name}-test-comparison.md`);
8111
8189
  await writeFile2(comparisonReportPath, result.testComparison.comparisonReport, options.dryRun);
8112
8190
  }
8113
8191
  logger.divider();
8114
- logger.success("Conversion complete!");
8115
8192
  if (result.testComparison) {
8116
8193
  const conversionRecord = await sessionStore.storeConversion(
8117
8194
  "aura",
8118
8195
  bundle.name,
8119
8196
  result.bundle.name,
8120
8197
  bundlePath,
8121
- path6.join(outputDir, result.bundle.name),
8198
+ path7.join(outputDir, result.bundle.name),
8122
8199
  result.testComparison,
8123
8200
  result.warnings
8124
8201
  );
@@ -8128,14 +8205,21 @@ Tip: You can provide just the component name (e.g., "AccountCard") or a full pat
8128
8205
  if (result.tests) totalFiles++;
8129
8206
  if (result.behaviorSpec) totalFiles++;
8130
8207
  if (result.testComparison) totalFiles += 3;
8208
+ logger.successToast(
8209
+ "Conversion Complete",
8210
+ [
8211
+ `${bundle.name} \u2192 ${result.bundle.name}`,
8212
+ `${totalFiles} files created`
8213
+ ],
8214
+ path7.join(outputDir, result.bundle.name)
8215
+ );
8131
8216
  const sessionSummary = sessionStore.getSessionSummary();
8132
8217
  logger.summaryBox("Conversion Summary", [
8133
8218
  { label: "Component", value: `${bundle.name} \u2192 ${result.bundle.name}`, type: "success" },
8134
8219
  { label: "Files created", value: `${totalFiles}`, type: "info" },
8135
8220
  { label: "Behaviors mapped", value: `${result.testComparison?.behaviorTests.length || 0}`, type: "info" },
8136
8221
  { label: "Warnings", value: `${result.warnings.length}`, type: result.warnings.length > 0 ? "warn" : "success" },
8137
- { label: "Session conversions", value: `${sessionSummary.conversions}`, type: "info" },
8138
- { label: "Output", value: path6.join(outputDir, result.bundle.name), type: "info" }
8222
+ { label: "Output", value: path7.join(outputDir, result.bundle.name), type: "info" }
8139
8223
  ]);
8140
8224
  if (result.warnings.length > 0) {
8141
8225
  if (options.verbose) {
@@ -8185,6 +8269,7 @@ var init_aura = __esm({
8185
8269
  init_path_resolver();
8186
8270
  init_session_store();
8187
8271
  init_preview_generator();
8272
+ init_project_detector();
8188
8273
  }
8189
8274
  });
8190
8275
 
@@ -8686,8 +8771,12 @@ var vf_exports = {};
8686
8771
  __export(vf_exports, {
8687
8772
  convertVf: () => convertVf
8688
8773
  });
8689
- import * as path7 from "path";
8774
+ import * as path8 from "path";
8690
8775
  async function convertVf(inputPath, options) {
8776
+ const { root, changed } = await ensureProjectRoot();
8777
+ if (changed) {
8778
+ logger.success(`Found project root: ${root}`);
8779
+ }
8691
8780
  const resolved = await resolveVfPath(inputPath);
8692
8781
  if (!resolved.found) {
8693
8782
  const searchInfo = resolved.searchedLocations && resolved.searchedLocations.length > 0 ? `
@@ -8793,18 +8882,26 @@ Tip: You can provide just the page name (e.g., "ContactList") or a full path (e.
8793
8882
  }
8794
8883
  logger.success(`Generated LWC: ${result.bundle.name}`);
8795
8884
  logger.step(6, "Writing output files...");
8796
- const outputDir = path7.resolve(options.output);
8885
+ const outputDir = path8.resolve(options.output);
8797
8886
  const writtenFiles = await writeLwcBundle(outputDir, result.bundle, options.dryRun);
8798
8887
  if (result.notes.length > 0) {
8799
8888
  await writeConversionNotes(outputDir, result.bundle.name, result.notes, options.dryRun);
8800
8889
  }
8801
8890
  logger.divider();
8802
- logger.success("Conversion complete!");
8891
+ const totalFiles = writtenFiles.length + 1;
8892
+ logger.successToast(
8893
+ "Conversion Complete",
8894
+ [
8895
+ `${vfPage.name} \u2192 ${result.bundle.name}`,
8896
+ `${totalFiles} files created`
8897
+ ],
8898
+ path8.join(outputDir, result.bundle.name)
8899
+ );
8803
8900
  logger.summaryBox("Conversion Summary", [
8804
8901
  { label: "Page", value: `${vfPage.name} \u2192 ${result.bundle.name}`, type: "success" },
8805
- { label: "Files created", value: `${writtenFiles.length + 1}`, type: "info" },
8902
+ { label: "Files created", value: `${totalFiles}`, type: "info" },
8806
8903
  { label: "Warnings", value: `${result.warnings.length}`, type: result.warnings.length > 0 ? "warn" : "success" },
8807
- { label: "Output", value: path7.join(outputDir, result.bundle.name), type: "info" }
8904
+ { label: "Output", value: path8.join(outputDir, result.bundle.name), type: "info" }
8808
8905
  ]);
8809
8906
  if (result.warnings.length > 0) {
8810
8907
  if (options.verbose) {
@@ -8853,6 +8950,7 @@ var init_vf = __esm({
8853
8950
  init_full_conversion();
8854
8951
  init_path_resolver();
8855
8952
  init_preview_generator();
8953
+ init_project_detector();
8856
8954
  }
8857
8955
  });
8858
8956
 
@@ -9276,8 +9374,8 @@ var init_vf_grader = __esm({
9276
9374
  });
9277
9375
 
9278
9376
  // src/grading/grader.ts
9279
- import fs6 from "fs-extra";
9280
- import * as path9 from "path";
9377
+ import fs7 from "fs-extra";
9378
+ import * as path10 from "path";
9281
9379
  var Grader;
9282
9380
  var init_grader = __esm({
9283
9381
  "src/grading/grader.ts"() {
@@ -9298,13 +9396,13 @@ var init_grader = __esm({
9298
9396
  * Read sfdx-project.json and return package directories
9299
9397
  */
9300
9398
  async getPackageDirectories(rootPath) {
9301
- const sfdxProjectPath = path9.join(rootPath, "sfdx-project.json");
9302
- if (await fs6.pathExists(sfdxProjectPath)) {
9399
+ const sfdxProjectPath = path10.join(rootPath, "sfdx-project.json");
9400
+ if (await fs7.pathExists(sfdxProjectPath)) {
9303
9401
  try {
9304
- const projectConfig = await fs6.readJson(sfdxProjectPath);
9402
+ const projectConfig = await fs7.readJson(sfdxProjectPath);
9305
9403
  if (projectConfig.packageDirectories && Array.isArray(projectConfig.packageDirectories)) {
9306
9404
  return projectConfig.packageDirectories.map(
9307
- (pkg) => path9.join(rootPath, pkg.path)
9405
+ (pkg) => path10.join(rootPath, pkg.path)
9308
9406
  );
9309
9407
  }
9310
9408
  } catch (error) {
@@ -9323,10 +9421,10 @@ var init_grader = __esm({
9323
9421
  const searchDir = async (dirPath, depth = 0) => {
9324
9422
  if (depth > 5) return;
9325
9423
  try {
9326
- const entries = await fs6.readdir(dirPath, { withFileTypes: true });
9424
+ const entries = await fs7.readdir(dirPath, { withFileTypes: true });
9327
9425
  for (const entry of entries) {
9328
9426
  if (entry.isDirectory()) {
9329
- const fullPath = path9.join(dirPath, entry.name);
9427
+ const fullPath = path10.join(dirPath, entry.name);
9330
9428
  if (entry.name === "pages") {
9331
9429
  pagesDirectories.push(fullPath);
9332
9430
  } else if (entry.name === "components") {
@@ -9371,7 +9469,7 @@ var init_grader = __esm({
9371
9469
  async gradeSingle(filePath, type) {
9372
9470
  const resolvedType = type === "both" ? this.detectType(filePath) : type;
9373
9471
  if (resolvedType === "aura") {
9374
- const bundlePath = filePath.endsWith(".cmp") ? path9.dirname(filePath) : filePath;
9472
+ const bundlePath = filePath.endsWith(".cmp") ? path10.dirname(filePath) : filePath;
9375
9473
  return this.auraGrader.grade(bundlePath);
9376
9474
  } else if (resolvedType === "vf") {
9377
9475
  return this.vfGrader.grade(filePath);
@@ -9403,8 +9501,8 @@ var init_grader = __esm({
9403
9501
  }
9404
9502
  if (type === "aura" || type === "both") {
9405
9503
  const auraFallbacks = [
9406
- path9.join(cwd, "force-app/main/default/aura"),
9407
- path9.join(cwd, "src/aura")
9504
+ path10.join(cwd, "force-app/main/default/aura"),
9505
+ path10.join(cwd, "src/aura")
9408
9506
  ];
9409
9507
  for (const fallback of auraFallbacks) {
9410
9508
  if (!paths.includes(fallback)) {
@@ -9414,10 +9512,10 @@ var init_grader = __esm({
9414
9512
  }
9415
9513
  if (type === "vf" || type === "both") {
9416
9514
  const vfFallbacks = [
9417
- path9.join(cwd, "force-app/main/default/pages"),
9418
- path9.join(cwd, "src/pages"),
9419
- path9.join(cwd, "force-app/main/default/components"),
9420
- path9.join(cwd, "src/components")
9515
+ path10.join(cwd, "force-app/main/default/pages"),
9516
+ path10.join(cwd, "src/pages"),
9517
+ path10.join(cwd, "force-app/main/default/components"),
9518
+ path10.join(cwd, "src/components")
9421
9519
  ];
9422
9520
  for (const fallback of vfFallbacks) {
9423
9521
  if (!paths.includes(fallback)) {
@@ -9429,14 +9527,14 @@ var init_grader = __esm({
9429
9527
  }
9430
9528
  async scanDirectory(dir, type) {
9431
9529
  const results = [];
9432
- if (!await fs6.pathExists(dir)) return results;
9530
+ if (!await fs7.pathExists(dir)) return results;
9433
9531
  async function walk(currentDir) {
9434
- const entries = await fs6.readdir(currentDir, { withFileTypes: true });
9532
+ const entries = await fs7.readdir(currentDir, { withFileTypes: true });
9435
9533
  for (const entry of entries) {
9436
- const fullPath = path9.join(currentDir, entry.name);
9534
+ const fullPath = path10.join(currentDir, entry.name);
9437
9535
  if (entry.isDirectory()) {
9438
9536
  if (type !== "vf") {
9439
- const children = await fs6.readdir(fullPath);
9537
+ const children = await fs7.readdir(fullPath);
9440
9538
  if (children.some((f) => f.endsWith(".cmp"))) {
9441
9539
  results.push(fullPath);
9442
9540
  continue;
@@ -9575,7 +9673,7 @@ var require_picocolors = __commonJS({
9575
9673
  });
9576
9674
 
9577
9675
  // src/utils/vf-controller-resolver.ts
9578
- import fs11 from "fs-extra";
9676
+ import fs12 from "fs-extra";
9579
9677
  function extractControllerNames(markup) {
9580
9678
  const controllers = [];
9581
9679
  const seen = /* @__PURE__ */ new Set();
@@ -9671,8 +9769,8 @@ __export(interactive_exports, {
9671
9769
  runInteractiveTui: () => runInteractiveTui
9672
9770
  });
9673
9771
  import * as p from "@clack/prompts";
9674
- import * as path13 from "path";
9675
- import fs12 from "fs-extra";
9772
+ import * as path14 from "path";
9773
+ import fs13 from "fs-extra";
9676
9774
  function showBreadcrumbs(currentStep, conversionType) {
9677
9775
  const breadcrumb = STEPS.map((step, i) => {
9678
9776
  if (step === "Controllers" && conversionType === "aura") {
@@ -9699,16 +9797,16 @@ async function findAuraComponents() {
9699
9797
  const components3 = [];
9700
9798
  const cwd = process.cwd();
9701
9799
  for (const searchPath of searchPaths) {
9702
- const fullPath = path13.join(cwd, searchPath);
9703
- if (await fs12.pathExists(fullPath)) {
9800
+ const fullPath = path14.join(cwd, searchPath);
9801
+ if (await fs13.pathExists(fullPath)) {
9704
9802
  try {
9705
- const entries = await fs12.readdir(fullPath, { withFileTypes: true });
9803
+ const entries = await fs13.readdir(fullPath, { withFileTypes: true });
9706
9804
  for (const entry of entries) {
9707
9805
  if (entry.isDirectory()) {
9708
- const cmpFile = path13.join(fullPath, entry.name, `${entry.name}.cmp`);
9709
- if (await fs12.pathExists(cmpFile)) {
9806
+ const cmpFile = path14.join(fullPath, entry.name, `${entry.name}.cmp`);
9807
+ if (await fs13.pathExists(cmpFile)) {
9710
9808
  components3.push({
9711
- value: path13.join(searchPath, entry.name),
9809
+ value: path14.join(searchPath, entry.name),
9712
9810
  label: `\u26A1 ${entry.name}`,
9713
9811
  hint: searchPath
9714
9812
  });
@@ -9730,14 +9828,14 @@ async function findVfPages() {
9730
9828
  const pages = [];
9731
9829
  const cwd = process.cwd();
9732
9830
  for (const searchPath of searchPaths) {
9733
- const fullPath = path13.join(cwd, searchPath);
9734
- if (await fs12.pathExists(fullPath)) {
9831
+ const fullPath = path14.join(cwd, searchPath);
9832
+ if (await fs13.pathExists(fullPath)) {
9735
9833
  try {
9736
- const entries = await fs12.readdir(fullPath, { withFileTypes: true });
9834
+ const entries = await fs13.readdir(fullPath, { withFileTypes: true });
9737
9835
  for (const entry of entries) {
9738
9836
  if (entry.isFile() && entry.name.endsWith(".page")) {
9739
9837
  pages.push({
9740
- value: path13.join(searchPath, entry.name),
9838
+ value: path14.join(searchPath, entry.name),
9741
9839
  label: `\u{1F4C4} ${entry.name.replace(".page", "")}`,
9742
9840
  hint: searchPath
9743
9841
  });
@@ -9758,14 +9856,14 @@ async function findApexControllers() {
9758
9856
  const controllers = [];
9759
9857
  const cwd = process.cwd();
9760
9858
  for (const searchPath of searchPaths) {
9761
- const fullPath = path13.join(cwd, searchPath);
9762
- if (await fs12.pathExists(fullPath)) {
9859
+ const fullPath = path14.join(cwd, searchPath);
9860
+ if (await fs13.pathExists(fullPath)) {
9763
9861
  try {
9764
- const entries = await fs12.readdir(fullPath, { withFileTypes: true });
9862
+ const entries = await fs13.readdir(fullPath, { withFileTypes: true });
9765
9863
  for (const entry of entries) {
9766
9864
  if (entry.isFile() && entry.name.endsWith(".cls")) {
9767
9865
  controllers.push({
9768
- value: path13.join(searchPath, entry.name),
9866
+ value: path14.join(searchPath, entry.name),
9769
9867
  label: `\u{1F4CB} ${entry.name.replace(".cls", "")}`
9770
9868
  });
9771
9869
  }
@@ -9991,11 +10089,11 @@ async function runInteractiveTui() {
9991
10089
  }
9992
10090
  while (currentStep === 2 && conversionType === "vf" && componentPath && action !== "grade") {
9993
10091
  showBreadcrumbs(currentStep, conversionType);
9994
- const resolvedPagePath = path13.resolve(componentPath);
9995
- if (await fs12.pathExists(resolvedPagePath)) {
10092
+ const resolvedPagePath = path14.resolve(componentPath);
10093
+ if (await fs13.pathExists(resolvedPagePath)) {
9996
10094
  const s = p.spinner();
9997
10095
  s.start("Analyzing page for controller references...");
9998
- const pageContent = await fs12.readFile(resolvedPagePath, "utf-8");
10096
+ const pageContent = await fs13.readFile(resolvedPagePath, "utf-8");
9999
10097
  const result = await findVfControllers(pageContent);
10000
10098
  detectedControllers = result.controllers;
10001
10099
  s.stop("Analysis complete");
@@ -10045,7 +10143,7 @@ async function runInteractiveTui() {
10045
10143
  if (addMore) {
10046
10144
  const allControllers = await findApexControllers();
10047
10145
  const availableControllers = allControllers.filter(
10048
- (c) => !controllerPaths.includes(path13.resolve(c.value))
10146
+ (c) => !controllerPaths.includes(path14.resolve(c.value))
10049
10147
  );
10050
10148
  if (availableControllers.length > 0) {
10051
10149
  const additional = await p.multiselect({
@@ -10054,7 +10152,7 @@ async function runInteractiveTui() {
10054
10152
  required: false
10055
10153
  });
10056
10154
  if (!isCancel2(additional)) {
10057
- controllerPaths.push(...additional.map((c) => path13.resolve(c)));
10155
+ controllerPaths.push(...additional.map((c) => path14.resolve(c)));
10058
10156
  }
10059
10157
  }
10060
10158
  }
@@ -10081,7 +10179,7 @@ async function runInteractiveTui() {
10081
10179
  continue wizardLoop;
10082
10180
  }
10083
10181
  controllerPath = selected;
10084
- controllerPaths = [path13.resolve(controllerPath)];
10182
+ controllerPaths = [path14.resolve(controllerPath)];
10085
10183
  }
10086
10184
  }
10087
10185
  }
@@ -10188,7 +10286,7 @@ async function runInteractiveTui() {
10188
10286
  if (controllerPaths.length > 0) {
10189
10287
  summaryLines.push(`${import_picocolors.default.dim("Controllers:")} ${controllerPaths.length} selected`);
10190
10288
  controllerPaths.forEach((cp) => {
10191
- summaryLines.push(` ${import_picocolors.default.dim("\u2022")} ${path13.basename(cp)}`);
10289
+ summaryLines.push(` ${import_picocolors.default.dim("\u2022")} ${path14.basename(cp)}`);
10192
10290
  });
10193
10291
  }
10194
10292
  summaryLines.push(`${import_picocolors.default.dim("Mode:")} ${conversionMode === "full" ? "\u26A1 Full" : "\u{1F4DD} Scaffolding"}`);
@@ -10256,13 +10354,13 @@ var init_types = __esm({
10256
10354
  });
10257
10355
 
10258
10356
  // src/tui/store/persistence.ts
10259
- import fs13 from "fs-extra";
10260
- import path14 from "path";
10357
+ import fs14 from "fs-extra";
10358
+ import path15 from "path";
10261
10359
  import os4 from "os";
10262
10360
  async function savePreferences(prefs) {
10263
10361
  try {
10264
- await fs13.ensureDir(CONFIG_DIR);
10265
- await fs13.writeJson(PREFS_PATH, prefs, { spaces: 2 });
10362
+ await fs14.ensureDir(CONFIG_DIR);
10363
+ await fs14.writeJson(PREFS_PATH, prefs, { spaces: 2 });
10266
10364
  } catch (error) {
10267
10365
  console.error("Error saving preferences:", error);
10268
10366
  throw error;
@@ -10270,9 +10368,9 @@ async function savePreferences(prefs) {
10270
10368
  }
10271
10369
  function loadPreferencesSync() {
10272
10370
  try {
10273
- fs13.ensureDirSync(CONFIG_DIR);
10274
- if (fs13.pathExistsSync(PREFS_PATH)) {
10275
- const data = fs13.readJsonSync(PREFS_PATH);
10371
+ fs14.ensureDirSync(CONFIG_DIR);
10372
+ if (fs14.pathExistsSync(PREFS_PATH)) {
10373
+ const data = fs14.readJsonSync(PREFS_PATH);
10276
10374
  return { ...DEFAULT_PREFERENCES, ...data };
10277
10375
  }
10278
10376
  } catch (error) {
@@ -10285,8 +10383,8 @@ var init_persistence = __esm({
10285
10383
  "use strict";
10286
10384
  init_esm_shims();
10287
10385
  init_types();
10288
- CONFIG_DIR = path14.join(os4.homedir(), ".lwc-convert");
10289
- PREFS_PATH = path14.join(CONFIG_DIR, "preferences.json");
10386
+ CONFIG_DIR = path15.join(os4.homedir(), ".lwc-convert");
10387
+ PREFS_PATH = path15.join(CONFIG_DIR, "preferences.json");
10290
10388
  }
10291
10389
  });
10292
10390
 
@@ -10433,8 +10531,8 @@ var init_store = __esm({
10433
10531
  await savePreferences(newPrefs);
10434
10532
  },
10435
10533
  // Project actions
10436
- setProjectPath: (path16) => {
10437
- set({ projectPath: path16 });
10534
+ setProjectPath: (path17) => {
10535
+ set({ projectPath: path17 });
10438
10536
  },
10439
10537
  setComponents: (aura, vf) => {
10440
10538
  set({ auraComponents: aura, vfComponents: vf });
@@ -11188,8 +11286,8 @@ var init_feedback = __esm({
11188
11286
  });
11189
11287
 
11190
11288
  // src/tui/utils/discovery.ts
11191
- import fs14 from "fs-extra";
11192
- import path15 from "path";
11289
+ import fs15 from "fs-extra";
11290
+ import path16 from "path";
11193
11291
  async function discoverComponents(projectPath) {
11194
11292
  const auraComponents = [];
11195
11293
  const vfComponents = [];
@@ -11202,8 +11300,8 @@ async function discoverComponents(projectPath) {
11202
11300
  "pages"
11203
11301
  ];
11204
11302
  for (const searchPath of searchPaths) {
11205
- const fullPath = path15.join(projectPath, searchPath);
11206
- if (await fs14.pathExists(fullPath)) {
11303
+ const fullPath = path16.join(projectPath, searchPath);
11304
+ if (await fs15.pathExists(fullPath)) {
11207
11305
  if (searchPath.includes("aura")) {
11208
11306
  const components3 = await discoverAuraComponents(fullPath);
11209
11307
  auraComponents.push(...components3);
@@ -11219,8 +11317,8 @@ async function discoverComponents(projectPath) {
11219
11317
  "components"
11220
11318
  ];
11221
11319
  for (const searchPath of vfComponentPaths) {
11222
- const fullPath = path15.join(projectPath, searchPath);
11223
- if (await fs14.pathExists(fullPath)) {
11320
+ const fullPath = path16.join(projectPath, searchPath);
11321
+ if (await fs15.pathExists(fullPath)) {
11224
11322
  const components3 = await discoverVfComponents(fullPath);
11225
11323
  vfComponents.push(...components3);
11226
11324
  }
@@ -11240,11 +11338,11 @@ async function discoverComponents(projectPath) {
11240
11338
  async function discoverAuraComponents(auraPath) {
11241
11339
  const components3 = [];
11242
11340
  try {
11243
- const entries = await fs14.readdir(auraPath, { withFileTypes: true });
11341
+ const entries = await fs15.readdir(auraPath, { withFileTypes: true });
11244
11342
  for (const entry of entries) {
11245
11343
  if (entry.isDirectory()) {
11246
- const componentPath = path15.join(auraPath, entry.name);
11247
- const files = await fs14.readdir(componentPath);
11344
+ const componentPath = path16.join(auraPath, entry.name);
11345
+ const files = await fs15.readdir(componentPath);
11248
11346
  const cmpFile = files.find((f) => f.endsWith(".cmp"));
11249
11347
  if (cmpFile) {
11250
11348
  components3.push({
@@ -11268,14 +11366,14 @@ async function discoverAuraComponents(auraPath) {
11268
11366
  async function discoverVfPages(pagesPath) {
11269
11367
  const pages = [];
11270
11368
  try {
11271
- const entries = await fs14.readdir(pagesPath, { withFileTypes: true });
11369
+ const entries = await fs15.readdir(pagesPath, { withFileTypes: true });
11272
11370
  for (const entry of entries) {
11273
11371
  if (entry.isFile() && entry.name.endsWith(".page")) {
11274
11372
  const name = entry.name.replace(".page", "");
11275
- const pagePath = path15.join(pagesPath, entry.name);
11373
+ const pagePath = path16.join(pagesPath, entry.name);
11276
11374
  const relatedFiles = [entry.name];
11277
11375
  const metaFile = `${entry.name}-meta.xml`;
11278
- if (await fs14.pathExists(path15.join(pagesPath, metaFile))) {
11376
+ if (await fs15.pathExists(path16.join(pagesPath, metaFile))) {
11279
11377
  relatedFiles.push(metaFile);
11280
11378
  }
11281
11379
  pages.push({
@@ -11297,11 +11395,11 @@ async function discoverVfPages(pagesPath) {
11297
11395
  async function discoverVfComponents(componentsPath) {
11298
11396
  const components3 = [];
11299
11397
  try {
11300
- const entries = await fs14.readdir(componentsPath, { withFileTypes: true });
11398
+ const entries = await fs15.readdir(componentsPath, { withFileTypes: true });
11301
11399
  for (const entry of entries) {
11302
11400
  if (entry.isFile() && entry.name.endsWith(".component")) {
11303
11401
  const name = entry.name.replace(".component", "");
11304
- const componentPath = path15.join(componentsPath, entry.name);
11402
+ const componentPath = path16.join(componentsPath, entry.name);
11305
11403
  components3.push({
11306
11404
  id: `vf-component-${name}`,
11307
11405
  name,
@@ -13094,7 +13192,7 @@ function ConversionWizard() {
13094
13192
  setSelectedComponentIndex(0);
13095
13193
  setComponentListScrollOffset(0);
13096
13194
  },
13097
- onSourcePathChange: (path16) => updateWizardState({ sourcePath: path16 }),
13195
+ onSourcePathChange: (path17) => updateWizardState({ sourcePath: path17 }),
13098
13196
  onComponentSelect: (component) => {
13099
13197
  updateWizardState({ sourcePath: component.path });
13100
13198
  },
@@ -13406,7 +13504,7 @@ var init_Modal = __esm({
13406
13504
  // src/tui/screens/ExportModal.tsx
13407
13505
  import { useState as useState8 } from "react";
13408
13506
  import { Box as Box18, Text as Text21 } from "ink";
13409
- import fs15 from "fs-extra";
13507
+ import fs16 from "fs-extra";
13410
13508
  import { Fragment, jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
13411
13509
  function ExportModal() {
13412
13510
  const preferences = useStore((state) => state.preferences);
@@ -13447,7 +13545,7 @@ function ExportModal() {
13447
13545
  default:
13448
13546
  content = JSON.stringify(data, null, 2);
13449
13547
  }
13450
- await fs15.writeFile(options.outputPath, content);
13548
+ await fs16.writeFile(options.outputPath, content);
13451
13549
  setExportSuccess(true);
13452
13550
  setTimeout(() => {
13453
13551
  closeModal();
@@ -13559,7 +13657,7 @@ function ExportModal() {
13559
13657
  {
13560
13658
  label: "Output Path",
13561
13659
  value: options.outputPath,
13562
- onChange: (path16) => setOptions((o) => ({ ...o, outputPath: path16 })),
13660
+ onChange: (path17) => setOptions((o) => ({ ...o, outputPath: path17 })),
13563
13661
  focus: focusedField === 4
13564
13662
  }
13565
13663
  ) }),
@@ -13887,10 +13985,10 @@ import { Command } from "commander";
13887
13985
  // src/utils/update-checker.ts
13888
13986
  init_esm_shims();
13889
13987
  init_options();
13890
- import fs5 from "fs-extra";
13891
- import path8 from "path";
13988
+ import fs6 from "fs-extra";
13989
+ import path9 from "path";
13892
13990
  import os3 from "os";
13893
- var CACHE_FILE = path8.join(os3.tmpdir(), "lwc-convert-update-check.json");
13991
+ var CACHE_FILE = path9.join(os3.tmpdir(), "lwc-convert-update-check.json");
13894
13992
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
13895
13993
  var FETCH_TIMEOUT_MS = 3e3;
13896
13994
  async function fetchLatestVersion() {
@@ -13925,8 +14023,8 @@ function isNewerVersion(latest, current) {
13925
14023
  }
13926
14024
  async function readCache() {
13927
14025
  try {
13928
- if (await fs5.pathExists(CACHE_FILE)) {
13929
- return await fs5.readJson(CACHE_FILE);
14026
+ if (await fs6.pathExists(CACHE_FILE)) {
14027
+ return await fs6.readJson(CACHE_FILE);
13930
14028
  }
13931
14029
  } catch {
13932
14030
  }
@@ -13934,7 +14032,7 @@ async function readCache() {
13934
14032
  }
13935
14033
  async function writeCache(cache) {
13936
14034
  try {
13937
- await fs5.writeJson(CACHE_FILE, cache);
14035
+ await fs6.writeJson(CACHE_FILE, cache);
13938
14036
  } catch {
13939
14037
  }
13940
14038
  }
@@ -13974,7 +14072,7 @@ init_esm_shims();
13974
14072
  init_logger();
13975
14073
  init_grader();
13976
14074
  init_path_resolver();
13977
- import fs7 from "fs-extra";
14075
+ import fs8 from "fs-extra";
13978
14076
 
13979
14077
  // src/cli/tui/grade-tui.ts
13980
14078
  init_esm_shims();
@@ -14272,7 +14370,7 @@ async function launchGradeTui(components3, summary) {
14272
14370
  process.stdin.setRawMode(true);
14273
14371
  hideCursor();
14274
14372
  render(state);
14275
- return new Promise((resolve7) => {
14373
+ return new Promise((resolve8) => {
14276
14374
  const handleKeypress = (str, key) => {
14277
14375
  if (!key) return;
14278
14376
  if (state.isSearching) {
@@ -14295,7 +14393,7 @@ async function launchGradeTui(components3, summary) {
14295
14393
  showCursor();
14296
14394
  clearScreen();
14297
14395
  process.stdin.setRawMode(false);
14298
- resolve7();
14396
+ resolve8();
14299
14397
  return;
14300
14398
  }
14301
14399
  if (state.viewMode === "detail") {
@@ -14361,15 +14459,34 @@ function shouldUseInteractive() {
14361
14459
  }
14362
14460
 
14363
14461
  // src/cli/commands/grade.ts
14462
+ function getGradeEmoji(grade2) {
14463
+ switch (grade2) {
14464
+ case "A":
14465
+ return "\u{1F7E2}";
14466
+ case "B":
14467
+ return "\u{1F7E1}";
14468
+ case "C":
14469
+ return "\u{1F7E0}";
14470
+ case "D":
14471
+ return "\u{1F534}";
14472
+ case "F":
14473
+ return "\u26D4";
14474
+ default:
14475
+ return "\u26AA";
14476
+ }
14477
+ }
14478
+ function getComplexityIcon(complexity) {
14479
+ return complexity.includes("Complex") || complexity === "Moderate" ? "\u26A0" : "\u2713";
14480
+ }
14364
14481
  async function grade(target, options) {
14365
14482
  const grader = new Grader();
14366
14483
  let scope = "project";
14367
14484
  let targetPath = target;
14368
14485
  if (target) {
14369
- if (await fs7.pathExists(target)) {
14370
- const stat = await fs7.stat(target);
14486
+ if (await fs8.pathExists(target)) {
14487
+ const stat = await fs8.stat(target);
14371
14488
  if (stat.isDirectory()) {
14372
- const files = await fs7.readdir(target);
14489
+ const files = await fs8.readdir(target);
14373
14490
  if (files.some((f) => f.endsWith(".cmp"))) {
14374
14491
  scope = "component";
14375
14492
  } else {
@@ -14428,7 +14545,7 @@ async function grade(target, options) {
14428
14545
  if (options.format === "json") {
14429
14546
  const output = { summary, components: filteredResults };
14430
14547
  if (options.output) {
14431
- await fs7.writeJson(options.output, output, { spaces: 2 });
14548
+ await fs8.writeJson(options.output, output, { spaces: 2 });
14432
14549
  logger.success(`Results written to ${options.output}`);
14433
14550
  } else {
14434
14551
  console.log(JSON.stringify(output, null, 2));
@@ -14436,7 +14553,7 @@ async function grade(target, options) {
14436
14553
  } else if (options.format === "csv") {
14437
14554
  const csvContent = generateCsvReport(filteredResults, summary);
14438
14555
  if (options.output) {
14439
- await fs7.writeFile(options.output, csvContent);
14556
+ await fs8.writeFile(options.output, csvContent);
14440
14557
  logger.success(`CSV report written to ${options.output}`);
14441
14558
  } else {
14442
14559
  console.log(csvContent);
@@ -14493,11 +14610,14 @@ function filterResults(results, filter) {
14493
14610
  return results;
14494
14611
  }
14495
14612
  function printConsoleReport(results, summary, detailed) {
14496
- console.log("Component".padEnd(30) + "Type".padEnd(10) + "Score".padEnd(10) + "Grade".padEnd(10) + "Complexity");
14497
- console.log("-".repeat(80));
14613
+ console.log("");
14614
+ console.log("Components:");
14498
14615
  results.forEach((r) => {
14616
+ const emoji = getGradeEmoji(r.letterGrade);
14617
+ const icon = getComplexityIcon(r.complexity);
14618
+ const effort = `${r.conversionEffort.manualHours.estimate}h`;
14499
14619
  console.log(
14500
- r.componentName.padEnd(30) + r.componentType.padEnd(10) + r.overallScore.toString().padEnd(10) + r.letterGrade.padEnd(10) + r.complexity
14620
+ ` ${emoji} ${r.letterGrade.padEnd(2)} ${r.componentName.padEnd(24)}Score: ${r.overallScore.toString().padStart(2)} Effort: ${effort.padStart(4)} ${icon} ${r.complexity}`
14501
14621
  );
14502
14622
  });
14503
14623
  logger.blank();
@@ -14571,8 +14691,8 @@ function generateCsvReport(results, summary) {
14571
14691
  // src/cli/commands/deps.ts
14572
14692
  init_esm_shims();
14573
14693
  init_logger();
14574
- import fs10 from "fs-extra";
14575
- import * as path12 from "path";
14694
+ import fs11 from "fs-extra";
14695
+ import * as path13 from "path";
14576
14696
 
14577
14697
  // src/dependency-graph/analyzer.ts
14578
14698
  init_esm_shims();
@@ -14581,8 +14701,8 @@ init_logger();
14581
14701
  // src/dependency-graph/aura-dependency-analyzer.ts
14582
14702
  init_esm_shims();
14583
14703
  init_logger();
14584
- import fs8 from "fs-extra";
14585
- import * as path10 from "path";
14704
+ import fs9 from "fs-extra";
14705
+ import * as path11 from "path";
14586
14706
  import * as htmlparser23 from "htmlparser2";
14587
14707
  import { DomHandler as DomHandler3 } from "domhandler";
14588
14708
  function extractMarkupDependencies(markup, includeBaseComponents) {
@@ -14755,13 +14875,13 @@ function extractJsDependencies(jsContent) {
14755
14875
  }
14756
14876
  async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
14757
14877
  try {
14758
- const stat = await fs8.stat(bundlePath);
14878
+ const stat = await fs9.stat(bundlePath);
14759
14879
  if (!stat.isDirectory()) {
14760
14880
  logger.debug(`Not a directory: ${bundlePath}`);
14761
14881
  return null;
14762
14882
  }
14763
- const componentName = path10.basename(bundlePath);
14764
- const files = await fs8.readdir(bundlePath);
14883
+ const componentName = path11.basename(bundlePath);
14884
+ const files = await fs9.readdir(bundlePath);
14765
14885
  const cmpFile = files.find((f) => f.endsWith(".cmp"));
14766
14886
  if (!cmpFile) {
14767
14887
  logger.debug(`No .cmp file found in ${bundlePath}`);
@@ -14770,18 +14890,18 @@ async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
14770
14890
  const context = {
14771
14891
  markup: ""
14772
14892
  };
14773
- context.markup = await fs8.readFile(path10.join(bundlePath, cmpFile), "utf-8");
14893
+ context.markup = await fs9.readFile(path11.join(bundlePath, cmpFile), "utf-8");
14774
14894
  const controllerFile = files.find((f) => f.endsWith("Controller.js"));
14775
14895
  if (controllerFile) {
14776
- context.controllerJs = await fs8.readFile(
14777
- path10.join(bundlePath, controllerFile),
14896
+ context.controllerJs = await fs9.readFile(
14897
+ path11.join(bundlePath, controllerFile),
14778
14898
  "utf-8"
14779
14899
  );
14780
14900
  }
14781
14901
  const helperFile = files.find((f) => f.endsWith("Helper.js"));
14782
14902
  if (helperFile) {
14783
- context.helperJs = await fs8.readFile(
14784
- path10.join(bundlePath, helperFile),
14903
+ context.helperJs = await fs9.readFile(
14904
+ path11.join(bundlePath, helperFile),
14785
14905
  "utf-8"
14786
14906
  );
14787
14907
  }
@@ -14806,13 +14926,13 @@ async function analyzeAuraComponent(bundlePath, includeBaseComponents = false) {
14806
14926
  }
14807
14927
  }
14808
14928
  async function getPackageDirectories(rootPath) {
14809
- const sfdxProjectPath = path10.join(rootPath, "sfdx-project.json");
14810
- if (await fs8.pathExists(sfdxProjectPath)) {
14929
+ const sfdxProjectPath = path11.join(rootPath, "sfdx-project.json");
14930
+ if (await fs9.pathExists(sfdxProjectPath)) {
14811
14931
  try {
14812
- const projectConfig = await fs8.readJson(sfdxProjectPath);
14932
+ const projectConfig = await fs9.readJson(sfdxProjectPath);
14813
14933
  if (projectConfig.packageDirectories && Array.isArray(projectConfig.packageDirectories)) {
14814
14934
  return projectConfig.packageDirectories.map(
14815
- (pkg) => path10.join(rootPath, pkg.path)
14935
+ (pkg) => path11.join(rootPath, pkg.path)
14816
14936
  );
14817
14937
  }
14818
14938
  } catch (error) {
@@ -14826,10 +14946,10 @@ async function findAuraDirectories(basePath) {
14826
14946
  async function searchDir(dirPath, depth = 0) {
14827
14947
  if (depth > 5) return;
14828
14948
  try {
14829
- const entries = await fs8.readdir(dirPath, { withFileTypes: true });
14949
+ const entries = await fs9.readdir(dirPath, { withFileTypes: true });
14830
14950
  for (const entry of entries) {
14831
14951
  if (entry.isDirectory()) {
14832
- const fullPath = path10.join(dirPath, entry.name);
14952
+ const fullPath = path11.join(dirPath, entry.name);
14833
14953
  if (entry.name === "aura") {
14834
14954
  auraDirectories.push(fullPath);
14835
14955
  } else if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
@@ -14855,19 +14975,19 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
14855
14975
  logger.debug(`Found aura directories from sfdx-project.json: ${searchPaths.join(", ")}`);
14856
14976
  }
14857
14977
  const fallbackPaths = [
14858
- path10.join(rootPath, "force-app/main/default/aura"),
14859
- path10.join(rootPath, "src/aura"),
14860
- path10.join(rootPath, "aura")
14978
+ path11.join(rootPath, "force-app/main/default/aura"),
14979
+ path11.join(rootPath, "src/aura"),
14980
+ path11.join(rootPath, "aura")
14861
14981
  ];
14862
14982
  for (const fallback of fallbackPaths) {
14863
14983
  if (!searchPaths.includes(fallback)) {
14864
14984
  searchPaths.push(fallback);
14865
14985
  }
14866
14986
  }
14867
- if (await fs8.pathExists(rootPath)) {
14868
- const stat = await fs8.stat(rootPath);
14987
+ if (await fs9.pathExists(rootPath)) {
14988
+ const stat = await fs9.stat(rootPath);
14869
14989
  if (stat.isDirectory()) {
14870
- const files = await fs8.readdir(rootPath);
14990
+ const files = await fs9.readdir(rootPath);
14871
14991
  if (files.some((f) => f.endsWith(".cmp"))) {
14872
14992
  searchPaths.unshift(rootPath);
14873
14993
  }
@@ -14875,10 +14995,10 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
14875
14995
  }
14876
14996
  logger.debug(`Searching for Aura components in: ${searchPaths.join(", ")}`);
14877
14997
  for (const searchPath of searchPaths) {
14878
- if (await fs8.pathExists(searchPath)) {
14879
- const stat = await fs8.stat(searchPath);
14998
+ if (await fs9.pathExists(searchPath)) {
14999
+ const stat = await fs9.stat(searchPath);
14880
15000
  if (stat.isDirectory()) {
14881
- const files = await fs8.readdir(searchPath);
15001
+ const files = await fs9.readdir(searchPath);
14882
15002
  if (files.some((f) => f.endsWith(".cmp"))) {
14883
15003
  const result = await analyzeAuraComponent(searchPath, includeBaseComponents);
14884
15004
  if (result) {
@@ -14886,8 +15006,8 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
14886
15006
  }
14887
15007
  } else {
14888
15008
  for (const item of files) {
14889
- const itemPath = path10.join(searchPath, item);
14890
- const itemStat = await fs8.stat(itemPath);
15009
+ const itemPath = path11.join(searchPath, item);
15010
+ const itemStat = await fs9.stat(itemPath);
14891
15011
  if (itemStat.isDirectory()) {
14892
15012
  const result = await analyzeAuraComponent(itemPath, includeBaseComponents);
14893
15013
  if (result) {
@@ -14910,8 +15030,8 @@ async function scanAuraComponents(rootPath, includeBaseComponents = false) {
14910
15030
  // src/dependency-graph/vf-dependency-analyzer.ts
14911
15031
  init_esm_shims();
14912
15032
  init_logger();
14913
- import fs9 from "fs-extra";
14914
- import * as path11 from "path";
15033
+ import fs10 from "fs-extra";
15034
+ import * as path12 from "path";
14915
15035
  import * as htmlparser24 from "htmlparser2";
14916
15036
  import { DomHandler as DomHandler4 } from "domhandler";
14917
15037
  function extractVfDependencies(markup) {
@@ -15093,25 +15213,25 @@ async function analyzeVfPage(pagePath) {
15093
15213
  try {
15094
15214
  let actualPath = pagePath;
15095
15215
  if (!pagePath.endsWith(".page")) {
15096
- if (await fs9.pathExists(pagePath)) {
15097
- const stat = await fs9.stat(pagePath);
15216
+ if (await fs10.pathExists(pagePath)) {
15217
+ const stat = await fs10.stat(pagePath);
15098
15218
  if (stat.isDirectory()) {
15099
- const files = await fs9.readdir(pagePath);
15219
+ const files = await fs10.readdir(pagePath);
15100
15220
  const pageFile = files.find((f) => f.endsWith(".page"));
15101
15221
  if (pageFile) {
15102
- actualPath = path11.join(pagePath, pageFile);
15222
+ actualPath = path12.join(pagePath, pageFile);
15103
15223
  } else {
15104
15224
  return null;
15105
15225
  }
15106
15226
  }
15107
15227
  }
15108
15228
  }
15109
- if (!await fs9.pathExists(actualPath)) {
15229
+ if (!await fs10.pathExists(actualPath)) {
15110
15230
  logger.debug(`VF page not found: ${actualPath}`);
15111
15231
  return null;
15112
15232
  }
15113
- const markup = await fs9.readFile(actualPath, "utf-8");
15114
- const pageName = path11.basename(actualPath, ".page");
15233
+ const markup = await fs10.readFile(actualPath, "utf-8");
15234
+ const pageName = path12.basename(actualPath, ".page");
15115
15235
  const dependencies = extractVfDependencies(markup);
15116
15236
  return {
15117
15237
  id: `vf:${pageName}`,
@@ -15129,25 +15249,25 @@ async function analyzeVfComponent(componentPath) {
15129
15249
  try {
15130
15250
  let actualPath = componentPath;
15131
15251
  if (!componentPath.endsWith(".component")) {
15132
- if (await fs9.pathExists(componentPath)) {
15133
- const stat = await fs9.stat(componentPath);
15252
+ if (await fs10.pathExists(componentPath)) {
15253
+ const stat = await fs10.stat(componentPath);
15134
15254
  if (stat.isDirectory()) {
15135
- const files = await fs9.readdir(componentPath);
15255
+ const files = await fs10.readdir(componentPath);
15136
15256
  const componentFile = files.find((f) => f.endsWith(".component"));
15137
15257
  if (componentFile) {
15138
- actualPath = path11.join(componentPath, componentFile);
15258
+ actualPath = path12.join(componentPath, componentFile);
15139
15259
  } else {
15140
15260
  return null;
15141
15261
  }
15142
15262
  }
15143
15263
  }
15144
15264
  }
15145
- if (!await fs9.pathExists(actualPath)) {
15265
+ if (!await fs10.pathExists(actualPath)) {
15146
15266
  logger.debug(`VF component not found: ${actualPath}`);
15147
15267
  return null;
15148
15268
  }
15149
- const markup = await fs9.readFile(actualPath, "utf-8");
15150
- const componentName = path11.basename(actualPath, ".component");
15269
+ const markup = await fs10.readFile(actualPath, "utf-8");
15270
+ const componentName = path12.basename(actualPath, ".component");
15151
15271
  const dependencies = extractVfDependencies(markup);
15152
15272
  return {
15153
15273
  id: `vf:${componentName}`,
@@ -15162,13 +15282,13 @@ async function analyzeVfComponent(componentPath) {
15162
15282
  }
15163
15283
  }
15164
15284
  async function getPackageDirectories2(rootPath) {
15165
- const sfdxProjectPath = path11.join(rootPath, "sfdx-project.json");
15166
- if (await fs9.pathExists(sfdxProjectPath)) {
15285
+ const sfdxProjectPath = path12.join(rootPath, "sfdx-project.json");
15286
+ if (await fs10.pathExists(sfdxProjectPath)) {
15167
15287
  try {
15168
- const projectConfig = await fs9.readJson(sfdxProjectPath);
15288
+ const projectConfig = await fs10.readJson(sfdxProjectPath);
15169
15289
  if (projectConfig.packageDirectories && Array.isArray(projectConfig.packageDirectories)) {
15170
15290
  return projectConfig.packageDirectories.map(
15171
- (pkg) => path11.join(rootPath, pkg.path)
15291
+ (pkg) => path12.join(rootPath, pkg.path)
15172
15292
  );
15173
15293
  }
15174
15294
  } catch (error) {
@@ -15183,10 +15303,10 @@ async function findVfDirectories(basePath) {
15183
15303
  async function searchDir(dirPath, depth = 0) {
15184
15304
  if (depth > 5) return;
15185
15305
  try {
15186
- const entries = await fs9.readdir(dirPath, { withFileTypes: true });
15306
+ const entries = await fs10.readdir(dirPath, { withFileTypes: true });
15187
15307
  for (const entry of entries) {
15188
15308
  if (entry.isDirectory()) {
15189
- const fullPath = path11.join(dirPath, entry.name);
15309
+ const fullPath = path12.join(dirPath, entry.name);
15190
15310
  if (entry.name === "pages") {
15191
15311
  pagesDirectories.push(fullPath);
15192
15312
  } else if (entry.name === "components") {
@@ -15217,9 +15337,9 @@ async function scanVfPages(rootPath) {
15217
15337
  logger.debug(`Found components directories from sfdx-project.json: ${componentSearchPaths.join(", ")}`);
15218
15338
  }
15219
15339
  const fallbackPagePaths = [
15220
- path11.join(rootPath, "force-app/main/default/pages"),
15221
- path11.join(rootPath, "src/pages"),
15222
- path11.join(rootPath, "pages")
15340
+ path12.join(rootPath, "force-app/main/default/pages"),
15341
+ path12.join(rootPath, "src/pages"),
15342
+ path12.join(rootPath, "pages")
15223
15343
  ];
15224
15344
  for (const fallback of fallbackPagePaths) {
15225
15345
  if (!pageSearchPaths.includes(fallback)) {
@@ -15227,9 +15347,9 @@ async function scanVfPages(rootPath) {
15227
15347
  }
15228
15348
  }
15229
15349
  const fallbackComponentPaths = [
15230
- path11.join(rootPath, "force-app/main/default/components"),
15231
- path11.join(rootPath, "src/components"),
15232
- path11.join(rootPath, "components")
15350
+ path12.join(rootPath, "force-app/main/default/components"),
15351
+ path12.join(rootPath, "src/components"),
15352
+ path12.join(rootPath, "components")
15233
15353
  ];
15234
15354
  for (const fallback of fallbackComponentPaths) {
15235
15355
  if (!componentSearchPaths.includes(fallback)) {
@@ -15240,10 +15360,10 @@ async function scanVfPages(rootPath) {
15240
15360
  pageSearchPaths.unshift(rootPath);
15241
15361
  } else if (rootPath.endsWith(".component")) {
15242
15362
  componentSearchPaths.unshift(rootPath);
15243
- } else if (await fs9.pathExists(rootPath)) {
15244
- const stat = await fs9.stat(rootPath);
15363
+ } else if (await fs10.pathExists(rootPath)) {
15364
+ const stat = await fs10.stat(rootPath);
15245
15365
  if (stat.isDirectory()) {
15246
- const files = await fs9.readdir(rootPath);
15366
+ const files = await fs10.readdir(rootPath);
15247
15367
  if (files.some((f) => f.endsWith(".page"))) {
15248
15368
  pageSearchPaths.unshift(rootPath);
15249
15369
  }
@@ -15255,18 +15375,18 @@ async function scanVfPages(rootPath) {
15255
15375
  logger.debug(`Searching for VF pages in: ${pageSearchPaths.join(", ")}`);
15256
15376
  logger.debug(`Searching for VF components in: ${componentSearchPaths.join(", ")}`);
15257
15377
  for (const searchPath of pageSearchPaths) {
15258
- if (await fs9.pathExists(searchPath)) {
15259
- const stat = await fs9.stat(searchPath);
15378
+ if (await fs10.pathExists(searchPath)) {
15379
+ const stat = await fs10.stat(searchPath);
15260
15380
  if (stat.isFile() && searchPath.endsWith(".page")) {
15261
15381
  const result = await analyzeVfPage(searchPath);
15262
15382
  if (result) {
15263
15383
  results.push(result);
15264
15384
  }
15265
15385
  } else if (stat.isDirectory()) {
15266
- const files = await fs9.readdir(searchPath);
15386
+ const files = await fs10.readdir(searchPath);
15267
15387
  for (const file of files) {
15268
15388
  if (file.endsWith(".page")) {
15269
- const result = await analyzeVfPage(path11.join(searchPath, file));
15389
+ const result = await analyzeVfPage(path12.join(searchPath, file));
15270
15390
  if (result) {
15271
15391
  results.push(result);
15272
15392
  }
@@ -15276,18 +15396,18 @@ async function scanVfPages(rootPath) {
15276
15396
  }
15277
15397
  }
15278
15398
  for (const searchPath of componentSearchPaths) {
15279
- if (await fs9.pathExists(searchPath)) {
15280
- const stat = await fs9.stat(searchPath);
15399
+ if (await fs10.pathExists(searchPath)) {
15400
+ const stat = await fs10.stat(searchPath);
15281
15401
  if (stat.isFile() && searchPath.endsWith(".component")) {
15282
15402
  const result = await analyzeVfComponent(searchPath);
15283
15403
  if (result) {
15284
15404
  results.push(result);
15285
15405
  }
15286
15406
  } else if (stat.isDirectory()) {
15287
- const files = await fs9.readdir(searchPath);
15407
+ const files = await fs10.readdir(searchPath);
15288
15408
  for (const file of files) {
15289
15409
  if (file.endsWith(".component")) {
15290
- const result = await analyzeVfComponent(path11.join(searchPath, file));
15410
+ const result = await analyzeVfComponent(path12.join(searchPath, file));
15291
15411
  if (result) {
15292
15412
  results.push(result);
15293
15413
  }
@@ -16294,7 +16414,7 @@ function formatSimpleMermaidOutput(graph, maxNodes = 30) {
16294
16414
  // src/cli/commands/deps.ts
16295
16415
  async function analyzeDeps(target, options) {
16296
16416
  logger.setVerbose(options.verbose);
16297
- const targetPath = target ? path12.resolve(target) : process.cwd();
16417
+ const targetPath = target ? path13.resolve(target) : process.cwd();
16298
16418
  logger.banner();
16299
16419
  logger.header("Dependency Graph Analysis");
16300
16420
  logger.info(`Analyzing: ${targetPath}`);
@@ -16370,10 +16490,10 @@ async function analyzeDeps(target, options) {
16370
16490
  }
16371
16491
  }
16372
16492
  async function writeOutput(filePath, content) {
16373
- const outputPath = path12.resolve(filePath);
16374
- const outputDir = path12.dirname(outputPath);
16375
- await fs10.ensureDir(outputDir);
16376
- await fs10.writeFile(outputPath, content, "utf-8");
16493
+ const outputPath = path13.resolve(filePath);
16494
+ const outputDir = path13.dirname(outputPath);
16495
+ await fs11.ensureDir(outputDir);
16496
+ await fs11.writeFile(outputPath, content, "utf-8");
16377
16497
  }
16378
16498
 
16379
16499
  // src/index.ts