<commit_before>import r from 'rethinkdb';
import ResourceArray from './ResourceArray';

import {
  mergeRelationships,
  retrieveManyRecords,
  retrieveSingleRecord,
} from './utils';

export default class Resource {
  /**
   * Instantiates a Resource.
   *
   * @param {Object} conn - RethinkDB connection object.
   * @param {Schema} schema
   * @param {Object} record
   */
  constructor(conn, schema, record) {
    if (!conn) {
      throw new TypeError('A valid RethinkDB connection is required to instantiate a Resource.');
    }

    if (!schema) {
      throw new TypeError('A valid schema is required to instantiate a Resource.');
    }

    if (!record) {
      throw new TypeError('A valid record is required to instantiate a Resource.');
    }

    this.conn = conn;
    this.schema = schema;
    this.id = record.id;
    this.meta = record.meta || {};

    this.attributes = {};
    this.relationships = {};

    Object.keys(record).forEach(field => {
      if (schema.hasAttribute(field)) {
        this.attributes[field] = record[field];
        return;
      }

      if (schema.hasRelationship(field)) {
        const relationship = schema.relationship(field);
        const recordsOrRecord = relationship.relation === 'hasMany'
          ? 'records'
          : 'record';

        this.relationships[field] = {
          ...relationship,
          [recordsOrRecord]: record[field],
        };

        return;
      }
    });
  }

  /**
   * Returns an attribute.
   *
   * ```
   * app.model('user').fetchResource('1').then(user => {
   *   user.attribute('name') === 'Dylan'
   * });
   * ```
   *
   * @param {String} attribute
   * @return {Any}
   */
  attribute(attribute) {
    return this.attributes[attribute];
  }

  /**
   * Returns all the attributes.
   *
   * @return {Object}
   */
  attributes() {
    return this.attributes;
  }

  /**
   * Returns a relationship of the resource.
   *
   * ```
   * app.model('user').fetchResource('1').then(user => {
   *   user.relationship('pets') === {
   *     type: 'animal',
   *     schema: Schema,
   *     relation: 'hasMany',
   *     records: [{
   *       id: '1',
   *       _archived: false,
   *     }, {
   *       id: '2',
   *       _archived: false,
   *     }],
   *     inverse: {
   *       type: 'user',
   *       relation: 'belongsTo',
   *       field: 'owner',
   *     },
   *   }
   *
   *   user.relationship('company') === {
   *     type: 'company',
   *     schema: Schema,
   *     relation: 'hasOne',
   *     record: {
   *       id: '1',
   *       _archived: false,
   *     },
   *     inverse: {
   *       type: 'user',
   *       relation: 'hasMany',
   *       field: 'employees',
   *     },
   *   }
   * });
   * ```
   *
   * @param {String} relationship
   * @return {Object}
   */
  relationship(relationship) {
    return this.relationships[relationship];
  }

  /**
   * Returns all the relationships.
   *
   * @return {Object}
   */
  relationships() {
    return this.relationships;
  }

  /**
   * Ensures that the state of this resource propagates through its relationships that demand
   * propagation.
   *
   * @return {Promise}
   */
  syncRelationships() {

  }

  /**
   * Fetches either the `Resource` or `ResourceArray` related to this resource by `relationship`.
   *
   * ```
   * app.model('user').fetchResource('1').then(user => {
   *   return user.fetch('company');
   * }).then(company => {
   *   // Resource
   * });
   * ```
   *
   * @param  {[type]} relationship [description]
   * @param  {[type]} options      =             {} [description]
   * @return {[type]}              [description]
   */
  fetch(relationship, options = {}) {
    if (!this.relationship(relationship)) {
      return Promise.resolve(null);
    }

    const { conn } = this;

    const {
      type,
      schema,
      relation,
      record: relatedRecord,<commit_msg>Fix documentation for `Resource.fetch`<commit_after>import r from 'rethinkdb';
import ResourceArray from './ResourceArray';

import {
  mergeRelationships,
  retrieveManyRecords,
  retrieveSingleRecord,
} from './utils';

export default class Resource {
  /**
   * Instantiates a Resource.
   *
   * @param {Object} conn - RethinkDB connection object.
   * @param {Schema} schema
   * @param {Object} record
   */
  constructor(conn, schema, record) {
    if (!conn) {
      throw new TypeError('A valid RethinkDB connection is required to instantiate a Resource.');
    }

    if (!schema) {
      throw new TypeError('A valid schema is required to instantiate a Resource.');
    }

    if (!record) {
      throw new TypeError('A valid record is required to instantiate a Resource.');
    }

    this.conn = conn;
    this.schema = schema;
    this.id = record.id;
    this.meta = record.meta || {};

    this.attributes = {};
    this.relationships = {};

    Object.keys(record).forEach(field => {
      if (schema.hasAttribute(field)) {
        this.attributes[field] = record[field];
        return;
      }

      if (schema.hasRelationship(field)) {
        const relationship = schema.relationship(field);
        const recordsOrRecord = relationship.relation === 'hasMany'
          ? 'records'
          : 'record';

        this.relationships[field] = {
          ...relationship,
          [recordsOrRecord]: record[field],
        };

        return;
      }
    });
  }

  /**
   * Returns an attribute.
   *
   * ```
   * app.model('user').fetchResource('1').then(user => {
   *   user.attribute('name') === 'Dylan'
   * });
   * ```
   *
   * @param {String} attribute
   * @return {Any}
   */
  attribute(attribute) {
    return this.attributes[attribute];
  }

  /**
   * Returns all the attributes.
   *
   * @return {Object}
   */
  attributes() {
    return this.attributes;
  }

  /**
   * Returns a relationship of the resource.
   *
   * ```
   * app.model('user').fetchResource('1').then(user => {
   *   user.relationship('pets') === {
   *     type: 'animal',
   *     schema: Schema,
   *     relation: 'hasMany',
   *     records: [{
   *       id: '1',
   *       _archived: false,
   *     }, {
   *       id: '2',
   *       _archived: false,
   *     }],
   *     inverse: {
   *       type: 'user',
   *       relation: 'belongsTo',
   *       field: 'owner',
   *     },
   *   }
   *
   *   user.relationship('company') === {
   *     type: 'company',
   *     schema: Schema,
   *     relation: 'hasOne',
   *     record: {
   *       id: '1',
   *       _archived: false,
   *     },
   *     inverse: {
   *       type: 'user',
   *       relation: 'hasMany',
   *       field: 'employees',
   *     },
   *   }
   * });
   * ```
   *
   * @param {String} relationship
   * @return {Object}
   */
  relationship(relationship) {
    return this.relationships[relationship];
  }

  /**
   * Returns all the relationships.
   *
   * @return {Object}
   */
  relationships() {
    return this.relationships;
  }

  /**
   * Ensures that the state of this resource propagates through its relationships that demand
   * propagation.
   *
   * @return {Promise}
   */
  syncRelationships() {

  }

  /**
   * Fetches either the `Resource` or `ResourceArray` related to this resource by `relationship`.
   *
   * ```
   * app.model('user').fetchResource('1').then(user => {
   *   return user.fetch('company');
   * }).then(company => {
   *   // Resource
   * });
   * ```
   *
   * @param {String} relationship
   * @param {Options} [options={}]
   * @return {Resource|ResourceArray}
   */
  fetch(relationship, options = {}) {
    if (!this.relationship(relationship)) {
      return Promise.resolve(null);
    }

    const { conn } = this;

    const {
      type,
      schema,
      relation,
      record: relatedRecord,
{'fraction_non_alphanumeric': 0.15483870967741936, 'fraction_numerical': 0.0015483870967741935, 'mean_word_length': 2.0880478087649403, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, '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': '4463096', 'n_tokens_mistral': 2455, 'n_tokens_neox': 2396, 'n_words': 513}