Skip to content

Commit 4df59bc

Browse files
aduh95danielleadams
authored andcommitted
module: add some typings to internal/modules/esm/resolve
PR-URL: #39504 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
1 parent 016b7ba commit 4df59bc

File tree

1 file changed

+121
-10
lines changed

1 file changed

+121
-10
lines changed

lib/internal/modules/esm/resolve.js

Lines changed: 121 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,26 @@ const userConditions = getOptionValue('--conditions');
5959
const DEFAULT_CONDITIONS = ObjectFreeze(['node', 'import', ...userConditions]);
6060
const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS);
6161

62+
/**
63+
* @typedef {string | string[] | Record<string, unknown>} Exports
64+
* @typedef {'module' | 'commonjs'} PackageType
65+
* @typedef {{
66+
* exports?: ExportConfig;
67+
* name?: string;
68+
* main?: string;
69+
* type?: PackageType;
70+
* }} PackageConfig
71+
*/
72+
6273
const emittedPackageWarnings = new SafeSet();
74+
75+
/**
76+
* @param {string} match
77+
* @param {URL} pjsonUrl
78+
* @param {boolean} isExports
79+
* @param {string | URL | undefined} base
80+
* @returns {void}
81+
*/
6382
function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) {
6483
const pjsonPath = fileURLToPath(pjsonUrl);
6584

@@ -76,6 +95,13 @@ function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) {
7695
);
7796
}
7897

98+
/**
99+
* @param {URL} url
100+
* @param {URL} packageJSONUrl
101+
* @param {string | URL | undefined} base
102+
* @param {string} main
103+
* @returns
104+
*/
79105
function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) {
80106
const { format } = defaultGetFormat(url);
81107
if (format !== 'module')
@@ -104,6 +130,10 @@ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) {
104130
);
105131
}
106132

133+
/**
134+
* @param {string[]} [conditions]
135+
* @returns {Set<string>}
136+
*/
107137
function getConditionsSet(conditions) {
108138
if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) {
109139
if (!ArrayIsArray(conditions)) {
@@ -118,9 +148,19 @@ function getConditionsSet(conditions) {
118148
const realpathCache = new SafeMap();
119149
const packageJSONCache = new SafeMap(); /* string -> PackageConfig */
120150

151+
/**
152+
* @param {string | URL} path
153+
* @returns {import('fs').Stats}
154+
*/
121155
const tryStatSync =
122156
(path) => statSync(path, { throwIfNoEntry: false }) ?? new Stats();
123157

158+
/**
159+
* @param {string} path
160+
* @param {string} specifier
161+
* @param {string | URL | undefined} base
162+
* @returns {PackageConfig}
163+
*/
124164
function getPackageConfig(path, specifier, base) {
125165
const existing = packageJSONCache.get(path);
126166
if (existing !== undefined) {
@@ -173,6 +213,10 @@ function getPackageConfig(path, specifier, base) {
173213
return packageConfig;
174214
}
175215

216+
/**
217+
* @param {URL | string} resolved
218+
* @returns {PackageConfig}
219+
*/
176220
function getPackageScopeConfig(resolved) {
177221
let packageJSONUrl = new URL('./package.json', resolved);
178222
while (true) {
@@ -205,19 +249,25 @@ function getPackageScopeConfig(resolved) {
205249
}
206250

207251
/**
208-
* Legacy CommonJS main resolution:
209-
* 1. let M = pkg_url + (json main field)
210-
* 2. TRY(M, M.js, M.json, M.node)
211-
* 3. TRY(M/index.js, M/index.json, M/index.node)
212-
* 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node)
213-
* 5. NOT_FOUND
214252
* @param {string | URL} url
215253
* @returns {boolean}
216254
*/
217255
function fileExists(url) {
218256
return statSync(url, { throwIfNoEntry: false })?.isFile() ?? false;
219257
}
220258

259+
/**
260+
* Legacy CommonJS main resolution:
261+
* 1. let M = pkg_url + (json main field)
262+
* 2. TRY(M, M.js, M.json, M.node)
263+
* 3. TRY(M/index.js, M/index.json, M/index.node)
264+
* 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node)
265+
* 5. NOT_FOUND
266+
* @param {URL} packageJSONUrl
267+
* @param {PackageConfig} packageConfig
268+
* @param {string | URL | undefined} base
269+
* @returns {URL}
270+
*/
221271
function legacyMainResolve(packageJSONUrl, packageConfig, base) {
222272
let guess;
223273
if (packageConfig.main !== undefined) {
@@ -259,12 +309,21 @@ function legacyMainResolve(packageJSONUrl, packageConfig, base) {
259309
fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base));
260310
}
261311

312+
/**
313+
* @param {URL} search
314+
* @returns {URL | undefined}
315+
*/
262316
function resolveExtensionsWithTryExactName(search) {
263317
if (fileExists(search)) return search;
264318
return resolveExtensions(search);
265319
}
266320

267321
const extensions = ['.js', '.json', '.node', '.mjs'];
322+
323+
/**
324+
* @param {URL} search
325+
* @returns {URL | undefined}
326+
*/
268327
function resolveExtensions(search) {
269328
for (let i = 0; i < extensions.length; i++) {
270329
const extension = extensions[i];
@@ -274,6 +333,10 @@ function resolveExtensions(search) {
274333
return undefined;
275334
}
276335

336+
/**
337+
* @param {URL} search
338+
* @returns {URL | undefined}
339+
*/
277340
function resolveDirectoryEntry(search) {
278341
const dirPath = fileURLToPath(search);
279342
const pkgJsonPath = resolve(dirPath, 'package.json');
@@ -291,6 +354,11 @@ function resolveDirectoryEntry(search) {
291354
}
292355

293356
const encodedSepRegEx = /%2F|%2C/i;
357+
/**
358+
* @param {URL} resolved
359+
* @param {string | URL | undefined} base
360+
* @returns {URL | undefined}
361+
*/
294362
function finalizeResolution(resolved, base) {
295363
if (RegExpPrototypeTest(encodedSepRegEx, resolved.pathname))
296364
throw new ERR_INVALID_MODULE_SPECIFIER(
@@ -325,18 +393,35 @@ function finalizeResolution(resolved, base) {
325393
return resolved;
326394
}
327395

396+
/**
397+
* @param {string} specifier
398+
* @param {URL} packageJSONUrl
399+
* @param {string | URL | undefined} base
400+
*/
328401
function throwImportNotDefined(specifier, packageJSONUrl, base) {
329402
throw new ERR_PACKAGE_IMPORT_NOT_DEFINED(
330403
specifier, packageJSONUrl && fileURLToPath(new URL('.', packageJSONUrl)),
331404
fileURLToPath(base));
332405
}
333406

407+
/**
408+
* @param {string} specifier
409+
* @param {URL} packageJSONUrl
410+
* @param {string | URL | undefined} base
411+
*/
334412
function throwExportsNotFound(subpath, packageJSONUrl, base) {
335413
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
336414
fileURLToPath(new URL('.', packageJSONUrl)), subpath,
337415
base && fileURLToPath(base));
338416
}
339417

418+
/**
419+
*
420+
* @param {string | URL} subpath
421+
* @param {URL} packageJSONUrl
422+
* @param {boolean} internal
423+
* @param {string | URL | undefined} base
424+
*/
340425
function throwInvalidSubpath(subpath, packageJSONUrl, internal, base) {
341426
const reason = `request is not a valid subpath for the "${internal ?
342427
'imports' : 'exports'}" resolution of ${fileURLToPath(packageJSONUrl)}`;
@@ -478,6 +563,13 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath,
478563
base);
479564
}
480565

566+
/**
567+
*
568+
* @param {Exports} exports
569+
* @param {URL} packageJSONUrl
570+
* @param {string | URL | undefined} base
571+
* @returns
572+
*/
481573
function isConditionalExportsMainSugar(exports, packageJSONUrl, base) {
482574
if (typeof exports === 'string' || ArrayIsArray(exports)) return true;
483575
if (typeof exports !== 'object' || exports === null) return false;
@@ -504,8 +596,8 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) {
504596
/**
505597
* @param {URL} packageJSONUrl
506598
* @param {string} packageSubpath
507-
* @param {object} packageConfig
508-
* @param {string} base
599+
* @param {PackageConfig} packageConfig
600+
* @param {string | URL | undefined} base
509601
* @param {Set<string>} conditions
510602
* @returns {URL}
511603
*/
@@ -560,6 +652,12 @@ function packageExportsResolve(
560652
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
561653
}
562654

655+
/**
656+
* @param {string} name
657+
* @param {string | URL | undefined} base
658+
* @param {Set<string>} conditions
659+
* @returns
660+
*/
563661
function packageImportsResolve(name, base, conditions) {
564662
if (name === '#' || StringPrototypeStartsWith(name, '#/')) {
565663
const reason = 'is not a valid internal imports specifier name';
@@ -615,11 +713,20 @@ function packageImportsResolve(name, base, conditions) {
615713
throwImportNotDefined(name, packageJSONUrl, base);
616714
}
617715

716+
/**
717+
* @param {URL} url
718+
* @returns {PackageType}
719+
*/
618720
function getPackageType(url) {
619721
const packageConfig = getPackageScopeConfig(url);
620722
return packageConfig.type;
621723
}
622724

725+
/**
726+
* @param {string} specifier
727+
* @param {string | URL | undefined} base
728+
* @returns {{ packageName: string, packageSubpath: string, isScoped: boolean }}
729+
*/
623730
function parsePackageName(specifier, base) {
624731
let separatorIndex = StringPrototypeIndexOf(specifier, '/');
625732
let validPackageName = true;
@@ -659,7 +766,7 @@ function parsePackageName(specifier, base) {
659766

660767
/**
661768
* @param {string} specifier
662-
* @param {URL} base
769+
* @param {string | URL | undefined} base
663770
* @param {Set<string>} conditions
664771
* @returns {URL}
665772
*/
@@ -712,6 +819,10 @@ function packageResolve(specifier, base, conditions) {
712819
throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base));
713820
}
714821

822+
/**
823+
* @param {string} specifier
824+
* @returns {boolean}
825+
*/
715826
function isBareSpecifier(specifier) {
716827
return specifier[0] && specifier[0] !== '/' && specifier[0] !== '.';
717828
}
@@ -734,7 +845,7 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) {
734845

735846
/**
736847
* @param {string} specifier
737-
* @param {URL} base
848+
* @param {string | URL | undefined} base
738849
* @param {Set<string>} conditions
739850
* @returns {URL}
740851
*/

0 commit comments

Comments
 (0)