<commit_before>const dynamo = require('dynamodb');
const Proto = require('uberproto');
const { pick, isArray } = require('lodash');

const DEFAULT_ID_FIELD = 'id';
const RESERVED_ATTRIBUTE_NAMES = require('./lib/reserved-attribute-names');

const mapExpressionAttributeNames = function(names) {
  return names.map(name => {
    const upper = name.toUpperCase();
    if (~RESERVED_ATTRIBUTE_NAMES.indexOf(upper)) {
      return [`#${name}`, name];
    } else {
      return name;
    }
  });
}

class Service {
  constructor (options) {
    if (!(options && options.Model)) {
      throw new Error('DynamoDB options and options.Model must be supplied');
    }
    this.id = options.id || DEFAULT_ID_FIELD;
    this.events = options.events || [];
    this.paginate = options.paginate || {};
    this.Model = options.Model;
  }

  parseParams(_params) {
    const params = {
      ExpressionAttributeNames: {}
    };

    if (_params.query && _params.query.$select && Array.isArray(_params.query.$select)) {
      const select = _params.query.$select;

      if (!~select.indexOf(this.id)) select.push(this.id);

      const mapped = mapExpressionAttributeNames(select);

      params.ProjectionExpression = mapped.map(attr => {
        if (Array.isArray(attr)) {
          params.ExpressionAttributeNames[attr[0]] = attr[1];
          return attr[0];
        }
        return attr;
      }).join(', ');
    }

    if (!Object.keys(params.ExpressionAttributeNames).length) {
      delete params.ExpressionAttributeNames;
    }

    console.log('PARAMS', params);

    return params;
  }

  postSelect(doc, params) {
    if (params.query && params.query.$select && Array.isArray(params.query.$select)) {
      const out = pick(doc.get(), params.query.$select);
      out[this.id] = doc.get(this.id);
      return out;
    }
    return doc.get();
  }

  find(params) {
    if (!params.query) {
      return this.scan(params);
    }
  }

  scan(params) {
    return new Promise((resolve, reject) => {
      this.Model
        .scan()
        .loadAll()
        .exec()
      });
  }

  get (id, params) {
    return new Promise((resolve, reject) => {
      this.Model.get(id, this.parseParams(params), (err, doc) => {
        if (err) return reject(err);
        return resolve(doc ? doc.get() : undefined);
      });
    });
  }

  create (data, params) {
    return new Promise((resolve, reject) => {
      this.Model.create(data, (err, doc) => {
        if (err) return reject(err);
        return resolve(doc ? (isArray(doc)? _.map(doc, (d) => d.get()) : doc.get() ): undefined);
      });
    });
  }

  patch (id, data, params) {
    const patch = Object.assign({}, data);
    patch[this.id] = id;

    return new Promise((resolve, reject) => {
      this.Model.update(patch, (err, doc) => {
        if (err) return reject(err);
        return resolve(doc ? doc.get() : undefined);
      });
    });
  }

  update (id, data, params) {
    return this.patch(id, data, params);
  }

  remove(id, _params) {<commit_msg>Fix: doc.get is not a function<commit_after>const dynamo = require('dynamodb');
const Proto = require('uberproto');
const { pick, isArray, map } = require('lodash');

const DEFAULT_ID_FIELD = 'id';
const RESERVED_ATTRIBUTE_NAMES = require('./lib/reserved-attribute-names');

const mapExpressionAttributeNames = function(names) {
  return names.map(name => {
    const upper = name.toUpperCase();
    if (~RESERVED_ATTRIBUTE_NAMES.indexOf(upper)) {
      return [`#${name}`, name];
    } else {
      return name;
    }
  });
}

class Service {
  constructor (options) {
    if (!(options && options.Model)) {
      throw new Error('DynamoDB options and options.Model must be supplied');
    }
    this.id = options.id || DEFAULT_ID_FIELD;
    this.events = options.events || [];
    this.paginate = options.paginate || {};
    this.Model = options.Model;
  }

  parseParams(_params) {
    const params = {
      ExpressionAttributeNames: {}
    };

    if (_params.query && _params.query.$select && Array.isArray(_params.query.$select)) {
      const select = _params.query.$select;

      if (!~select.indexOf(this.id)) select.push(this.id);

      const mapped = mapExpressionAttributeNames(select);

      params.ProjectionExpression = mapped.map(attr => {
        if (Array.isArray(attr)) {
          params.ExpressionAttributeNames[attr[0]] = attr[1];
          return attr[0];
        }
        return attr;
      }).join(', ');
    }

    if (!Object.keys(params.ExpressionAttributeNames).length) {
      delete params.ExpressionAttributeNames;
    }

    console.log('PARAMS', params);

    return params;
  }

  postSelect(doc, params) {
    if (params.query && params.query.$select && Array.isArray(params.query.$select)) {
      const out = pick(doc.get(), params.query.$select);
      out[this.id] = doc.get(this.id);
      return out;
    }
    return doc.get();
  }

  find(params) {
    if (!params.query) {
      return this.scan(params);
    }
  }

  scan(params) {
    return new Promise((resolve, reject) => {
      this.Model
        .scan()
        .loadAll()
        .exec()
      });
  }

  get (id, params) {
    return new Promise((resolve, reject) => {
      this.Model.get(id, this.parseParams(params), (err, doc) => {
        if (err) return reject(err);
        return resolve(doc ? doc.get() : undefined);
      });
    });
  }

  create (data, params) {
    return new Promise((resolve, reject) => {
      this.Model.create(data, (err, doc) => {
        if (err) return reject(err);
        return resolve(doc ? (isArray(doc)? map(doc, (d) => d.get()) : doc.get() ): undefined);
      });
    });
  }

  patch (id, data, params) {
    const patch = Object.assign({}, data);
    patch[this.id] = id;

    return new Promise((resolve, reject) => {
      this.Model.update(patch, (err, doc) => {
        if (err) return reject(err);
        return resolve(doc ? doc.get() : undefined);
      });
    });
  }

  update (id, data, params) {
    return this.patch(id, data, params);
  }

  remove(id, _params) {
{'fraction_non_alphanumeric': 0.16292134831460675, 'fraction_numerical': 0.0009914077990746861, 'mean_word_length': 2.6662628709872807, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, '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': '5943694', 'n_tokens_mistral': 1924, 'n_tokens_neox': 1895, 'n_words': 404}