UNPKG

resolve.imports

Version:
66 lines (65 loc) 2.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolve = void 0; const pattern_key_compare_1 = require("pattern-key-compare"); const errors_js_1 = require("./errors.js"); /** * Resolve an import specifier based on the `imports` field in `package.json`. * * @param manifest of package.json * @param specifier import specifier * @return resolved specifier or undefined if not found * @see https://nodejs.org/api/packages.html#subpath-imports */ function resolve(manifest, specifier, options) { (0, errors_js_1.assert)(specifier.startsWith('#'), 'import specifier must start with #'); if (specifier === '#' || specifier === '#/') throw new errors_js_1.ERR_INVALID_MODULE_SPECIFIER(specifier, `is not a valid internal imports specifier name`, manifest.base); if (manifest.content.imports) { const conditions = new Set(options?.conditions ?? []); const matched = manifest.content.imports[specifier]; if (matched) { return noRecursive(resolvePackagePattern(matched, conditions)); } const expansionKeys = getExpensionKeys(Object.keys(manifest.content.imports)); for (const key of expansionKeys) { const keyParts = key.split('*'); const [prefix, suffix] = keyParts; if (specifier.startsWith(prefix)) { const replacer = resolvePackagePattern(manifest.content.imports[key], conditions); if (replacer) return noRecursive(replacePattern(replacer)); } function replacePattern(replacer) { const toKeep = suffix ? specifier.slice(prefix.length, -suffix.length) : specifier.slice(prefix.length); return replacer.replace(/\*/g, toKeep); } } } throw new errors_js_1.ERR_PACKAGE_IMPORT_NOT_DEFINED(specifier, manifest.path, manifest.base); } exports.resolve = resolve; function resolvePackagePattern(map, conditions) { if (typeof map === 'string') return map; if (Array.isArray(map)) { for (const item of map) { const result = resolvePackagePattern(item, conditions); if (result) return result; } return undefined; } for (const key of Object.keys(map)) { if (conditions.has(key)) return resolvePackagePattern(map[key], conditions); } return map.default; } function noRecursive(value) { (0, errors_js_1.assert)(!value?.startsWith('#'), 'recursive imports are not allowed'); return value; } function getExpensionKeys(keys) { return keys.filter(k => k.indexOf('*') >= 0).sort(pattern_key_compare_1.patternKeyCompare); }