|
/** |
|
* Copyright (c) 2015-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. |
|
*/ |
|
'use strict'; |
|
|
|
const Module = require('./Module'); |
|
const path = require('path'); |
|
|
|
RegExp.escape = s => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); |
|
|
|
class GlobModule extends Module { |
|
|
|
constructor(...args) { |
|
super(...args); |
|
} |
|
|
|
isHaste() { |
|
return Promise.resolve(false); |
|
} |
|
|
|
getCode(transformOptions) { |
|
return this.read(transformOptions).then(({code}) => code); |
|
} |
|
|
|
getMap(transformOptions) { |
|
return Promise.resolve(null); |
|
} |
|
|
|
getName() { |
|
return Promise.resolve(this.path); |
|
} |
|
|
|
getPackage() { |
|
return null; |
|
} |
|
|
|
getDependenciesSync() { |
|
const [, dir, file] = this.path.match(/(.*)\/([^/]+)$/); |
|
const pattern = '^' + RegExp.escape(file).replace(/\\\*/g, '([^/.]+)') + '$'; |
|
const matches = this._fastfs.matches(dir, pattern); |
|
const dependencies = matches.map(x => { |
|
return '.' + x.slice(dir.length); |
|
}); |
|
return dependencies; |
|
} |
|
|
|
getDependencies(transformOptions) { |
|
return Promise.resolve(this.getDependenciesSync()); |
|
} |
|
|
|
invalidate() {} |
|
|
|
read(transformOptions) { |
|
const dependencies = this.getDependenciesSync(); |
|
const filenamePattern = /\/([^/.]*).[^/.]+$/; |
|
|
|
const exportObjectEntries = dependencies.map(name => { |
|
const match = name.match(filenamePattern); |
|
if (match) { |
|
const filename = match[1]; |
|
return ` '${filename}': require('${name}'),\n`; |
|
} else { |
|
return ''; |
|
} |
|
}) |
|
.join(''); |
|
const source = `module.exports = {\n${exportObjectEntries}\n};`; |
|
|
|
const transformCode = this._transformCode; |
|
const codePromise = transformCode |
|
? transformCode(this, source, transformOptions) |
|
: Promise.resolve({code: source}); |
|
|
|
return codePromise.then(result => { |
|
return { |
|
...result, |
|
source, |
|
id: undefined, |
|
}; |
|
}); |
|
} |
|
|
|
hash() { |
|
return `Module : ${this.path}`; |
|
} |
|
|
|
isJSON() { |
|
return false; |
|
} |
|
|
|
isAsset() { |
|
return false; |
|
} |
|
|
|
isPolyfill() { |
|
return false; |
|
} |
|
|
|
isAsset_DEPRECATED() { |
|
return false; |
|
} |
|
|
|
toJSON() { |
|
return { |
|
hash: this.hash(), |
|
isJSON: this.isJSON(), |
|
isAsset: this.isAsset(), |
|
isAsset_DEPRECATED: this.isAsset_DEPRECATED(), |
|
type: this.type, |
|
path: this.path, |
|
}; |
|
} |
|
} |
|
|
|
const isGlob = file => file.indexOf('*') !== -1; |
|
|
|
const getGlobModule = (moduleCache, filePath) => { |
|
if (!moduleCache._moduleCache[filePath]) { |
|
moduleCache._moduleCache[filePath] = new GlobModule({ |
|
file: filePath, |
|
fastfs: moduleCache._fastfs, |
|
moduleCache: moduleCache, |
|
cache: moduleCache._cache, |
|
extractor: moduleCache._extractRequires, |
|
transformCode: moduleCache._transformCode, |
|
depGraphHelpers: moduleCache._depGraphHelpers, |
|
options: moduleCache._moduleOptions, |
|
}); |
|
} |
|
return moduleCache._moduleCache[filePath]; |
|
}; |
|
|
|
GlobModule.getGlobModule = (moduleCache, fromModule, toModule) => { |
|
if (isGlob(toModule)) { |
|
const basedir = path.dirname(fromModule.path); |
|
const modulepath = toModule.slice('glob!'.length); |
|
const filename = path.join(basedir, modulepath); |
|
return getGlobModule(moduleCache, filename); |
|
} else { |
|
if (toModule.indexOf('*') !== -1) { |
|
throw new Error(`You most likely forgot to prefix the file '${toModule}' with 'glob!' in ${fromModule.path}`); |
|
} |
|
} |
|
}; |
|
|
|
module.exports = GlobModule; |