simple-graphql
Version:
The simple way to generates GraphQL schemas and Sequelize models from your models definition.
139 lines • 6.64 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sequelize_1 = __importDefault(require("sequelize"));
const lodash_1 = __importDefault(require("lodash"));
const modelStaticsMethod_1 = __importDefault(require("./modelStaticsMethod"));
function toSequelizeModel(sequelize, schema, context) {
var _a, _b;
const dbDefinition = {};
const versionConfig = (_a = schema.options.tableOptions) === null || _a === void 0 ? void 0 : _a.version;
let versionField = null;
if (versionConfig === true || typeof versionConfig === 'string') {
versionField = typeof versionConfig === 'string' ? versionConfig : 'version';
}
const primaryKey = (_b = schema.options.tableOptions) === null || _b === void 0 ? void 0 : _b.primaryKey;
if (primaryKey) {
dbDefinition.id = {
field: primaryKey.field,
type: primaryKey.type,
defaultValue: primaryKey.defaultValue,
primaryKey: true,
autoIncrement: primaryKey.autoIncrement
};
}
const extAttributes = {};
lodash_1.default.forOwn(schema.config.fields, (value, key) => {
var _a;
if (key === versionField)
return;
let columnOptions = null;
if (value.enum) {
columnOptions = {
type: sequelize_1.default.STRING(191)
};
}
else if (value.elements) {
columnOptions = {
type: sequelize_1.default.JSON
};
}
else if (value.type) {
const typeConfig = context.typeConfig(value.type);
if (!typeConfig) {
throw new Error(`Type "${value.type}" has not register.`);
}
if (!typeConfig.columnOptions) {
throw new Error(`Column type of "${value.type}" is not supported.`);
}
columnOptions =
typeof typeConfig.columnOptions === 'function'
? typeConfig.columnOptions(schema, key, value)
: typeConfig.columnOptions;
}
else {
columnOptions = {
type: sequelize_1.default.JSON
};
}
if (columnOptions) {
extAttributes[key] = Object.assign(Object.assign(Object.assign({}, columnOptions), { allowNull: value.nullable !== false }), (((_a = value.metadata) === null || _a === void 0 ? void 0 : _a.column) || {}));
}
});
return [
sequelize.define(schema.name, dbDefinition, schema.options.tableOptions),
extAttributes
];
}
function buildModelAssociations(schemas, models) {
// 每次associations的改动, 会触发Model.refreshAttributes操作
// 如果先初始化associations, 再通过通过Model.rawAttributes / refreshAttributes添加其他字段
// 性能大概提升30%
const schemaMap = {};
schemas.forEach((schema) => (schemaMap[schema.name] = schema));
const getForeignKey = (config) => {
var _a, _b;
if (config.foreignKey) {
return config.foreignKey;
}
else if (config.foreignField) {
const schema = schemaMap[config.target];
const field = schema === null || schema === void 0 ? void 0 : schema.config.fields[config.foreignField];
if (field) {
return ((_b = (_a = field.metadata) === null || _a === void 0 ? void 0 : _a.column) === null || _b === void 0 ? void 0 : _b.field) || config.foreignField + 'Id';
}
}
return config.foreignField + 'Id';
};
for (const schema of schemas) {
lodash_1.default.forOwn(schema.config.associations.hasMany, (config, key) => {
models[schema.name].hasMany(models[config.target], Object.assign(Object.assign({}, config), { as: key, foreignKey: getForeignKey(config) }));
});
lodash_1.default.forOwn(schema.config.associations.belongsToMany, (config, key) => {
models[schema.name].belongsToMany(models[config.target], Object.assign(Object.assign({}, config), { as: key, foreignKey: getForeignKey(config),
// through: config.through && {...config.through, model: models[config.through.model]}
through: config.through }));
});
lodash_1.default.forOwn(schema.config.associations.hasOne, (config, key) => {
models[schema.name].hasOne(models[config.target], Object.assign(Object.assign({}, config), { as: key, foreignKey: getForeignKey(config) }));
});
lodash_1.default.forOwn(schema.config.associations.belongsTo, (config, key) => {
const foreignKey = getForeignKey(config);
models[schema.name].belongsTo(models[config.target], Object.assign(Object.assign({}, config), { as: key, foreignKey: foreignKey, targetKey: config.targetKey || 'id' }));
const foreignKeyName = typeof foreignKey === 'string' ? foreignKey : foreignKey.name;
if (foreignKeyName != config.foreignField + 'Id') {
models[schema.name].rawAttributes[config.foreignField + 'Id'] = {
type: sequelize_1.default.INTEGER,
field: foreignKeyName
};
}
});
}
}
exports.default = (sequelize, schemas, context) => {
const result = {};
const extAttributesMap = {};
for (const schema of schemas) {
if (result[schema.name]) {
throw new Error(`Schema ${schema.name} already define.`);
}
const [model, extAttributes] = toSequelizeModel(schema.sequelize || sequelize, schema, context);
Object.assign(model, Object.assign(Object.assign(Object.assign({ sgSchema: schema }, modelStaticsMethod_1.default), schema.config.statics), { getSGContext: () => context }));
Object.assign(model.prototype, Object.assign({ getSGContext: () => context, _fieldType: schema.name }, schema.config.methods));
result[schema.name] = model;
extAttributesMap[schema.name] = extAttributes;
}
buildModelAssociations(schemas, result);
return lodash_1.default.values(result).map((model) => {
lodash_1.default.toPairs(extAttributesMap[model.name]).forEach(([key, attribute]) => {
if (model.rawAttributes[key] == null) {
model.rawAttributes[key] = attribute;
}
});
model.refreshAttributes();
return model;
});
};
//# sourceMappingURL=buildSequelizeModels.js.map