<commit_before>/* @flow */
/* eslint-disable no-param-reassign, class-methods-use-this  */

import dox from 'dox';
import fs from 'fs';
import path from 'path';
import {
  GraphQLString,
  GraphQLFloat,
  GraphQLBoolean,
  GraphQLObjectType,
  GraphQLEnumType,
} from 'graphql';
import { GraphQLJSON, upperFirst, TypeComposer } from 'graphql-compose';

import type {
  GraphQLArgumentConfig,
  GraphQLFieldConfigArgumentMap,
  GraphQLFieldMap,
  GraphQLInputType,
} from 'graphql/type/definition';

export type ElasticApiParserOptsT = {
  version?:
    '5_0'
    | '5_x'
    | '2_4'
    | '2_3'
    | '2_2'
    | '2_1'
    | '2_0'
    | '1_7'
    | '1_6'
    | '1_5'
    | '1_4'
    | '1_3'
    | '1_2'
    | '1_1'
    | '1_0'
    | '0_90',
  prefix?: string,
};

export type ElasticParamConfigT = {
  type: string,
  name?: string,
  options?: mixed,
  default?: mixed,
};

export type ElasticCaSettingsUrlT = {
  fmt: string,
  req: {
    [name: string]: ElasticParamConfigT,
  },
};

export type ElasticCaSettingsT = {
  params: {
    [name: string]: ElasticParamConfigT,
  },
  url?: ElasticCaSettingsUrlT,
  urls?: ElasticCaSettingsUrlT[],
};

export const elasticApiFilesPath = './node_modules/elasticsearch/src/lib/apis/';

export default class ElasticApiParser {
  cachedEnums: {
    [fieldName: string]: { [valsStringified: string]: GraphQLEnumType },
  };
  version: string;
  prefix: string;

  constructor(opts: ElasticApiParserOptsT = {}) {
    // derived from installed package `elasticsearch`
    // from ../../node_modules/elasticsearch/src/lib/apis/VERSION.js
    this.version = opts.version || '5_0';
    this.prefix = opts.prefix || 'Elastic';
    this.cachedEnums = {};
  }

  run() {
    this.cachedEnums = {};
    const apiFilePath = path.resolve(elasticApiFilesPath, `${this.version}.js`);
    const source = this.loadApiFile(apiFilePath);
    return this.parseSource(source);
  }

  parseSource(source: string): GraphQLFieldMap<*, *> {
    let result = {};

    if (!source || typeof source !== 'string') {
      throw Error('Empty source. It should be non-empty string.');
    }

    const doxAST = dox.parseComments(source, { raw: true });
    if (!doxAST || !Array.isArray(doxAST)) {
      throw Error('Incorrect responce from dox.parseComments');
    }

    doxAST.forEach(item => {
      if (!item.ctx || !item.ctx.string) {<commit_msg>fix(ElasticApiParser): Add `elasticApiFilesPath` option<commit_after>/* @flow */
/* eslint-disable no-param-reassign, class-methods-use-this  */

import dox from 'dox';
import fs from 'fs';
import path from 'path';
import {
  GraphQLString,
  GraphQLFloat,
  GraphQLBoolean,
  GraphQLObjectType,
  GraphQLEnumType,
} from 'graphql';
import { GraphQLJSON, upperFirst, TypeComposer } from 'graphql-compose';

import type {
  GraphQLArgumentConfig,
  GraphQLFieldConfigArgumentMap,
  GraphQLFieldMap,
  GraphQLInputType,
} from 'graphql/type/definition';

export type ElasticApiParserOptsT = {
  version?:
    '5_0'
    | '5_x'
    | '2_4'
    | '2_3'
    | '2_2'
    | '2_1'
    | '2_0'
    | '1_7'
    | '1_6'
    | '1_5'
    | '1_4'
    | '1_3'
    | '1_2'
    | '1_1'
    | '1_0'
    | '0_90',
  prefix?: string,
  elasticApiFilesPath?: string,
};

export type ElasticParamConfigT = {
  type: string,
  name?: string,
  options?: mixed,
  default?: mixed,
};

export type ElasticCaSettingsUrlT = {
  fmt: string,
  req: {
    [name: string]: ElasticParamConfigT,
  },
};

export type ElasticCaSettingsT = {
  params: {
    [name: string]: ElasticParamConfigT,
  },
  url?: ElasticCaSettingsUrlT,
  urls?: ElasticCaSettingsUrlT[],
};

export default class ElasticApiParser {
  cachedEnums: {
    [fieldName: string]: { [valsStringified: string]: GraphQLEnumType },
  };
  version: string;
  prefix: string;
  elasticApiFilesPath: string;

  constructor(opts: ElasticApiParserOptsT = {}) {
    // derived from installed package `elasticsearch`
    // from ../../node_modules/elasticsearch/src/lib/apis/VERSION.js
    this.version = opts.version || '5_0';
    this.prefix = opts.prefix || 'Elastic';
    this.elasticApiFilesPath = opts.elasticApiFilesPath || './node_modules/elasticsearch/src/lib/apis/';
    this.cachedEnums = {};
  }

  run() {
    this.cachedEnums = {};
    const apiFilePath = path.resolve(this.elasticApiFilesPath, `${this.version}.js`);
    const source = this.loadApiFile(apiFilePath);
    return this.parseSource(source);
  }

  parseSource(source: string): GraphQLFieldMap<*, *> {
    let result = {};

    if (!source || typeof source !== 'string') {
      throw Error('Empty source. It should be non-empty string.');
    }

    const doxAST = dox.parseComments(source, { raw: true });
    if (!doxAST || !Array.isArray(doxAST)) {
      throw Error('Incorrect responce from dox.parseComments');
    }

    doxAST.forEach(item => {
      if (!item.ctx || !item.ctx.string) {
{'fraction_non_alphanumeric': 0.1466173144149702, 'fraction_numerical': 0.013983137980670367, 'mean_word_length': 3.3898916967509027, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5489388', 'n_tokens_mistral': 1720, 'n_tokens_neox': 1705, 'n_words': 350}