| |
| |
| |
| |
| |
| "use strict"; |
|
|
| const DescriptionFileUtils = require("./DescriptionFileUtils"); |
|
|
| |
| |
| |
| |
|
|
| const slashCode = "/".charCodeAt(0); |
|
|
| |
| |
| const NO_SELF_REF = Symbol("NoSelfRef"); |
|
|
| module.exports = class SelfReferencePlugin { |
| |
| |
| |
| |
| |
| constructor(source, fieldNamePath, target) { |
| this.source = source; |
| this.target = target; |
| this.fieldName = fieldNamePath; |
| |
| |
| |
| |
| |
| |
| this._nameCache = new WeakMap(); |
| } |
|
|
| |
| |
| |
| |
| apply(resolver) { |
| const target = resolver.ensureHook(this.target); |
| resolver |
| .getHook(this.source) |
| .tapAsync("SelfReferencePlugin", (request, resolveContext, callback) => { |
| if (!request.descriptionFileData) return callback(); |
|
|
| const req = request.request; |
| if (!req) return callback(); |
|
|
| const { descriptionFileData } = request; |
| let name = this._nameCache.get(descriptionFileData); |
| if (name === undefined) { |
| |
| const exportsField = DescriptionFileUtils.getField( |
| descriptionFileData, |
| this.fieldName, |
| ); |
| if (!exportsField) { |
| this._nameCache.set(descriptionFileData, NO_SELF_REF); |
| return callback(); |
| } |
| const rawName = DescriptionFileUtils.getField( |
| descriptionFileData, |
| "name", |
| ); |
| if (typeof rawName !== "string") { |
| this._nameCache.set(descriptionFileData, NO_SELF_REF); |
| return callback(); |
| } |
| name = rawName; |
| this._nameCache.set(descriptionFileData, name); |
| } else if (name === NO_SELF_REF) { |
| return callback(); |
| } |
|
|
| if ( |
| req.startsWith(name) && |
| (req.length === name.length || |
| req.charCodeAt(name.length) === slashCode) |
| ) { |
| const remainingRequest = `.${req.slice(name.length)}`; |
| |
| const obj = { |
| ...request, |
| request: remainingRequest, |
| path: (request.descriptionFileRoot), |
| relativePath: ".", |
| }; |
|
|
| resolver.doResolve( |
| target, |
| obj, |
| "self reference", |
| resolveContext, |
| callback, |
| ); |
| } else { |
| return callback(); |
| } |
| }); |
| } |
| }; |
|
|