UNPKG

apeman-app-rest

Version:
130 lines (113 loc) 2.85 kB
/** * Endpoint for one * @augments Endpoint * @class OneEndpoint */ 'use strict' const Endpoint = require('./endpoint') const { toData, defineOne } = require('apemanmodel') const validateModelExists = require('../validating/validate_model_exists') const validateInclude = require('../validating/validate_include') const co = require('co') /** @lends OneEndpoint */ class OneEndpoint extends Endpoint { /** * @override */ getDefaultConfig () { return { name: 'one' } } /** * @override */ handle (ctx, next) { const s = this let succeed = s.bindSucceed(ctx) let fail = s.bindFail(ctx) let { state } = ctx let { model, id, include } = state let { associations } = model if (typeof id === 'undefined') { throw new Error('state.id is required.') } return co(function * () { let error = s.validate(null, state) if (error) { return fail(error) } let instance = yield s.one(id, state) let data = toData(model, instance, { relationships: OneEndpoint.relationships(instance, associations) }) if (include) { include.forEach((include) => { delete data.attributes[ include ] }) } return succeed( {}, data, { self: '.' }, OneEndpoint.included(instance, associations, include) ) }) } /** * @override */ validate (data, state) { let { model, id, instance, include } = state let includeError = validateInclude(model, include) if (includeError) { return includeError } let existsError = validateModelExists(model, id, instance) if (existsError) { return existsError } return null } one (id, state) { const s = this let { model, transaction, include } = state let one = defineOne(model, transaction) return co(function * () { return yield one(id, include) }) } } Object.assign(OneEndpoint, { included (found, associations, include) { let hasInclude = include && (include.length > 0) if (!hasInclude) { return undefined } return include .map((name) => { let association = associations[ name ] return toData(association.target, found[ name ] || []) }) .reduce((a, b) => [].concat(a, b), []) .filter((included) => included) }, relationships (found, associations) { let names = associations && Object.keys(associations) let hasRelationships = names.length > 0 if (!hasRelationships) { return undefined } return names.reduce((result, name) => Object.assign(result, { [name]: { links: { self: `./relationships/${name}/`, related: `./${name}` } } }), {}) } }) module.exports = OneEndpoint