@reliverse/pathkit 1.0.5 → 1.1.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/bin/mod.js CHANGED
@@ -1,50 +1,726 @@
1
- import { normalizeWindowsPath } from "./pathkit-impl/_internal.js";
2
- import {
1
+ import fs from "node:fs/promises";
2
+ const EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
3
+ const SLASH = "/";
4
+ const BACK_SLASH = "\\";
5
+ const DOT = ".";
6
+ const DOUBLE_DOT = "..";
7
+ const EMPTY = "";
8
+ const normalizedAliasSymbol = Symbol.for("pathkit:normalizedAlias");
9
+ const DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
10
+ const DRIVE_LETTER_RE = /^[A-Za-z]:$/;
11
+ const UNC_REGEX = /^[/\\]{2}/;
12
+ const IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
13
+ const ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
14
+ const PATH_ROOT_RE = /^[/\\]|^[a-zA-Z]:[/\\]/;
15
+ const IMPORT_REGEX = /(?:import\s+(?:[\s\S]*?)\s+from\s+|import\s*\(\s*)\s*(['"])((?:@)[^'"]+)\1/g;
16
+ const log = (msg) => console.log(`\x1B[2m${msg}\x1B[0m`);
17
+ async function cleanDirs(dirs) {
18
+ await Promise.all(
19
+ dirs.map(async (d) => {
20
+ try {
21
+ await fs.rm(d, { recursive: true, force: true });
22
+ log(`\u2713 cleaned: ${d}`);
23
+ } catch (error) {
24
+ log(
25
+ `\u2717 error cleaning ${d}: ${error instanceof Error ? error.message : String(error)}`
26
+ );
27
+ }
28
+ })
29
+ );
30
+ }
31
+ async function copyDir(src, dest) {
32
+ log(`\u2713 copying: ${src} \u2192 ${dest}`);
33
+ try {
34
+ await fs.mkdir(dest, { recursive: true });
35
+ const entries = await fs.readdir(src, { withFileTypes: true });
36
+ await Promise.all(
37
+ entries.map(async (entry) => {
38
+ const srcPath = join(src, entry.name);
39
+ const destPath = join(dest, entry.name);
40
+ if (entry.isDirectory()) {
41
+ return copyDir(srcPath, destPath);
42
+ }
43
+ await fs.copyFile(srcPath, destPath);
44
+ log(` copied: ${srcPath} \u2192 ${destPath}`);
45
+ })
46
+ );
47
+ } catch (error) {
48
+ const errorMsg = error instanceof Error ? error.message : String(error);
49
+ log(`\u2717 error copying directory ${src} to ${dest}: ${errorMsg}`);
50
+ throw error;
51
+ }
52
+ }
53
+ function normalizeWindowsPath(input = "") {
54
+ if (!input) return input;
55
+ return input.replace(/\\/g, SLASH).replace(DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
56
+ }
57
+ function compareAliases(a, b) {
58
+ return b.split(SLASH).length - a.split(SLASH).length;
59
+ }
60
+ function cwd() {
61
+ if (typeof process !== "undefined" && typeof process.cwd === "function") {
62
+ return process.cwd().replace(/\\/g, SLASH);
63
+ }
64
+ return SLASH;
65
+ }
66
+ function normalizeString(path2, allowAboveRoot) {
67
+ let res = EMPTY;
68
+ let lastSegmentLength = 0;
69
+ let lastSlash = -1;
70
+ let dots = 0;
71
+ let char = null;
72
+ for (let index = 0; index <= path2.length; ++index) {
73
+ if (index < path2.length) {
74
+ char = path2[index];
75
+ } else if (char === SLASH) {
76
+ break;
77
+ } else {
78
+ char = SLASH;
79
+ }
80
+ if (char === SLASH) {
81
+ if (lastSlash === index - 1 || dots === 1) {
82
+ } else if (dots === 2) {
83
+ if (res.length < 2 || lastSegmentLength !== 2 || !res.endsWith(DOT) || res[res.length - 2] !== DOT) {
84
+ if (res.length > 2) {
85
+ const lastSlashIndex = res.lastIndexOf(SLASH);
86
+ if (lastSlashIndex === -1) {
87
+ res = EMPTY;
88
+ lastSegmentLength = 0;
89
+ } else {
90
+ res = res.slice(0, lastSlashIndex);
91
+ lastSegmentLength = res.length - 1 - res.lastIndexOf(SLASH);
92
+ }
93
+ lastSlash = index;
94
+ dots = 0;
95
+ continue;
96
+ }
97
+ if (res.length > 0) {
98
+ res = EMPTY;
99
+ lastSegmentLength = 0;
100
+ lastSlash = index;
101
+ dots = 0;
102
+ continue;
103
+ }
104
+ }
105
+ if (allowAboveRoot) {
106
+ res += res.length > 0 ? `${SLASH}..` : DOUBLE_DOT;
107
+ lastSegmentLength = 2;
108
+ }
109
+ } else {
110
+ const segment = path2.slice(lastSlash + 1, index);
111
+ if (res.length > 0) {
112
+ res += `${SLASH}${segment}`;
113
+ } else {
114
+ res = segment;
115
+ }
116
+ lastSegmentLength = segment.length;
117
+ }
118
+ lastSlash = index;
119
+ dots = 0;
120
+ } else if (char === DOT && dots !== -1) {
121
+ ++dots;
122
+ } else {
123
+ dots = -1;
124
+ }
125
+ }
126
+ return res;
127
+ }
128
+ const sep = SLASH;
129
+ const normalize = (path2) => {
130
+ if (path2.length === 0) return DOT;
131
+ const originalPath = path2;
132
+ path2 = normalizeWindowsPath(path2);
133
+ const isPathAbsolute = IS_ABSOLUTE_RE.test(path2);
134
+ const trailingSeparator = path2.endsWith(SLASH);
135
+ path2 = normalizeString(path2, !isPathAbsolute);
136
+ if (path2.length === 0) {
137
+ if (isPathAbsolute) return SLASH;
138
+ return trailingSeparator && originalPath.length > 0 && originalPath !== DOT ? "./" : DOT;
139
+ }
140
+ if (trailingSeparator && !path2.endsWith(SLASH)) {
141
+ path2 += SLASH;
142
+ }
143
+ if (DRIVE_LETTER_RE.test(path2) && path2.length === 2) {
144
+ path2 += SLASH;
145
+ }
146
+ if (UNC_REGEX.test(originalPath.replace(/\\/g, SLASH))) {
147
+ const normOriginal = originalPath.replace(/\\/g, SLASH);
148
+ if (normOriginal.startsWith("//./")) {
149
+ return `//./${path2.startsWith(SLASH) ? path2.substring(1) : path2}`;
150
+ }
151
+ if (normOriginal.startsWith("//") && !normOriginal.startsWith("//./")) {
152
+ return `//${path2.startsWith(SLASH) ? path2.substring(1) : path2}`;
153
+ }
154
+ }
155
+ if (isPathAbsolute && !IS_ABSOLUTE_RE.test(path2) && path2 !== SLASH) {
156
+ return `${SLASH}${path2}`;
157
+ }
158
+ return path2;
159
+ };
160
+ const join = (...segments) => {
161
+ if (segments.length === 0) return DOT;
162
+ let joined = EMPTY;
163
+ for (const segment of segments) {
164
+ if (typeof segment !== "string") {
165
+ throw new TypeError("Arguments to path.join must be strings");
166
+ }
167
+ if (segment.length > 0) {
168
+ if (joined.length === 0) {
169
+ joined = segment;
170
+ } else {
171
+ joined += `${SLASH}${segment}`;
172
+ }
173
+ }
174
+ }
175
+ if (joined.length === 0) return DOT;
176
+ return normalize(joined);
177
+ };
178
+ const resolve = (...args) => {
179
+ let resolvedPath = EMPTY;
180
+ let resolvedAbsolute = false;
181
+ for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
182
+ const path2 = i >= 0 ? args[i] : cwd();
183
+ if (typeof path2 !== "string") {
184
+ throw new TypeError("Arguments to path.resolve must be strings");
185
+ }
186
+ if (path2.length === 0) continue;
187
+ const normalizedSegment = normalizeWindowsPath(path2);
188
+ resolvedPath = `${normalizedSegment}${SLASH}${resolvedPath}`;
189
+ resolvedAbsolute = IS_ABSOLUTE_RE.test(normalizedSegment);
190
+ }
191
+ resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
192
+ if (resolvedAbsolute) {
193
+ if (IS_ABSOLUTE_RE.test(resolvedPath)) {
194
+ return resolvedPath;
195
+ }
196
+ return `${SLASH}${resolvedPath}`;
197
+ }
198
+ return resolvedPath.length > 0 ? resolvedPath : DOT;
199
+ };
200
+ const isAbsolute = (p) => {
201
+ if (typeof p !== "string") return false;
202
+ return IS_ABSOLUTE_RE.test(normalizeWindowsPath(p));
203
+ };
204
+ const toNamespacedPath = (p) => {
205
+ if (typeof p !== "string" || p.length === 0) return p;
206
+ return normalize(p);
207
+ };
208
+ const extname = (p) => {
209
+ if (typeof p !== "string") return EMPTY;
210
+ const path2 = normalizeWindowsPath(p);
211
+ let lastSlashIdx = path2.lastIndexOf(SLASH);
212
+ if (lastSlashIdx === -1) lastSlashIdx = 0;
213
+ const basePart = lastSlashIdx === 0 ? path2 : path2.substring(lastSlashIdx + 1);
214
+ if (basePart === DOT || basePart === DOUBLE_DOT) return EMPTY;
215
+ const lastDotIdx = basePart.lastIndexOf(DOT);
216
+ if (lastDotIdx <= 0) return EMPTY;
217
+ return basePart.substring(lastDotIdx);
218
+ };
219
+ const relative = (from, to) => {
220
+ const resolvedFrom = resolve(from);
221
+ const resolvedTo = resolve(to);
222
+ if (resolvedFrom === resolvedTo) return EMPTY;
223
+ const fromSegments = resolvedFrom.replace(ROOT_FOLDER_RE, "$1").split(SLASH).filter(Boolean);
224
+ const toSegments = resolvedTo.replace(ROOT_FOLDER_RE, "$1").split(SLASH).filter(Boolean);
225
+ 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()) {
226
+ return resolvedTo;
227
+ }
228
+ let commonSegments = 0;
229
+ const maxCommon = Math.min(fromSegments.length, toSegments.length);
230
+ while (commonSegments < maxCommon && fromSegments[commonSegments] === toSegments[commonSegments]) {
231
+ commonSegments++;
232
+ }
233
+ const upSegments = Array(fromSegments.length - commonSegments).fill(
234
+ DOUBLE_DOT
235
+ );
236
+ const downSegments = toSegments.slice(commonSegments);
237
+ const result = [...upSegments, ...downSegments].join(SLASH);
238
+ return result.length > 0 ? result : DOT;
239
+ };
240
+ const dirname = (p) => {
241
+ if (typeof p !== "string" || p.length === 0) return DOT;
242
+ const normalizedPath = normalizeWindowsPath(p);
243
+ const lastSlash = normalizedPath.lastIndexOf(SLASH);
244
+ if (lastSlash === -1) {
245
+ return IS_ABSOLUTE_RE.test(normalizedPath) ? SLASH : DOT;
246
+ }
247
+ if (lastSlash === 0) return SLASH;
248
+ const dir = normalizedPath.slice(0, lastSlash);
249
+ if (DRIVE_LETTER_RE.test(dir) && dir.length === 2) {
250
+ return dir + SLASH;
251
+ }
252
+ return normalize(dir);
253
+ };
254
+ const format = (p) => {
255
+ if (typeof p !== "object" || p === null) {
256
+ throw new TypeError(
257
+ 'Parameter "pathObject" must be an object, not null or other type.'
258
+ );
259
+ }
260
+ const dir = p.dir || p.root || "";
261
+ const base = p.base || `${p.name || ""}${p.ext || ""}`;
262
+ if (!dir) return base;
263
+ if (dir === p.root) return `${dir}${base}`;
264
+ return normalize(`${dir}${SLASH}${base}`);
265
+ };
266
+ const basename = (p, ext) => {
267
+ if (typeof p !== "string") throw new TypeError("Path must be a string.");
268
+ if (ext !== void 0 && typeof ext !== "string")
269
+ throw new TypeError("[basename] `ext` must be a string.");
270
+ const normalizedPath = normalizeWindowsPath(p);
271
+ let end = normalizedPath.length;
272
+ while (end > 0 && normalizedPath[end - 1] === SLASH) {
273
+ end--;
274
+ }
275
+ if (end === 0) return EMPTY;
276
+ let start = normalizedPath.lastIndexOf(SLASH, end - 1);
277
+ start = start === -1 ? 0 : start + 1;
278
+ let filename2 = normalizedPath.slice(start, end);
279
+ if (ext && filename2.endsWith(ext) && filename2 !== ext) {
280
+ filename2 = filename2.slice(0, filename2.length - ext.length);
281
+ }
282
+ return filename2;
283
+ };
284
+ const parse = (p) => {
285
+ if (typeof p !== "string") throw new TypeError("Path must be a string.");
286
+ const normalizedPath = normalizeWindowsPath(p);
287
+ const B = basename(normalizedPath);
288
+ const E = extname(B);
289
+ const N = B.slice(0, B.length - E.length);
290
+ const D = dirname(normalizedPath);
291
+ let R = EMPTY;
292
+ const rootMatch = PATH_ROOT_RE.exec(normalizedPath);
293
+ if (rootMatch) {
294
+ R = rootMatch[0];
295
+ if (DRIVE_LETTER_RE.test(R) && R.length === 2 && normalizedPath.length > 2 && normalizedPath[2] === SLASH) {
296
+ R += SLASH;
297
+ } else if (R === SLASH && D.startsWith("//")) {
298
+ if (UNC_REGEX.exec(D)) {
299
+ const uncParts = D.split(SLASH).slice(0, 3);
300
+ R = uncParts.join(SLASH) || R;
301
+ }
302
+ }
303
+ }
304
+ const resolvedDir = D === DOT && R !== EMPTY && R !== DOT ? R : D;
305
+ return {
306
+ root: R,
307
+ dir: resolvedDir,
308
+ base: B,
309
+ ext: E,
310
+ name: N
311
+ };
312
+ };
313
+ function filename(pathString) {
314
+ const base = basename(pathString);
315
+ if (!base) return void 0;
316
+ const separatorIndex = base.lastIndexOf(DOT);
317
+ return separatorIndex <= 0 ? base : base.slice(0, separatorIndex);
318
+ }
319
+ function normalizeAliases(aliases) {
320
+ if (aliases[normalizedAliasSymbol]) {
321
+ return aliases;
322
+ }
323
+ const sortedAliasesEntries = Object.entries(aliases).map(
324
+ ([key, value]) => [normalizeWindowsPath(key), normalizeWindowsPath(value)]
325
+ ).sort(([a], [b]) => compareAliases(a, b));
326
+ const sortedAliases = Object.fromEntries(sortedAliasesEntries);
327
+ for (const key in sortedAliases) {
328
+ for (const aliasPrefix in sortedAliases) {
329
+ if (aliasPrefix === key || key.startsWith(aliasPrefix + SLASH) || key === aliasPrefix)
330
+ continue;
331
+ const value = sortedAliases[key];
332
+ if (value?.startsWith(aliasPrefix)) {
333
+ const nextChar = value[aliasPrefix.length];
334
+ if (nextChar === void 0 || nextChar === SLASH) {
335
+ sortedAliases[key] = sortedAliases[aliasPrefix] + value.slice(aliasPrefix.length);
336
+ }
337
+ }
338
+ }
339
+ }
340
+ const finalNormalizedAliases = { ...sortedAliases };
341
+ Object.defineProperty(finalNormalizedAliases, normalizedAliasSymbol, {
342
+ value: true,
343
+ enumerable: false
344
+ });
345
+ return finalNormalizedAliases;
346
+ }
347
+ function resolveAlias(path2, aliases) {
348
+ const normalizedPath = normalizeWindowsPath(path2);
349
+ const normalizedAliases = normalizeAliases(aliases);
350
+ for (const [alias, to] of Object.entries(normalizedAliases)) {
351
+ const effectiveAlias = alias.endsWith(SLASH) ? alias : alias + SLASH;
352
+ const effectivePath = normalizedPath.endsWith(SLASH) ? normalizedPath : normalizedPath + SLASH;
353
+ if (effectivePath.startsWith(effectiveAlias)) {
354
+ return join(to, normalizedPath.slice(alias.length));
355
+ }
356
+ if (normalizedPath === alias) {
357
+ return to;
358
+ }
359
+ }
360
+ return normalizedPath;
361
+ }
362
+ function reverseResolveAlias(path2, aliases) {
363
+ const normalizedPath = normalizeWindowsPath(path2);
364
+ const normalizedAliases = normalizeAliases(aliases);
365
+ const matches = [];
366
+ for (const [alias, to] of Object.entries(normalizedAliases)) {
367
+ const effectiveTo = to.endsWith(SLASH) ? to : to + SLASH;
368
+ const effectivePath = normalizedPath.endsWith(SLASH) ? normalizedPath : normalizedPath + SLASH;
369
+ if (effectivePath.startsWith(effectiveTo)) {
370
+ matches.push(join(alias, normalizedPath.slice(to.length)));
371
+ }
372
+ if (normalizedPath === to) {
373
+ matches.push(alias);
374
+ }
375
+ }
376
+ return matches.sort((a, b) => b.length - a.length);
377
+ }
378
+ const findAliasMatch = (importPath, paths) => {
379
+ if (paths[importPath]?.[0]) {
380
+ return {
381
+ key: importPath,
382
+ root: importPath,
383
+ resolvedPath: paths[importPath][0],
384
+ suffix: ""
385
+ };
386
+ }
387
+ for (const aliasKey in paths) {
388
+ if (aliasKey.endsWith("/*")) {
389
+ const aliasRoot = aliasKey.slice(0, -2);
390
+ if (importPath === aliasRoot || importPath.startsWith(`${aliasRoot}/`)) {
391
+ const suffix = importPath === aliasRoot ? "" : importPath.slice(aliasRoot.length + 1);
392
+ const targetPaths = paths[aliasKey];
393
+ if (targetPaths?.[0]) {
394
+ const resolvedPathPattern = targetPaths[0].slice(0, -2);
395
+ return {
396
+ key: aliasKey,
397
+ root: aliasRoot,
398
+ resolvedPath: resolvedPathPattern,
399
+ suffix
400
+ };
401
+ }
402
+ }
403
+ }
404
+ }
405
+ return null;
406
+ };
407
+ const toRelativeImport = (absPath, fromDir) => {
408
+ const rel = normalizeWindowsPath(relative(fromDir, absPath));
409
+ return rel.startsWith(DOT) ? rel : `./${rel}`;
410
+ };
411
+ async function resolveFileWithExtensions(basePath, extensions = ["", ...EXTENSIONS, ".json"]) {
412
+ for (const ext of extensions) {
413
+ try {
414
+ const fullPath = basePath + ext;
415
+ const stat = await fs.stat(fullPath);
416
+ if (stat.isFile()) {
417
+ return fullPath;
418
+ }
419
+ } catch {
420
+ }
421
+ }
422
+ for (const ext of extensions) {
423
+ try {
424
+ const indexPath = join(basePath, `index${ext}`);
425
+ const stat = await fs.stat(indexPath);
426
+ if (stat.isFile()) {
427
+ return indexPath;
428
+ }
429
+ } catch {
430
+ }
431
+ }
432
+ return null;
433
+ }
434
+ function getTargetExtension(relPath, originalExt) {
435
+ const foundExt = extname(relPath);
436
+ if (originalExt) {
437
+ return relPath;
438
+ }
439
+ if (foundExt) {
440
+ return relPath.slice(0, -foundExt.length);
441
+ }
442
+ return relPath;
443
+ }
444
+ async function convertStringAliasRelative({
445
+ importPath,
446
+ importerFile,
447
+ pathPattern,
448
+ targetDir
449
+ }) {
450
+ const paths = { [pathPattern]: ["./*"] };
451
+ const importerDir = dirname(importerFile);
452
+ const match = findAliasMatch(importPath, paths);
453
+ if (!match) return importPath;
454
+ const absPath = resolve(targetDir, match.resolvedPath, match.suffix);
455
+ const resolvedFile = await resolveFileWithExtensions(absPath);
456
+ const relPath = toRelativeImport(resolvedFile || absPath, importerDir);
457
+ const originalExt = extname(importPath);
458
+ return getTargetExtension(relPath, originalExt);
459
+ }
460
+ function replaceAllInString(original, searchValue, replaceValue) {
461
+ let currentPosition = 0;
462
+ let result = "";
463
+ while (currentPosition < original.length) {
464
+ const foundIdx = original.indexOf(searchValue, currentPosition);
465
+ if (foundIdx === -1) {
466
+ result += original.substring(currentPosition);
467
+ break;
468
+ }
469
+ result += original.substring(currentPosition, foundIdx);
470
+ result += replaceValue;
471
+ currentPosition = foundIdx + searchValue.length;
472
+ }
473
+ return result;
474
+ }
475
+ async function processFile(filePath, aliasToReplace, targetDir, pathExtFilter) {
476
+ const content = await fs.readFile(filePath, "utf-8");
477
+ let updated = content;
478
+ const changes = [];
479
+ const matches = Array.from(content.matchAll(IMPORT_REGEX));
480
+ const normalizedAlias = aliasToReplace.endsWith("/*") ? aliasToReplace : `${aliasToReplace}/*`;
481
+ for (const match of matches) {
482
+ const originalQuote = match[1];
483
+ const importPath = match[2];
484
+ const importExt = extname(importPath);
485
+ const shouldProcess = pathExtFilter === "js" && importExt === ".js" || pathExtFilter === "ts" && importExt === ".ts" || pathExtFilter === "none" && importExt === "" || pathExtFilter === "js-ts-none";
486
+ if (!shouldProcess) continue;
487
+ const relPath = await convertStringAliasRelative({
488
+ importPath,
489
+ importerFile: filePath,
490
+ pathPattern: normalizedAlias,
491
+ targetDir
492
+ });
493
+ if (importPath !== relPath) {
494
+ changes.push({ from: importPath, to: relPath });
495
+ const searchString = `${originalQuote}${importPath}${originalQuote}`;
496
+ const replacementString = `${originalQuote}${relPath}${originalQuote}`;
497
+ updated = replaceAllInString(updated, searchString, replacementString);
498
+ }
499
+ }
500
+ if (content !== updated) {
501
+ await fs.writeFile(filePath, updated);
502
+ log(`\u2713 processed: ${filePath}`);
503
+ }
504
+ return changes;
505
+ }
506
+ async function processAllFiles({
507
+ srcDir,
508
+ aliasToReplace,
509
+ extensionsToProcess,
510
+ rootDir,
511
+ pathExtFilter
512
+ }) {
513
+ try {
514
+ const entries = await fs.readdir(srcDir, { withFileTypes: true });
515
+ const results = [];
516
+ await Promise.all(
517
+ entries.map(async (entry) => {
518
+ const fullPath = join(srcDir, entry.name);
519
+ if (entry.isDirectory()) {
520
+ if (entry.name === "node_modules" || entry.name.startsWith("."))
521
+ return;
522
+ const subdirResults = await processAllFiles({
523
+ srcDir: fullPath,
524
+ aliasToReplace,
525
+ extensionsToProcess,
526
+ rootDir,
527
+ pathExtFilter
528
+ });
529
+ results.push(...subdirResults);
530
+ } else if (extensionsToProcess.includes(extname(entry.name))) {
531
+ const changes = await processFile(
532
+ fullPath,
533
+ aliasToReplace,
534
+ rootDir,
535
+ pathExtFilter
536
+ );
537
+ if (changes.length > 0) {
538
+ results.push({ file: fullPath, changes });
539
+ }
540
+ }
541
+ })
542
+ );
543
+ return results;
544
+ } catch (error) {
545
+ log(
546
+ `error processing directory ${srcDir}: ${error instanceof Error ? error.message : String(error)}`
547
+ );
548
+ return [];
549
+ }
550
+ }
551
+ async function convertImportsAliasToRelative({
552
+ targetDir,
553
+ aliasToReplace,
554
+ // e.g. @, ~, @/*, ~/*
555
+ pathExtFilter
556
+ }) {
557
+ const normalizedAlias = aliasToReplace.endsWith("/*") ? aliasToReplace : `${aliasToReplace}/*`;
558
+ log(
559
+ `Converting aliased imports starting with '${aliasToReplace}' to relative paths in "${targetDir}"...`
560
+ );
561
+ log(` (Assuming "${normalizedAlias}" resolves relative to "${targetDir}")`);
562
+ log(` (Using extension mode: ${pathExtFilter})`);
563
+ const results = await processAllFiles({
564
+ srcDir: targetDir,
565
+ aliasToReplace: normalizedAlias,
566
+ extensionsToProcess: EXTENSIONS,
567
+ rootDir: targetDir,
568
+ pathExtFilter
569
+ });
570
+ if (results.length > 0) {
571
+ log("\n[convertImportsAliasToRelative] Summary of changes:");
572
+ for (const { file, changes } of results) {
573
+ const displayPath = relative(targetDir, file) || basename(file);
574
+ log(` in ${displayPath}:`);
575
+ for (const { from, to } of changes) {
576
+ log(` - ${from} \u2192 ${to}`);
577
+ }
578
+ }
579
+ } else {
580
+ }
581
+ log("Import path conversion process complete.");
582
+ return results;
583
+ }
584
+ async function convertImportsExt({
585
+ targetDir,
586
+ extFrom,
587
+ extTo
588
+ }) {
589
+ const fromExtStr = extFrom === "none" ? "" : `.${extFrom}`;
590
+ const toExtStr = extTo === "none" ? "" : `.${extTo}`;
591
+ const importRegex = new RegExp(
592
+ `(?:import\\s+(?:[\\s\\S]*?)\\s+from\\s+|import\\s*\\(\\s*)\\s*(['"])([^'"]+${fromExtStr.replace(".", "\\.")})(\\1)`,
593
+ "g"
594
+ );
595
+ try {
596
+ const entries = await fs.readdir(targetDir, { withFileTypes: true });
597
+ const results = [];
598
+ await Promise.all(
599
+ entries.map(async (entry) => {
600
+ const fullPath = join(targetDir, entry.name);
601
+ if (entry.isDirectory()) {
602
+ if (entry.name === "node_modules" || entry.name.startsWith(".")) {
603
+ return;
604
+ }
605
+ const subdirResults = await convertImportsExt({
606
+ targetDir: fullPath,
607
+ extFrom,
608
+ extTo
609
+ });
610
+ results.push(...subdirResults);
611
+ } else if (EXTENSIONS.includes(extname(entry.name))) {
612
+ const content = await fs.readFile(fullPath, "utf-8");
613
+ let updated = content;
614
+ const changes = [];
615
+ const matches = Array.from(content.matchAll(importRegex));
616
+ for (const match of matches) {
617
+ const quote = match[1];
618
+ const importPath = match[2];
619
+ let replacementPath;
620
+ if (extFrom === "none") {
621
+ replacementPath = importPath + toExtStr;
622
+ } else if (extTo === "none") {
623
+ replacementPath = importPath.slice(0, -fromExtStr.length);
624
+ } else {
625
+ replacementPath = importPath.slice(0, -fromExtStr.length) + toExtStr;
626
+ }
627
+ if (importPath === replacementPath) continue;
628
+ changes.push({ from: importPath, to: replacementPath });
629
+ const searchStr = `${quote}${importPath}${quote}`;
630
+ const replaceStr = `${quote}${replacementPath}${quote}`;
631
+ updated = replaceAllInString(updated, searchStr, replaceStr);
632
+ }
633
+ if (content !== updated) {
634
+ await fs.writeFile(fullPath, updated);
635
+ log(`\u2713 processed: ${fullPath}`);
636
+ if (changes.length > 0) {
637
+ results.push({ file: fullPath, changes });
638
+ }
639
+ }
640
+ }
641
+ })
642
+ );
643
+ if (results.length > 0) {
644
+ log("\n[convertImportsExt] Summary of changes:");
645
+ for (const { file, changes } of results) {
646
+ const displayPath = relative(targetDir, file) || basename(file);
647
+ log(` in ${displayPath}:`);
648
+ for (const { from, to } of changes) {
649
+ log(` - ${from} \u2192 ${to}`);
650
+ }
651
+ }
652
+ } else {
653
+ }
654
+ return results;
655
+ } catch (error) {
656
+ log(
657
+ `error processing directory ${targetDir}: ${error instanceof Error ? error.message : String(error)}`
658
+ );
659
+ return [];
660
+ }
661
+ }
662
+ const _pathBase = {
3
663
  sep,
4
664
  normalize,
5
665
  join,
6
666
  resolve,
7
- normalizeString,
8
667
  isAbsolute,
9
- toNamespacedPath,
10
- extname,
11
- relative,
12
668
  dirname,
13
- format,
14
- basename,
15
- parse
16
- } from "./pathkit-impl/_path.js";
17
- import { delimiter, posix, win32 } from "./pathkit-impl/args-impl.js";
18
- import {
19
- normalizeAliases,
20
- resolveAlias,
21
- reverseResolveAlias,
22
- filename
23
- } from "./pathkit-impl/args-utils.js";
24
- export {
25
669
  basename,
26
- delimiter,
27
- dirname,
28
670
  extname,
29
- filename,
30
671
  format,
31
- isAbsolute,
32
- join,
33
- normalize,
34
- normalizeAliases,
35
- normalizeString,
36
- normalizeWindowsPath,
37
672
  parse,
38
- posix,
39
- relative,
40
- resolve,
41
- resolveAlias,
42
- reverseResolveAlias,
43
- sep,
44
673
  toNamespacedPath,
45
- win32
674
+ relative,
675
+ filename
676
+ };
677
+ const _platforms = {
678
+ posix: { ..._pathBase },
679
+ win32: {
680
+ ..._pathBase,
681
+ sep: BACK_SLASH,
682
+ delimiter: ";",
683
+ isAbsolute: (p) => {
684
+ if (typeof p !== "string") return false;
685
+ return /^[a-zA-Z]:[/\\]/.test(p) || /^[/\\]{2}/.test(p);
686
+ },
687
+ toNamespacedPath: (p) => {
688
+ if (typeof p !== "string" || p.length === 0) return p;
689
+ const resolved = resolve(p);
690
+ if (/^[a-zA-Z]:/.test(resolved)) {
691
+ return `\\\\?\\${resolved.replace(/\//g, BACK_SLASH)}`;
692
+ }
693
+ if (/^[/\\]{2}/.test(resolved)) {
694
+ return `\\\\?\\UNC\\${resolved.substring(2).replace(/\//g, BACK_SLASH)}`;
695
+ }
696
+ return p.replace(/\//g, BACK_SLASH);
697
+ }
698
+ }
699
+ };
700
+ const mix = (platformDefault = "currentSystem") => {
701
+ const actualDefault = platformDefault === "currentSystem" ? globalThis.process?.platform === "win32" ? "win32" : "posix" : platformDefault;
702
+ const defaultPathObject = actualDefault === "win32" ? _platforms.win32 : _platforms.posix;
703
+ return new Proxy(defaultPathObject, {
704
+ get(target, prop) {
705
+ if (prop === "delimiter") return actualDefault === "win32" ? ";" : ":";
706
+ if (prop === "posix") return _platforms.posix;
707
+ if (prop === "win32") return _platforms.win32;
708
+ if (prop in target) {
709
+ return target[prop];
710
+ }
711
+ if (prop in _pathBase) {
712
+ return _pathBase[prop];
713
+ }
714
+ return void 0;
715
+ }
716
+ });
46
717
  };
47
- const pathObj = {
718
+ const path = mix();
719
+ const win32 = _platforms.win32;
720
+ const delimiter = globalThis.process?.platform === "win32" ? ";" : ":";
721
+ export {
722
+ _pathBase as posix,
723
+ win32,
48
724
  basename,
49
725
  delimiter,
50
726
  dirname,
@@ -54,17 +730,19 @@ const pathObj = {
54
730
  isAbsolute,
55
731
  join,
56
732
  normalize,
57
- normalizeAliases,
58
- normalizeString,
59
- normalizeWindowsPath,
60
733
  parse,
61
- posix,
62
734
  relative,
63
735
  resolve,
64
- resolveAlias,
65
- reverseResolveAlias,
66
736
  sep,
67
737
  toNamespacedPath,
68
- win32
738
+ normalizeAliases,
739
+ resolveAlias,
740
+ reverseResolveAlias,
741
+ normalizeWindowsPath,
742
+ cleanDirs,
743
+ copyDir,
744
+ convertStringAliasRelative,
745
+ convertImportsAliasToRelative,
746
+ convertImportsExt
69
747
  };
70
- export default pathObj;
748
+ export default path;