You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.8 KiB
JavaScript

"use strict";
const mapObj = require("map-obj");
const filterObj = require("filter-obj");
const typeRules = require("./type-rules");
const generateDescriptor = require("./generate-descriptor");
const getSchemaKeys = require("./util/get-schema-keys");
const nullMissingFields = require("./util/null-missing-fields");
/* TODO: Traits implementing traits */
module.exports = function createTrait(name, schema, options = {}) {
let schemaDescriptors = mapObj(schema, (key, rule) => {
return generateDescriptor(rule, key, true);
});
let schemaKeys = getSchemaKeys(schema);
return typeRules._createTypeRule({
_isTrait: true,
_name: name,
_schema: schema,
applyImplementation: function (implementation) {
/* FIXME: Verify that there are no extraneous keys or unspecified values */
let validatedImplementation = Object.create({
_data: {}
}, schemaDescriptors);
let implementationWithoutSlots = filterObj(implementation, (key, value) => {
return (value == null || value._isSlotRule !== true);
});
let nullFields = nullMissingFields(implementation, schemaKeys);
Object.assign(validatedImplementation, implementationWithoutSlots, nullFields);
let implementationSchema = mapObj(implementation, (key, value) => {
if (value != null && value._isSlotRule === true) {
return [key, {
isSlot: true,
rule: schema[key]
}];
} else {
return [key, {
isSlot: false,
rule: value
}];
}
});
let implementationDescriptors = mapObj(implementationSchema, (key, value) => {
return generateDescriptor(value.rule, key, value.isSlot);
});
let slotSchemaKeys = Object.keys(filterObj(implementationSchema, (key, value) => {
return value.isSlot;
}));
return {implementationSchema, implementationDescriptors, slotSchemaKeys};
}
});
};