bit-bin
Version:
<a href="https://opensource.org/licenses/Apache-2.0"><img alt="apache" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a> <a href="https://github.com/teambit/bit/blob/master/CONTRIBUTING.md"><img alt="prs" src="https://img.shields.io/b
422 lines (320 loc) • 15.2 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _defineProperty2() {
const data = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
_defineProperty2 = function () {
return data;
};
return data;
}
function path() {
const data = _interopRequireWildcard(require("path"));
path = function () {
return data;
};
return data;
}
function _utils() {
const data = require("../utils");
_utils = function () {
return data;
};
return data;
}
function _constants() {
const data = require("../constants");
_constants = function () {
return data;
};
return data;
}
function _logger() {
const data = _interopRequireDefault(require("../logger/logger"));
_logger = function () {
return data;
};
return data;
}
function _linkContent() {
const data = require("./link-content");
_linkContent = function () {
return data;
};
return data;
}
function _componentIdToPackageName() {
const data = _interopRequireDefault(require("../utils/bit/component-id-to-package-name"));
_componentIdToPackageName = function () {
return data;
};
return data;
}
function _path2() {
const data = require("../utils/path");
_path2 = function () {
return data;
};
return data;
}
/**
* a dependency component may have multiple files required by the main component.
* this class generates the link content of one file of a dependency.
* @see RelativePath docs for more info
*/
class DependencyFileLinkGenerator {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
constructor({
consumer,
bitMap,
component,
relativePath,
dependencyComponent,
createNpmLinkFiles,
targetDir
}) {
(0, _defineProperty2().default)(this, "consumer", void 0);
(0, _defineProperty2().default)(this, "bitMap", void 0);
(0, _defineProperty2().default)(this, "component", void 0);
(0, _defineProperty2().default)(this, "componentMap", void 0);
(0, _defineProperty2().default)(this, "relativePath", void 0);
(0, _defineProperty2().default)(this, "dependencyId", void 0);
(0, _defineProperty2().default)(this, "dependencyComponent", void 0);
(0, _defineProperty2().default)(this, "createNpmLinkFiles", void 0);
(0, _defineProperty2().default)(this, "targetDir", void 0);
(0, _defineProperty2().default)(this, "dependencyComponentMap", void 0);
(0, _defineProperty2().default)(this, "linkFiles", void 0);
(0, _defineProperty2().default)(this, "relativePathInDependency", void 0);
(0, _defineProperty2().default)(this, "hasDist", void 0);
(0, _defineProperty2().default)(this, "shouldDistsBeInsideTheComponent", void 0);
this.consumer = consumer;
this.bitMap = bitMap;
this.component = component; // $FlowFixMe componentMap should be set here
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
this.componentMap = this.component.componentMap;
this.relativePath = relativePath;
this.dependencyComponent = dependencyComponent;
this.dependencyId = dependencyComponent.id;
this.createNpmLinkFiles = createNpmLinkFiles;
this.targetDir = targetDir;
}
generate() {
this.linkFiles = [];
if (this.component.dependenciesSavedAsComponents) {
this.dependencyComponent.componentMap = this.bitMap.getComponent(this.dependencyId);
this.dependencyComponentMap = this.dependencyComponent.componentMap;
}
this.relativePathInDependency = path().normalize(this.relativePath.destinationRelativePath);
this.hasDist = this.component.dists.writeDistsFiles && !this.component.dists.isEmpty();
this.shouldDistsBeInsideTheComponent = this.consumer ? this.consumer.shouldDistsBeInsideTheComponent() : true;
if (this.relativePath.isCustomResolveUsed) {
return this.generateForCustomResolve();
}
const linkFile = this.prepareLinkFile({
linkPath: this.getLinkPath(),
relativePathInDependency: this.relativePathInDependency,
depRootDir: this._getDepRootDir()
});
this.linkFiles.push(linkFile);
if (this.hasDist) {
this.generateForDist();
}
return this.linkFiles;
}
generateForCustomResolve() {
const distRoot = this._getDistRoot();
const relativeDistPathInDependency = this._getRelativeDistPathInDependency();
const dependencyDistExt = (0, _utils().getExt)(relativeDistPathInDependency);
const relativeDistExtInDependency = _linkContent().EXTENSIONS_TO_REPLACE_TO_JS_IN_PACKAGES.includes(dependencyDistExt) ? 'js' : dependencyDistExt;
const depRootDir = this._getDepRootDir();
const depRootDirDist = this._getDepRootDirDist();
const isCustomResolvedWithDistInside = Boolean(this.shouldDistsBeInsideTheComponent && this.hasDist);
const relativePathInDependency = `${(0, _utils().getWithoutExt)(this.relativePathInDependency)}.${relativeDistExtInDependency}`;
const linkFile = this.prepareLinkFile({
linkPath: this.getLinkPathForCustomResolve(relativeDistExtInDependency),
relativePathInDependency,
depRootDir: isCustomResolvedWithDistInside ? depRootDirDist : depRootDir
});
if (this.createNpmLinkFiles && linkFile.linkContent) {
linkFile.postInstallLink = true;
}
this.linkFiles.push(linkFile);
if (this.hasDist && !this.shouldDistsBeInsideTheComponent) {
// when isCustomResolvedUsed, the link is generated inside node_module directory, so for
// dist inside the component, only one link is needed at the parentRootDir. for dist
// outside the component dir, another link is needed for the dist/parentRootDir.
const importSourcePath = this._getImportSourcePathForCustomResolve(relativeDistExtInDependency);
const linkFileInNodeModules = this.prepareLinkFile({
linkPath: path().join(distRoot, importSourcePath),
relativePathInDependency: relativeDistPathInDependency,
depRootDir: depRootDirDist
});
this.linkFiles.push(linkFileInNodeModules);
}
if ((0, _utils().getExt)(this.relativePathInDependency) === 'ts') {
// this is needed for when building Angular components inside a capsule, so we don't care
// about the case when dist is outside the components
const linkFileTs = this.prepareLinkFile({
linkPath: this.getLinkPathForCustomResolve(relativeDistExtInDependency).replace('.js', '.d.ts'),
relativePathInDependency: relativePathInDependency.replace('.js', '.ts'),
depRootDir: isCustomResolvedWithDistInside ? depRootDirDist : depRootDir
});
if (this.createNpmLinkFiles && linkFile.linkContent) {
linkFileTs.postInstallLink = true;
}
this.linkFiles.push(linkFileTs);
}
return this.linkFiles;
}
generateForDist() {
const distRoot = this._getDistRoot();
const relativeDistPathInDependency = this._getRelativeDistPathInDependency();
const relativeDistExtInDependency = (0, _utils().getExt)(relativeDistPathInDependency);
const sourceRelativePathWithCompiledExt = `${(0, _utils().getWithoutExt)(this.relativePath.sourceRelativePath)}.${relativeDistExtInDependency}`;
const linkFileInDist = this.prepareLinkFile({
linkPath: path().join(distRoot, sourceRelativePathWithCompiledExt),
// Generate a link file inside dist folder of the dependent component
relativePathInDependency: relativeDistPathInDependency,
depRootDir: this._getDepRootDirDist()
});
this.linkFiles.push(linkFileInDist);
}
prepareLinkFile({
linkPath,
relativePathInDependency,
depRootDir
}) {
const actualFilePath = depRootDir ? path().join(depRootDir, relativePathInDependency) : relativePathInDependency;
const relativeFilePath = path().relative(path().dirname(linkPath), actualFilePath);
const importSpecifiers = this.relativePath.importSpecifiers;
const linkContent = this.getLinkContent(relativeFilePath);
const customResolveMapping = this._getCustomResolveMapping();
_logger().default.debug(`prepareLinkFile, on ${linkPath}`);
const linkPathExt = (0, _utils().getExt)(linkPath);
const isEs6 = Boolean(importSpecifiers && linkPathExt === 'js');
const symlinkTo = linkContent ? undefined : this._getSymlinkDest(actualFilePath);
const postInstallSymlink = this.createNpmLinkFiles && !linkContent;
return {
linkPath,
linkContent,
isEs6,
symlinkTo,
customResolveMapping,
postInstallSymlink
};
}
_getSymlinkDest(filePath) {
if (this.createNpmLinkFiles) {
return this._getPackagePathToInternalFile();
}
if (!this.component.dependenciesSavedAsComponents) {
return path().join(this.getTargetDir(), 'node_modules', this._getPackagePathToInternalFile());
} // if dependencies are saved as components, the above logic will create a symlink to a symlink
return filePath;
}
getLinkContent(relativeFilePath) {
return (0, _linkContent().getLinkToPackageContent)(relativeFilePath, this._getPackagePath(), this.relativePath.importSpecifiers);
}
_getPackagePath() {
const ext = (0, _utils().getExt)(this.relativePath.destinationRelativePath);
if (this.relativePath.destinationRelativePath === (0, _path2().pathNormalizeToLinux)(this.dependencyComponent.mainFile) && !_linkContent().EXTENSIONS_NOT_SUPPORT_DIRS.includes(ext)) {
return this._getPackageName();
}
const distFileIsNotFound = !this.dependencyComponent.dists.isEmpty() && !this.dependencyComponent.dists.hasFileParallelToSrcFile(this.relativePath.destinationRelativePath);
if (distFileIsNotFound) {
return this._getPackagePathByDistWithComponentPrefix();
} // the link is to an internal file, not to the main file
return this._getPackagePathToInternalFile();
}
/**
* temporary workaround for Angular compiler when all dists have the prefix of the component id
*/
_getPackagePathByDistWithComponentPrefix() {
const distFileWithDependencyPrefix = path().join(this.dependencyId.toStringWithoutVersion(), this.relativePath.destinationRelativePath);
if (!this.dependencyComponent.dists.isEmpty() && this.dependencyComponent.dists.hasFileParallelToSrcFile(distFileWithDependencyPrefix)) {
const distFile = (0, _utils().searchFilesIgnoreExt)(this.dependencyComponent.dists.get(), distFileWithDependencyPrefix, 'relative'); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return this._getPackagePathToInternalFile(distFile);
}
return this._getPackageName();
}
_getPackageName() {
return (0, _componentIdToPackageName().default)(this.dependencyId, this.dependencyComponent.bindingPrefix, this.dependencyComponent.defaultScope);
} // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
_getPackagePathToInternalFile(filePath = this.relativePath.destinationRelativePath) {
const packageName = this._getPackageName();
const internalFileInsidePackage = this._getInternalFileInsidePackage(filePath);
const ext = (0, _utils().getExt)(internalFileInsidePackage);
const internalFileWithoutExt = _linkContent().EXTENSIONS_TO_STRIP_FROM_PACKAGES.includes(ext) ? (0, _utils().getWithoutExt)(internalFileInsidePackage) : internalFileInsidePackage;
return `${packageName}/${internalFileWithoutExt}`;
}
_getInternalFileInsidePackage(filePath) {
const dependencySavedLocallyAndDistIsOutside = this.dependencyComponentMap && !this.shouldDistsBeInsideTheComponent;
const distPrefix = this.dependencyComponent.dists.isEmpty() || this.relativePath.isCustomResolveUsed || dependencySavedLocallyAndDistIsOutside ? '' : `${_constants().DEFAULT_DIST_DIRNAME}/`;
return distPrefix + filePath;
}
_getCustomResolveMapping() {
if (!this.relativePath.isCustomResolveUsed) return null; // $FlowFixMe importSource is set for custom resolved
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return {
[this.relativePath.importSource]: this._getPackagePath()
};
}
getTargetDir() {
const determineTargetDir = () => {
if (this.targetDir) return this.targetDir;
const writtenPath = this.component.writtenPath; // $FlowFixMe when running from bit build, the writtenPath is not available but it should have rootDir as it's related to the dists links
if (!writtenPath) return this.componentMap.rootDir;
if (path().isAbsolute(writtenPath)) {
throw new Error('getTargetDir: component.writtenPath should be relative');
}
return writtenPath;
};
const targetDir = determineTargetDir();
if (!targetDir || !(typeof targetDir === 'string')) {
throw new Error('targetDir must be of type string');
}
return targetDir;
}
getLinkPath() {
const sourceRelativePath = this.relativePath.sourceRelativePath;
const parentDir = this.getTargetDir();
return path().join(parentDir, sourceRelativePath);
}
getLinkPathForCustomResolve(relativeDistExtInDependency) {
const parentDir = this.getTargetDir();
const importSourcePath = this._getImportSourcePathForCustomResolve(relativeDistExtInDependency); // if createNpmLinkFiles, the path will be part of the postinstall script, so it shouldn't be absolute
return this.createNpmLinkFiles ? importSourcePath : path().join(parentDir, importSourcePath);
}
_getDistRoot() {
return this.component.dists.getDistDir(this.consumer, this.componentMap.getRootDir());
}
_getRelativeDistPathInDependency() {
const relativeDistPathInDependency = (0, _utils().searchFilesIgnoreExt)(this.dependencyComponent.dists.get(), this.relativePathInDependency);
return relativeDistPathInDependency // $FlowFixMe relative is defined
? relativeDistPathInDependency.relative : this.relativePathInDependency;
}
_getImportSourcePathForCustomResolve(relativeDistExtInDependency) {
// $FlowFixMe relativePath.importSource is set when isCustomResolveUsed
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const importSource = this.relativePath.importSource;
const importSourceFileExt = relativeDistExtInDependency || path().extname(this.relativePath.sourceRelativePath); // e.g. for require('utils/is-string'), the link should be at node_modules/utils/is-string/index.js
const importSourceFile = path().extname(importSource) ? importSource : path().join(importSource, `${_constants().DEFAULT_INDEX_NAME}.${importSourceFileExt}`);
return path().join('node_modules', importSourceFile);
}
_getDepRootDir() {
if (!this.dependencyComponentMap) return undefined;
return this.dependencyComponentMap.getRootDir();
}
_getDepRootDirDist() {
const rootDir = this._getDepRootDir();
return rootDir ? this.dependencyComponent.dists.getDistDir(this.consumer, rootDir) : undefined;
}
}
exports.default = DependencyFileLinkGenerator;