UNPKG

ember-auto-import

Version:
193 lines 10.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _AutoImportResolverPlugin_instances, _AutoImportResolverPlugin_appRoot, _AutoImportResolverPlugin_v2AddonResolver, _AutoImportResolverPlugin_packageCache, _AutoImportResolverPlugin_resolve; Object.defineProperty(exports, "__esModule", { value: true }); exports.AutoImportResolverPlugin = void 0; const path_1 = require("path"); const module_request_1 = require("./module-request"); const shared_internals_1 = require("@embroider/shared-internals"); class AutoImportResolverPlugin { constructor(appRoot, v2AddonResolver) { _AutoImportResolverPlugin_instances.add(this); _AutoImportResolverPlugin_appRoot.set(this, void 0); _AutoImportResolverPlugin_v2AddonResolver.set(this, void 0); __classPrivateFieldSet(this, _AutoImportResolverPlugin_appRoot, appRoot, "f"); __classPrivateFieldSet(this, _AutoImportResolverPlugin_v2AddonResolver, v2AddonResolver, "f"); } apply(compiler) { compiler.hooks.normalModuleFactory.tap('ember-auto-import', (nmf) => { let defaultResolve = getDefaultResolveHook(nmf.hooks.resolve.taps); nmf.hooks.resolve.tapAsync({ name: 'ember-auto-import', stage: 50 }, (state, callback) => { let request = module_request_1.ModuleRequest.create(WebpackRequestAdapter.create, { resolveFunction: defaultResolve, state, }); if (!request) { defaultResolve(state, callback); return; } __classPrivateFieldGet(this, _AutoImportResolverPlugin_instances, "m", _AutoImportResolverPlugin_resolve).call(this, request).then((resolution) => { switch (resolution.type) { case 'not_found': callback(resolution.err); break; case 'found': callback(null, undefined); break; default: throw assertNever(resolution); } }, (err) => callback(err)); }); }); } } exports.AutoImportResolverPlugin = AutoImportResolverPlugin; _AutoImportResolverPlugin_appRoot = new WeakMap(), _AutoImportResolverPlugin_v2AddonResolver = new WeakMap(), _AutoImportResolverPlugin_instances = new WeakSet(), _AutoImportResolverPlugin_packageCache = function _AutoImportResolverPlugin_packageCache() { return shared_internals_1.PackageCache.shared('ember-auto-import', __classPrivateFieldGet(this, _AutoImportResolverPlugin_appRoot, "f")); }, _AutoImportResolverPlugin_resolve = function _AutoImportResolverPlugin_resolve(request) { return __awaiter(this, void 0, void 0, function* () { let renamedModule = __classPrivateFieldGet(this, _AutoImportResolverPlugin_v2AddonResolver, "f").handleRenaming(request.specifier); if (renamedModule !== request.specifier) { request = request.alias(renamedModule); } let requestedPackage = (0, shared_internals_1.packageName)(request.specifier); if (requestedPackage) { let pkg = __classPrivateFieldGet(this, _AutoImportResolverPlugin_instances, "m", _AutoImportResolverPlugin_packageCache).call(this).ownerOfFile(request.fromFile); if (pkg && !pkg.hasDependency(requestedPackage) && shared_internals_1.emberVirtualPeerDeps.has(requestedPackage)) { request = request.rehome((0, path_1.resolve)(__classPrivateFieldGet(this, _AutoImportResolverPlugin_appRoot, "f"), 'package.json')); } } return yield request.defaultResolve(); }); }; // Despite being absolutely riddled with way-too-powerful tap points, // webpack still doesn't succeed in making it possible to provide a // fallback to the default resolve hook in the NormalModuleFactory. So // instead we will find the default behavior and call it from our own tap, // giving us a chance to handle its failures. function getDefaultResolveHook( // eslint-disable-next-line @typescript-eslint/ban-types taps) { let { fn } = taps.find((t) => t.name === 'NormalModuleFactory'); return fn; } class WebpackRequestAdapter { static create({ resolveFunction, state, }) { let specifier = state.request; if (specifier.startsWith('!') // ignores internal webpack resolvers ) { return; } let fromFile; if (state.contextInfo.issuer) { fromFile = state.contextInfo.issuer; } if (!fromFile) { return; } return { initialState: { specifier, fromFile, meta: state.contextInfo._embroiderMeta, }, adapter: new WebpackRequestAdapter(resolveFunction, state), }; } constructor(resolveFunction, originalState) { this.resolveFunction = resolveFunction; this.originalState = originalState; } get debugType() { return 'webpack'; } // Webpack mostly relies on mutation to adjust requests. We could create a // whole new ResolveData instead, and that would allow defaultResolving to // happen, but for the output of that process to actually affect the // downstream code in Webpack we would still need to mutate the original // ResolveData with the results (primarily the `createData`). So since we // cannot avoid the mutation anyway, it seems best to do it earlier rather // than later, so that everything from here forward is "normal". // // Technically a NormalModuleLoader `resolve` hook *can* directly return a // Module, but that is not how the stock one works, and it would force us to // copy more of Webpack's default behaviors into the inside of our hook. Like, // we would need to invoke afterResolve, createModule, createModuleClass, etc, // just like webpack does if we wanted to produce a Module directly. // // So the mutation strategy is much less intrusive, even though it means there // is the risk of state leakage all over the place. // // We mitigate that risk by waiting until the last possible moment to apply // our desired ModuleRequest fields to the ResolveData. This means that as // requests evolve through the module-resolver they aren't actually all // mutating the shared state. Only when a request is allowed to bubble back // out to webpack does that happen. toWebpackResolveData(request) { let specifier = request.specifier; this.originalState.request = specifier; this.originalState.context = (0, path_1.dirname)(request.fromFile); this.originalState.contextInfo.issuer = request.fromFile; this.originalState.contextInfo._embroiderMeta = request.meta; if (request.resolvedTo && typeof request.resolvedTo !== 'function') { if (request.resolvedTo.type === 'found') { this.originalState.createData = request.resolvedTo.result; } } return this.originalState; } notFoundResponse(request) { let err = new Error(`module not found ${request.specifier}`); err.code = 'MODULE_NOT_FOUND'; return { type: 'not_found', err }; } resolve(request) { return __awaiter(this, void 0, void 0, function* () { return this._resolve(request); }); } _resolve(request) { return __awaiter(this, void 0, void 0, function* () { return yield new Promise((resolve) => this.resolveFunction(this.toWebpackResolveData(request), (err) => { if (err) { // unfortunately webpack doesn't let us distinguish between Not Found // and other unexpected exceptions here. resolve({ type: 'not_found', err }); } else { resolve({ type: 'found', result: this.originalState.createData, filename: this.originalState.createData.resource, }); } })); }); } } function assertNever(_value) { throw new Error(`not supposed to get here`); } //# sourceMappingURL=resolver-plugin.js.map