'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getIndexFileName = exports.getLinkContent = exports.writeDependencyLinks = exports.writeEntryPointsForComponent = undefined;

var _regenerator;

function _load_regenerator() {
  return _regenerator = _interopRequireDefault(require('babel-runtime/regenerator'));
}

/**
 * The following scenario will help understanding why links are needed.
 * Component A has a dependency B. (for instance, in a.js there is a require statement to 'b.js').
 * While importing component A, it knows about the B dependency and it saves it under 'dependencies' directory of A.
 * The problem is that the above require is broken, because 'b.js' is not in the same place where it was originally.
 * This function solves this issue by creating the 'b.js' file in the original location and points to the new location
 * under 'dependencies' of A.
 */
var writeDependencyLinks = function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3(componentDependencies, consumer, createNpmLinkFiles) {
    var _this = this;

    var consumerPath, componentLink, componentLinks, allLinksP, allLinks, linksWithoutNulls, linksWithoutDuplications;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            consumerPath = consumer.getPath();

            componentLink = function componentLink(depId, depComponent, relativePath, parentComponent, parentComponentMap) {
              var getParentDir = function getParentDir() {
                // when running from bit build, the writtenPath is not available
                if (!parentComponent.writtenPath) return consumer.toAbsolutePath(parentComponentMap.rootDir);
                if ((_path || _load_path()).default.isAbsolute(parentComponent.writtenPath)) return parentComponent.writtenPath;
                return consumer.toAbsolutePath(parentComponent.writtenPath);
              };
              var parentDir = getParentDir();
              var relativePathInDependency = (_path || _load_path()).default.normalize(relativePath.destinationRelativePath);
              var mainFile = depComponent.dists.calculateMainDistFile(depComponent.mainFile);
              var hasDist = parentComponent.dists.writeDistsFiles && !parentComponent.dists.isEmpty();
              var distRoot = parentComponent.dists.getDistDirForConsumer(consumer, parentComponentMap.rootDir);

              var relativeDistPathInDependency = (0, (_utils || _load_utils()).searchFilesIgnoreExt)(depComponent.dists.get(), relativePathInDependency, 'relative');
              relativeDistPathInDependency = relativeDistPathInDependency // $FlowFixMe relative is defined
              ? relativeDistPathInDependency.relative : relativePathInDependency;

              var relativeDistExtInDependency = (0, (_utils || _load_utils()).getExt)(relativeDistPathInDependency);
              var sourceRelativePath = relativePath.sourceRelativePath;
              var getLinkPath = function getLinkPath() {
                if (!relativePath.isCustomResolveUsed) return (_path || _load_path()).default.join(parentDir, sourceRelativePath);
                // $FlowFixMe relativePath.importSource is set when isCustomResolveUsed
                var importSource = relativePath.importSource;
                var importSourceFileExt = relativeDistExtInDependency || (_path || _load_path()).default.extname(relativePath.sourceRelativePath);
                // e.g. for require('utils/is-string'), the link should be at node_modules/utils/is-string/index.js
                var importSourceFile = (_path || _load_path()).default.extname(importSource) ? importSource : (_path || _load_path()).default.join(importSource, `${(_constants || _load_constants()).DEFAULT_INDEX_NAME}.${importSourceFileExt}`);
                var importSourcePath = (_path || _load_path()).default.join('node_modules', importSourceFile);
                // if createNpmLinkFiles, the path will be part of the postinstall script, so it shouldn't be absolute
                return createNpmLinkFiles ? importSourcePath : (_path || _load_path()).default.join(parentDir, importSourcePath);
              };
              var linkPath = getLinkPath();

              var distLinkPath = void 0;
              var linkFiles = [];
              var depComponentMap = parentComponent.dependenciesSavedAsComponents ? consumer.bitMap.getComponent(depId, true) : undefined;

              var depRootDir = depComponentMap ? (_path || _load_path()).default.join(consumerPath, depComponentMap.rootDir) : undefined;
              var isNpmLink = createNpmLinkFiles || !parentComponent.dependenciesSavedAsComponents;
              var depRootDirDist = depComponentMap ? depComponent.dists.getDistDirForConsumer(consumer, depComponentMap.rootDir) : undefined;

              if (hasDist) {
                if (relativePath.isCustomResolveUsed) {
                  if (!consumer.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.
                    // $FlowFixMe relativePath.importSource is set when isCustomResolveUsed
                    distLinkPath = (_path || _load_path()).default.join(distRoot, 'node_modules', relativePath.importSource);
                    var _linkFile = prepareLinkFile(depId, mainFile, distLinkPath, relativeDistPathInDependency, relativePath, depRootDirDist, isNpmLink);
                    linkFiles.push(_linkFile);
                  }
                } else {
                  var _sourceRelativePathWithCompiledExt = `${(0, (_utils || _load_utils()).getWithoutExt)(sourceRelativePath)}.${relativeDistExtInDependency}`;
                  distLinkPath = (_path || _load_path()).default.join(distRoot, _sourceRelativePathWithCompiledExt);
                  // Generate a link file inside dist folder of the dependent component
                  var _linkFile2 = prepareLinkFile(depId, mainFile, distLinkPath, relativeDistPathInDependency, relativePath, depRootDirDist, isNpmLink);
                  linkFiles.push(_linkFile2);
                }
              }

              var sourceRelativePathWithCompiledExt = `${(0, (_utils || _load_utils()).getWithoutExt)(relativePathInDependency)}.${relativeDistExtInDependency}`;
              var linkFile = prepareLinkFile(depId, mainFile, linkPath, relativePath.isCustomResolveUsed && depRootDirDist && consumer.shouldDistsBeInsideTheComponent() && hasDist ? sourceRelativePathWithCompiledExt : relativePathInDependency, relativePath, relativePath.isCustomResolveUsed && depRootDirDist && consumer.shouldDistsBeInsideTheComponent() && hasDist ? depRootDirDist : depRootDir, isNpmLink);
              if (relativePath.isCustomResolveUsed && createNpmLinkFiles) {
                linkFile.postInstallLink = true;
              }

              linkFiles.push(linkFile);
              return linkFiles;
            };

            componentLinks = function () {
              var _ref2 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee(dependencies, parentComponent, parentComponentMap) {
                var directDependencies, flattenedDependencies, links, internalCustomResolvedLinks, flattenLinks, groupLinks, linksToWrite, postInstallLinks;
                return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
                  while (1) {
                    switch (_context.prev = _context.next) {
                      case 0:
                        directDependencies = parentComponent.getAllDependencies();
                        flattenedDependencies = parentComponent.getAllFlattenedDependencies();

                        if (!(!directDependencies || !directDependencies.length)) {
                          _context.next = 4;
                          break;
                        }

                        return _context.abrupt('return', []);

                      case 4:
                        links = directDependencies.map(function (dep) {
                          if (!dep.relativePaths || (_ramda || _load_ramda()).default.isEmpty(dep.relativePaths)) return [];
                          var resolveDepVersion = dep.id;
                          // Check if the dependency is latest, if yes we need to resolve if from the flatten dependencies to get the
                          // Actual version number, because on the bitmap we have only specific versions
                          if (dep.id.getVersion().latest) {
                            resolveDepVersion = flattenedDependencies.resolveVersion(dep.id).toString();
                          }

                          // Helper function to look for the component object
                          var _byComponentId = function _byComponentId(dependency) {
                            return dependency.id.toString() === resolveDepVersion.toString();
                          };
                          // Get the real dependency component
                          var depComponent = (_ramda || _load_ramda()).default.find(_byComponentId, dependencies);

                          if (!depComponent) {
                            var errorMessage = `link-generation: failed finding ${resolveDepVersion.toString()} in the dependencies array of ${parentComponent.id}.
The dependencies array has the following ids: ${dependencies.map(function (d) {
                              return d.id;
                            }).join(', ')}`;
                            throw new (_generalError || _load_generalError()).default(errorMessage);
                          }

                          var currLinks = dep.relativePaths.map(function (relativePath) {
                            return componentLink(resolveDepVersion, depComponent, relativePath, parentComponent, parentComponentMap);
                          });
                          return (_ramda || _load_ramda()).default.flatten(currLinks);
                        });
                        internalCustomResolvedLinks = parentComponent.customResolvedPaths.length ? getInternalCustomResolvedLinks(parentComponent, createNpmLinkFiles) : [];
                        flattenLinks = (_ramda || _load_ramda()).default.flatten(links).concat(internalCustomResolvedLinks);
                        groupLinks = (0, (_lodash2 || _load_lodash2()).default)(flattenLinks, function (link) {
                          return link.linkPath;
                        });
                        linksToWrite = [];
                        postInstallLinks = [];

                        Object.keys(groupLinks).forEach(function (group) {
                          var content = '';
                          var firstGroupItem = groupLinks[group][0];
                          if (firstGroupItem.isEs6) {
                            // check by the first item of the array, it can be any other item as well
                            content = 'Object.defineProperty(exports, "__esModule", { value: true });\n';
                          }
                          content += groupLinks[group].map(function (linkItem) {
                            return linkItem.linkContent;
                          }).join('\n');
                          var linkFile = { filePath: group, content };
                          if (firstGroupItem.postInstallLink) postInstallLinks.push(linkFile);else linksToWrite.push(linkFile);
                        });

                        if (!postInstallLinks.length) {
                          _context.next = 14;
                          break;
                        }

                        _context.next = 14;
                        return generatePostInstallScript(parentComponent, postInstallLinks);

                      case 14:
                        return _context.abrupt('return', linksToWrite);

                      case 15:
                      case 'end':
                        return _context.stop();
                    }
                  }
                }, _callee, _this);
              }));

              return function componentLinks(_x4, _x5, _x6) {
                return _ref2.apply(this, arguments);
              };
            }();

            allLinksP = componentDependencies.map(function () {
              var _ref3 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(componentWithDeps) {
                var componentMap, directLinks, indirectLinks;
                return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
                  while (1) {
                    switch (_context2.prev = _context2.next) {
                      case 0:
                        componentMap = consumer.bitMap.getComponent(componentWithDeps.component.id, true);

                        if (!(componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED)) {
                          _context2.next = 4;
                          break;
                        }

                        (_logger || _load_logger()).default.debug(`writeDependencyLinks, ignoring a component ${componentWithDeps.component.id} as it is an author component`);
                        return _context2.abrupt('return', null);

                      case 4:
                        // it must be IMPORTED. We don't pass NESTED to this function
                        (_logger || _load_logger()).default.debug(`writeDependencyLinks, generating links for ${componentWithDeps.component.id}`);
                        componentWithDeps.component.stripOriginallySharedDir(consumer.bitMap);

                        _context2.next = 8;
                        return componentLinks(componentWithDeps.allDependencies, componentWithDeps.component, componentMap);

                      case 8:
                        directLinks = _context2.sent;

                        if (!componentWithDeps.component.dependenciesSavedAsComponents) {
                          _context2.next = 14;
                          break;
                        }

                        _context2.next = 12;
                        return Promise.all(componentWithDeps.allDependencies.map(function (dep) {
                          var depComponentMap = consumer.bitMap.getComponent(dep.id, true);
                          // We pass here the componentWithDeps.dependencies again because it contains the full dependencies objects
                          // also the indirect ones
                          // The dep.dependencies contain only an id and relativePaths and not the full object
                          return componentLinks(componentWithDeps.allDependencies, dep, depComponentMap);
                        }));

                      case 12:
                        indirectLinks = _context2.sent;
                        return _context2.abrupt('return', [directLinks].concat(_toConsumableArray(indirectLinks)));

                      case 14:
                        return _context2.abrupt('return', directLinks);

                      case 15:
                      case 'end':
                        return _context2.stop();
                    }
                  }
                }, _callee2, _this);
              }));

              return function (_x7) {
                return _ref3.apply(this, arguments);
              };
            }());
            _context3.next = 6;
            return Promise.all(allLinksP);

          case 6:
            allLinks = _context3.sent;
            linksWithoutNulls = (_ramda || _load_ramda()).default.flatten(allLinks).filter(function (x) {
              return x;
            });
            linksWithoutDuplications = (0, (_lodash || _load_lodash()).default)(linksWithoutNulls, 'filePath');
            return _context3.abrupt('return', Promise.all(linksWithoutDuplications.map(function (link) {
              return (0, (_utils || _load_utils()).outputFile)(link);
            })));

          case 10:
          case 'end':
            return _context3.stop();
        }
      }
    }, _callee3, this);
  }));

  return function writeDependencyLinks(_x, _x2, _x3) {
    return _ref.apply(this, arguments);
  };
}();

/**
 * when using custom module resolutions, and inside a component there is a file that requires
 * another file by custom-resolved syntax, we must generate links on the imported component inside
 * node_modules.
 *
 * E.g. original component "utils/jump" has two files:
 * bar/foo.js => require('utils/is-string); // "src" is set to be a module-directory
 * utils/is-string.js
 *
 * imported component:
 * components/utils/jump/bar/foo.js
 * components/utils/jump/utils/is-string.js
 * components/utils/jump/node_modules/utils/is-string // this is the file we generate here
 */


var generatePostInstallScript = function () {
  var _ref4 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4(component, postInstallLinks) {
    var componentDir, linkPathsObject, postInstallCode, POST_INSTALL_FILENAME, postInstallFilePath, postInstallScript, override;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            componentDir = component.writtenPath;
            // convert from array to object for easier parsing in the postinstall script

            linkPathsObject = postInstallLinks.reduce(function (acc, val) {
              acc[val.filePath] = val.content;
              return acc;
            }, {});

            if (component.packageJsonInstance) {
              _context4.next = 4;
              break;
            }

            throw new Error(`packageJsonInstance is missing for ${component.id.toString()}`);

          case 4:
            postInstallCode = (0, (_postinstall || _load_postinstall()).default)(JSON.stringify(linkPathsObject));
            POST_INSTALL_FILENAME = '.bit.postinstall.js';
            postInstallFilePath = (_path || _load_path()).default.join(componentDir, POST_INSTALL_FILENAME);
            // await fs.writeFile(postInstallFilePath, postInstallCode);

            postInstallScript = `node ${POST_INSTALL_FILENAME}`;

            component.packageJsonInstance.scripts = { postinstall: postInstallScript };
            override = true;
            _context4.next = 12;
            return Promise.all([(_fsExtra || _load_fsExtra()).default.writeFile(postInstallFilePath, postInstallCode), component.packageJsonInstance.write({ override })]);

          case 12:
          case 'end':
            return _context4.stop();
        }
      }
    }, _callee4, this);
  }));

  return function generatePostInstallScript(_x8, _x9) {
    return _ref4.apply(this, arguments);
  };
}();

/**
 * Relevant for IMPORTED and NESTED only
 */


var writeEntryPointsForComponent = function () {
  var _ref5 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5(component, consumer) {
    var componentId, componentMap, componentRoot, mainFile, indexName, entryPointFileContent, entryPointPath, distDir, entryPointDist;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            componentId = component.id.toString();
            componentMap = consumer.bitMap.getComponent(componentId);
            componentRoot = component.writtenPath || componentMap.rootDir;

            if (!(componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED)) {
              _context5.next = 5;
              break;
            }

            return _context5.abrupt('return', Promise.resolve());

          case 5:
            mainFile = component.dists.calculateMainDistFile(component.mainFile);
            indexName = getIndexFileName(mainFile); // Move to bit-javascript

            entryPointFileContent = getLinkContent(`./${mainFile}`);
            entryPointPath = (_path || _load_path()).default.join(componentRoot, indexName);

            if (!(!component.dists.isEmpty() && component.dists.writeDistsFiles && !consumer.shouldDistsBeInsideTheComponent())) {
              _context5.next = 15;
              break;
            }

            distDir = component.dists.getDistDirForConsumer(consumer, componentMap.rootDir);
            entryPointDist = (_path || _load_path()).default.join(distDir, indexName);

            (_logger || _load_logger()).default.debug(`writeEntryPointFile, on ${entryPointDist}`);
            _context5.next = 15;
            return (0, (_utils || _load_utils()).outputFile)({ filePath: entryPointDist, content: entryPointFileContent, override: false });

          case 15:
            (_logger || _load_logger()).default.debug(`writeEntryPointFile, on ${entryPointPath}`);
            return _context5.abrupt('return', (0, (_utils || _load_utils()).outputFile)({ filePath: entryPointPath, content: entryPointFileContent, override: false }));

          case 17:
          case 'end':
            return _context5.stop();
        }
      }
    }, _callee5, this);
  }));

  return function writeEntryPointsForComponent(_x10, _x11) {
    return _ref5.apply(this, arguments);
  };
}();

var _fsExtra;

function _load_fsExtra() {
  return _fsExtra = _interopRequireDefault(require('fs-extra'));
}

var _path;

function _load_path() {
  return _path = _interopRequireDefault(require('path'));
}

var _normalizePath;

function _load_normalizePath() {
  return _normalizePath = _interopRequireDefault(require('normalize-path'));
}

var _ramda;

function _load_ramda() {
  return _ramda = _interopRequireDefault(require('ramda'));
}

var _lodash;

function _load_lodash() {
  return _lodash = _interopRequireDefault(require('lodash.uniqby'));
}

var _lodash2;

function _load_lodash2() {
  return _lodash2 = _interopRequireDefault(require('lodash.groupby'));
}

var _constants;

function _load_constants() {
  return _constants = require('../constants');
}

var _utils;

function _load_utils() {
  return _utils = require('../utils');
}

var _logger;

function _load_logger() {
  return _logger = _interopRequireDefault(require('../logger/logger'));
}

var _scope;

function _load_scope() {
  return _scope = require('../scope');
}

var _component;

function _load_component() {
  return _component = _interopRequireDefault(require('../consumer/component'));
}

var _dependencies;

function _load_dependencies() {
  return _dependencies = require('../consumer/component/dependencies');
}

var _bitId;

function _load_bitId() {
  return _bitId = require('../bit-id');
}

var _fileTypesPlugins;

function _load_fileTypesPlugins() {
  return _fileTypesPlugins = _interopRequireDefault(require('../plugins/file-types-plugins'));
}

var _globalConfig;

function _load_globalConfig() {
  return _globalConfig = require('../api/consumer/lib/global-config');
}

var _consumer;

function _load_consumer() {
  return _consumer = require('../consumer');
}

var _componentMap;

function _load_componentMap() {
  return _componentMap = _interopRequireDefault(require('../consumer/bit-map/component-map'));
}

var _generalError;

function _load_generalError() {
  return _generalError = _interopRequireDefault(require('../error/general-error'));
}

var _postinstall;

function _load_postinstall() {
  return _postinstall = _interopRequireDefault(require('../consumer/component/templates/postinstall.default-template'));
}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

var LINKS_CONTENT_TEMPLATES = {
  js: "module.exports = require('{filePath}');",
  ts: "export * from '{filePath}';",
  jsx: "export * from '{filePath}';",
  tsx: "export * from '{filePath}';",
  css: "@import '{filePath}.css';",
  scss: "@import '{filePath}.scss';",
  sass: "@import '{filePath}.sass';",
  less: "@import '{filePath}.less';",
  vue: "<script>\nmodule.exports = require('{filePath}.vue');\n</script>"
};

var PACKAGES_LINKS_CONTENT_TEMPLATES = {
  css: "@import '~{filePath}';",
  scss: "@import '~{filePath}';",
  sass: "@import '~{filePath}';",
  less: "@import '~{filePath}';",
  'st.css': ':import { -st-from: "{filePath}";}',
  vue: "<script>\nmodule.exports = require('{filePath}.vue');\n</script>"
};

var fileExtentionsForNpmLinkGenerator = ['js', 'ts', 'jsx', 'tsx'];

// todo: move to bit-javascript
function getIndexFileName(mainFile) {
  return `${(_constants || _load_constants()).DEFAULT_INDEX_NAME}.${(0, (_utils || _load_utils()).getExt)(mainFile)}`;
}

// todo: move to bit-javascript
function getLinkContent(filePath, importSpecifiers, createNpmLinkFiles, bitPackageName) {
  var fileExt = (0, (_utils || _load_utils()).getExt)(filePath);
  /**
   * Get the template for the generated link file.
   *
   * For ES6 and TypeScript the template is more complicated and we often need to know how originally the variables were
   * imported, whether default (e.g. import foo from './bar') or non-default (e.g. import { foo } from './bar').
   *
   * The importSpecifier.linkFile attribute exists when the main-file doesn't require the variable directly, but uses a
   * link-file to require it indirectly. E.g. src/bar.js: `import foo from './utils;` utils/index.js: `import foo from './foo';`
   */
  var getTemplate = function getTemplate() {
    if (importSpecifiers && importSpecifiers.length) {
      if (fileExt === 'js' || fileExt === 'jsx') {
        // @see e2e/flows/es6-link-files.e2e.js file for cases covered by the following snippet
        return importSpecifiers.map(function (importSpecifier) {
          if (!importSpecifier.linkFile) {
            // when no link-file is involved, use the standard non-es6 syntax (a privilege that doesn't exist for TS)
            return LINKS_CONTENT_TEMPLATES.js;
          }
          // for link files we need to know whether the main-file imports the variable as default or non-default
          var exportPart = 'exports';
          if (importSpecifier.mainFile.isDefault) {
            exportPart += '.default';
          } else {
            exportPart += `.${importSpecifier.mainFile.name}`;
          }
          var pathPart = "require('{filePath}')";

          if (importSpecifier.linkFile.isDefault) {
            pathPart += '.default';
          } else {
            pathPart += `.${importSpecifier.mainFile.name}`;
          }

          return `${exportPart} = ${pathPart};`;
        }).join('\n');
      } else if (fileExt === 'ts' || fileExt === 'tsx') {
        return importSpecifiers.map(function (importSpecifier) {
          var importPart = 'import ';
          if (importSpecifier.linkFile && importSpecifier.linkFile.isDefault || !importSpecifier.linkFile && importSpecifier.mainFile.isDefault) {
            importPart += `${importSpecifier.mainFile.name}`;
          } else {
            importPart += `{ ${importSpecifier.mainFile.name} }`;
          }
          importPart += " from '{filePath}';";

          var exportPart = 'export ';
          if (importSpecifier.mainFile.isDefault) {
            exportPart += `default ${importSpecifier.mainFile.name};`;
          } else {
            exportPart += `{ ${importSpecifier.mainFile.name} };`;
          }
          return `${importPart}\n${exportPart}`;
        }).join('\n');
      }
    }
    (_fileTypesPlugins || _load_fileTypesPlugins()).default.forEach(function (plugin) {
      LINKS_CONTENT_TEMPLATES[plugin.getExtension()] = plugin.getTemplate(importSpecifiers);
    });

    if (createNpmLinkFiles && !fileExtentionsForNpmLinkGenerator.includes(fileExt)) {
      return PACKAGES_LINKS_CONTENT_TEMPLATES[fileExt];
    }
    return LINKS_CONTENT_TEMPLATES[fileExt];
  };

  if (!filePath.startsWith('.')) {
    filePath = `./${filePath}`; // it must be relative, otherwise, it'll search it in node_modules
  }

  var filePathWithoutExt = (0, (_utils || _load_utils()).getWithoutExt)(filePath);
  var template = getTemplate();
  if (createNpmLinkFiles) {
    filePathWithoutExt = bitPackageName;
  } else {
    filePathWithoutExt = (0, (_utils || _load_utils()).getWithoutExt)(filePath); // remove the extension
  }

  if (!template) {
    throw new (_generalError || _load_generalError()).default(`no template was found for ${filePath}, because .${fileExt} extension is not supported`);
  }
  return template.replace(/{filePath}/g, (0, (_normalizePath || _load_normalizePath()).default)(filePathWithoutExt));
}

function prepareLinkFile(componentId, mainFile, linkPath, relativePathInDependency, relativePath, depRootDir, isNpmLink) {
  // this is used to convert the component name to a valid npm package  name
  var packagePath = `${(0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_REGISTRY_DOMAIN_PREFIX) || (_constants || _load_constants()).DEFAULT_REGISTRY_DOMAIN_PREFIX}/${componentId.toStringWithoutVersion().replace(/\//g, '.')}`;
  var actualFilePath = depRootDir ? (_path || _load_path()).default.join(depRootDir, relativePathInDependency) : relativePathInDependency;
  if (relativePathInDependency === mainFile) {
    actualFilePath = depRootDir ? (_path || _load_path()).default.join(depRootDir, mainFile) : mainFile;
  }
  var relativeFilePath = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(linkPath), actualFilePath);
  var importSpecifiers = relativePath.importSpecifiers;
  var linkContent = getLinkContent(relativeFilePath, importSpecifiers, isNpmLink, packagePath);
  (_logger || _load_logger()).default.debug(`prepareLinkFile, on ${linkPath}`);
  var linkPathExt = (0, (_utils || _load_utils()).getExt)(linkPath);
  var isEs6 = importSpecifiers && linkPathExt === 'js';
  return { linkPath, linkContent, isEs6 };
}function getInternalCustomResolvedLinks(component, createNpmLinkFiles) {
  var componentDir = component.writtenPath;
  var getDestination = function getDestination(importSource) {
    return `node_modules/${importSource}`;
  };
  return component.customResolvedPaths.map(function (customPath) {
    var sourceAbs = (_path || _load_path()).default.join(componentDir, customPath.destinationPath);
    var dest = getDestination(customPath.importSource);
    var destAbs = (_path || _load_path()).default.join(componentDir, dest);
    var destRelative = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(destAbs), sourceAbs);
    var linkContent = getLinkContent(destRelative);
    return { linkPath: createNpmLinkFiles ? dest : destAbs, linkContent, postInstallLink: createNpmLinkFiles };
  });
}

exports.writeEntryPointsForComponent = writeEntryPointsForComponent;
exports.writeDependencyLinks = writeDependencyLinks;
exports.getLinkContent = getLinkContent;
exports.getIndexFileName = getIndexFileName;