<commit_before>import pluralize from 'pluralize';
import { Module } from 'oors';
import camelCase from 'lodash/camelCase';
import glob from 'glob';
import fse from 'fs-extra';
import path from 'path';
import { createLoaders } from 'oors-mongodb/build/libs/graphql';

class RADModule extends Module {
  static schema = {
    type: 'object',
    properties: {
      autoload: {
        type: 'object',
        properties: {
          services: {
            type: 'boolean',
            default: true,
          },
          methods: {
            type: 'boolean',
            default: true,
          },
        },
      },
      autoCreateLoaders: {
        type: 'boolean',
        default: true,
      },
    },
  };

  name = 'oors.rad';

  services = {};

  hooks = {
    'oors.graphql.buildContext': ({ context }) => {
      Object.assign(context, {
        getService: this.getService,
        getModule: name => this.app.modules.get(name),
      });
    },
  };

  async setup({ autoCreateLoaders }) {
    const dependencies = [];
    if (autoCreateLoaders) {
      dependencies.push('oors.graphql', 'oors.mongodb');
    }

    await this.loadDependencies(dependencies);

    await this.runHook('load', this.collectFromModule);

    this.exportProperties(['registerModuleService', 'setService', 'getService', 'getLoadersName']);

    if (autoCreateLoaders) {
      const { loaders } = this.deps['oors.graphql'];
      this.on('module:oors.mongodb:repository', ({ repository, key }) => {
        this.deps['oors.graphql'].addLoaders(createLoaders(repository), this.getLoadersName(key));
      });
      this.export({
        getLoaders: repositoryName => loaders[this.getLoadersName(repositoryName)],
      });
    }
  }

  collectFromModule = async module => {
    const tasks = [];

    if (module.getConfig('oors.rad.autoload.services', this.getConfig('autoload.services'))) {
      tasks.push(this.loadModuleServices(module));
    }

    if (module.getConfig('oors.rad.autoload.methods', this.getConfig('autoload.methods'))) {
      tasks.push(this.loadModuleMethods(module));
    }

    if (!tasks.length) {
      return;
    }

    await Promise.all(tasks);
  };

  async loadModuleServices(module) {
    const dirPath = path.resolve(path.dirname(module.filePath), 'services');

    try {
      const stat = await fse.stat(dirPath);
      const isDirectory = stat && stat.isDirectory();
      if (!isDirectory) {
        return;
      }
    } catch (err) {
      return;
    }

    await new Promise((resolve, reject) => {
      glob(path.resolve(dirPath, '*.js'), { nodir: true }, (err, files) => {
        if (err) {
          reject(err);
          return;
        }

        files.forEach(file => {
          const Service = require(file).default; // eslint-disable-line global-require, import/no-dynamic-require
          const service = new Service(module);
          if (!service.name) {
            throw new Error(`Unable to register a service without a name! ${service}`);
          }
          this.registerModuleService(module, service);
        });

        resolve();
      });
    });
  }

  // eslint-disable-next-line class-methods-use-this
  async loadModuleMethods(module) {
    const dirPath = path.resolve(path.dirname(module.filePath), 'methods');

    try {
      const stat = await fse.stat(dirPath);
      const isDirectory = stat && stat.isDirectory();
      if (!isDirectory) {
        return;
      }
    } catch (err) {
      return;
    }

    await new Promise((resolve, reject) => {
      glob(path.resolve(dirPath, '*.js'), { nodir: true }, (err, files) => {
        if (err) {
          reject(err);
          return;
        }

        files.forEach(file => {
          const method = require(file).default; // eslint-disable-line global-require, import/no-dynamic-require
          const { name } = path.parse(file);

          if (typeof method !== 'function') {
            throw new Error(
              `Unable to register "${name}" method for ${module.name} module! (not a function)`,
            );
          }

          module.export(name, (...args) => method.call(module, { args, module }));
        });
<commit_msg>[oors-rad] getService will be available to module methods<commit_after>import pluralize from 'pluralize';
import { Module } from 'oors';
import camelCase from 'lodash/camelCase';
import glob from 'glob';
import fse from 'fs-extra';
import path from 'path';
import { createLoaders } from 'oors-mongodb/build/libs/graphql';

class RADModule extends Module {
  static schema = {
    type: 'object',
    properties: {
      autoload: {
        type: 'object',
        properties: {
          services: {
            type: 'boolean',
            default: true,
          },
          methods: {
            type: 'boolean',
            default: true,
          },
        },
      },
      autoCreateLoaders: {
        type: 'boolean',
        default: true,
      },
    },
  };

  name = 'oors.rad';

  services = {};

  hooks = {
    'oors.graphql.buildContext': ({ context }) => {
      Object.assign(context, {
        getService: this.getService,
        getModule: name => this.app.modules.get(name),
      });
    },
  };

  async setup({ autoCreateLoaders }) {
    const dependencies = [];
    if (autoCreateLoaders) {
      dependencies.push('oors.graphql', 'oors.mongodb');
    }

    await this.loadDependencies(dependencies);

    await this.runHook('load', this.collectFromModule);

    this.exportProperties(['registerModuleService', 'setService', 'getService', 'getLoadersName']);

    if (autoCreateLoaders) {
      const { loaders } = this.deps['oors.graphql'];
      this.on('module:oors.mongodb:repository', ({ repository, key }) => {
        this.deps['oors.graphql'].addLoaders(createLoaders(repository), this.getLoadersName(key));
      });
      this.export({
        getLoaders: repositoryName => loaders[this.getLoadersName(repositoryName)],
      });
    }
  }

  collectFromModule = async module => {
    const tasks = [];

    if (module.getConfig('oors.rad.autoload.services', this.getConfig('autoload.services'))) {
      tasks.push(this.loadModuleServices(module));
    }

    if (module.getConfig('oors.rad.autoload.methods', this.getConfig('autoload.methods'))) {
      tasks.push(this.loadModuleMethods(module));
    }

    if (!tasks.length) {
      return;
    }

    await Promise.all(tasks);
  };

  async loadModuleServices(module) {
    const dirPath = path.resolve(path.dirname(module.filePath), 'services');

    try {
      const stat = await fse.stat(dirPath);
      const isDirectory = stat && stat.isDirectory();
      if (!isDirectory) {
        return;
      }
    } catch (err) {
      return;
    }

    await new Promise((resolve, reject) => {
      glob(path.resolve(dirPath, '*.js'), { nodir: true }, (err, files) => {
        if (err) {
          reject(err);
          return;
        }

        files.forEach(file => {
          const Service = require(file).default; // eslint-disable-line global-require, import/no-dynamic-require
          const service = new Service(module);
          if (!service.name) {
            throw new Error(`Unable to register a service without a name! ${service}`);
          }
          this.registerModuleService(module, service);
        });

        resolve();
      });
    });
  }

  // eslint-disable-next-line class-methods-use-this
  async loadModuleMethods(module) {
    const dirPath = path.resolve(path.dirname(module.filePath), 'methods');

    try {
      const stat = await fse.stat(dirPath);
      const isDirectory = stat && stat.isDirectory();
      if (!isDirectory) {
        return;
      }
    } catch (err) {
      return;
    }

    await new Promise((resolve, reject) => {
      glob(path.resolve(dirPath, '*.js'), { nodir: true }, (err, files) => {
        if (err) {
          reject(err);
          return;
        }

        files.forEach(file => {
          const method = require(file).default; // eslint-disable-line global-require, import/no-dynamic-require
          const { name } = path.parse(file);

          if (typeof method !== 'function') {
            throw new Error(
              `Unable to register "${name}" method for ${module.name} module! (not a function)`,
            );
          }

          module.export(name, (...args) =>
            method.call(module, { args, module, getService: this.getService }),
          );
        });

{'fraction_non_alphanumeric': 0.14651190335188913, 'fraction_numerical': 0.0, 'mean_word_length': 2.286882055274426, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 27, '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': '3078399', 'n_tokens_mistral': 2527, 'n_tokens_neox': 2450, 'n_words': 509}