-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The main change is that `resolve` now returns a URL for files that do not exist (such as `/whatever`) and for protocols that are unknown (such as `xss:alert(1)`). Given that we used to fail and not anymore, and that resolving only makes sense if you try to load afterwards, which will now perhaps throw, I don’t think it’s perhaps *technically* breaking. Commits with particular interest: 54e0cb5051886fd6f9c8219561554d0481e998c2 85301803e1788f6918917b44179ab9d138801e40 9c683204dbd63e9a516213d75cb32be1236adc8f 02926d3c6aaf70eba6d80423beb2d5df97e1ebc7 08ae8401f187051d98942d7b0d213e276e63a86f 951da5282c7b00eb86a989336d628218fb2df057 3ce51ae9c08fb1281591f563568d760192ea07a2 ccada8bccc3ec90fa895b9f19ae37a460c318f60 a2a8e31cbc441cd2b513227be09d90568aa77b5a ffb1929b6a9b42d9c751723b842a4405154f0d15 6aafb6fbbb0d697fe6b696020a986f46859b480f 569267d04832345e0984049ba50dd5587db7c13a 645b788bea836a2121fd49b935ae204dee36a9c0 dcaded006eb78dc23703ed537b34a503df6f6417
- Loading branch information
Showing
10 changed files
with
284 additions
and
302 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,129 +1,55 @@ | ||
// Manually “tree shaken” from: | ||
// <https://github.com/nodejs/node/blob/3e74590/lib/internal/modules/esm/package_config.js> | ||
// Last checked on: Apr 24, 2023. | ||
// <https://github.com/nodejs/node/blob/45f5c9b/lib/internal/modules/esm/package_config.js> | ||
// Last checked on: Nov 2, 2023. | ||
|
||
/** | ||
* @typedef {import('./errors.js').ErrnoException} ErrnoException | ||
* | ||
* @typedef {'commonjs' | 'module' | 'none'} PackageType | ||
* | ||
* @typedef PackageConfig | ||
* @property {string} pjsonPath | ||
* @property {boolean} exists | ||
* @property {string | undefined} main | ||
* @property {string | undefined} name | ||
* @property {PackageType} type | ||
* @property {Record<string, unknown> | undefined} exports | ||
* @property {Record<string, unknown> | undefined} imports | ||
* @typedef {import('./package-json-reader.js').PackageConfig} PackageConfig | ||
*/ | ||
|
||
import {URL, fileURLToPath} from 'node:url' | ||
import {codes} from './errors.js' | ||
import packageJsonReader from './package-json-reader.js' | ||
|
||
const {ERR_INVALID_PACKAGE_CONFIG} = codes | ||
|
||
/** @type {Map<string, PackageConfig>} */ | ||
const packageJsonCache = new Map() | ||
|
||
/** | ||
* @param {string} path | ||
* @param {URL | string} specifier Note: `specifier` is actually optional, not base. | ||
* @param {URL} [base] | ||
* @returns {PackageConfig} | ||
*/ | ||
export function getPackageConfig(path, specifier, base) { | ||
const existing = packageJsonCache.get(path) | ||
if (existing !== undefined) { | ||
return existing | ||
} | ||
|
||
const source = packageJsonReader.read(path).string | ||
|
||
if (source === undefined) { | ||
/** @type {PackageConfig} */ | ||
const packageConfig = { | ||
pjsonPath: path, | ||
exists: false, | ||
main: undefined, | ||
name: undefined, | ||
type: 'none', | ||
exports: undefined, | ||
imports: undefined | ||
} | ||
packageJsonCache.set(path, packageConfig) | ||
return packageConfig | ||
} | ||
|
||
/** @type {Record<string, unknown>} */ | ||
let packageJson | ||
try { | ||
packageJson = JSON.parse(source) | ||
} catch (error) { | ||
const exception = /** @type {ErrnoException} */ (error) | ||
|
||
throw new ERR_INVALID_PACKAGE_CONFIG( | ||
path, | ||
(base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier), | ||
exception.message | ||
) | ||
} | ||
|
||
const {exports, imports, main, name, type} = packageJson | ||
|
||
/** @type {PackageConfig} */ | ||
const packageConfig = { | ||
pjsonPath: path, | ||
exists: true, | ||
main: typeof main === 'string' ? main : undefined, | ||
name: typeof name === 'string' ? name : undefined, | ||
type: type === 'module' || type === 'commonjs' ? type : 'none', | ||
// @ts-expect-error Assume `Record<string, unknown>`. | ||
exports, | ||
// @ts-expect-error Assume `Record<string, unknown>`. | ||
imports: imports && typeof imports === 'object' ? imports : undefined | ||
} | ||
packageJsonCache.set(path, packageConfig) | ||
return packageConfig | ||
} | ||
|
||
/** | ||
* @param {URL} resolved | ||
* @param {URL | string} resolved | ||
* @returns {PackageConfig} | ||
*/ | ||
export function getPackageScopeConfig(resolved) { | ||
let packageJsonUrl = new URL('package.json', resolved) | ||
let packageJSONUrl = new URL('package.json', resolved) | ||
|
||
while (true) { | ||
const packageJsonPath = packageJsonUrl.pathname | ||
|
||
if (packageJsonPath.endsWith('node_modules/package.json')) break | ||
const packageJSONPath = packageJSONUrl.pathname | ||
if (packageJSONPath.endsWith('node_modules/package.json')) { | ||
break | ||
} | ||
|
||
const packageConfig = getPackageConfig( | ||
fileURLToPath(packageJsonUrl), | ||
resolved | ||
const packageConfig = packageJsonReader.read( | ||
fileURLToPath(packageJSONUrl), | ||
{specifier: resolved} | ||
) | ||
if (packageConfig.exists) return packageConfig | ||
|
||
const lastPackageJsonUrl = packageJsonUrl | ||
packageJsonUrl = new URL('../package.json', packageJsonUrl) | ||
if (packageConfig.exists) { | ||
return packageConfig | ||
} | ||
|
||
const lastPackageJSONUrl = packageJSONUrl | ||
packageJSONUrl = new URL('../package.json', packageJSONUrl) | ||
|
||
// Terminates at root where ../package.json equals ../../package.json | ||
// (can't just check "/package.json" for Windows support). | ||
if (packageJsonUrl.pathname === lastPackageJsonUrl.pathname) break | ||
if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) { | ||
break | ||
} | ||
} | ||
|
||
const packageJsonPath = fileURLToPath(packageJsonUrl) | ||
/** @type {PackageConfig} */ | ||
const packageConfig = { | ||
pjsonPath: packageJsonPath, | ||
const packageJSONPath = fileURLToPath(packageJSONUrl) | ||
|
||
return { | ||
pjsonPath: packageJSONPath, | ||
exists: false, | ||
main: undefined, | ||
name: undefined, | ||
type: 'none', | ||
exports: undefined, | ||
imports: undefined | ||
} | ||
packageJsonCache.set(packageJsonPath, packageConfig) | ||
return packageConfig | ||
} |
Oops, something went wrong.