{"size": 1676, "ext": "js", "max_stars_repo_path": "src/index.js", "max_stars_repo_name": "eeyang92/class-to-mongoose-schema", "max_stars_repo_stars_event_min_datetime": "2017-09-01T06:47:00.000Z", "max_stars_repo_stars_event_max_datetime": "2020-02-20T00:43:42.000Z", "max_issues_repo_path": "src/index.js", "max_issues_repo_name": "eeyang92/class-to-mongoose-schema", "max_issues_repo_issues_event_min_datetime": "2018-06-28T15:45:36.000Z", "max_issues_repo_issues_event_max_datetime": "2018-12-31T02:46:30.000Z", "max_forks_repo_path": "src/index.js", "max_forks_repo_name": "eeyang92/class-to-mongoose-schema", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 2, "max_issues_count": 1, "max_forks_count": null, "avg_line_length": 23.2777777778, "max_line_length": 83, "alphanum_fraction": 0.6437947494}
import { Schema } from 'mongoose'

function isAttribute(obj) {
	if (obj === String || obj === Number || obj === Boolean || obj === Date ||
		obj === Schema.Types.Mixed || obj === Schema.Types.ObjectId) {
		return true
	}

	return false
}

function getAllProps(obj) {
	let props = {
		methods: {},
		staticMethods: {},
		attributes: {},
		staticAttributes: {}
	}

	const usedNames = new Set()

	do {
		const tempStatics = Object.getOwnPropertyNames(obj.constructor).filter((value) =>
			value !== 'length' && value !== 'name' && value !== 'prototype' &&
			!usedNames.has(value)
		)

		tempStatics.forEach((value) => {
			const pValue = obj.constructor[value]
			if (typeof pValue === 'function' && !isAttribute(pValue)) {
				props.staticMethods[value] = pValue
			} else {
				props.staticAttributes[value] = pValue
			}

			usedNames.add(value)
		})

		const temp = Object.getOwnPropertyNames(obj)
			.concat(Object.getOwnPropertySymbols(obj).map(s => s.toString()))
			.filter((value, i, arr) =>
				value !== 'constructor' &&
				(i == 0 || value !== arr[i - 1]) &&
				!usedNames.has(value)
			)

		temp.forEach((value) => {
			const pValue = obj[value]
			if (typeof pValue === 'function' && !isAttribute(pValue)) {
				props.methods[value] = pValue
			} else {
				props.attributes[value] = pValue
			}

			usedNames.add(value)
		})
	}
	while ((obj = Object.getPrototypeOf(obj)) && Object.getPrototypeOf(obj))

	return props
}

export default function classToSchema(obj, schemaOptions) {
	const props = getAllProps(obj)
	const schema = new Schema(props.attributes, schemaOptions)

	schema.statics = props.staticMethods
	schema.methods = props.methods

	return schema
}
