const mongoose = require('mongoose');

const { Schema } = mongoose;

const roleSchema = new Schema({
	name: { type: String, required: true },
	permissions: [{ type: String }],

	// inheritance
	roles: [{ type: Schema.Types.ObjectId }],
}, {
	timestamps: true,
});

const roleModel = mongoose.model('role', roleSchema);

roleSchema.methods.getPermissions = function getPermissions() {
	return roleModel.resolvePermissions([this._id]);
};

roleSchema.statics.resolvePermissions = function resolvePermissions(roleIds) {
	const processedRoleIds = [];
	const permissions = new Set();

	function resolveSubRoles(roleId) {
		return roleModel.findById(roleId)
			.then((role) => {
				if (typeof role !== 'object') {
					role = {};
				}
				if (Array.isArray(role.permissions) === false) {
					role.permissions = [];
				}
				role.permissions.forEach(p => permissions.add(p));
				const promises = role.roles
					.filter(id => !processedRoleIds.includes(id))
					.map((id) => {
						processedRoleIds.push(id);
						return resolveSubRoles(id); // recursion
					});
				return Promise.all(promises);
			});
	}

	return Promise.all(roleIds.map(id => resolveSubRoles(id)))
		.then(() => permissions);
};


module.exports = roleModel;

@@ -262,63 +262,8 @@
 );%0A%0A
-const roleModel = mongoose.model('role', roleSchema);%0A%0A
 role
@@ -303,30 +303,16 @@
 unction 
-getPermissions
 () %7B%0A%09re
@@ -411,34 +411,16 @@
 unction 
-resolvePermissions
 (roleIds
@@ -1108,16 +1108,70 @@
 s);%0A%7D;%0A%0A
+const roleModel = mongoose.model('role', roleSchema);%0A
 %0Amodule.

revert role model changes