/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
'use strict';
// $FlowFixMe it exists!
const Module = require('module');
const path = require('path');
import type {ResolutionContext} from './types';
const builtinModules = new Set(
// $FlowFixMe "process.binding" exists
Module.builtinModules || Object.keys(process.binding('natives')),
);
module.exports = (pnp: any) => (
context: ResolutionContext,
request: string,
platform: string | null,
) => {
// We don't support builtin modules, so we force pnp to resolve those
// modules as regular npm packages by appending a `/` character
if (builtinModules.has(request)) {
request += '/';
}
const unqualifiedPath = pnp.resolveToUnqualified(
request,
context.originModulePath,
);
const baseExtensions = context.sourceExts.map(extension => `.${extension}`);
let finalExtensions = [...baseExtensions];
if (context.preferNativePlatform) {
finalExtensions = [
...baseExtensions.map(extension => `.native${extension}`),
...finalExtensions,
];
}
if (platform) {
// We must keep a const reference to make Flow happy
const p = platform;
finalExtensions = [
...baseExtensions.map(extension => `.${p}${extension}`),
...finalExtensions,
];
}
try {
return {
type: 'sourceFile',
filePath: pnp.resolveUnqualified(unqualifiedPath, {
extensions: finalExtensions,
}),
};
} catch (error) {
// Only catch the error if it was caused by the resolution process
if (error.code !== 'QUALIFIED_PATH_RESOLUTION_FAILED') {
throw error;
}
const dirname = path.dirname(unqualifiedPath);
const basename = path.basename(unqualifiedPath);
const assetResolutions = context.resolveAsset(dirname, basename, platform);
if (assetResolutions) {
return {
type: 'assetFiles',
filePaths: assetResolutions.map<string>(name => `${dirname}/${name}`),
};
} else {
throw error;
}
}
};