<commit_before>const crypto = require('crypto');
const moment = require('moment');
const objectSorter = require('../helpers/objectSorter');
const { MissingArgumentsError } = require('../helpers/errors');

class User {
	constructor(document, db, config) {
		if (document == null || db == null || config == null) {
			throw new MissingArgumentsError();
		}

		this.document = document;
		this.db = db;
		this.config = config;
	}

	// TODO: 各種操作用メソッドの追加

	verifyPassword(password) {
		if (password == null) {
			throw new MissingArgumentsError();
		}

		const passwordHashElements = this.document.passwordHash.split('.');
		const hash = passwordHashElements[0];
		const salt = passwordHashElements[1];

		const sha256 = crypto.createHash('sha256');
		sha256.update(`${password}.${salt}`);

		return hash == sha256.digest('hex');
	}

	async serializeAsync() {
		const res = {};
		Object.assign(res, this.document);

		// createdAt
		res.createdAt = parseInt(moment(res._id.getTimestamp()).format('X'));

		// id
		res.id = res._id.toString();
		delete res._id;

		// passwordHash
		delete res.passwordHash;

		// followingsCount, followersCount
		const userFollowingsCollection = this.db.dbProvider.connection.collection('userFollowings'); // TODO: dbProviderを直接操作しないように修正する
		const postsCollection = this.db.dbProvider.connection.collection('posts');
		[res.followingsCount, res.followersCount, res.statusPostsCount] = await Promise.all([
			userFollowingsCollection.count({ source: this.document._id }),
			userFollowingsCollection.count({ target: this.document._id }),
			postsCollection.count({ type: 'status', userId: this.document._id })
		]);

		return objectSorter(res);
	}

	// 最新の情報を取得して同期する
	async fetchAsync() {
		this.document = (await this.db.users.findByIdAsync(this.document._id)).document;
	}

	// static methods

	/**
	 * idからドキュメントモデルのインスタンスを取得します
	 *
	 * @return {Promise<User>}
	 */
	static async findByIdAsync(id, db, config) {
		if (id == null || db == null || config == null) {
			throw new MissingArgumentsError();
		}
<commit_msg>rename<commit_after>const crypto = require('crypto');
const moment = require('moment');
const objectSorter = require('../helpers/objectSorter');
const { MissingArgumentsError } = require('../helpers/errors');

class User {
	constructor(document, db, config) {
		if (document == null || db == null || config == null) {
			throw new MissingArgumentsError();
		}

		this.document = document;
		this.db = db;
		this.config = config;
	}

	// TODO: 各種操作用メソッドの追加

	verifyPassword(password) {
		if (password == null) {
			throw new MissingArgumentsError();
		}

		const passwordHashElements = this.document.passwordHash.split('.');
		const hash = passwordHashElements[0];
		const salt = passwordHashElements[1];

		const sha256 = crypto.createHash('sha256');
		sha256.update(`${password}.${salt}`);

		return hash == sha256.digest('hex');
	}

	async serializeAsync() {
		const res = {};
		Object.assign(res, this.document);

		// createdAt
		res.createdAt = parseInt(moment(res._id.getTimestamp()).format('X'));

		// id
		res.id = res._id.toString();
		delete res._id;

		// passwordHash
		delete res.passwordHash;

		// followingsCount, followersCount, postsCount.status
		const userFollowingsCollection = this.db.dbProvider.connection.collection('userFollowings'); // TODO: dbProviderを直接操作しないように修正する
		const postsCollection = this.db.dbProvider.connection.collection('posts');
		res.postsCount = {};
		[res.followingsCount, res.followersCount, res.postsCount.status] = await Promise.all([
			userFollowingsCollection.count({ source: this.document._id }),
			userFollowingsCollection.count({ target: this.document._id }),
			postsCollection.count({ type: 'status', userId: this.document._id })
		]);

		return objectSorter(res);
	}

	// 最新の情報を取得して同期する
	async fetchAsync() {
		this.document = (await this.db.users.findByIdAsync(this.document._id)).document;
	}

	// static methods

	/**
	 * idからドキュメントモデルのインスタンスを取得します
	 *
	 * @return {Promise<User>}
	 */
	static async findByIdAsync(id, db, config) {
		if (id == null || db == null || config == null) {
			throw new MissingArgumentsError();
		}

{'fraction_non_alphanumeric': 0.15072463768115943, 'fraction_numerical': 0.00676328502415459, 'mean_word_length': 4.268447837150127, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '3190391', 'n_tokens_mistral': 1479, 'n_tokens_neox': 1337, 'n_words': 260}