@reliverse/pathkit 1.1.5 → 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.
- package/bin/impl/getFileImportsExports.d.ts +27 -0
- package/bin/impl/getFileImportsExports.js +191 -0
- package/bin/mod.d.ts +5 -5
- package/bin/mod.js +75 -34
- package/package.json +2 -20
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface ImportExportSpecifier {
|
|
2
|
+
type: "named" | "default" | "namespace" | "all";
|
|
3
|
+
name: string;
|
|
4
|
+
alias?: string;
|
|
5
|
+
isType?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ImportExportInfo {
|
|
8
|
+
statement: string;
|
|
9
|
+
type: "static" | "dynamic";
|
|
10
|
+
kind: "import" | "export";
|
|
11
|
+
source?: string;
|
|
12
|
+
pathType?: "alias" | "relative" | "absolute" | "bare" | "module";
|
|
13
|
+
pathTypeSymbol?: string;
|
|
14
|
+
isTypeOnly?: boolean;
|
|
15
|
+
specifiers?: ImportExportSpecifier[];
|
|
16
|
+
start: number;
|
|
17
|
+
end: number;
|
|
18
|
+
}
|
|
19
|
+
export interface GetFileImportsExportsOptions {
|
|
20
|
+
kind?: "import" | "export" | "all";
|
|
21
|
+
pathTypes?: ("alias" | "relative" | "absolute" | "bare" | "module")[];
|
|
22
|
+
limitPerType?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* analyzes a file's content to extract import and export statements
|
|
26
|
+
*/
|
|
27
|
+
export declare function getFileImportsExports(content: string, options?: GetFileImportsExportsOptions): ImportExportInfo[];
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
export function getFileImportsExports(content, options = {}) {
|
|
2
|
+
const {
|
|
3
|
+
kind = "all",
|
|
4
|
+
pathTypes = ["alias", "relative", "absolute", "bare", "module"],
|
|
5
|
+
limitPerType
|
|
6
|
+
} = options;
|
|
7
|
+
const results = [];
|
|
8
|
+
const patterns = {
|
|
9
|
+
// import statements with from clause
|
|
10
|
+
staticImport: /import\s+(?:type\s+)?(?:(?:\w+)(?:\s*,\s*)?)?(?:\{[^}]*\}|\*\s+as\s+\w+)?\s+from\s+['"]([^'"]+)['"]|import\s+(?:type\s+)?(\w+)\s+from\s+['"]([^'"]+)['"]/g,
|
|
11
|
+
// dynamic imports
|
|
12
|
+
dynamicImport: /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
13
|
+
// export statements with from clause
|
|
14
|
+
staticExport: /export\s+(?:type\s+)?(?:\{[^}]*\}|\*(?:\s+as\s+\w+)?)\s+from\s+['"]([^'"]+)['"]/g,
|
|
15
|
+
// default exports without from
|
|
16
|
+
defaultExport: /export\s+default\s+(?:\w+|\{[^}]*\}|class\s+\w+|function\s+\w+)/g,
|
|
17
|
+
// named exports without from
|
|
18
|
+
namedExport: /export\s+(?:const|let|var|function|class|enum|interface|type)\s+(\w+)/g
|
|
19
|
+
};
|
|
20
|
+
function getPathType(path) {
|
|
21
|
+
if (path.startsWith(".")) return "relative";
|
|
22
|
+
if (path.startsWith("/")) return "absolute";
|
|
23
|
+
if (path.startsWith("@") || path.startsWith("~")) return "alias";
|
|
24
|
+
if (path.startsWith("http://") || path.startsWith("https://"))
|
|
25
|
+
return "module";
|
|
26
|
+
return "bare";
|
|
27
|
+
}
|
|
28
|
+
function extractSpecifiers(statement) {
|
|
29
|
+
const specifiers = [];
|
|
30
|
+
const isTypeOnly = statement.includes("import type") || statement.includes("export type");
|
|
31
|
+
const namespaceMatch = /(?:import|export)\s+(?:type\s+)?\*\s+as\s+(\w+)/.exec(statement);
|
|
32
|
+
if (namespaceMatch?.[1]) {
|
|
33
|
+
specifiers.push({
|
|
34
|
+
type: "namespace",
|
|
35
|
+
name: namespaceMatch[1],
|
|
36
|
+
isType: isTypeOnly
|
|
37
|
+
});
|
|
38
|
+
return specifiers;
|
|
39
|
+
}
|
|
40
|
+
const defaultMatch = /import\s+(?:type\s+)?(\w+)(?:\s*,|\s+from)/.exec(
|
|
41
|
+
statement
|
|
42
|
+
);
|
|
43
|
+
if (defaultMatch?.[1] && !statement.includes("{")) {
|
|
44
|
+
specifiers.push({
|
|
45
|
+
type: "default",
|
|
46
|
+
name: defaultMatch[1],
|
|
47
|
+
isType: isTypeOnly
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const namedMatch = /{([^}]*)}/.exec(statement);
|
|
51
|
+
if (namedMatch?.[1]) {
|
|
52
|
+
const items = namedMatch[1].split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
53
|
+
for (const item of items) {
|
|
54
|
+
const typeMatch = /^type\s+(.+)/.exec(item);
|
|
55
|
+
const actualItem = typeMatch ? typeMatch[1] : item;
|
|
56
|
+
if (!actualItem) continue;
|
|
57
|
+
const isItemType = !!typeMatch || isTypeOnly;
|
|
58
|
+
if (actualItem.includes(" as ")) {
|
|
59
|
+
const [name, alias] = actualItem.split(" as ").map((p) => p.trim());
|
|
60
|
+
if (!name) continue;
|
|
61
|
+
specifiers.push({
|
|
62
|
+
type: "named",
|
|
63
|
+
name,
|
|
64
|
+
alias,
|
|
65
|
+
isType: isItemType
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
specifiers.push({
|
|
69
|
+
type: "named",
|
|
70
|
+
name: actualItem,
|
|
71
|
+
isType: isItemType
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return specifiers;
|
|
77
|
+
}
|
|
78
|
+
if (kind === "import" || kind === "all") {
|
|
79
|
+
const importMatches = [...content.matchAll(patterns.staticImport)];
|
|
80
|
+
for (const match of importMatches) {
|
|
81
|
+
const source = match[1] || match[3];
|
|
82
|
+
if (!source) continue;
|
|
83
|
+
const pathType = getPathType(source);
|
|
84
|
+
if (!pathType || !pathTypes.includes(pathType)) continue;
|
|
85
|
+
const info = {
|
|
86
|
+
statement: match[0],
|
|
87
|
+
type: "static",
|
|
88
|
+
kind: "import",
|
|
89
|
+
source,
|
|
90
|
+
pathType,
|
|
91
|
+
pathTypeSymbol: pathType === "alias" ? /^[@~]/.exec(source)?.[0] : void 0,
|
|
92
|
+
isTypeOnly: match[0].includes("import type"),
|
|
93
|
+
specifiers: extractSpecifiers(match[0]),
|
|
94
|
+
start: match.index ?? 0,
|
|
95
|
+
end: (match.index ?? 0) + match[0].length
|
|
96
|
+
};
|
|
97
|
+
results.push(info);
|
|
98
|
+
}
|
|
99
|
+
const dynamicMatches = [...content.matchAll(patterns.dynamicImport)];
|
|
100
|
+
for (const match of dynamicMatches) {
|
|
101
|
+
const source = match[1];
|
|
102
|
+
if (!source) continue;
|
|
103
|
+
const pathType = getPathType(source);
|
|
104
|
+
if (!pathType || !pathTypes.includes(pathType)) continue;
|
|
105
|
+
const info = {
|
|
106
|
+
statement: match[0],
|
|
107
|
+
type: "dynamic",
|
|
108
|
+
kind: "import",
|
|
109
|
+
source,
|
|
110
|
+
pathType,
|
|
111
|
+
pathTypeSymbol: pathType === "alias" ? /^[@~]/.exec(source)?.[0] : void 0,
|
|
112
|
+
isTypeOnly: false,
|
|
113
|
+
specifiers: [],
|
|
114
|
+
start: match.index ?? 0,
|
|
115
|
+
end: (match.index ?? 0) + match[0].length
|
|
116
|
+
};
|
|
117
|
+
results.push(info);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (kind === "export" || kind === "all") {
|
|
121
|
+
const exportMatches = [...content.matchAll(patterns.staticExport)];
|
|
122
|
+
for (const match of exportMatches) {
|
|
123
|
+
const source = match[1];
|
|
124
|
+
if (!source) continue;
|
|
125
|
+
const pathType = getPathType(source);
|
|
126
|
+
if (!pathType || !pathTypes.includes(pathType)) continue;
|
|
127
|
+
const info = {
|
|
128
|
+
statement: match[0],
|
|
129
|
+
type: "static",
|
|
130
|
+
kind: "export",
|
|
131
|
+
source,
|
|
132
|
+
pathType,
|
|
133
|
+
pathTypeSymbol: pathType === "alias" ? /^[@~]/.exec(source)?.[0] : void 0,
|
|
134
|
+
isTypeOnly: match[0].includes("export type"),
|
|
135
|
+
specifiers: extractSpecifiers(match[0]),
|
|
136
|
+
start: match.index ?? 0,
|
|
137
|
+
end: (match.index ?? 0) + match[0].length
|
|
138
|
+
};
|
|
139
|
+
results.push(info);
|
|
140
|
+
}
|
|
141
|
+
const defaultMatches = [...content.matchAll(patterns.defaultExport)];
|
|
142
|
+
for (const match of defaultMatches) {
|
|
143
|
+
const info = {
|
|
144
|
+
statement: match[0],
|
|
145
|
+
type: "static",
|
|
146
|
+
kind: "export",
|
|
147
|
+
source: void 0,
|
|
148
|
+
pathType: void 0,
|
|
149
|
+
pathTypeSymbol: void 0,
|
|
150
|
+
isTypeOnly: false,
|
|
151
|
+
specifiers: [{ type: "default", name: "default" }],
|
|
152
|
+
start: match.index,
|
|
153
|
+
end: match.index + match[0].length
|
|
154
|
+
};
|
|
155
|
+
results.push(info);
|
|
156
|
+
}
|
|
157
|
+
const namedMatches = [...content.matchAll(patterns.namedExport)];
|
|
158
|
+
for (const match of namedMatches) {
|
|
159
|
+
const name = match[1];
|
|
160
|
+
if (!name) continue;
|
|
161
|
+
const info = {
|
|
162
|
+
statement: match[0],
|
|
163
|
+
type: "static",
|
|
164
|
+
kind: "export",
|
|
165
|
+
source: void 0,
|
|
166
|
+
pathType: void 0,
|
|
167
|
+
pathTypeSymbol: void 0,
|
|
168
|
+
isTypeOnly: match[0].includes("export type"),
|
|
169
|
+
specifiers: [{ type: "named", name }],
|
|
170
|
+
start: match.index,
|
|
171
|
+
end: match.index + match[0].length
|
|
172
|
+
};
|
|
173
|
+
results.push(info);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (limitPerType) {
|
|
177
|
+
const groupedByType = results.reduce(
|
|
178
|
+
(acc, curr) => {
|
|
179
|
+
const key = `${curr.kind}-${curr.pathType || "none"}`;
|
|
180
|
+
if (!acc[key]) acc[key] = [];
|
|
181
|
+
acc[key].push(curr);
|
|
182
|
+
return acc;
|
|
183
|
+
},
|
|
184
|
+
{}
|
|
185
|
+
);
|
|
186
|
+
return Object.values(groupedByType).flatMap(
|
|
187
|
+
(group) => group.slice(0, limitPerType)
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
return results;
|
|
191
|
+
}
|
package/bin/mod.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PlatformPath } from "node:path";
|
|
2
|
+
import { getFileImportsExports, type ImportExportInfo, type ImportExportSpecifier, type GetFileImportsExportsOptions } from "./impl/getFileImportsExports.js";
|
|
2
3
|
declare const normalizedAliasSymbol: unique symbol;
|
|
3
4
|
interface NormalizedRecord extends Record<string, string> {
|
|
4
5
|
[normalizedAliasSymbol]?: true;
|
|
@@ -18,7 +19,7 @@ export interface FormatInputPathObject {
|
|
|
18
19
|
name?: string;
|
|
19
20
|
}
|
|
20
21
|
type PathExtFilter = "js" | "ts" | "none" | "js-ts-none";
|
|
21
|
-
type ImportExtType = "js" | "ts" | "none";
|
|
22
|
+
type ImportExtType = "js" | "ts" | "none" | "none-and-js";
|
|
22
23
|
/**
|
|
23
24
|
* normalizes windows paths to use forward slashes
|
|
24
25
|
*/
|
|
@@ -96,8 +97,7 @@ declare function convertStringAliasRelative({ importPath, importerFile, pathPatt
|
|
|
96
97
|
/**
|
|
97
98
|
* main function to convert import paths from aliases to relative paths
|
|
98
99
|
*/
|
|
99
|
-
declare function convertImportsAliasToRelative({ targetDir, aliasToReplace,
|
|
100
|
-
pathExtFilter, }: {
|
|
100
|
+
declare function convertImportsAliasToRelative({ targetDir, aliasToReplace, pathExtFilter, }: {
|
|
101
101
|
targetDir: string;
|
|
102
102
|
aliasToReplace: string;
|
|
103
103
|
pathExtFilter: PathExtFilter;
|
|
@@ -219,6 +219,6 @@ declare const path: PlatformPath & {
|
|
|
219
219
|
};
|
|
220
220
|
declare const win32: PlatformPath;
|
|
221
221
|
declare const delimiter: string;
|
|
222
|
-
export type { PlatformPath, PathExtFilter, ImportExtType };
|
|
223
|
-
export { _pathBase as posix, win32, basename, delimiter, dirname, extname, filename, format, isAbsolute, join, normalize, parse, relative, resolve, sep, toNamespacedPath, normalizeAliases, resolveAlias, reverseResolveAlias, normalizeWindowsPath, convertStringAliasRelative, convertImportsAliasToRelative, convertImportsExt, stripPathSegments, stripPathSegmentsInDirectory, attachPathSegments, attachPathSegmentsInDirectory, };
|
|
222
|
+
export type { PlatformPath, PathExtFilter, ImportExtType, ImportExportInfo, ImportExportSpecifier, GetFileImportsExportsOptions, };
|
|
223
|
+
export { _pathBase as posix, win32, basename, delimiter, dirname, extname, filename, format, isAbsolute, join, normalize, parse, relative, resolve, sep, toNamespacedPath, normalizeAliases, resolveAlias, reverseResolveAlias, normalizeWindowsPath, convertStringAliasRelative, convertImportsAliasToRelative, convertImportsExt, stripPathSegments, stripPathSegmentsInDirectory, attachPathSegments, attachPathSegmentsInDirectory, getFileImportsExports, };
|
|
224
224
|
export default path;
|
package/bin/mod.js
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
getFileImportsExports
|
|
4
|
+
} from "./impl/getFileImportsExports.js";
|
|
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;
|
|
4
18
|
const EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
5
19
|
const SLASH = "/";
|
|
6
20
|
const BACK_SLASH = "\\";
|
|
@@ -36,7 +50,7 @@ function normalizeString(path2, allowAboveRoot) {
|
|
|
36
50
|
let char = null;
|
|
37
51
|
for (let index = 0; index <= path2.length; ++index) {
|
|
38
52
|
if (index < path2.length) {
|
|
39
|
-
char = path2[index];
|
|
53
|
+
char = path2[index] ?? null;
|
|
40
54
|
} else if (char === SLASH) {
|
|
41
55
|
break;
|
|
42
56
|
} else {
|
|
@@ -187,7 +201,7 @@ const relative = (from, to) => {
|
|
|
187
201
|
if (resolvedFrom === resolvedTo) return EMPTY;
|
|
188
202
|
const fromSegments = resolvedFrom.replace(ROOT_FOLDER_RE, "$1").split(SLASH).filter(Boolean);
|
|
189
203
|
const toSegments = resolvedTo.replace(ROOT_FOLDER_RE, "$1").split(SLASH).filter(Boolean);
|
|
190
|
-
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()) {
|
|
191
205
|
return resolvedTo;
|
|
192
206
|
}
|
|
193
207
|
let commonSegments = 0;
|
|
@@ -342,6 +356,7 @@ function reverseResolveAlias(path2, aliases) {
|
|
|
342
356
|
}
|
|
343
357
|
const findAliasMatch = (importPath, paths) => {
|
|
344
358
|
const firstPathKey = Object.keys(paths)[0];
|
|
359
|
+
if (!firstPathKey) return null;
|
|
345
360
|
const baseAlias = firstPathKey.replace("/*", "");
|
|
346
361
|
if (importPath.startsWith("@") && !importPath.startsWith(baseAlias)) {
|
|
347
362
|
return null;
|
|
@@ -452,6 +467,7 @@ async function processFile(filePath, aliasToReplace, targetDir, pathExtFilter) {
|
|
|
452
467
|
for (const match of matches) {
|
|
453
468
|
const originalQuote = match[1];
|
|
454
469
|
const importPath = match[2];
|
|
470
|
+
if (!importPath) continue;
|
|
455
471
|
if (!importPath.startsWith(baseAlias)) {
|
|
456
472
|
continue;
|
|
457
473
|
}
|
|
@@ -516,7 +532,7 @@ async function processAllFiles({
|
|
|
516
532
|
);
|
|
517
533
|
return results;
|
|
518
534
|
} catch (error) {
|
|
519
|
-
|
|
535
|
+
logger(
|
|
520
536
|
`error processing directory ${srcDir}: ${error instanceof Error ? error.message : String(error)}`
|
|
521
537
|
);
|
|
522
538
|
return [];
|
|
@@ -525,14 +541,15 @@ async function processAllFiles({
|
|
|
525
541
|
async function convertImportsAliasToRelative({
|
|
526
542
|
targetDir,
|
|
527
543
|
aliasToReplace,
|
|
528
|
-
// e.g. @, ~, @/*, ~/*
|
|
529
544
|
pathExtFilter
|
|
530
545
|
}) {
|
|
531
546
|
const normalizedAlias = aliasToReplace.endsWith("/*") ? aliasToReplace : `${aliasToReplace}/*`;
|
|
532
|
-
|
|
547
|
+
logger(
|
|
533
548
|
`Converting aliased imports starting with '${aliasToReplace}' to relative paths in "${targetDir}"...`
|
|
534
549
|
);
|
|
535
|
-
|
|
550
|
+
logger(
|
|
551
|
+
` (Assuming "${normalizedAlias}" resolves relative to "${targetDir}")`
|
|
552
|
+
);
|
|
536
553
|
const results = await processAllFiles({
|
|
537
554
|
srcDir: targetDir,
|
|
538
555
|
aliasToReplace: normalizedAlias,
|
|
@@ -541,17 +558,17 @@ async function convertImportsAliasToRelative({
|
|
|
541
558
|
pathExtFilter
|
|
542
559
|
});
|
|
543
560
|
if (results.length > 0) {
|
|
544
|
-
|
|
561
|
+
logger("\n[convertImportsAliasToRelative] Summary of changes:", true);
|
|
545
562
|
for (const { file, changes } of results) {
|
|
546
563
|
const displayPath = relative(targetDir, file) || basename(file);
|
|
547
|
-
|
|
564
|
+
logger(() => ` in ${displayPath}:`, true);
|
|
548
565
|
for (const { from, to } of changes) {
|
|
549
|
-
|
|
566
|
+
logger(() => ` - ${from} \u2192 ${to}`, true);
|
|
550
567
|
}
|
|
551
568
|
}
|
|
552
569
|
} else {
|
|
553
570
|
}
|
|
554
|
-
|
|
571
|
+
logger("Import path conversion process complete.");
|
|
555
572
|
return results;
|
|
556
573
|
}
|
|
557
574
|
async function convertImportsExt({
|
|
@@ -559,7 +576,7 @@ async function convertImportsExt({
|
|
|
559
576
|
extFrom,
|
|
560
577
|
extTo
|
|
561
578
|
}) {
|
|
562
|
-
const fromExtStr = extFrom === "none" ? "" : `.${extFrom}`;
|
|
579
|
+
const fromExtStr = extFrom === "none" ? "" : extFrom === "none-and-js" ? "(?:\\.js)?" : `.${extFrom}`;
|
|
563
580
|
const toExtStr = extTo === "none" ? "" : `.${extTo}`;
|
|
564
581
|
const importRegex = new RegExp(
|
|
565
582
|
`(?:import\\s+(?:[\\s\\S]*?)\\s+from\\s+|import\\s*\\(\\s*)\\s*(['"])([^'"]+${fromExtStr.replace(".", "\\.")})(\\1)`,
|
|
@@ -583,13 +600,21 @@ async function convertImportsExt({
|
|
|
583
600
|
const content = await fs.readFile(fullPath, "utf-8");
|
|
584
601
|
let updated = content;
|
|
585
602
|
const changes = [];
|
|
586
|
-
|
|
587
|
-
|
|
603
|
+
let match;
|
|
604
|
+
match = importRegex.exec(content);
|
|
605
|
+
while (match !== null) {
|
|
588
606
|
const quote = match[1];
|
|
589
607
|
const importPath = match[2];
|
|
608
|
+
if (!importPath) continue;
|
|
590
609
|
let replacementPath;
|
|
591
610
|
if (extFrom === "none") {
|
|
592
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
|
+
}
|
|
593
618
|
} else if (extTo === "none") {
|
|
594
619
|
replacementPath = importPath.slice(0, -fromExtStr.length);
|
|
595
620
|
} else {
|
|
@@ -600,6 +625,7 @@ async function convertImportsExt({
|
|
|
600
625
|
const searchStr = `${quote}${importPath}${quote}`;
|
|
601
626
|
const replaceStr = `${quote}${replacementPath}${quote}`;
|
|
602
627
|
updated = replaceAllInString(updated, searchStr, replaceStr);
|
|
628
|
+
match = importRegex.exec(updated);
|
|
603
629
|
}
|
|
604
630
|
if (content !== updated) {
|
|
605
631
|
await fs.writeFile(fullPath, updated);
|
|
@@ -612,19 +638,18 @@ async function convertImportsExt({
|
|
|
612
638
|
})
|
|
613
639
|
);
|
|
614
640
|
if (results.length > 0) {
|
|
615
|
-
|
|
641
|
+
logger("\n[convertImportsExt] Summary of changes:", true);
|
|
616
642
|
for (const { file, changes } of results) {
|
|
617
643
|
const displayPath = relative(targetDir, file) || basename(file);
|
|
618
|
-
|
|
644
|
+
logger(() => ` in ${displayPath}:`, true);
|
|
619
645
|
for (const { from, to } of changes) {
|
|
620
|
-
|
|
646
|
+
logger(() => ` - ${from} \u2192 ${to}`, true);
|
|
621
647
|
}
|
|
622
648
|
}
|
|
623
|
-
} else {
|
|
624
649
|
}
|
|
625
650
|
return results;
|
|
626
651
|
} catch (error) {
|
|
627
|
-
|
|
652
|
+
logger(
|
|
628
653
|
`error processing directory ${targetDir}: ${error instanceof Error ? error.message : String(error)}`
|
|
629
654
|
);
|
|
630
655
|
return [];
|
|
@@ -648,13 +673,17 @@ function stripPathSegments(path2, count = 1, alias = "") {
|
|
|
648
673
|
}
|
|
649
674
|
pathSegments = pathSegments.filter(Boolean);
|
|
650
675
|
const leadingPreservedSegments = [];
|
|
651
|
-
if (alias && pathSegments.length > 0 && pathSegments[0]
|
|
676
|
+
if (alias && pathSegments.length > 0 && pathSegments[0]?.startsWith(alias)) {
|
|
652
677
|
const preserved = pathSegments.shift();
|
|
653
|
-
|
|
678
|
+
if (preserved) {
|
|
679
|
+
leadingPreservedSegments.push(preserved);
|
|
680
|
+
}
|
|
654
681
|
}
|
|
655
682
|
while (pathSegments.length > 0 && (pathSegments[0] === DOT || pathSegments[0] === DOUBLE_DOT)) {
|
|
656
683
|
const preserved = pathSegments.shift();
|
|
657
|
-
|
|
684
|
+
if (preserved) {
|
|
685
|
+
leadingPreservedSegments.push(preserved);
|
|
686
|
+
}
|
|
658
687
|
}
|
|
659
688
|
const numToStrip = Math.min(count, pathSegments.length);
|
|
660
689
|
const remainingBodySegments = pathSegments.slice(numToStrip);
|
|
@@ -679,8 +708,14 @@ async function stripPathSegmentsInDirectory({
|
|
|
679
708
|
alias = "",
|
|
680
709
|
extensionsToProcess = EXTENSIONS
|
|
681
710
|
}) {
|
|
682
|
-
|
|
683
|
-
|
|
711
|
+
logger(
|
|
712
|
+
() => `[stripPathSegmentsInDirectory] Processing directory: ${targetDir}`,
|
|
713
|
+
true
|
|
714
|
+
);
|
|
715
|
+
logger(
|
|
716
|
+
() => ` - segmentsToStrip: ${segmentsToStrip}, alias: ${alias}`,
|
|
717
|
+
true
|
|
718
|
+
);
|
|
684
719
|
try {
|
|
685
720
|
const entries = await fs.readdir(targetDir, { withFileTypes: true });
|
|
686
721
|
const results = [];
|
|
@@ -704,6 +739,7 @@ async function stripPathSegmentsInDirectory({
|
|
|
704
739
|
for (const match of matches) {
|
|
705
740
|
const originalQuote = match[1];
|
|
706
741
|
const importPath = match[2];
|
|
742
|
+
if (!importPath) continue;
|
|
707
743
|
if (!importPath.includes(SLASH)) {
|
|
708
744
|
continue;
|
|
709
745
|
}
|
|
@@ -735,19 +771,19 @@ async function stripPathSegmentsInDirectory({
|
|
|
735
771
|
})
|
|
736
772
|
);
|
|
737
773
|
if (results.length > 0) {
|
|
738
|
-
|
|
774
|
+
logger(() => "[stripPathSegmentsInDirectory] Summary of changes:", true);
|
|
739
775
|
for (const { file, changes } of results) {
|
|
740
776
|
const displayPath = relative(targetDir, file) || basename(file);
|
|
741
|
-
|
|
777
|
+
logger(() => ` in ${displayPath}:`, true);
|
|
742
778
|
for (const { from, to } of changes) {
|
|
743
|
-
|
|
779
|
+
logger(() => ` - ${from} \u2192 ${to}`, true);
|
|
744
780
|
}
|
|
745
781
|
}
|
|
746
782
|
} else {
|
|
747
783
|
}
|
|
748
784
|
return results;
|
|
749
785
|
} catch (error) {
|
|
750
|
-
|
|
786
|
+
logger(
|
|
751
787
|
`error processing directory ${targetDir}: ${error instanceof Error ? error.message : String(error)}`
|
|
752
788
|
);
|
|
753
789
|
return [];
|
|
@@ -818,6 +854,7 @@ async function attachPathSegmentsInDirectory({
|
|
|
818
854
|
for (const match of matches) {
|
|
819
855
|
const originalQuote = match[1];
|
|
820
856
|
const importPath = match[2];
|
|
857
|
+
if (!importPath) continue;
|
|
821
858
|
if (!importPath.includes(SLASH)) continue;
|
|
822
859
|
const modifiedPath = attachPathSegments(
|
|
823
860
|
importPath,
|
|
@@ -841,18 +878,21 @@ async function attachPathSegmentsInDirectory({
|
|
|
841
878
|
})
|
|
842
879
|
);
|
|
843
880
|
if (results.length > 0) {
|
|
844
|
-
|
|
881
|
+
logger(
|
|
882
|
+
() => "\n[attachPathSegmentsInDirectory] Summary of changes:",
|
|
883
|
+
true
|
|
884
|
+
);
|
|
845
885
|
for (const { file, changes } of results) {
|
|
846
886
|
const displayPath = relative(targetDir, file) || basename(file);
|
|
847
|
-
|
|
887
|
+
logger(() => ` in ${displayPath}:`, true);
|
|
848
888
|
for (const { from, to } of changes) {
|
|
849
|
-
|
|
889
|
+
logger(() => ` - ${from} \u2192 ${to}`, true);
|
|
850
890
|
}
|
|
851
891
|
}
|
|
852
892
|
}
|
|
853
893
|
return results;
|
|
854
894
|
} catch (error) {
|
|
855
|
-
|
|
895
|
+
logger(
|
|
856
896
|
`error processing directory ${targetDir}: ${error instanceof Error ? error.message : String(error)}`
|
|
857
897
|
);
|
|
858
898
|
return [];
|
|
@@ -944,6 +984,7 @@ export {
|
|
|
944
984
|
stripPathSegments,
|
|
945
985
|
stripPathSegmentsInDirectory,
|
|
946
986
|
attachPathSegments,
|
|
947
|
-
attachPathSegmentsInDirectory
|
|
987
|
+
attachPathSegmentsInDirectory,
|
|
988
|
+
getFileImportsExports
|
|
948
989
|
};
|
|
949
990
|
export default path;
|
package/package.json
CHANGED
|
@@ -5,26 +5,8 @@
|
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"name": "@reliverse/pathkit",
|
|
7
7
|
"type": "module",
|
|
8
|
-
"version": "1.1.
|
|
9
|
-
"devDependencies": {
|
|
10
|
-
"@biomejs/biome": "1.9.4",
|
|
11
|
-
"@eslint/js": "^9.27.0",
|
|
12
|
-
"@reliverse/dler": "^1.4.6",
|
|
13
|
-
"@reliverse/relifso": "^1.2.10",
|
|
14
|
-
"@reliverse/relinka": "^1.4.6",
|
|
15
|
-
"@reliverse/rematch": "^1.1.0",
|
|
16
|
-
"@stylistic/eslint-plugin": "^4.2.0",
|
|
17
|
-
"@types/bun": "^1.2.14",
|
|
18
|
-
"@types/node": "^22.15.21",
|
|
19
|
-
"eslint": "^9.27.0",
|
|
20
|
-
"eslint-plugin-no-relative-import-paths": "^1.6.1",
|
|
21
|
-
"eslint-plugin-perfectionist": "^4.13.0",
|
|
22
|
-
"knip": "^5.57.2",
|
|
23
|
-
"magic-string": "^0.30.17",
|
|
24
|
-
"p-map": "^7.0.3",
|
|
25
|
-
"typescript": "^5.8.3",
|
|
26
|
-
"typescript-eslint": "^8.32.1"
|
|
27
|
-
},
|
|
8
|
+
"version": "1.1.7",
|
|
9
|
+
"devDependencies": {},
|
|
28
10
|
"exports": {
|
|
29
11
|
".": "./bin/mod.js"
|
|
30
12
|
},
|