Adapt interface of node-haste duplicates

Summary: Adapts mocked / duplicated functionality from `node-haste` to match the new synchronous return types in the original.

Reviewed By: jeanlauliac

Differential Revision: D4819137

fbshipit-source-id: 183316adc3fae161ad9999bf72bccb8218ef8941
This commit is contained in:
David Aurelio 2017-04-03 09:55:28 -07:00 committed by Facebook Github Bot
parent 015700ea7c
commit 6bdc5e9f21
5 changed files with 82 additions and 78 deletions

View File

@ -24,9 +24,9 @@ module.exports = class Module {
constructor( constructor(
path: string, path: string,
moduleCache: ModuleCache, moduleCache: ModuleCache,
info: Promise<TransformedFile>, info: TransformedFile,
) { ) {
this.hasteID = info.then(({hasteID}) => hasteID); this.hasteID = Promise.resolve(info.hasteID);
this.moduleCache = moduleCache; this.moduleCache = moduleCache;
this.name = this.hasteID.then(name => name || getName(path)); this.name = this.hasteID.then(name => name || getName(path));
this.path = path; this.path = path;

View File

@ -16,22 +16,20 @@ const Package = require('./Package');
import type {PackageData, TransformedFile} from '../types.flow'; import type {PackageData, TransformedFile} from '../types.flow';
type GetFn<T> = (path: string) => Promise<T>;
type GetClosestPackageFn = (filePath: string) => ?string; type GetClosestPackageFn = (filePath: string) => ?string;
module.exports = class ModuleCache { module.exports = class ModuleCache {
_getClosestPackage: GetClosestPackageFn; _getClosestPackage: GetClosestPackageFn;
getPackageData: GetFn<PackageData>; getTransformedFile: string => TransformedFile;
getTransformedFile: GetFn<TransformedFile>;
modules: Map<string, Module>; modules: Map<string, Module>;
packages: Map<string, Package>; packages: Map<string, Package>;
constructor(getClosestPackage: GetClosestPackageFn, getTransformedFile: GetFn<TransformedFile>) { constructor(
getClosestPackage: GetClosestPackageFn,
getTransformedFile: string => TransformedFile,
) {
this._getClosestPackage = getClosestPackage; this._getClosestPackage = getClosestPackage;
this.getTransformedFile = getTransformedFile; this.getTransformedFile = getTransformedFile;
this.getPackageData = path => getTransformedFile(path).then(
f => f.package || Promise.reject(new Error(`"${path}" does not exist`))
);
this.modules = new Map(); this.modules = new Map();
this.packages = new Map(); this.packages = new Map();
} }
@ -58,6 +56,14 @@ module.exports = class ModuleCache {
return p; return p;
} }
getPackageData(path: string): PackageData {
const pkg = this.getTransformedFile(path).package;
if (!pkg) {
throw new Error(`"${path}" does not exist`);
}
return pkg;
}
getPackageOf(filePath: string) { getPackageOf(filePath: string) {
const candidate = this._getClosestPackage(filePath); const candidate = this._getClosestPackage(filePath);
return candidate != null ? this.getPackage(candidate) : null; return candidate != null ? this.getPackage(candidate) : null;

View File

@ -17,12 +17,12 @@ const path = require('path');
import type {PackageData} from '../types.flow'; import type {PackageData} from '../types.flow';
module.exports = class Package { module.exports = class Package {
data: Promise<PackageData>; data: PackageData;
path: string; path: string;
root: string; root: string;
type: 'Package'; type: 'Package';
constructor(packagePath: string, data: Promise<PackageData>) { constructor(packagePath: string, data: PackageData) {
this.data = data; this.data = data;
this.path = packagePath; this.path = packagePath;
this.root = path.dirname(packagePath); this.root = path.dirname(packagePath);
@ -31,80 +31,76 @@ module.exports = class Package {
getMain() { getMain() {
// Copied from node-haste/Package.js // Copied from node-haste/Package.js
return this.data.then(data => { const replacements = getReplacements(this.data);
const replacements = getReplacements(data); if (typeof replacements === 'string') {
if (typeof replacements === 'string') { return path.join(this.root, replacements);
return path.join(this.root, replacements); }
}
let main = getMain(data); let main = getMain(this.data);
if (replacements && typeof replacements === 'object') { if (replacements && typeof replacements === 'object') {
main = replacements[main] || main = replacements[main] ||
replacements[main + '.js'] || replacements[main + '.js'] ||
replacements[main + '.json'] || replacements[main + '.json'] ||
replacements[main.replace(/(\.js|\.json)$/, '')] || replacements[main.replace(/(\.js|\.json)$/, '')] ||
main; main;
} }
return path.join(this.root, main); return path.join(this.root, main);
});
} }
getName() { getName() {
return this.data.then(p => nullthrows(p.name)); return Promise.resolve(nullthrows(this.data.name));
} }
isHaste() { isHaste() {
return this.data.then(p => !!p.name); return Promise.resolve(!!this.data.name);
} }
redirectRequire(name: string) { redirectRequire(name: string) {
// Copied from node-haste/Package.js // Copied from node-haste/Package.js
return this.data.then(data => { const replacements = getReplacements(this.data);
const replacements = getReplacements(data);
if (!replacements || typeof replacements !== 'object') {
return name;
}
if (!path.isAbsolute(name)) {
const replacement = replacements[name];
// support exclude with "someDependency": false
return replacement === false
? false
: replacement || name;
}
let relPath = './' + path.relative(this.root, name);
if (path.sep !== '/') {
relPath = relPath.replace(new RegExp('\\' + path.sep, 'g'), '/');
}
let redirect = replacements[relPath];
// false is a valid value
if (redirect == null) {
redirect = replacements[relPath + '.js'];
if (redirect == null) {
redirect = replacements[relPath + '.json'];
}
}
// support exclude with "./someFile": false
if (redirect === false) {
return false;
}
if (redirect) {
return path.join(
this.root,
redirect
);
}
if (!replacements || typeof replacements !== 'object') {
return name; return name;
}); }
if (!path.isAbsolute(name)) {
const replacement = replacements[name];
// support exclude with "someDependency": false
return replacement === false
? false
: replacement || name;
}
let relPath = './' + path.relative(this.root, name);
if (path.sep !== '/') {
relPath = relPath.replace(new RegExp('\\' + path.sep, 'g'), '/');
}
let redirect = replacements[relPath];
// false is a valid value
if (redirect == null) {
redirect = replacements[relPath + '.js'];
if (redirect == null) {
redirect = replacements[relPath + '.json'];
}
}
// support exclude with "./someFile": false
if (redirect === false) {
return false;
}
if (redirect) {
return path.join(
this.root,
redirect
);
}
return name;
} }
}; };

View File

@ -33,14 +33,13 @@ export type Package = {
path: Path, path: Path,
root: Path, root: Path,
type: 'Package', type: 'Package',
getMain(): Promise<Path>, getMain(): Path,
getName(): Promise<ModuleID>, getName(): Promise<ModuleID>,
isHaste(): Promise<boolean>, isHaste(): Promise<boolean>,
redirectRequire(id: ModuleID): Promise<Path | false>, redirectRequire(id: ModuleID): Path | false,
}; };
// when changing this to `type`, the code does not typecheck any more export type ModuleCache = {
export interface ModuleCache {
getAssetModule(path: Path): Module, getAssetModule(path: Path): Module,
getModule(path: Path): Module, getModule(path: Path): Module,
getPackage(path: Path): Package, getPackage(path: Path): Package,

View File

@ -63,10 +63,13 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
transformedFiles, transformedFiles,
} = options; } = options;
const files = Object.keys(transformedFiles); const files = Object.keys(transformedFiles);
const getTransformedFile = function getTransformedFile(path) {
path => Promise.resolve( const result = transformedFiles[path];
transformedFiles[path] || Promise.reject(new Error(`"${path} does not exist`)) if (!result) {
); throw new Error(`"${path} does not exist`);
}
return result;
}
const helpers = new DependencyGraphHelpers({ const helpers = new DependencyGraphHelpers({
assetExts, assetExts,