refactor: minimize repeated code by re-using parseInclude
, parseWhere
and getMethod
feat(include): ability to specify multiple includes, as an array
This commit is contained in:
parent
00e8e89767
commit
11291f0e08
@ -78,6 +78,10 @@ DELETE /role/{id}/teams?members=5
|
|||||||
DELETE /team/{id}/role/{id}
|
DELETE /team/{id}/role/{id}
|
||||||
DELETE /role/{id}/team/{id}
|
DELETE /role/{id}/team/{id}
|
||||||
|
|
||||||
|
# include
|
||||||
|
# include nested associations (you can specify an array if includes)
|
||||||
|
GET /team/{id}/role/{id}?include=SomeRoleAssociation
|
||||||
|
|
||||||
# you also get routes to associate objects with each other
|
# you also get routes to associate objects with each other
|
||||||
GET /associate/role/{id}/employee/{id} # associates role {id} with employee {id}
|
GET /associate/role/{id}/employee/{id} # associates role {id} with employee {id}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hapi-sequelize-crud",
|
"name": "hapi-sequelize-crud",
|
||||||
"version": "1.5.2",
|
"version": "2.0.0",
|
||||||
"description": "Hapi plugin that automatically generates RESTful API for CRUD",
|
"description": "Hapi plugin that automatically generates RESTful API for CRUD",
|
||||||
"main": "build/index.js",
|
"main": "build/index.js",
|
||||||
"config": {
|
"config": {
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
import joi from 'joi';
|
import joi from 'joi';
|
||||||
import error from '../error';
|
import error from '../error';
|
||||||
import { capitalize } from 'lodash/string';
|
import { capitalize } from 'lodash/string';
|
||||||
|
import { getMethod } from '../utils';
|
||||||
|
|
||||||
let prefix;
|
let prefix;
|
||||||
|
|
||||||
export default (server, a, b, options) => {
|
export default (server, a, b, names, options) => {
|
||||||
prefix = options.prefix;
|
prefix = options.prefix;
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: `${prefix}/associate/${a._singular}/{aid}/${b._singular}/{bid}`,
|
path: `${prefix}/associate/${names.a.singular}/{aid}/${names.b.singular}/{bid}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
@ -25,12 +26,15 @@ export default (server, a, b, options) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let fna = (instancea['add' + b.name] || instancea['set' + b.name]).bind(instancea);
|
const fna = getMethod(instancea, names.b, false, 'add') ||
|
||||||
let fnb = (instanceb['add' + a.name] || instanceb['set' + a.name]).bind(instanceb);
|
getMethod(instancea, names.b, false, 'set');
|
||||||
|
const fnb = getMethod(instanceb, names.a, false, 'add') ||
|
||||||
|
getMethod(instanceb, names.a, false, 'set');
|
||||||
|
|
||||||
await fna(instanceb);
|
await fna(instanceb);
|
||||||
await fnb(instancea);
|
await fnb(instancea);
|
||||||
|
|
||||||
reply(instancea);
|
reply([instancea, instanceb]);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,118 +1,94 @@
|
|||||||
import joi from 'joi';
|
import joi from 'joi';
|
||||||
import error from '../error';
|
import error from '../error';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { parseInclude, parseWhere, getMethod } from '../utils';
|
||||||
|
|
||||||
let prefix;
|
let prefix;
|
||||||
|
|
||||||
export default (server, a, b, options) => {
|
export default (server, a, b, names, options) => {
|
||||||
prefix = options.prefix;
|
prefix = options.prefix;
|
||||||
|
|
||||||
get(server, a, b);
|
get(server, a, b, names);
|
||||||
list(server, a, b);
|
list(server, a, b, names);
|
||||||
scope(server, a, b);
|
scope(server, a, b, names);
|
||||||
scopeScope(server, a, b);
|
scopeScope(server, a, b, names);
|
||||||
destroy(server, a, b);
|
destroy(server, a, b, names);
|
||||||
destroyScope(server, a, b);
|
destroyScope(server, a, b, names);
|
||||||
update(server, a, b);
|
update(server, a, b, names);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const get = (server, a, b) => {
|
export const get = (server, a, b, names) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._singular}/{bid}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.singular}/{bid}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let include = [];
|
const include = parseInclude(request);
|
||||||
if (request.query.include)
|
|
||||||
include = [request.models[request.query.include]];
|
|
||||||
|
|
||||||
let instance = await b.findOne({
|
const base = a.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
id: request.params.aid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const method = getMethod(base, names.b);
|
||||||
|
const list = await method({ where: {
|
||||||
id: request.params.bid
|
id: request.params.bid
|
||||||
},
|
}, include });
|
||||||
|
|
||||||
include: include.concat({
|
|
||||||
where: {
|
|
||||||
id: request.params.aid
|
|
||||||
},
|
|
||||||
model: a
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
reply(list);
|
reply(list);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const list = (server, a, b) => {
|
export const list = (server, a, b, names) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._plural}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let include = [];
|
const include = parseInclude(request);
|
||||||
if (request.query.include)
|
const where = parseWhere(request);
|
||||||
include = [request.models[request.query.include]];
|
|
||||||
|
|
||||||
let where = _.omit(request.query, 'include');
|
const base = await a.findOne({
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await b.findAll({
|
|
||||||
where,
|
|
||||||
|
|
||||||
include: include.concat({
|
|
||||||
where: {
|
where: {
|
||||||
id: request.params.aid
|
id: request.params.aid
|
||||||
},
|
}
|
||||||
model: a
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const method = getMethod(base, names.b);
|
||||||
|
const list = await method({ where, include });
|
||||||
|
|
||||||
reply(list);
|
reply(list);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const scope = (server, a, b) => {
|
export const scope = (server, a, b, names) => {
|
||||||
let scopes = Object.keys(b.options.scopes);
|
let scopes = Object.keys(b.options.scopes);
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._plural}/{scope}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}/{scope}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let include = [];
|
const include = parseInclude(request);
|
||||||
if (request.query.include)
|
const where = parseWhere(request);
|
||||||
include = [request.models[request.query.include]];
|
|
||||||
|
|
||||||
let where = _.omit(request.query, 'include');
|
const base = await a.findOne({
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await b.scope(request.params.scope).findAll({
|
|
||||||
where,
|
|
||||||
include: include.concat({
|
|
||||||
where: {
|
where: {
|
||||||
id: request.params.aid
|
id: request.params.aid
|
||||||
},
|
}
|
||||||
model: a
|
});
|
||||||
})
|
|
||||||
|
const method = getMethod(base, names.b);
|
||||||
|
const list = await method({
|
||||||
|
scope: request.params.scope,
|
||||||
|
where,
|
||||||
|
include
|
||||||
});
|
});
|
||||||
|
|
||||||
reply(list);
|
reply(list);
|
||||||
@ -129,7 +105,7 @@ export const scope = (server, a, b) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const scopeScope = (server, a, b) => {
|
export const scopeScope = (server, a, b, names) => {
|
||||||
let scopes = {
|
let scopes = {
|
||||||
a: Object.keys(a.options.scopes),
|
a: Object.keys(a.options.scopes),
|
||||||
b: Object.keys(b.options.scopes)
|
b: Object.keys(b.options.scopes)
|
||||||
@ -137,23 +113,12 @@ export const scopeScope = (server, a, b) => {
|
|||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: `${prefix}/${a._plural}/{scopea}/${b._plural}/{scopeb}`,
|
path: `${prefix}/${names.a.plural}/{scopea}/${names.b.plural}/{scopeb}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let include = [];
|
const include = parseInclude(request);
|
||||||
if (request.query.include)
|
const where = parseWhere(request);
|
||||||
include = [request.models[request.query.include]];
|
|
||||||
|
|
||||||
let where = _.omit(request.query, 'include');
|
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await b.scope(request.params.scopeb).findAll({
|
let list = await b.scope(request.params.scopeb).findAll({
|
||||||
where,
|
where,
|
||||||
@ -176,33 +141,23 @@ export const scopeScope = (server, a, b) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const destroy = (server, a, b) => {
|
export const destroy = (server, a, b, names) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._plural}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let where = _.omit(request.query, 'include');
|
const include = parseInclude(request);
|
||||||
|
const where = parseWhere(request);
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
const base = await a.findOne({
|
||||||
try {
|
where: request.params.aid
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await b.findAll({
|
|
||||||
where,
|
|
||||||
include: {
|
|
||||||
model: a,
|
|
||||||
where: {
|
|
||||||
id: request.params.aid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const method = getMethod(base, names.b);
|
||||||
|
const list = await method({ where, include });
|
||||||
|
|
||||||
await* list.map(instance => instance.destroy());
|
await* list.map(instance => instance.destroy());
|
||||||
|
|
||||||
reply(list);
|
reply(list);
|
||||||
@ -210,34 +165,29 @@ export const destroy = (server, a, b) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const destroyScope = (server, a, b) => {
|
export const destroyScope = (server, a, b, names) => {
|
||||||
let scopes = Object.keys(b.options.scopes);
|
let scopes = Object.keys(b.options.scopes);
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._plural}/{scope}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}/{scope}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let where = _.omit(request.query, 'include');
|
const include = parseInclude(request);
|
||||||
|
const where = parseWhere(request);
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
const base = await a.findOne({
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await b.scope(request.params.scope).findAll({
|
|
||||||
where,
|
|
||||||
|
|
||||||
include: {
|
|
||||||
model: a,
|
|
||||||
where: {
|
where: {
|
||||||
id: request.params.aid
|
id: request.params.aid
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
const method = getMethod(base, names.b);
|
||||||
|
const list = await method({
|
||||||
|
scope: request.params.scope,
|
||||||
|
where,
|
||||||
|
include
|
||||||
});
|
});
|
||||||
|
|
||||||
await* list.map(instance => instance.destroy());
|
await* list.map(instance => instance.destroy());
|
||||||
@ -256,24 +206,25 @@ export const destroyScope = (server, a, b) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const update = (server, a, b) => {
|
export const update = (server, a, b, names) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._plural}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let list = await b.findOne({
|
const include = parseInclude(request);
|
||||||
include: {
|
const where = parseWhere(request);
|
||||||
model: a,
|
|
||||||
where: {
|
|
||||||
id: request.params.aid,
|
|
||||||
|
|
||||||
...request.query
|
const base = await a.findOne({
|
||||||
}
|
where: {
|
||||||
|
id: request.params.aid
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const method = getMethod(base, names.b);
|
||||||
|
const list = await method({ where, include });
|
||||||
|
|
||||||
await* list.map(instance => instance.update(request.payload));
|
await* list.map(instance => instance.update(request.payload));
|
||||||
|
|
||||||
reply(list);
|
reply(list);
|
||||||
|
@ -1,82 +1,87 @@
|
|||||||
import joi from 'joi';
|
import joi from 'joi';
|
||||||
import error from '../error';
|
import error from '../error';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { parseInclude, parseWhere, getMethod } from '../utils';
|
||||||
|
|
||||||
let prefix;
|
let prefix;
|
||||||
|
|
||||||
export default (server, a, b, options) => {
|
export default (server, a, b, names, options) => {
|
||||||
prefix = options.prefix;
|
prefix = options.prefix;
|
||||||
|
|
||||||
get(server, a, b);
|
get(server, a, b, names);
|
||||||
create(server, a, b);
|
create(server, a, b, names);
|
||||||
destroy(server, a, b);
|
destroy(server, a, b, names);
|
||||||
update(server, a, b);
|
update(server, a, b, names);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const get = (server, a, b) => {
|
export const get = (server, a, b, names) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._singular}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.singular}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let include = [];
|
const include = parseInclude(request);
|
||||||
if (request.query.include)
|
const where = parseWhere(request);
|
||||||
include = [request.models[request.query.include]];
|
|
||||||
|
|
||||||
let where = _.omit(request.query, 'include');
|
const base = await a.findOne({
|
||||||
|
|
||||||
let [instance] = await b.findAll({
|
|
||||||
where,
|
|
||||||
|
|
||||||
include: include.concat({
|
|
||||||
model: a,
|
|
||||||
where: {
|
where: {
|
||||||
id: request.params.aid
|
id: request.params.aid
|
||||||
}
|
}
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
const method = getMethod(base, names.b, false);
|
||||||
|
|
||||||
reply(instance);
|
const list = await method({ where, include, limit: 1 });
|
||||||
|
|
||||||
|
if (Array.isArray(list)) {
|
||||||
|
reply(list[0]);
|
||||||
|
} else {
|
||||||
|
reply(list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const create = (server, a, b) => {
|
export const create = (server, a, b, names) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: `${prefix}/${a._singular}/{id}/${b._singular}`,
|
path: `${prefix}/${names.a.singular}/{id}/${names.b.singular}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
request.payload[a.name + 'Id'] = request.params.id;
|
const base = await a.findOne({
|
||||||
let instance = await request.models[b.name].create(request.payload);
|
where: {
|
||||||
|
id: request.params.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const method = getMethod(base, names.b, false, 'create');
|
||||||
|
const instance = await method(request.payload);
|
||||||
|
|
||||||
reply(instance);
|
reply(instance);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const destroy = (server, a, b) => {
|
export const destroy = (server, a, b, names) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._singular}/{bid}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.singular}/{bid}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let instance = await b.findOne({
|
const include = parseInclude(request);
|
||||||
where: {
|
const where = parseWhere(request);
|
||||||
id: request.params.bid
|
|
||||||
},
|
|
||||||
|
|
||||||
include: [{
|
const base = await a.findOne({
|
||||||
model: a,
|
|
||||||
where: {
|
where: {
|
||||||
id: request.params.aid
|
id: request.params.aid
|
||||||
}
|
}
|
||||||
}]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const method = getMethod(base, names.b, false);
|
||||||
|
|
||||||
|
const instance = await method({ where, include });
|
||||||
await instance.destroy();
|
await instance.destroy();
|
||||||
|
|
||||||
reply(instance);
|
reply(instance);
|
||||||
@ -84,26 +89,25 @@ export const destroy = (server, a, b) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const update = (server, a, b) => {
|
export const update = (server, a, b, names) => {
|
||||||
server.route({
|
server.route({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
path: `${prefix}/${a._singular}/{aid}/${b._singular}/{bid}`,
|
path: `${prefix}/${names.a.singular}/{aid}/${names.b.singular}/{bid}`,
|
||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let instance = await b.findOne({
|
const include = parseInclude(request);
|
||||||
where: {
|
const where = parseWhere(request);
|
||||||
id: request.params.bid
|
|
||||||
},
|
|
||||||
|
|
||||||
include: [{
|
const base = await a.findOne({
|
||||||
model: a,
|
|
||||||
where: {
|
where: {
|
||||||
id: request.params.aid
|
id: request.params.aid
|
||||||
}
|
}
|
||||||
}]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const method = getMethod(base, names.b, false);
|
||||||
|
|
||||||
|
const instance = await method({ where, include });
|
||||||
await instance.update(request.payload);
|
await instance.update(request.payload);
|
||||||
|
|
||||||
reply(instance);
|
reply(instance);
|
||||||
|
78
src/crud.js
78
src/crud.js
@ -1,6 +1,7 @@
|
|||||||
import joi from 'joi';
|
import joi from 'joi';
|
||||||
import error from './error';
|
import error from './error';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { parseInclude, parseWhere } from './utils';
|
||||||
|
|
||||||
let prefix;
|
let prefix;
|
||||||
|
|
||||||
@ -23,20 +24,10 @@ export const list = (server, model) => {
|
|||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
if (request.query.include)
|
const include = parseInclude(request);
|
||||||
var include = [request.models[request.query.include]];
|
const where = parseWhere(request);
|
||||||
|
|
||||||
let where = _.omit(request.query, 'include');
|
const list = await model.findAll({
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await model.findAll({
|
|
||||||
where, include
|
where, include
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -52,20 +43,10 @@ export const get = (server, model) => {
|
|||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
if (request.query.include)
|
const include = parseInclude(request);
|
||||||
var include = [request.models[request.query.include]];
|
const where = parseWhere(request);
|
||||||
|
|
||||||
let where = request.params.id ? { id : request.params.id } : _.omit(request.query, 'include');
|
const instance = await model.findOne({ where, include });
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let instance = await model.findOne({ where, include });
|
|
||||||
|
|
||||||
reply(instance);
|
reply(instance);
|
||||||
},
|
},
|
||||||
@ -88,20 +69,10 @@ export const scope = (server, model) => {
|
|||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
if (request.query.include)
|
const include = parseInclude(request);
|
||||||
var include = [request.models[request.query.include]];
|
const where = parseWhere(request);
|
||||||
|
|
||||||
let where = _.omit(request.query, 'include');
|
const list = await model.scope(request.params.scope).findAll({ include, where });
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await model.scope(request.params.scope).findAll({ include, where });
|
|
||||||
|
|
||||||
reply(list);
|
reply(list);
|
||||||
},
|
},
|
||||||
@ -122,7 +93,7 @@ export const create = (server, model) => {
|
|||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let instance = await model.create(request.payload);
|
const instance = await model.create(request.payload);
|
||||||
|
|
||||||
reply(instance);
|
reply(instance);
|
||||||
}
|
}
|
||||||
@ -136,17 +107,10 @@ export const destroy = (server, model) => {
|
|||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let where = request.params.id ? { id : request.params.id } : request.query;
|
const include = parseInclude(request);
|
||||||
|
const where = parseWhere(request);
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
const list = await model.findAll({ where });
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await model.findAll({ where });
|
|
||||||
|
|
||||||
await* list.map(instance => instance.destroy());
|
await* list.map(instance => instance.destroy());
|
||||||
|
|
||||||
@ -164,18 +128,8 @@ export const destroyScope = (server, model) => {
|
|||||||
|
|
||||||
@error
|
@error
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
if (request.query.include)
|
const include = parseInclude(request);
|
||||||
var include = [request.models[request.query.include]];
|
const where = parseWhere(request);
|
||||||
|
|
||||||
let where = _.omit(request.query, 'include');
|
|
||||||
|
|
||||||
for (const key of Object.keys(where)) {
|
|
||||||
try {
|
|
||||||
where[key] = JSON.parse(where[key]);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = await model.scope(request.params.scope).findAll({ include, where });
|
let list = await model.scope(request.params.scope).findAll({ include, where });
|
||||||
|
|
||||||
|
39
src/index.js
39
src/index.js
@ -36,12 +36,25 @@ const register = (server, options = {}, next) => {
|
|||||||
for (let key of Object.keys(model.associations)) {
|
for (let key of Object.keys(model.associations)) {
|
||||||
let association = model.associations[key];
|
let association = model.associations[key];
|
||||||
let { associationType, source, target } = association;
|
let { associationType, source, target } = association;
|
||||||
|
// console.dir(association, null, { depth: null });
|
||||||
|
|
||||||
let sourceName = source.options.name;
|
let sourceName = source.options.name;
|
||||||
let targetName = target.options.name;
|
let targetName = target.options.name;
|
||||||
|
|
||||||
target._plural = targetName.plural.toLowerCase();
|
|
||||||
target._singular = targetName.singular.toLowerCase();
|
const names = (rev) => {
|
||||||
|
const arr = [{
|
||||||
|
plural: sourceName.plural.toLowerCase(),
|
||||||
|
singular: sourceName.singular.toLowerCase(),
|
||||||
|
original: sourceName
|
||||||
|
}, {
|
||||||
|
plural: association.options.name.plural.toLowerCase(),
|
||||||
|
singular: association.options.name.singular.toLowerCase(),
|
||||||
|
original: association.options.name
|
||||||
|
}];
|
||||||
|
|
||||||
|
return rev ? { b: arr[0], a: arr[1] } : { a: arr[0], b: arr[1] };
|
||||||
|
}
|
||||||
|
|
||||||
let targetAssociations = target.associations[sourceName.plural] || target.associations[sourceName.singular];
|
let targetAssociations = target.associations[sourceName.plural] || target.associations[sourceName.singular];
|
||||||
let sourceType = association.associationType,
|
let sourceType = association.associationType,
|
||||||
@ -49,26 +62,26 @@ const register = (server, options = {}, next) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (sourceType === 'BelongsTo' && (targetType === 'BelongsTo' || !targetType)) {
|
if (sourceType === 'BelongsTo' && (targetType === 'BelongsTo' || !targetType)) {
|
||||||
associations.oneToOne(server, source, target, options);
|
associations.oneToOne(server, source, target, names(), options);
|
||||||
associations.oneToOne(server, target, source, options);
|
associations.oneToOne(server, target, source, names(1), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceType === 'BelongsTo' && targetType === 'HasMany') {
|
if (sourceType === 'BelongsTo' && targetType === 'HasMany') {
|
||||||
associations.oneToOne(server, source, target, options);
|
associations.oneToOne(server, source, target, names(), options);
|
||||||
associations.oneToOne(server, target, source, options);
|
associations.oneToOne(server, target, source, names(1), options);
|
||||||
associations.oneToMany(server, target, source, options);
|
associations.oneToMany(server, target, source, names(1), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceType === 'BelongsToMany' && targetType === 'BelongsToMany') {
|
if (sourceType === 'BelongsToMany' && targetType === 'BelongsToMany') {
|
||||||
associations.oneToOne(server, source, target, options);
|
associations.oneToOne(server, source, target, names(), options);
|
||||||
associations.oneToOne(server, target, source, options);
|
associations.oneToOne(server, target, source, names(1), options);
|
||||||
|
|
||||||
associations.oneToMany(server, source, target, options);
|
associations.oneToMany(server, source, target, names(), options);
|
||||||
associations.oneToMany(server, target, source, options);
|
associations.oneToMany(server, target, source, names(1), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
associations.associate(server, source, target, options);
|
associations.associate(server, source, target, names(), options);
|
||||||
associations.associate(server, target, source, options);
|
associations.associate(server, target, source, names(1), options);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// There might be conflicts in case of models associated with themselves and some other
|
// There might be conflicts in case of models associated with themselves and some other
|
||||||
// rare cases.
|
// rare cases.
|
||||||
|
39
src/utils.js
Normal file
39
src/utils.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { omit } from 'lodash';
|
||||||
|
|
||||||
|
export const parseInclude = request => {
|
||||||
|
const include = Array.isArray(request.query.include) ? request.query.include
|
||||||
|
: [request.query.include];
|
||||||
|
|
||||||
|
return include.map(a => {
|
||||||
|
if (typeof a === 'string') return request.models[a];
|
||||||
|
|
||||||
|
if (a && typeof a.model === 'string' && a.model.length) {
|
||||||
|
a.model = request.models[a.model];
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}).filter(a => a);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const parseWhere = request => {
|
||||||
|
const where = omit(request.query, 'include');
|
||||||
|
|
||||||
|
for (const key of Object.keys(where)) {
|
||||||
|
try {
|
||||||
|
where[key] = JSON.parse(where[key]);
|
||||||
|
} catch (e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return where;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getMethod = (model, association, plural = true, method = 'get') => {
|
||||||
|
const a = plural ? association.original.plural : association.original.singular;
|
||||||
|
const b = plural ? association.original.singular : association.original.plural; // alternative
|
||||||
|
const fn = model[`${method}${a}`] || model[`${method}${b}`];
|
||||||
|
if (fn) return fn.bind(model);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user