-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathutils.ts
87 lines (77 loc) · 3.1 KB
/
utils.ts
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
78
79
80
81
82
83
84
85
86
87
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { parseNodeModuleCachePath, getPackageNameVersionFromUrl } from "./parser";
import { cache, importmap, isDebuggingEnabled } from "./config";
import { logger } from "./logger";
/**
* ******************************************************
* UTILS 📦
* ------------------------------------------------------
* @description a collection of utility functions
* @summary a collection of utility functions
* which aren't reliant on each other (for easy testability)
*
* ******************************************************
*/
const log = logger({ file: "loader", isLogging: isDebuggingEnabled() });
export const ensureDirSync = (dirPath: string) => {
if (existsSync(dirPath)) return;
const parentDir = dirname(dirPath);
if (parentDir !== dirPath) ensureDirSync(parentDir);
mkdirSync(dirPath);
};
export const ensureFileSync = (path: string) => {
const dirPath = dirname(path);
if (!existsSync(dirPath)) ensureDirSync(dirPath);
try {
writeFileSync(path, "", { flag: "wx" });
} catch {
log.error(`ensureDirSync: Failed in creating ${path}`);
}
};
export const checkIfNodeOrFileProtocol = (modulePath: string) => {
const { protocol = "" } = new URL(modulePath);
const isNode = protocol === "node:";
const isFile = protocol === "file:";
return isNode || isFile;
};
export const resolveModulePath = (specifier: string, cacheMapPath: string): string | null => {
try {
const modulePath = importmap.resolve(specifier, cacheMapPath);
log.debug("resolveModulePath:", { modulePath });
return modulePath;
} catch {
/*
If a module is not found in the importmap, we should just let the loader to skip it.
- Users might have installed it using `npm`.
- It can be a node-js dependency. (e.g. `assert`). We detect builtins using `node:` protocol.
But it is still not widely adopted yet.
*/
log.debug(`Failed in resolving ${specifier} in ${cacheMapPath}`);
return null;
}
};
export const resolveNodeModuleCachePath = async (modulePath: string) => {
try {
const { name, version, file = "" } = getPackageNameVersionFromUrl(modulePath);
const nodeModuleCachePath = join(cache, `${name}@${version}`, file);
log.debug("resolveNodeModuleCachePath:", { nodeModuleCachePath });
return nodeModuleCachePath;
} catch (err) {
log.error("resolveNodeModuleCachePath:", err);
return;
}
};
export const resolveParsedModulePath = async (modulePath: string, nodeModuleCachePath: string) => {
try {
const parsedNodeModuleCachePath = await parseNodeModuleCachePath(modulePath, nodeModuleCachePath);
log.debug("resolveParsedModulePath:", { nodeModuleCachePath, parsedNodeModuleCachePath });
return parsedNodeModuleCachePath;
} catch (err) {
log.error("resolveParsedModulePath:", err);
return;
}
};
export const getVersion = (urlParts: string[]) => (index: number) => urlParts?.[index]?.split("/")?.[0] || "";
export const getLastPart = (part: string, char: string) =>
(part?.length && char && part?.split(char)?.reverse()[0]) || "";