"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ReactMain = void 0;
function _devFiles() {
  const data = require("@teambit/dev-files");
  _devFiles = function () {
    return data;
  };
  return data;
}
function _lodash() {
  const data = require("lodash");
  _lodash = function () {
    return data;
  };
  return data;
}
function _cli() {
  const data = require("@teambit/cli");
  _cli = function () {
    return data;
  };
  return data;
}
function _compiler() {
  const data = require("@teambit/compiler");
  _compiler = function () {
    return data;
  };
  return data;
}
function _component() {
  const data = require("@teambit/component");
  _component = function () {
    return data;
  };
  return data;
}
function _envs() {
  const data = require("@teambit/envs");
  _envs = function () {
    return data;
  };
  return data;
}
function _graphql() {
  const data = require("@teambit/graphql");
  _graphql = function () {
    return data;
  };
  return data;
}
function _schema() {
  const data = require("@teambit/schema");
  _schema = function () {
    return data;
  };
  return data;
}
function _pkg() {
  const data = require("@teambit/pkg");
  _pkg = function () {
    return data;
  };
  return data;
}
function _tester() {
  const data = require("@teambit/tester");
  _tester = function () {
    return data;
  };
  return data;
}
function _typescript() {
  const data = require("@teambit/typescript");
  _typescript = function () {
    return data;
  };
  return data;
}
function _webpack() {
  const data = require("@teambit/webpack");
  _webpack = function () {
    return data;
  };
  return data;
}
function _generator() {
  const data = require("@teambit/generator");
  _generator = function () {
    return data;
  };
  return data;
}
function _workspace() {
  const data = require("@teambit/workspace");
  _workspace = function () {
    return data;
  };
  return data;
}
function _dependencyResolver() {
  const data = require("@teambit/dependency-resolver");
  _dependencyResolver = function () {
    return data;
  };
  return data;
}
function _typescript2() {
  const data = _interopRequireDefault(require("typescript"));
  _typescript2 = function () {
    return data;
  };
  return data;
}
function _application() {
  const data = require("@teambit/application");
  _application = function () {
    return data;
  };
  return data;
}
function _logger() {
  const data = require("@teambit/logger");
  _logger = function () {
    return data;
  };
  return data;
}
function _worker() {
  const data = require("@teambit/worker");
  _worker = function () {
    return data;
  };
  return data;
}
function _react() {
  const data = require("./react.aspect");
  _react = function () {
    return data;
  };
  return data;
}
function _react2() {
  const data = require("./react.env");
  _react2 = function () {
    return data;
  };
  return data;
}
function _web() {
  const data = require("./apps/web");
  _web = function () {
    return data;
  };
  return data;
}
function _react3() {
  const data = require("./react.graphql");
  _react3 = function () {
    return data;
  };
  return data;
}
function _react4() {
  const data = require("./react.templates");
  _react4 = function () {
    return data;
  };
  return data;
}
function _react5() {
  const data = require("./react.schema");
  _react5 = function () {
    return data;
  };
  return data;
}
function _reactApi() {
  const data = require("./react.api.transformer");
  _reactApi = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
class ReactMain {
  constructor(
  /**
   * an instance of the React env.
   */
  reactEnv, envs, application, reactAppType, dependencyResolver, logger) {
    this.reactEnv = reactEnv;
    this.envs = envs;
    this.application = application;
    this.reactAppType = reactAppType;
    this.dependencyResolver = dependencyResolver;
    this.logger = logger;
    _defineProperty(this, "env", this.reactEnv);
  }
  getReactAppType(name) {
    return new (_web().ReactAppType)(name, this.reactEnv, this.logger, this.dependencyResolver);
  }

  /**
   * use this to register apps programmatically.
   */
  async registerApp(reactApp) {
    return this.application.registerApp(this.reactAppType.createApp(reactApp));
  }

  /**
   * override the env's typescript config for both dev and build time.
   * Replaces both overrideTsConfig (devConfig) and overrideBuildTsConfig (buildConfig)
   */
  useTypescript(modifiers, tsModule = _typescript2().default) {
    const overrides = {};
    const devTransformers = modifiers === null || modifiers === void 0 ? void 0 : modifiers.devConfig;
    if (devTransformers) {
      overrides.getCompiler = () => this.reactEnv.getCompiler(devTransformers, tsModule);
    }
    const buildTransformers = modifiers === null || modifiers === void 0 ? void 0 : modifiers.buildConfig;
    if (buildTransformers) {
      const buildPipeModifiers = {
        tsModifier: {
          transformers: buildTransformers,
          module: tsModule
        }
      };
      overrides.getBuildPipe = () => this.reactEnv.getBuildPipe(buildPipeModifiers);
    }
    return this.envs.override(overrides);
  }

  /**
   * @deprecated use useTypescript()
   * override the TS config of the React environment.
   * @param tsModule typeof `ts` module instance.
   */
  overrideTsConfig(tsconfig = {}, compilerOptions = {}, tsModule = _typescript2().default) {
    const transformer = configMutator => {
      configMutator.mergeTsConfig(tsconfig);
      configMutator.raw.compileJs = compilerOptions.compileJs ?? configMutator.raw.compileJs;
      configMutator.raw.compileJsx = compilerOptions.compileJsx ?? configMutator.raw.compileJsx;
      if (compilerOptions.types) {
        configMutator.addTypes(compilerOptions.types);
      }
      const genericCompilerOptions = (0, _lodash().omit)(compilerOptions, ['types', 'compileJs', 'compileJsx']);
      configMutator.raw = Object.assign(configMutator.raw, genericCompilerOptions);
      return configMutator;
    };
    // return this.envs.override({
    //   getCompiler: () => this.reactEnv.getCompiler([transformer], tsModule),
    // });
    return this.useTypescript({
      devConfig: [transformer]
    }, tsModule);
  }

  /**
   * Override the Bit documentation link. See docs: https://bit.dev/refrence/docs/doc-templates
   */
  overrideDocsTemplate(templatePath) {
    return this.envs.override({
      getDevEnvId: context => this.reactEnv.getDevEnvId(context.envDefinition.id),
      getDocsTemplate: () => templatePath
    });
  }

  /**
   * @deprecated use useTypescript()
   * override the build tsconfig.
   */
  overrideBuildTsConfig(tsconfig = {}, compilerOptions = {}, tsModule = _typescript2().default) {
    const transformer = configMutator => {
      configMutator.mergeTsConfig(tsconfig);
      configMutator.raw.compileJs = compilerOptions.compileJs ?? configMutator.raw.compileJs;
      configMutator.raw.compileJsx = compilerOptions.compileJsx ?? configMutator.raw.compileJsx;
      if (compilerOptions.types) {
        configMutator.addTypes(compilerOptions.types);
      }
      const genericCompilerOptions = (0, _lodash().omit)(compilerOptions, ['types', 'compileJs', 'compileJsx']);
      configMutator.raw = Object.assign(configMutator.raw, genericCompilerOptions);
      return configMutator;
    };
    // return this.envs.override({
    //   getBuildPipe: () => this.reactEnv.getBuildPipe([transformer], tsModule),
    // });
    return this.useTypescript({
      buildConfig: [transformer]
    }, tsModule);
  }

  /**
   * override the env's dev server and preview webpack configurations.
   * Replaces both overrideDevServerConfig and overridePreviewConfig
   */
  useWebpack(modifiers) {
    const overrides = {};
    const devServerTransformers = modifiers === null || modifiers === void 0 ? void 0 : modifiers.devServerConfig;
    if (devServerTransformers || modifiers !== null && modifiers !== void 0 && modifiers.webpackModulePath || modifiers !== null && modifiers !== void 0 && modifiers.webpackDevServerModulePath) {
      overrides.getDevServer = context => this.reactEnv.getDevServer(context, devServerTransformers, modifiers === null || modifiers === void 0 ? void 0 : modifiers.webpackModulePath, modifiers === null || modifiers === void 0 ? void 0 : modifiers.webpackDevServerModulePath);
      overrides.getDevEnvId = context => this.reactEnv.getDevEnvId(context.envDefinition.id);
    }
    const previewTransformers = modifiers === null || modifiers === void 0 ? void 0 : modifiers.previewConfig;
    if (previewTransformers || modifiers !== null && modifiers !== void 0 && modifiers.webpackModulePath) {
      overrides.getBundler = context => this.reactEnv.getBundler(context, previewTransformers, modifiers === null || modifiers === void 0 ? void 0 : modifiers.webpackModulePath);
    }
    return this.envs.override(overrides);
  }

  /**
   * An API to mutate the prettier config
   * @param modifiers
   * @returns
   */
  useEslint(modifiers) {
    const transformers = (modifiers === null || modifiers === void 0 ? void 0 : modifiers.transformers) || [];
    return this.envs.override({
      getLinter: context => this.reactEnv.getLinter(context, transformers)
    });
  }

  /**
   * An API to mutate the prettier config
   * @param modifiers
   * @returns
   */
  usePrettier(modifiers) {
    const transformers = (modifiers === null || modifiers === void 0 ? void 0 : modifiers.transformers) || [];
    return this.envs.override({
      getFormatter: context => this.reactEnv.getFormatter(context, transformers)
    });
  }

  /**
   * @deprecated use useWebpack()
   * override the dev server webpack config.
   */
  overrideDevServerConfig(config) {
    const transformer = configMutator => {
      return configMutator.merge([config]);
    };
    return this.envs.override({
      getDevServer: context => this.reactEnv.getDevServer(context, [transformer]),
      getDevEnvId: context => this.reactEnv.getDevEnvId(context.envDefinition.id)
    });
  }

  /**
   * @deprecated use useWebpack()
   * override the preview webpack config.
   */
  overridePreviewConfig(config) {
    const transformer = configMutator => {
      return configMutator.merge([config]);
    };
    return this.envs.override({
      getBundler: context => this.reactEnv.getBundler(context, [transformer])
    });
  }
  overrideMounter(mounterPath) {
    return this.envs.override({
      getMounter: () => {
        return mounterPath;
      }
    });
  }

  /**
   * create a new composition of the react environment.
   */
  compose(transformers, targetEnv = {}) {
    return this.envs.compose(this.envs.merge(targetEnv, this.reactEnv), transformers);
  }

  /**
   * override the jest configuration.
   * @param jestConfigPath {typeof jest} absolute path to jest.config.json.
   * @param jestModulePath absolute path to jest
   */
  overrideJestConfig(jestConfigPath, jestModulePath) {
    const buildTransformers = [() => jestConfigPath];
    return this.envs.override({
      getTester: () => this.reactEnv.getTester(jestConfigPath, jestModulePath),
      getBuildPipe: () => this.reactEnv.getBuildPipe({
        jestModifier: {
          transformers: buildTransformers,
          module: jestModulePath
        }
      })
    });
  }

  /**
   * override the build pipeline of the component environment.
   */
  overrideBuildPipe(tasks) {
    return this.envs.override({
      getBuildPipe: () => tasks
    });
  }

  /**
   * override the compiler tasks inside the build pipeline of the component environment.
   */
  overrideCompilerTasks(tasks) {
    const pipeWithoutCompiler = this.reactEnv.getBuildPipeWithoutCompiler();
    return this.envs.override({
      getBuildPipe: () => [...tasks, ...pipeWithoutCompiler]
    });
  }

  /**
   * override the dependency configuration of the component environment.
   */
  overrideDependencies(dependencyPolicy) {
    return this.envs.override({
      getDependencies: async () => {
        const reactDeps = await this.reactEnv.getDependencies();
        return (0, _lodash().merge)(reactDeps, dependencyPolicy);
      }
    });
  }

  /**
   * override the workspace compiler.
   */
  overrideCompiler(compiler) {
    return this.envs.override({
      getCompiler: () => {
        return compiler;
      }
    });
  }

  /**
   * TODO: @gilad we need to implement this.
   */
  overrideEslintConfig() {}

  /**
   * override the package json props of the component environment.
   */
  overridePackageJsonProps(props) {
    return this.envs.override({
      getPackageJsonProps: () => {
        return _objectSpread(_objectSpread({}, this.reactEnv.getPackageJsonProps()), props);
      }
    });
  }

  /**
   * returns doc adjusted specifically for react components.
   */
  getDocs(component) {
    const docsArray = component.state._consumer.docs;
    if (!docsArray || !docsArray[0]) {
      return null;
    }
    const docs = docsArray[0];
    return {
      abstract: docs.description,
      filePath: docs.filePath,
      properties: docs.properties
    };
  }
  static async provider([envs, tsAspect, compiler, webpack, workspace, graphql, pkg, tester, application, generator, dependencyResolver, loggerMain, schemaMain, workerMain, devFilesMain], config, slots, harmony) {
    const logger = loggerMain.createLogger(_react().ReactAspect.id);
    const reactEnv = new (_react2().ReactEnv)(tsAspect, compiler, webpack, workspace, workerMain, pkg, tester, config, dependencyResolver, devFilesMain, logger, _compiler().CompilerAspect.id);
    const appType = new (_web().ReactAppType)('react-app', reactEnv, logger, dependencyResolver);
    const react = new ReactMain(reactEnv, envs, application, appType, dependencyResolver, logger);
    graphql.register(() => (0, _react3().reactSchema)(react));
    envs.registerEnv(reactEnv);
    if (generator) {
      const envContext = new (_envs().EnvContext)(_component().ComponentID.fromString(_react().ReactAspect.id), loggerMain, workerMain, harmony);
      generator.registerComponentTemplate(() => (0, _react4().getTemplates)(envContext));
    }
    if (application) application.registerAppType(appType);
    if (schemaMain) schemaMain.registerSchemaClasses(() => [_react5().ReactSchema]);
    if (tsAspect) tsAspect.registerApiTransformer([new (_reactApi().ReactAPITransformer)()]);
    return react;
  }
}
exports.ReactMain = ReactMain;
_defineProperty(ReactMain, "runtime", _cli().MainRuntime);
_defineProperty(ReactMain, "dependencies", [_envs().EnvsAspect, _typescript().TypescriptAspect, _compiler().CompilerAspect, _webpack().WebpackAspect, _workspace().WorkspaceAspect, _graphql().GraphqlAspect, _pkg().PkgAspect, _tester().TesterAspect, _application().ApplicationAspect, _generator().GeneratorAspect, _dependencyResolver().DependencyResolverAspect, _logger().LoggerAspect, _schema().SchemaAspect, _worker().WorkerAspect, _devFiles().DevFilesAspect]);
_react().ReactAspect.addRuntime(ReactMain);

//# sourceMappingURL=react.main.runtime.js.map