"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.getAdapterInit = getAdapterInit;
var _get2 = _interopRequireDefault(require("lodash/get"));
var _reporter = _interopRequireDefault(require("gatsby-cli/lib/reporter"));
var _createRequireFromPath = require("gatsby-core-utils/create-require-from-path");
var _path = require("path");
var _fsExtra = require("fs-extra");
var _execa = _interopRequireDefault(require("execa"));
var _package = require("gatsby/package.json");
var _semver = require("semver");
var _preferDefault = require("../../bootstrap/prefer-default");
var _getLatestGatsbyFiles = require("../get-latest-gatsby-files");
const getAdaptersCacheDir = () => (0, _path.join)(process.cwd(), `.cache/adapters`);
const createAdaptersCacheDir = async () => {
  await (0, _fsExtra.ensureDir)(getAdaptersCacheDir());
  await (0, _fsExtra.emptyDir)(getAdaptersCacheDir());
  const packageJsonPath = (0, _path.join)(getAdaptersCacheDir(), `package.json`);
  await (0, _fsExtra.outputJson)(packageJsonPath, {
    name: `gatsby-adapters`,
    description: `This directory contains adapters that have been automatically installed by Gatsby.`,
    version: `1.0.0`,
    private: true,
    author: `Gatsby`,
    license: `MIT`
  });
};
async function getAdapterInit() {
  // 1. Find the correct adapter and its details (e.g. version)
  const latestAdapters = await (0, _getLatestGatsbyFiles.getLatestAdapters)();
  const adapterToUse = latestAdapters.find(candidate => candidate.test());
  if (!adapterToUse) {
    _reporter.default.verbose(`No adapter was found for the current environment. Skipping adapter initialization.`);
    return undefined;
  }

  // 2. Check if the user has manually installed the adapter and try to resolve it from there
  try {
    const siteRequire = (0, _createRequireFromPath.createRequireFromPath)(`${process.cwd()}/:internal:`);
    const adapterPackageJson = siteRequire(`${adapterToUse.module}/package.json`);
    const adapterGatsbyPeerDependency = (0, _get2.default)(adapterPackageJson, `peerDependencies.gatsby`);
    const moduleVersion = adapterPackageJson === null || adapterPackageJson === void 0 ? void 0 : adapterPackageJson.version;

    // Check if the peerDependency of the adapter is compatible with the current Gatsby version
    if (adapterGatsbyPeerDependency && !(0, _semver.satisfies)(_package.version, adapterGatsbyPeerDependency, {
      includePrerelease: true
    })) {
      _reporter.default.warn(`The ${adapterToUse.name} adapter is not compatible with your current Gatsby version ${_package.version} - It requires gatsby@${adapterGatsbyPeerDependency}`);
      return undefined;
    }

    // Cross-check the adapter version with the version manifest and see if the adapter version is correct for the current Gatsby version
    const versionForCurrentGatsbyVersion = adapterToUse.versions.find(entry => (0, _semver.satisfies)(_package.version, entry.gatsbyVersion, {
      includePrerelease: true
    }));
    const isAdapterCompatible = versionForCurrentGatsbyVersion && (0, _semver.satisfies)(moduleVersion, versionForCurrentGatsbyVersion.moduleVersion, {
      includePrerelease: true
    });
    if (!versionForCurrentGatsbyVersion) {
      _reporter.default.warn(`The ${adapterToUse.name} adapter is not compatible with your current Gatsby version ${_package.version}.`);
      return undefined;
    }
    if (!isAdapterCompatible) {
      _reporter.default.warn(`${adapterToUse.module}@${moduleVersion} is not compatible with your current Gatsby version ${_package.version} - Install ${adapterToUse.module}@${versionForCurrentGatsbyVersion.moduleVersion} or later.`);
      return undefined;
    }
    const required = siteRequire.resolve(adapterToUse.module);
    if (required) {
      _reporter.default.verbose(`Reusing existing adapter ${adapterToUse.module} inside node_modules`);

      // TODO: double preferDefault is most ceirtainly wrong - figure it out
      return (0, _preferDefault.preferDefault)((0, _preferDefault.preferDefault)(await import(required)));
    }
  } catch (e) {
    // no-op
  }

  // 3. Check if a previous run has installed the correct adapter into .cache/adapters already and try to resolve it from there
  try {
    const adaptersRequire = (0, _createRequireFromPath.createRequireFromPath)(`${getAdaptersCacheDir()}/:internal:`);
    const required = adaptersRequire.resolve(adapterToUse.module);
    if (required) {
      _reporter.default.verbose(`Reusing existing adapter ${adapterToUse.module} inside .cache/adapters`);

      // TODO: double preferDefault is most ceirtainly wrong - figure it out
      return (0, _preferDefault.preferDefault)((0, _preferDefault.preferDefault)(await import(required)));
    }
  } catch (e) {
    // no-op
  }
  const installTimer = _reporter.default.activityTimer(`Installing ${adapterToUse.name} adapter`);
  // 4. If both a manually installed version and a cached version are not found, install the adapter into .cache/adapters
  try {
    installTimer.start();
    await createAdaptersCacheDir();
    const options = {
      stderr: `inherit`,
      cwd: getAdaptersCacheDir()
    };
    const npmAdditionalCliArgs = [`--no-progress`, `--no-audit`, `--no-fund`, `--loglevel`, `error`, `--color`, `always`, `--legacy-peer-deps`, `--save-exact`];
    await (0, _execa.default)(`npm`, [`install`, ...npmAdditionalCliArgs, adapterToUse.module], options);
    installTimer.end();
    _reporter.default.info(`If you plan on staying on this deployment platform, consider installing ${adapterToUse.module} as a dependency in your project. This will give you faster and more robust installs.`);
    const adaptersRequire = (0, _createRequireFromPath.createRequireFromPath)(`${getAdaptersCacheDir()}/:internal:`);
    const required = adaptersRequire.resolve(adapterToUse.module);
    if (required) {
      _reporter.default.verbose(`Using installed adapter ${adapterToUse.module} inside .cache/adapters`);

      // TODO: double preferDefault is most ceirtainly wrong - figure it out
      return (0, _preferDefault.preferDefault)((0, _preferDefault.preferDefault)(await import(required)));
    }
  } catch (e) {
    installTimer.end();
    _reporter.default.warn(`Could not install adapter ${adapterToUse.module}. Please install it yourself by adding it to your package.json's dependencies and try building your project again.`);
  }
  return undefined;
}
//# sourceMappingURL=init.js.map