@reliverse/pathkit 1.1.6 → 1.1.7

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.
@@ -29,7 +29,7 @@ export function getFileImportsExports(content, options = {}) {
29
29
  const specifiers = [];
30
30
  const isTypeOnly = statement.includes("import type") || statement.includes("export type");
31
31
  const namespaceMatch = /(?:import|export)\s+(?:type\s+)?\*\s+as\s+(\w+)/.exec(statement);
32
- if (namespaceMatch) {
32
+ if (namespaceMatch?.[1]) {
33
33
  specifiers.push({
34
34
  type: "namespace",
35
35
  name: namespaceMatch[1],
@@ -40,7 +40,7 @@ export function getFileImportsExports(content, options = {}) {
40
40
  const defaultMatch = /import\s+(?:type\s+)?(\w+)(?:\s*,|\s+from)/.exec(
41
41
  statement
42
42
  );
43
- if (defaultMatch && !statement.includes("{")) {
43
+ if (defaultMatch?.[1] && !statement.includes("{")) {
44
44
  specifiers.push({
45
45
  type: "default",
46
46
  name: defaultMatch[1],
@@ -48,14 +48,16 @@ export function getFileImportsExports(content, options = {}) {
48
48
  });
49
49
  }
50
50
  const namedMatch = /{([^}]*)}/.exec(statement);
51
- if (namedMatch) {
51
+ if (namedMatch?.[1]) {
52
52
  const items = namedMatch[1].split(",").map((item) => item.trim()).filter((item) => item.length > 0);
53
53
  for (const item of items) {
54
54
  const typeMatch = /^type\s+(.+)/.exec(item);
55
55
  const actualItem = typeMatch ? typeMatch[1] : item;
56
+ if (!actualItem) continue;
56
57
  const isItemType = !!typeMatch || isTypeOnly;
57
58
  if (actualItem.includes(" as ")) {
58
59
  const [name, alias] = actualItem.split(" as ").map((p) => p.trim());
60
+ if (!name) continue;
59
61
  specifiers.push({
60
62
  type: "named",
61
63
  name,
@@ -79,7 +81,7 @@ export function getFileImportsExports(content, options = {}) {
79
81
  const source = match[1] || match[3];
80
82
  if (!source) continue;
81
83
  const pathType = getPathType(source);
82
- if (!pathTypes.includes(pathType)) continue;
84
+ if (!pathType || !pathTypes.includes(pathType)) continue;
83
85
  const info = {
84
86
  statement: match[0],
85
87
  type: "static",
@@ -89,8 +91,8 @@ export function getFileImportsExports(content, options = {}) {
89
91
  pathTypeSymbol: pathType === "alias" ? /^[@~]/.exec(source)?.[0] : void 0,
90
92
  isTypeOnly: match[0].includes("import type"),
91
93
  specifiers: extractSpecifiers(match[0]),
92
- start: match.index,
93
- end: match.index + match[0].length
94
+ start: match.index ?? 0,
95
+ end: (match.index ?? 0) + match[0].length
94
96
  };
95
97
  results.push(info);
96
98
  }
@@ -99,7 +101,7 @@ export function getFileImportsExports(content, options = {}) {
99
101
  const source = match[1];
100
102
  if (!source) continue;
101
103
  const pathType = getPathType(source);
102
- if (!pathTypes.includes(pathType)) continue;
104
+ if (!pathType || !pathTypes.includes(pathType)) continue;
103
105
  const info = {
104
106
  statement: match[0],
105
107
  type: "dynamic",
@@ -109,8 +111,8 @@ export function getFileImportsExports(content, options = {}) {
109
111
  pathTypeSymbol: pathType === "alias" ? /^[@~]/.exec(source)?.[0] : void 0,
110
112
  isTypeOnly: false,
111
113
  specifiers: [],
112
- start: match.index,
113
- end: match.index + match[0].length
114
+ start: match.index ?? 0,
115
+ end: (match.index ?? 0) + match[0].length
114
116
  };
115
117
  results.push(info);
116
118
  }
@@ -121,7 +123,7 @@ export function getFileImportsExports(content, options = {}) {
121
123
  const source = match[1];
122
124
  if (!source) continue;
123
125
  const pathType = getPathType(source);
124
- if (!pathTypes.includes(pathType)) continue;
126
+ if (!pathType || !pathTypes.includes(pathType)) continue;
125
127
  const info = {
126
128
  statement: match[0],
127
129
  type: "static",
@@ -131,8 +133,8 @@ export function getFileImportsExports(content, options = {}) {
131
133
  pathTypeSymbol: pathType === "alias" ? /^[@~]/.exec(source)?.[0] : void 0,
132
134
  isTypeOnly: match[0].includes("export type"),
133
135
  specifiers: extractSpecifiers(match[0]),
134
- start: match.index,
135
- end: match.index + match[0].length
136
+ start: match.index ?? 0,
137
+ end: (match.index ?? 0) + match[0].length
136
138
  };
137
139
  results.push(info);
138
140
  }
package/bin/mod.d.ts CHANGED
@@ -19,7 +19,7 @@ export interface FormatInputPathObject {
19
19
  name?: string;
20
20
  }
21
21
  type PathExtFilter = "js" | "ts" | "none" | "js-ts-none";
22
- type ImportExtType = "js" | "ts" | "none";
22
+ type ImportExtType = "js" | "ts" | "none" | "none-and-js";
23
23
  /**
24
24
  * normalizes windows paths to use forward slashes
25
25
  */
@@ -97,8 +97,7 @@ declare function convertStringAliasRelative({ importPath, importerFile, pathPatt
97
97
  /**
98
98
  * main function to convert import paths from aliases to relative paths
99
99
  */
100
- declare function convertImportsAliasToRelative({ targetDir, aliasToReplace, // e.g. @, ~, @/*, ~/*
101
- pathExtFilter, }: {
100
+ declare function convertImportsAliasToRelative({ targetDir, aliasToReplace, pathExtFilter, }: {
102
101
  targetDir: string;
103
102
  aliasToReplace: string;
104
103
  pathExtFilter: PathExtFilter;
package/bin/mod.js CHANGED
@@ -2,8 +2,19 @@ import fs from "node:fs/promises";
2
2
  import {
3
3
  getFileImportsExports
4
4
  } from "./impl/getFileImportsExports.js";
5
- const log = (msg) => console.log(`\x1B[2m${msg}\x1B[0m`);
6
- const logInternal = (msg) => console.log(`\x1B[36;2m${msg}\x1B[0m`);
5
+ const logger = (msg, debugOnly = false) => {
6
+ if (!debugOnly || DEBUG_MODE) {
7
+ const message = typeof msg === "function" ? msg() : msg;
8
+ console.log(`\x1B[2m${message}\x1B[0m`);
9
+ }
10
+ };
11
+ const logInternal = (msg) => {
12
+ if (DEBUG_MODE) {
13
+ const message = typeof msg === "function" ? msg() : msg;
14
+ console.log(`\x1B[36;2m${message}\x1B[0m`);
15
+ }
16
+ };
17
+ const DEBUG_MODE = false;
7
18
  const EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
8
19
  const SLASH = "/";
9
20
  const BACK_SLASH = "\\";
@@ -39,7 +50,7 @@ function normalizeString(path2, allowAboveRoot) {
39
50
  let char = null;
40
51
  for (let index = 0; index <= path2.length; ++index) {
41
52
  if (index < path2.length) {
42
- char = path2[index];
53
+ char = path2[index] ?? null;
43
54
  } else if (char === SLASH) {
44
55
  break;
45
56
  } else {
@@ -190,7 +201,7 @@ const relative = (from, to) => {
190
201
  if (resolvedFrom === resolvedTo) return EMPTY;
191
202
  const fromSegments = resolvedFrom.replace(ROOT_FOLDER_RE, "$1").split(SLASH).filter(Boolean);
192
203
  const toSegments = resolvedTo.replace(ROOT_FOLDER_RE, "$1").split(SLASH).filter(Boolean);
193
- if (fromSegments.length > 0 && toSegments.length > 0 && DRIVE_LETTER_RE.test(fromSegments[0]) && DRIVE_LETTER_RE.test(toSegments[0]) && fromSegments[0].toUpperCase() !== toSegments[0].toUpperCase()) {
204
+ if (fromSegments.length > 0 && toSegments.length > 0 && fromSegments[0] && toSegments[0] && DRIVE_LETTER_RE.test(fromSegments[0]) && DRIVE_LETTER_RE.test(toSegments[0]) && fromSegments[0].toUpperCase() !== toSegments[0].toUpperCase()) {
194
205
  return resolvedTo;
195
206
  }
196
207
  let commonSegments = 0;
@@ -345,6 +356,7 @@ function reverseResolveAlias(path2, aliases) {
345
356
  }
346
357
  const findAliasMatch = (importPath, paths) => {
347
358
  const firstPathKey = Object.keys(paths)[0];
359
+ if (!firstPathKey) return null;
348
360
  const baseAlias = firstPathKey.replace("/*", "");
349
361
  if (importPath.startsWith("@") && !importPath.startsWith(baseAlias)) {
350
362
  return null;
@@ -455,6 +467,7 @@ async function processFile(filePath, aliasToReplace, targetDir, pathExtFilter) {
455
467
  for (const match of matches) {
456
468
  const originalQuote = match[1];
457
469
  const importPath = match[2];
470
+ if (!importPath) continue;
458
471
  if (!importPath.startsWith(baseAlias)) {
459
472
  continue;
460
473
  }
@@ -519,7 +532,7 @@ async function processAllFiles({
519
532
  );
520
533
  return results;
521
534
  } catch (error) {
522
- log(
535
+ logger(
523
536
  `error processing directory ${srcDir}: ${error instanceof Error ? error.message : String(error)}`
524
537
  );
525
538
  return [];
@@ -528,14 +541,15 @@ async function processAllFiles({
528
541
  async function convertImportsAliasToRelative({
529
542
  targetDir,
530
543
  aliasToReplace,
531
- // e.g. @, ~, @/*, ~/*
532
544
  pathExtFilter
533
545
  }) {
534
546
  const normalizedAlias = aliasToReplace.endsWith("/*") ? aliasToReplace : `${aliasToReplace}/*`;
535
- log(
547
+ logger(
536
548
  `Converting aliased imports starting with '${aliasToReplace}' to relative paths in "${targetDir}"...`
537
549
  );
538
- log(` (Assuming "${normalizedAlias}" resolves relative to "${targetDir}")`);
550
+ logger(
551
+ ` (Assuming "${normalizedAlias}" resolves relative to "${targetDir}")`
552
+ );
539
553
  const results = await processAllFiles({
540
554
  srcDir: targetDir,
541
555
  aliasToReplace: normalizedAlias,
@@ -544,17 +558,17 @@ async function convertImportsAliasToRelative({
544
558
  pathExtFilter
545
559
  });
546
560
  if (results.length > 0) {
547
- log("\n[convertImportsAliasToRelative] Summary of changes:");
561
+ logger("\n[convertImportsAliasToRelative] Summary of changes:", true);
548
562
  for (const { file, changes } of results) {
549
563
  const displayPath = relative(targetDir, file) || basename(file);
550
- log(` in ${displayPath}:`);
564
+ logger(() => ` in ${displayPath}:`, true);
551
565
  for (const { from, to } of changes) {
552
- log(` - ${from} \u2192 ${to}`);
566
+ logger(() => ` - ${from} \u2192 ${to}`, true);
553
567
  }
554
568
  }
555
569
  } else {
556
570
  }
557
- log("Import path conversion process complete.");
571
+ logger("Import path conversion process complete.");
558
572
  return results;
559
573
  }
560
574
  async function convertImportsExt({
@@ -562,7 +576,7 @@ async function convertImportsExt({
562
576
  extFrom,
563
577
  extTo
564
578
  }) {
565
- const fromExtStr = extFrom === "none" ? "" : `.${extFrom}`;
579
+ const fromExtStr = extFrom === "none" ? "" : extFrom === "none-and-js" ? "(?:\\.js)?" : `.${extFrom}`;
566
580
  const toExtStr = extTo === "none" ? "" : `.${extTo}`;
567
581
  const importRegex = new RegExp(
568
582
  `(?:import\\s+(?:[\\s\\S]*?)\\s+from\\s+|import\\s*\\(\\s*)\\s*(['"])([^'"]+${fromExtStr.replace(".", "\\.")})(\\1)`,
@@ -591,9 +605,16 @@ async function convertImportsExt({
591
605
  while (match !== null) {
592
606
  const quote = match[1];
593
607
  const importPath = match[2];
608
+ if (!importPath) continue;
594
609
  let replacementPath;
595
610
  if (extFrom === "none") {
596
611
  replacementPath = importPath + toExtStr;
612
+ } else if (extFrom === "none-and-js") {
613
+ if (importPath.endsWith(".js")) {
614
+ replacementPath = importPath.slice(0, -3) + toExtStr;
615
+ } else {
616
+ replacementPath = importPath + toExtStr;
617
+ }
597
618
  } else if (extTo === "none") {
598
619
  replacementPath = importPath.slice(0, -fromExtStr.length);
599
620
  } else {
@@ -617,19 +638,18 @@ async function convertImportsExt({
617
638
  })
618
639
  );
619
640
  if (results.length > 0) {
620
- log("\n[convertImportsExt] Summary of changes:");
641
+ logger("\n[convertImportsExt] Summary of changes:", true);
621
642
  for (const { file, changes } of results) {
622
643
  const displayPath = relative(targetDir, file) || basename(file);
623
- log(` in ${displayPath}:`);
644
+ logger(() => ` in ${displayPath}:`, true);
624
645
  for (const { from, to } of changes) {
625
- log(` - ${from} \u2192 ${to}`);
646
+ logger(() => ` - ${from} \u2192 ${to}`, true);
626
647
  }
627
648
  }
628
- } else {
629
649
  }
630
650
  return results;
631
651
  } catch (error) {
632
- log(
652
+ logger(
633
653
  `error processing directory ${targetDir}: ${error instanceof Error ? error.message : String(error)}`
634
654
  );
635
655
  return [];
@@ -653,13 +673,17 @@ function stripPathSegments(path2, count = 1, alias = "") {
653
673
  }
654
674
  pathSegments = pathSegments.filter(Boolean);
655
675
  const leadingPreservedSegments = [];
656
- if (alias && pathSegments.length > 0 && pathSegments[0].startsWith(alias)) {
676
+ if (alias && pathSegments.length > 0 && pathSegments[0]?.startsWith(alias)) {
657
677
  const preserved = pathSegments.shift();
658
- leadingPreservedSegments.push(preserved);
678
+ if (preserved) {
679
+ leadingPreservedSegments.push(preserved);
680
+ }
659
681
  }
660
682
  while (pathSegments.length > 0 && (pathSegments[0] === DOT || pathSegments[0] === DOUBLE_DOT)) {
661
683
  const preserved = pathSegments.shift();
662
- leadingPreservedSegments.push(preserved);
684
+ if (preserved) {
685
+ leadingPreservedSegments.push(preserved);
686
+ }
663
687
  }
664
688
  const numToStrip = Math.min(count, pathSegments.length);
665
689
  const remainingBodySegments = pathSegments.slice(numToStrip);
@@ -684,8 +708,14 @@ async function stripPathSegmentsInDirectory({
684
708
  alias = "",
685
709
  extensionsToProcess = EXTENSIONS
686
710
  }) {
687
- log(`[stripPathSegmentsInDirectory] Processing directory: ${targetDir}`);
688
- log(` - segmentsToStrip: ${segmentsToStrip}, alias: ${alias}`);
711
+ logger(
712
+ () => `[stripPathSegmentsInDirectory] Processing directory: ${targetDir}`,
713
+ true
714
+ );
715
+ logger(
716
+ () => ` - segmentsToStrip: ${segmentsToStrip}, alias: ${alias}`,
717
+ true
718
+ );
689
719
  try {
690
720
  const entries = await fs.readdir(targetDir, { withFileTypes: true });
691
721
  const results = [];
@@ -709,6 +739,7 @@ async function stripPathSegmentsInDirectory({
709
739
  for (const match of matches) {
710
740
  const originalQuote = match[1];
711
741
  const importPath = match[2];
742
+ if (!importPath) continue;
712
743
  if (!importPath.includes(SLASH)) {
713
744
  continue;
714
745
  }
@@ -740,19 +771,19 @@ async function stripPathSegmentsInDirectory({
740
771
  })
741
772
  );
742
773
  if (results.length > 0) {
743
- log("[stripPathSegmentsInDirectory] Summary of changes:");
774
+ logger(() => "[stripPathSegmentsInDirectory] Summary of changes:", true);
744
775
  for (const { file, changes } of results) {
745
776
  const displayPath = relative(targetDir, file) || basename(file);
746
- log(` in ${displayPath}:`);
777
+ logger(() => ` in ${displayPath}:`, true);
747
778
  for (const { from, to } of changes) {
748
- log(` - ${from} \u2192 ${to}`);
779
+ logger(() => ` - ${from} \u2192 ${to}`, true);
749
780
  }
750
781
  }
751
782
  } else {
752
783
  }
753
784
  return results;
754
785
  } catch (error) {
755
- log(
786
+ logger(
756
787
  `error processing directory ${targetDir}: ${error instanceof Error ? error.message : String(error)}`
757
788
  );
758
789
  return [];
@@ -823,6 +854,7 @@ async function attachPathSegmentsInDirectory({
823
854
  for (const match of matches) {
824
855
  const originalQuote = match[1];
825
856
  const importPath = match[2];
857
+ if (!importPath) continue;
826
858
  if (!importPath.includes(SLASH)) continue;
827
859
  const modifiedPath = attachPathSegments(
828
860
  importPath,
@@ -846,18 +878,21 @@ async function attachPathSegmentsInDirectory({
846
878
  })
847
879
  );
848
880
  if (results.length > 0) {
849
- log("\n[attachPathSegmentsInDirectory] Summary of changes:");
881
+ logger(
882
+ () => "\n[attachPathSegmentsInDirectory] Summary of changes:",
883
+ true
884
+ );
850
885
  for (const { file, changes } of results) {
851
886
  const displayPath = relative(targetDir, file) || basename(file);
852
- log(` in ${displayPath}:`);
887
+ logger(() => ` in ${displayPath}:`, true);
853
888
  for (const { from, to } of changes) {
854
- log(` - ${from} \u2192 ${to}`);
889
+ logger(() => ` - ${from} \u2192 ${to}`, true);
855
890
  }
856
891
  }
857
892
  }
858
893
  return results;
859
894
  } catch (error) {
860
- log(
895
+ logger(
861
896
  `error processing directory ${targetDir}: ${error instanceof Error ? error.message : String(error)}`
862
897
  );
863
898
  return [];
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "license": "MIT",
6
6
  "name": "@reliverse/pathkit",
7
7
  "type": "module",
8
- "version": "1.1.6",
8
+ "version": "1.1.7",
9
9
  "devDependencies": {},
10
10
  "exports": {
11
11
  ".": "./bin/mod.js"