aboutsummaryrefslogtreecommitdiff
path: root/packages/config/vite/relAlias.ts
blob: 1a502b510b5b198de084ef34ab205141195722b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import fs from 'fs/promises';
import path from 'path';
import { Alias } from 'vite';

const projectPath = path.resolve(__dirname, '../../../');
const pkgJsonCache = new Map();

const SRC_DIR_PATH = `${path.sep}src${path.sep}`;

const resolver: Alias = {
	find: /^(~\/.+)/,
	replacement: '$1',
	async customResolver(source, importer) {
		let root: null | string = null;

		if (importer) importer = path.normalize(importer);

		const [_, sourcePath] = source.split('~/');

		const relativeImporter = importer?.replace(projectPath, '');
		if (relativeImporter && relativeImporter.includes(SRC_DIR_PATH)) {
			const [pkg] = relativeImporter.split(SRC_DIR_PATH);
			root = path.join(projectPath, pkg, 'src');
		} else if (importer) {
			const pathObj = path.parse(importer);

			let parent = pathObj.dir;
			while (parent !== pathObj.root) {
				parent = path.dirname(parent);

				let hasPkgJson = pkgJsonCache.get(parent);

				if (hasPkgJson === undefined)
					try {
						await fs.stat(path.join(parent, 'package.json'));
						pkgJsonCache.set(parent, (hasPkgJson = true));
					} catch {
						pkgJsonCache.set(parent, (hasPkgJson = false));
					}

				if (hasPkgJson) {
					root = parent;
					break;
				}
			}

			if (root === null)
				throw new Error(`Failed to resolve import path ${source} in file ${importer}`);
		} else {
			throw new Error(`Failed to resolve import path ${source} in file ${importer}`);
		}

		const absolutePath = path.join(root, sourcePath);

		const folderItems = await fs.readdir(path.join(absolutePath, '..'));

		const item = folderItems.find((i) => i.startsWith(sourcePath.split('/').at(-1)!))!;

		const fullPath = absolutePath + path.extname(item);

		const stats = await fs.stat(fullPath);

		if (stats.isDirectory()) {
			const directoryItems = await fs.readdir(absolutePath + path.extname(item));

			const indexFile = directoryItems.find((i) => i.startsWith('index'));
			if (!indexFile)
				throw new Error(`Failed to resolve import path ${source} in file ${importer}`);

			return path.join(absolutePath, indexFile);
		} else {
			return fullPath;
		}
	}
};

export default resolver;