text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  const path_1 = require("path");
  const localfs_1 = require("apollo-codegen-core/lib/localfs");
  const fg = require("glob");
  const minimatch = require("minimatch");
  const graphql_1 = require("graphql");
  const load_schema_1 = require("./load-schema");
  const loading_1 = require("apollo-codegen-core/lib/loading");
  function loadEndpointConfig(obj, shouldDefaultURL) {
      let preSubscriptions;
      if (typeof obj === "string") {
          preSubscriptions = {
              url: obj
          };
      }
      else {
          preSubscriptions =
              obj ||
                  (shouldDefaultURL ? { url: "http://localhost:4000/graphql" } : undefined);
      }
      if (preSubscriptions &&
          !preSubscriptions.subscriptions &&
          preSubscriptions.url) {
          preSubscriptions.subscriptions = preSubscriptions.url.replace("http", "ws");
      }
      return preSubscriptions;
  }
  function loadSchemaConfig(obj, defaultEndpoint) {
      return {
          schema: obj.schema,
          endpoint: loadEndpointConfig(obj.endpoint, !obj.engineKey && defaultEndpoint),
          engineKey: obj.engineKey,
          clientSide: obj.clientSide,
          extends: obj.extends
      };
  }
  function loadDocumentSet(obj) {
      return {
          schema: obj.schema,
          includes: typeof obj.includes === "string"
              ? [obj.includes]
              : obj.includes
                  ? obj.includes
                  : ["**"],
          excludes: typeof obj.excludes === "string"
              ? [obj.excludes]
              : obj.excludes
                  ? obj.excludes
                  : ["node_modules/**"]
      };
  }
  function loadConfig(obj, configFile, configDir, defaultEndpoint, defaultSchema) {
      const schemasObj = (obj.schemas || {});
      Object.keys(schemasObj).forEach(key => {
          schemasObj[key] = loadSchemaConfig(schemasObj[key], defaultEndpoint);
      });
      if (Object.keys(schemasObj).length == 0 && defaultSchema) {
          schemasObj["default"] = loadSchemaConfig({}, defaultEndpoint);
      }
      return {
          configFile,
          projectFolder: configDir,
          schemas: schemasObj,
          name: path_1.basename(configDir),
          queries: (obj.queries
              ? Array.isArray(obj.queries)
                  ? obj.queries
                  : [obj.queries]
              : Object.keys(schemasObj).length == 1
                  ? [{ schema: Object.keys(schemasObj)[0] }]
                  : []).map(d => loadDocumentSet(d)),
          engineEndpoint: obj.engineEndpoint
      };
  }
  exports.loadConfig = loadConfig;
  function loadConfigFromFile(file, defaultEndpoint, defaultSchema) {
      if (file.endsWith(".js")) {
          delete require.cache[require.resolve(file)];
          return loadConfig(require(file), file, path_1.dirname(file), defaultEndpoint, defaultSchema);
      }
      else if (file.endsWith("package.json")) {
          const apolloKey = JSON.parse(localfs_1.fs.readFileSync(file).toString()).apollo;
          if (apolloKey) {
              return loadConfig(apolloKey, file, path_1.dirname(file), defaultEndpoint, defaultSchema);
          }
          else {
              return loadConfig({}, file, path_1.dirname(file), defaultEndpoint, defaultSchema);
          }
      }
      else {
          throw new Error("Unsupported config file format");
      }
  }
  exports.loadConfigFromFile = loadConfigFromFile;
  function findAndLoadConfig(dir, defaultEndpoint, defaultSchema) {
      if (localfs_1.fs.existsSync(path_1.join(dir, "apollo.config.js"))) {
          return loadConfigFromFile(path_1.join(dir, "apollo.config.js"), defaultEndpoint, defaultSchema);
      }
      else if (localfs_1.fs.existsSync(path_1.join(dir, "package.json"))) {
          return loadConfigFromFile(path_1.join(dir, "package.json"), defaultEndpoint, defaultSchema);
      }
      else {
          return loadConfig({}, dir, dir, defaultEndpoint, defaultSchema);
      }
  }
  exports.findAndLoadConfig = findAndLoadConfig;
  async function resolveSchema(name, config) {
      const referredSchema = (config.schemas || {})[name];
      const loadAsAST = () => {
          const ast = loading_1.loadQueryDocuments([referredSchema.schema])[0];
          if (referredSchema.clientSide) {
              graphql_1.visit(ast, {
                  enter(node) {
                      if (node.kind == "FieldDefinition") {
                          node.__client = true;
                      }
                  }
              });
          }
          return ast;
      };
      return referredSchema.extends
          ? graphql_1.extendSchema((await resolveSchema(referredSchema.extends, config)), loadAsAST())
          : referredSchema.clientSide
              ? graphql_1.buildASTSchema(loadAsAST())
              : await load_schema_1.loadSchema(referredSchema, config);
  }
  exports.resolveSchema = resolveSchema;
  async function resolveDocumentSets(config, needSchema) {
      return await Promise.all((config.queries || []).map(async (doc) => {
          const referredSchema = doc.schema
              ? (config.schemas || {})[doc.schema]
              : undefined;
          const schemaPaths = [];
          let currentSchema = (config.schemas || {})[doc.schema];
          while (currentSchema) {
              if (currentSchema.schema) {
                  schemaPaths.push(currentSchema.schema);
              }
              currentSchema = (config.schemas || {})[currentSchema.extends];
          }
          return {
              schema: needSchema && doc.schema
                  ? await resolveSchema(doc.schema, config)
                  : undefined,
              endpoint: referredSchema ? referredSchema.endpoint : undefined,
              engineKey: referredSchema ? referredSchema.engineKey : undefined,
              documentPaths: doc.includes
                  .flatMap(i => localfs_1.withGlobalFS(() => fg.sync(i, { cwd: config.projectFolder, absolute: true })))
                  .filter(f => ![...doc.excludes, ...schemaPaths].some(e => minimatch(path_1.relative(config.projectFolder, f), e))),
              originalSet: doc
          };
      }));
  }
  exports.resolveDocumentSets = resolveDocumentSets;
  //# sourceMappingURL=config.js.map