<commit_before>'use strict'

const _ = require('lodash')
const inflection = require('inflection')

// TODO: allow comment syntax to allow the user to override the relationship definition for a model

const RELATIONSHIP_TYPES = Object.freeze({
  BELONGS_TO: 'belongsTo',
  BELONGS_TO_MANY: 'belongsToMany',
  HAS_ONE: 'hasOne',
  HAS_MANY: 'hasMany',
  MORPH_ONE: 'morphOne',
  MORPH_TO: 'morphTo',
  MORPH_MANY: 'morphMany'
})

const MATCHERS = Object.freeze({
  INNER_FUNCTION_BLOCK: /\)\s*{([\s\S]*)}/,
  RELATIONSHIP_TYPE: /return\s*this\s*\.\s*([^\(]*)\s*\(/,
  THROUGH: /\.*through\s*\(/,
  MODEL_TO_NAME: new RegExp(`(?:${_.values(RELATIONSHIP_TYPES).join('|')})\\s*\\(([^,\\)]*)`),
  THROUGH_MODEL_NAME: new RegExp(`\\s*through\\s*\\(([^,\\)]*)`)
})

const capture = (str, matcher) => matcher.test(str) ? str.match(matcher)[1] : null

module.exports = (Model, options) => {
  const instance = new Model()
  const proto = Reflect.getPrototypeOf(instance)

  options = _.defaults(options, {
    modelName: _.upperFirst(inflection.singularize(_.toLower(instance.tableName)))
  })

  const relationships = {}
  Reflect.ownKeys(proto).forEach(prop => {
    if (_.includes(['constructor', 'tableName', 'idAttribute'], prop)) return

    const relationName = prop
    const functionString = proto[relationName].toString()
    const innerBlock = functionString.match(MATCHERS.INNER_FUNCTION_BLOCK)

    if (!innerBlock) return

    relationships[prop] = {
      name: prop,
      type: capture(functionString, MATCHERS.RELATIONSHIP_TYPE),
      through: MATCHERS.THROUGH.test(functionString),
      keyFrom: null,
      keyTo: null,
      modelFromName: options.modelName,
      modelToName: capture(functionString, MATCHERS.MODEL_TO_NAME),
      throughModelName: capture(functionString, MATCHERS.THROUGH_MODEL_NAME)
    }

    if (RELATIONSHIP_TYPES.BELONGS_TO === relationships[prop].type) {<commit_msg>Reduce code<commit_after>'use strict'

const _ = require('lodash')
const inflection = require('inflection')

// TODO: allow comment syntax to allow the user to override the relationship definition for a model

const RELATIONSHIP_TYPES = Object.freeze({
  BELONGS_TO: 'belongsTo',
  BELONGS_TO_MANY: 'belongsToMany',
  HAS_ONE: 'hasOne',
  HAS_MANY: 'hasMany',
  MORPH_ONE: 'morphOne',
  MORPH_TO: 'morphTo',
  MORPH_MANY: 'morphMany'
})

const MATCHERS = Object.freeze({
  INNER_FUNCTION_BLOCK: /\)\s*{([\s\S]*)}/,
  RELATIONSHIP_TYPE: /return\s*this\s*\.\s*([^\(]*)\s*\(/,
  THROUGH: /\.*through\s*\(/,
  MODEL_TO_NAME: new RegExp(`(?:${_.values(RELATIONSHIP_TYPES).join('|')})\\s*\\(([^,\\)]*)`),
  THROUGH_MODEL_NAME: new RegExp(`\\s*through\\s*\\(([^,\\)]*)`)
})

const capture = (str, matcher) => matcher.test(str) ? str.match(matcher)[1] : null

module.exports = (Model, options) => {
  const instance = new Model()
  const proto = Reflect.getPrototypeOf(instance)

  options = _.defaults(options, {
    modelName: _.upperFirst(inflection.singularize(_.toLower(instance.tableName)))
  })

  const relationships = {}
  Reflect.ownKeys(proto).forEach(prop => {
    if (_.includes(['constructor', 'tableName', 'idAttribute'], prop)) return

    const functionString = proto[prop].toString()
    const innerBlock = functionString.match(MATCHERS.INNER_FUNCTION_BLOCK)

    if (!innerBlock) return

    relationships[prop] = {
      name: prop,
      type: capture(functionString, MATCHERS.RELATIONSHIP_TYPE),
      through: MATCHERS.THROUGH.test(functionString),
      keyFrom: null,
      keyTo: null,
      modelFromName: options.modelName,
      modelToName: capture(functionString, MATCHERS.MODEL_TO_NAME),
      throughModelName: capture(functionString, MATCHERS.THROUGH_MODEL_NAME)
    }

    if (RELATIONSHIP_TYPES.BELONGS_TO === relationships[prop].type) {
{'fraction_non_alphanumeric': 0.1636604774535809, 'fraction_numerical': 0.0005305039787798408, 'mean_word_length': 4.465217391304348, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '3759569', 'n_tokens_mistral': 1359, 'n_tokens_neox': 1316, 'n_words': 238}