| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- const _ = require('lodash')
- const config = require('../../config')
- const bcrypt = require('bcrypt')
- const sequelize = require('./sequelize')
- const User = require('./user')
- const Session = require('./session')
- const Role = require('./role')
- const setup = require('./setup')
- const { dict } = require('../util')
- const { Op } = require('sequelize')
- const UserRole = User.belongsToMany(Role, { through: 'userRoles' })
- const isUUID = (str) =>
- typeof str === 'string' &&
- /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(str)
- const fetch = async (Type, refs) => {
- if (!Array.isArray(refs)) {
- return (await fetch(Type, [refs]))[0]
- }
- let ret = refs.slice(0)
- const keys = []
- const ids = []
- for (let ref of refs) {
- if (isUUID(ref)) ids.push(ref)
- else if (typeof ref === 'string') keys.push(ref)
- }
- if (keys.length || ids.length) {
- const or = []
- if (ids.length) or.push({
- id: {
- [Op.in]: ids
- }
- })
- if (keys.length) or.push({
- key: {
- [Op.in]: keys
- }
- })
- const recs = dict(await Type.findAll({
- where: {
- [Op.or]: or
- },
- paranoid: false
- }))
- if (recs.length !== ids.length + keys.length) {
- const missing = [
- ...ids.filter(id => !recs[id]),
- ...keys.filter(key => !recs[key])
- ].join(', ')
- throw new Error(`Not all references retrieved. Expected ${ids.length + keys.length}, got ${recs.length}. Missing ${missing} from ${Type.name}.`)
- }
- ret = ret.map(ref => recs[ref] || ref)
- }
- return dict(ret)
- }
- const upsert = async (Type, object, fields) => {
- if (!fields) {
- fields = ['key']
- }
- for (var field of fields) {
- if (!object[field]) {
- throw new Error(`Missing upsert field '${field}' in ${JSON.stringify(object)}.`)
- }
- }
- const existing = await Type.findOne({where: _.pick(object, fields), paranoid: false})
- let record
- if (existing) {
- Object.assign(existing, object)
- await existing.save()
- record = existing
- } else {
- record = await Type.create(object)
- }
- for (let assoc of Object.values(Type.associations)) {
- if (object[assoc.as]) {
- if (assoc.associationType === 'BelongsToMany' || assoc.associationType === 'BelongsTo') {
- const recs = await fetch(assoc.target, object[assoc.as])
- await assoc.set(record, recs)
- }
- }
- }
- return record
- }
- const fill = (Type, objects, fields) => Promise.all(objects.map(object =>
- upsert(Type, object, fields)
- ))
- module.exports = {
- init: () => {
- //return sequelize.sync()
- },
- sequelize,
- User,
- Session,
- Role,
- UserRole,
- upsert,
- setup,
- fill,
- fetch
- }
|