2016-10-20 00:12:21 -07:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2013-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
2016-11-02 13:40:48 -07:00
|
|
|
*
|
|
|
|
* @flow
|
2016-10-20 00:12:21 -07:00
|
|
|
*/
|
|
|
|
|
2016-07-29 11:00:08 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const isAbsolutePath = require('absolute-path');
|
2016-10-20 00:12:21 -07:00
|
|
|
const path = require('path');
|
2016-07-29 11:00:08 -07:00
|
|
|
|
2016-11-04 10:42:41 -07:00
|
|
|
import type Cache from './Cache';
|
|
|
|
import type FastFs from './fastfs';
|
2016-11-02 13:40:48 -07:00
|
|
|
|
2016-07-29 11:00:08 -07:00
|
|
|
class Package {
|
|
|
|
|
2016-11-02 13:40:48 -07:00
|
|
|
path: string;
|
|
|
|
root: string;
|
|
|
|
_fastfs: FastFs;
|
|
|
|
type: string;
|
|
|
|
_cache: Cache;
|
|
|
|
|
|
|
|
_reading: Promise<{
|
|
|
|
name: string,
|
|
|
|
'react-native': mixed,
|
|
|
|
browser: mixed,
|
|
|
|
main: ?string,
|
|
|
|
}>;
|
|
|
|
|
|
|
|
constructor({ file, fastfs, cache }: {
|
|
|
|
file: string,
|
|
|
|
fastfs: FastFs,
|
|
|
|
cache: Cache,
|
|
|
|
}) {
|
2016-07-29 11:00:08 -07:00
|
|
|
this.path = path.resolve(file);
|
|
|
|
this.root = path.dirname(this.path);
|
|
|
|
this._fastfs = fastfs;
|
|
|
|
this.type = 'Package';
|
|
|
|
this._cache = cache;
|
|
|
|
}
|
|
|
|
|
|
|
|
getMain() {
|
|
|
|
return this.read().then(json => {
|
|
|
|
var replacements = getReplacements(json);
|
|
|
|
if (typeof replacements === 'string') {
|
|
|
|
return path.join(this.root, replacements);
|
|
|
|
}
|
|
|
|
|
|
|
|
let main = json.main || 'index';
|
|
|
|
|
|
|
|
if (replacements && typeof replacements === 'object') {
|
|
|
|
main = replacements[main] ||
|
|
|
|
replacements[main + '.js'] ||
|
|
|
|
replacements[main + '.json'] ||
|
|
|
|
replacements[main.replace(/(\.js|\.json)$/, '')] ||
|
|
|
|
main;
|
|
|
|
}
|
|
|
|
|
2016-11-02 13:40:48 -07:00
|
|
|
/* $FlowFixMe: `getReplacements` doesn't validate the return value. */
|
2016-07-29 11:00:08 -07:00
|
|
|
return path.join(this.root, main);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
isHaste() {
|
|
|
|
return this._cache.get(this.path, 'package-haste', () =>
|
|
|
|
this.read().then(json => !!json.name)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-11-04 10:42:41 -07:00
|
|
|
getName(): Promise<string> {
|
2016-07-29 11:00:08 -07:00
|
|
|
return this._cache.get(this.path, 'package-name', () =>
|
|
|
|
this.read().then(json => json.name)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidate() {
|
|
|
|
this._cache.invalidate(this.path);
|
|
|
|
}
|
|
|
|
|
2016-11-02 13:40:48 -07:00
|
|
|
redirectRequire(name: string) {
|
2016-07-29 11:00:08 -07:00
|
|
|
return this.read().then(json => {
|
|
|
|
var replacements = getReplacements(json);
|
|
|
|
|
|
|
|
if (!replacements || typeof replacements !== 'object') {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2016-09-06 08:52:17 -07:00
|
|
|
if (!isAbsolutePath(name)) {
|
2016-07-29 11:00:08 -07:00
|
|
|
const replacement = replacements[name];
|
|
|
|
// support exclude with "someDependency": false
|
|
|
|
return replacement === false
|
|
|
|
? false
|
|
|
|
: replacement || name;
|
|
|
|
}
|
|
|
|
|
2016-09-06 08:52:17 -07:00
|
|
|
let relPath = './' + path.relative(this.root, name);
|
|
|
|
if (path.sep !== '/') {
|
|
|
|
relPath = relPath.replace(path.sep, '/');
|
2016-07-29 11:00:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
2016-11-02 13:40:48 -07:00
|
|
|
/* $FlowFixMe: `getReplacements` doesn't validate the return value. */
|
2016-07-29 11:00:08 -07:00
|
|
|
redirect
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return name;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
read() {
|
|
|
|
if (!this._reading) {
|
|
|
|
this._reading = this._fastfs.readFile(this.path)
|
|
|
|
.then(jsonStr => JSON.parse(jsonStr));
|
|
|
|
}
|
|
|
|
|
|
|
|
return this._reading;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getReplacements(pkg) {
|
|
|
|
let rn = pkg['react-native'];
|
|
|
|
let browser = pkg.browser;
|
|
|
|
if (rn == null) {
|
|
|
|
return browser;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (browser == null) {
|
|
|
|
return rn;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof rn === 'string') {
|
2016-11-02 13:40:48 -07:00
|
|
|
/* $FlowFixMe: It is likely unsafe to assume all packages would
|
|
|
|
* contain a "main" */
|
2016-07-29 11:00:08 -07:00
|
|
|
rn = { [pkg.main]: rn };
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof browser === 'string') {
|
2016-11-02 13:40:48 -07:00
|
|
|
/* $FlowFixMe: It is likely unsafe to assume all packages would
|
|
|
|
* contain a "main" */
|
2016-07-29 11:00:08 -07:00
|
|
|
browser = { [pkg.main]: browser };
|
|
|
|
}
|
|
|
|
|
|
|
|
// merge with "browser" as default,
|
|
|
|
// "react-native" as override
|
|
|
|
return { ...browser, ...rn };
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Package;
|