concise
Version:
A tool belt for concise schemas
168 lines (141 loc) • 5.15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _timm = require("timm");
var _lodash = _interopRequireDefault(require("lodash.clonedeep"));
var _inflection = require("inflection");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable no-param-reassign */
const preprocess = schema0 => {
const schema = (0, _timm.addDefaults)((0, _lodash.default)(schema0), {
models: {},
authRules: []
});
addModelDefaults(schema.models);
processIncludes(schema.models);
addFieldDefaults(schema.models);
processRelations(schema.models);
return schema;
};
const addModelDefaults = models => {
Object.keys(models).forEach(modelName => {
models[modelName] = (0, _timm.addDefaults)(models[modelName], {
fields: {},
relations: {},
singular: modelName,
plural: (0, _inflection.pluralize)(modelName),
existsInServer: true,
existsInClient: true
});
});
};
const processIncludes = models => {
// Extract includes
const includes = {};
Object.keys(models).forEach(modelName => {
const model = models[modelName];
if (model.isIncludeOnly) {
includes[modelName] = model;
delete models[modelName];
}
}); // Apply includes
Object.keys(models).forEach(modelName => {
const model = models[modelName];
const modelIncludes = model.includes != null ? model.includes : {};
Object.keys(modelIncludes).forEach(includeName => {
const include = includes[includeName];
if (!include) {
throw new Error(`INCLUDE_NOT_FOUND ${modelName}/${includeName}`);
}
model.fields = (0, _timm.merge)((0, _lodash.default)(include.fields), model.fields);
model.relations = (0, _timm.merge)((0, _lodash.default)(include.relations), model.relations);
});
delete model.includes;
});
};
const addFieldDefaults = models => {
Object.keys(models).forEach(modelName => {
const {
fields
} = models[modelName];
Object.keys(fields).forEach(fieldName => {
fields[fieldName] = (0, _timm.addDefaults)(fields[fieldName], {
existsInServer: true,
existsInClient: true,
isMassAssignable: true
});
});
});
};
const processRelations = models => {
Object.keys(models).forEach(modelName => {
const {
relations
} = models[modelName];
Object.keys(relations).forEach(relationName => {
// Relation shorthand
let relation = relations[relationName];
if (relation === true) relation = {};
if (relation.isInverse) return; // Relation defaults
const {
isPlural = false
} = relation;
const fkName = getFkName(relationName, isPlural);
relation = (0, _timm.addDefaults)(relation, {
model: isPlural ? (0, _inflection.singularize)(relationName) : relationName,
fkName,
isPlural: false,
isInverse: false
});
const relatedModelName = relation.model; // Relation type
const relatedModel = models[relatedModelName];
if (!relatedModel) {
throw new Error(`RELATED_MODEL_NOT_FOUND ${modelName}/${relationName}/${relatedModelName}`);
}
const idField = relatedModel.fields.id;
if (!idField) {
throw new Error(`ID_FIELD_NOT_FOUND ${modelName}/${relationName}/${relatedModelName}`);
}
relation.type = idField.type; // Create inverse relation, if needed
const {
inverse
} = relation;
if (inverse !== false) {
let inverseRelation = inverse == null || inverse === true ? {} // inverse shorthand
: (0, _timm.omit)((0, _timm.clone)(inverse), ['name']);
inverseRelation = (0, _timm.addDefaults)(inverseRelation, {
model: modelName,
isPlural: true,
isInverse: true,
isRequired: relation.isRequired,
inverseName: relationName
});
const idField2 = models[modelName].fields.id;
inverseRelation.type = idField2 ? idField2.type : undefined;
const {
isPlural: isInversePlural
} = inverseRelation;
const inverseName = inverse && inverse.name || (isInversePlural ? (0, _inflection.pluralize)(modelName) : modelName);
const inverseFkName = getFkName(inverseName, isInversePlural != null ? isInversePlural : true);
inverseRelation.fkName = inverseFkName;
relatedModel.relations[inverseName] = inverseRelation;
relation.inverseName = inverseName;
}
if (relation.inverseName === undefined) relation.inverseName = null;
delete relation.inverse;
relations[relationName] = relation;
});
});
}; // ====================================
// Helpers
// ====================================
const getFkName = (relationName, isPlural) => {
const base = isPlural ? (0, _inflection.singularize)(relationName) : relationName;
return `${base}${isPlural ? 'Ids' : 'Id'}`;
}; // ====================================
// Public
// ====================================
var _default = preprocess;
exports.default = _default;