From 9ebf84a641d664681c8c5cb3794cd282bad4dbab Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Fri, 15 Sep 2017 09:37:02 -0700 Subject: [PATCH] 1.0.1 --- dist/js-data-express.js | 12 ++++++++++-- dist/js-data-express.js.map | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/dist/js-data-express.js b/dist/js-data-express.js index 3628e0b..224ff49 100644 --- a/dist/js-data-express.js +++ b/dist/js-data-express.js @@ -16,6 +16,14 @@ function parseQuery(query) { } if (query.orderBy || query.sort) { var orderBy = query.orderBy || query.sort; + if (orderBy && typeof orderBy === 'string' && orderBy[0] === '[') { + try { + orderBy = JSON.parse(orderBy); + } catch (err) { + console.error('orderBy querystring parameter is not a well-formatted array!'); + throw err; + } + } if (Array.isArray(orderBy)) { query.orderBy = orderBy.map(function (clause) { if (typeof clause === 'string' && clause.indexOf('{') >= 0) { @@ -510,10 +518,10 @@ function mount(app, store) { * otherwise `false` if the current version is not beta. */ var version = { - full: '1.0.0', + full: '1.0.1', major: 1, minor: 0, - patch: 0 + patch: 1 }; /** diff --git a/dist/js-data-express.js.map b/dist/js-data-express.js.map index 02b93bc..6fa8140 100644 --- a/dist/js-data-express.js.map +++ b/dist/js-data-express.js.map @@ -1 +1 @@ -{"version":3,"file":"js-data-express.js","sources":["../src/queryParser.js","../src/handlers.js","../src/index.js"],"sourcesContent":["export function parseQuery (query) {\n if (query.where) {\n try {\n query.where = JSON.parse(query.where)\n } catch (err) {}\n }\n if (query.orderBy || query.sort) {\n const orderBy = query.orderBy || query.sort\n if (Array.isArray(orderBy)) {\n query.orderBy = orderBy.map((clause) => {\n if (typeof clause === 'string' && clause.indexOf('{') >= 0) {\n return JSON.parse(clause)\n }\n return clause\n })\n }\n query.sort = undefined\n }\n}\n\nexport function queryParser (req, res, next) {\n req.jsdataOpts || (req.jsdataOpts = {})\n if (req.query.with) {\n req.jsdataOpts.with = req.query.with\n delete req.query.with\n }\n try {\n parseQuery(req.query)\n next()\n } catch (err) {\n next(err)\n }\n}\n","import { utils } from 'js-data'\n\nconst DEFAULTS = {\n create: {\n action (component, req) {\n return component.create(req.body, req.jsdataOpts)\n },\n statusCode: 201\n },\n createMany: {\n action (component, req) {\n return component.createMany(req.body, req.jsdataOpts)\n },\n statusCode: 201\n },\n destroy: {\n action (component, req) {\n return component.destroy(req.params.id, req.jsdataOpts)\n },\n statusCode: 204\n },\n destroyAll: {\n action (component, req) {\n return component.destroyAll(req.query, req.jsdataOpts)\n },\n statusCode: 204\n },\n find: {\n action (component, req) {\n return component.find(req.params.id, req.jsdataOpts)\n },\n statusCode: 200\n },\n findAll: {\n action (component, req) {\n return component.findAll(req.query, req.jsdataOpts)\n },\n statusCode: 200\n },\n update: {\n action (component, req) {\n return component.update(req.params.id, req.body, req.jsdataOpts)\n },\n statusCode: 200\n },\n updateAll: {\n action (component, req) {\n return component.updateAll(req.body, req.query, req.jsdataOpts)\n },\n statusCode: 200\n },\n updateMany: {\n action (component, req) {\n return component.updateMany(req.body, req.jsdataOpts)\n },\n statusCode: 200\n }\n}\n\nexport function makeRequestHandler (method, component, config = {}) {\n config[method] || (config[method] = {})\n const action = config[method].action || DEFAULTS[method].action\n\n return (req, res, next) => {\n action(component, req)\n .then((result) => {\n req.jsdataResult = result\n next()\n })\n .catch(next)\n }\n}\n\nexport function makeResponseHandler (method, component, config = {}) {\n const methodConfig = config[method] || {}\n const statusCode = methodConfig.statusCode || DEFAULTS[method].statusCode\n let toJSON\n\n // Pick the user's toJSON setting, in order of preference\n if (utils.isFunction(methodConfig.toJSON)) {\n toJSON = (component, result, opts) => methodConfig.toJSON(component, result, opts)\n } else if (methodConfig.toJSON === false) {\n toJSON = (component, result, opts) => result\n } else if (methodConfig.toJSON === true) {\n toJSON = (component, result, opts) => component.toJSON(result, opts)\n } else {\n if (utils.isFunction(config.toJSON)) {\n toJSON = (component, result, opts) => config.toJSON(component, result, opts)\n } else if (config.toJSON === false) {\n toJSON = (component, result, opts) => result\n } else {\n toJSON = (component, result, opts) => component.toJSON(result, opts)\n }\n }\n\n return (req, res, next) => {\n const result = req.jsdataResult\n\n res.status(statusCode)\n\n try {\n if (result !== undefined) {\n res.send(toJSON(component, result, req.jsdataOpts))\n }\n } catch (err) {\n return next(err)\n }\n\n res.end()\n }\n}\n","import {\n Component,\n Container,\n Mapper,\n utils\n} from 'js-data'\n\nimport { queryParser } from './queryParser'\nimport * as handlers from './handlers'\nimport express from 'express'\nimport bodyParser from 'body-parser'\n\nexport * from './queryParser'\n\nconst handlerNoop = (req, res, next) => {\n next()\n}\n\nfunction makeHandler (method, component, config = {}) {\n config[method] || (config[method] = {})\n const userRequestHandler = utils.isFunction(config[method].request) ? config[method].request : handlerNoop\n const defaultRequestHandler = handlers.makeRequestHandler(method, component, config)\n const defaultResponseHandler = handlers.makeResponseHandler(method, component, config)\n\n return (req, res, next) => {\n userRequestHandler(req, res, (err) => {\n if (err) {\n return next(err)\n }\n defaultRequestHandler(req, res, (err) => {\n if (err) {\n return next(err)\n }\n if (utils.isFunction(config[method].response)) {\n config[method].response(req, res, next)\n } else {\n defaultResponseHandler(req, res, next)\n }\n })\n })\n }\n}\n\n/**\n * A middleware method invoked on all requests\n *\n * @typedef RequestHandler\n * @type function\n * @param {object} req HTTP(S) Request Object\n * @param {object} res HTTP(S) Response Object\n * @param {function} next Express `next()` callback to continue the chain\n */\n\n/**\n * A method that handles all responses\n *\n * @typedef ResponseHandler\n * @type function\n * @param {object} req HTTP(S) Request Object\n * @param {object} res HTTP(S) Response Object\n * @param {function} next Express `next()` callback to continue the chain\n */\n\n/**\n * Custom defined method that retrieves data/results for an endpoint\n *\n * @typedef ActionHandler\n * @type function\n * @param {object} component Instance of `Mapper`, `Container`, `SimpleStore`,\n * or `DataStore`.\n * @param {object} req HTTP(S) Request Object\n *\n * @example A custom action\n * (component, req) => {\n * return new Promise((resolve, reject) => {\n * // ..some logic\n * return resolve(results)\n * })\n * }\n *\n * @returns {Promise} Promise that resolves with the result.\n */\n\n/**\n * @typedef Serializer\n * @type function\n * @param {object} component Instance of `Mapper`, `Container`, `SimpleStore`,\n * or `DataStore`.\n * @param {object} result The result of the endpoint's {@link ActionHandler}.\n * @param {object} opts Configuration options.\n * @returns {object|array|undefined} The serialized result.\n */\n\n/**\n * create action configs\n *\n * @typedef CreateConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * createMany action configs\n *\n * @typedef CreateManyConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * destroy action configs\n *\n * @typedef DestroyConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * destroyAll action configs\n *\n * @typedef DestroyAllConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * find action configs\n *\n * @typedef FindConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * findAll action configs\n *\n * @typedef FindAllConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * update action configs\n *\n * @typedef UpdateConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * UpdateAllConfig action configs\n *\n * @typedef UpdateAllConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * updateMany action configs\n *\n * @typedef UpdateManyConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * Define endpoint path with custom logic\n *\n * @typedef Endpoint\n * @type function\n * @param {Object} mapper Component Mapper object\n */\n\n/**\n * Configuration options for endpoints, actions, & request/response\n *\n * @typedef Config\n * @type object\n * @property {Endpoint} [getEndpoint] Define endpoints with custom method\n * @property {CreateConfig} [create] create action configs\n * @property {CreateManyConfig} [createMany] createMany action configs\n * @property {DestroyConfig} [destroy] destroy action configs\n * @property {DestroyAllConfig} [destroyAll] destroyAll action configs\n * @property {FindConfig} [find] find action configs\n * @property {FindAllConfig} [findAll] findAll action configs\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n * @property {UpdateConfig} [update] update action configs\n * @property {UpdateAllConfig} [updateAll] updateAll action configs\n * @property {UpdateManyConfig} [updateMany] updateMany action configs\n */\n\n/**\n * @class Router\n *\n * @param {object} component Instance of `Mapper`, `Container`, `SimpleStore`,\n * or `DataStore`.\n * @param {Config} [config] Optional configuration.\n *\n */\nexport function Router (component, config = {}) {\n if (!(component instanceof Mapper) && !(component instanceof Container)) {\n throw new Error('You must provide an instance of JSData.Container, JSData.DataStore, or JSData.Mapper!')\n }\n\n const router = this.router = express.Router()\n router.use(bodyParser.json())\n router.use(bodyParser.urlencoded({\n extended: true\n }))\n\n if (utils.isFunction(config.request)) {\n router.use(config.request)\n config.request = undefined\n }\n\n if (component instanceof Container) {\n utils.forOwn(component._mappers, (mapper, name) => {\n let endpoint = `/${mapper.endpoint || name}`\n if (utils.isFunction(config.getEndpoint)) {\n endpoint = config.getEndpoint(mapper)\n }\n router.use(endpoint, new Router(mapper, config).router)\n })\n } else if (component instanceof Mapper) {\n const createManyHandler = makeHandler('createMany', component, config)\n const createHandler = makeHandler('create', component, config)\n const updateManyHandler = makeHandler('updateMany', component, config)\n const updateAllHandler = makeHandler('updateAll', component, config)\n\n router.route('/')\n // GET /:resource\n .get(makeHandler('findAll', component, config))\n // POST /:resource\n .post(function (req, res, next) {\n if (utils.isArray(req.body)) {\n createManyHandler(req, res, next)\n } else {\n createHandler(req, res, next)\n }\n })\n // PUT /:resource\n .put(function (req, res, next) {\n if (utils.isArray(req.body)) {\n updateManyHandler(req, res, next)\n } else {\n updateAllHandler(req, res, next)\n }\n })\n // DELETE /:resource\n .delete(makeHandler('destroyAll', component, config))\n\n router.route('/:id')\n // GET /:resource/:id\n .get(makeHandler('find', component, config))\n // PUT /:resource/:id\n .put(makeHandler('update', component, config))\n // DELETE /:resource/:id\n .delete(makeHandler('destroy', component, config))\n }\n}\n\nComponent.extend({\n constructor: Router\n})\n\n/**\n * Convenience method that mounts {@link queryParser} and a store.\n *\n * @example Mount queryParser and store at \"/\"\n * import express from 'express';\n * import { mount, queryParser, Router } from 'js-data-express';\n * import { Container } from 'js-data';\n *\n * const app = express();\n * const store = new Container();\n * const UserMapper = store.defineMapper('user');\n * const CommentMapper = store.defineMapper('comment');\n * mount(app, store);\n *\n * @example Mount queryParser and store at \"/api\"\n * mount(app, store, '/api');\n *\n * @name module:js-data-express.mount\n * @method\n * @param {*} app\n * @param {object} store Instance of `Mapper`, `Container`, `SimpleStore`,\n * or `DataStore`.\n * @param {Config|string} [config] Configuration options.\n */\nexport function mount (app, store, config = {}) {\n if (!(store instanceof Container)) {\n throw new Error('You must provide an instance of JSData.Container or JSData.DataStore!')\n }\n if (utils.isString(config)) {\n config = { path: config }\n }\n config.path || (config.path = '/')\n\n app.use(config.path, queryParser)\n app.use(config.path, new Router(store, config).router)\n}\n\n/**\n * Details of the current version of the `js-data-express` module.\n *\n * @example ES2015 modules import\n * import { version } from 'js-data-express';\n * console.log(version.full);\n *\n * @example CommonJS import\n * var version = require('js-data-express').version;\n * console.log(version.full);\n *\n * @name module:js-data-express.version\n * @type {object}\n * @property {string} version.full The full semver value.\n * @property {number} version.major The major version number.\n * @property {number} version.minor The minor version number.\n * @property {number} version.patch The patch version number.\n * @property {(string|boolean)} version.alpha The alpha version value,\n * otherwise `false` if the current version is not alpha.\n * @property {(string|boolean)} version.beta The beta version value,\n * otherwise `false` if the current version is not beta.\n */\nexport const version = '<%= version %>'\n\n/**\n * {@link Router} class.\n *\n * @example ES2015 modules import\n * import { Router } from 'js-data-express';\n * const adapter = new Router();\n *\n * @example CommonJS import\n * var Router = require('js-data-express').Router;\n * var adapter = new Router();\n *\n * @name module:js-data-express.Router\n * @see Router\n * @type {Constructor}\n */\n\n/**\n * Registered as `js-data-express` in NPM.\n *\n * @example Install from NPM\n * npm i --save js-data-express@rc js-data@rc\n *\n * @example ES2015 modules import\n * import { Router } from 'js-data-express';\n * const adapter = new Router();\n *\n * @example CommonJS import\n * var Router = require('js-data-express').Router;\n * var adapter = new Router();\n *\n * @module js-data-express\n */\n"],"names":["parseQuery","query","where","JSON","parse","err","orderBy","sort","Array","isArray","map","clause","indexOf","undefined","queryParser","req","res","next","jsdataOpts","with","DEFAULTS","component","create","body","createMany","destroy","params","id","destroyAll","find","findAll","update","updateAll","updateMany","makeRequestHandler","method","config","action","then","result","jsdataResult","catch","makeResponseHandler","methodConfig","statusCode","toJSON","utils","isFunction","opts","status","send","end","handlerNoop","makeHandler","userRequestHandler","request","defaultRequestHandler","handlers","defaultResponseHandler","response","Router","Mapper","Container","Error","router","express","use","bodyParser","json","urlencoded","forOwn","_mappers","mapper","name","endpoint","getEndpoint","createManyHandler","createHandler","updateManyHandler","updateAllHandler","route","get","post","put","delete","Component","extend","mount","app","store","isString","path","version"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"js-data-express.js","sources":["../src/queryParser.js","../src/handlers.js","../src/index.js"],"sourcesContent":["export function parseQuery (query) {\n if (query.where) {\n try {\n query.where = JSON.parse(query.where)\n } catch (err) {}\n }\n if (query.orderBy || query.sort) {\n let orderBy = query.orderBy || query.sort\n if (orderBy && typeof orderBy === 'string' && orderBy[0] === '[') {\n try {\n orderBy = JSON.parse(orderBy)\n } catch (err) {\n console.error('orderBy querystring parameter is not a well-formatted array!')\n throw err\n }\n }\n if (Array.isArray(orderBy)) {\n query.orderBy = orderBy.map((clause) => {\n if (typeof clause === 'string' && clause.indexOf('{') >= 0) {\n return JSON.parse(clause)\n }\n return clause\n })\n }\n query.sort = undefined\n }\n}\n\nexport function queryParser (req, res, next) {\n req.jsdataOpts || (req.jsdataOpts = {})\n if (req.query.with) {\n req.jsdataOpts.with = req.query.with\n delete req.query.with\n }\n try {\n parseQuery(req.query)\n next()\n } catch (err) {\n next(err)\n }\n}\n","import { utils } from 'js-data'\n\nconst DEFAULTS = {\n create: {\n action (component, req) {\n return component.create(req.body, req.jsdataOpts)\n },\n statusCode: 201\n },\n createMany: {\n action (component, req) {\n return component.createMany(req.body, req.jsdataOpts)\n },\n statusCode: 201\n },\n destroy: {\n action (component, req) {\n return component.destroy(req.params.id, req.jsdataOpts)\n },\n statusCode: 204\n },\n destroyAll: {\n action (component, req) {\n return component.destroyAll(req.query, req.jsdataOpts)\n },\n statusCode: 204\n },\n find: {\n action (component, req) {\n return component.find(req.params.id, req.jsdataOpts)\n },\n statusCode: 200\n },\n findAll: {\n action (component, req) {\n return component.findAll(req.query, req.jsdataOpts)\n },\n statusCode: 200\n },\n update: {\n action (component, req) {\n return component.update(req.params.id, req.body, req.jsdataOpts)\n },\n statusCode: 200\n },\n updateAll: {\n action (component, req) {\n return component.updateAll(req.body, req.query, req.jsdataOpts)\n },\n statusCode: 200\n },\n updateMany: {\n action (component, req) {\n return component.updateMany(req.body, req.jsdataOpts)\n },\n statusCode: 200\n }\n}\n\nexport function makeRequestHandler (method, component, config = {}) {\n config[method] || (config[method] = {})\n const action = config[method].action || DEFAULTS[method].action\n\n return (req, res, next) => {\n action(component, req)\n .then((result) => {\n req.jsdataResult = result\n next()\n })\n .catch(next)\n }\n}\n\nexport function makeResponseHandler (method, component, config = {}) {\n const methodConfig = config[method] || {}\n const statusCode = methodConfig.statusCode || DEFAULTS[method].statusCode\n let toJSON\n\n // Pick the user's toJSON setting, in order of preference\n if (utils.isFunction(methodConfig.toJSON)) {\n toJSON = (component, result, opts) => methodConfig.toJSON(component, result, opts)\n } else if (methodConfig.toJSON === false) {\n toJSON = (component, result, opts) => result\n } else if (methodConfig.toJSON === true) {\n toJSON = (component, result, opts) => component.toJSON(result, opts)\n } else {\n if (utils.isFunction(config.toJSON)) {\n toJSON = (component, result, opts) => config.toJSON(component, result, opts)\n } else if (config.toJSON === false) {\n toJSON = (component, result, opts) => result\n } else {\n toJSON = (component, result, opts) => component.toJSON(result, opts)\n }\n }\n\n return (req, res, next) => {\n const result = req.jsdataResult\n\n res.status(statusCode)\n\n try {\n if (result !== undefined) {\n res.send(toJSON(component, result, req.jsdataOpts))\n }\n } catch (err) {\n return next(err)\n }\n\n res.end()\n }\n}\n","import {\n Component,\n Container,\n Mapper,\n utils\n} from 'js-data'\n\nimport { queryParser } from './queryParser'\nimport * as handlers from './handlers'\nimport express from 'express'\nimport bodyParser from 'body-parser'\n\nexport * from './queryParser'\n\nconst handlerNoop = (req, res, next) => {\n next()\n}\n\nfunction makeHandler (method, component, config = {}) {\n config[method] || (config[method] = {})\n const userRequestHandler = utils.isFunction(config[method].request) ? config[method].request : handlerNoop\n const defaultRequestHandler = handlers.makeRequestHandler(method, component, config)\n const defaultResponseHandler = handlers.makeResponseHandler(method, component, config)\n\n return (req, res, next) => {\n userRequestHandler(req, res, (err) => {\n if (err) {\n return next(err)\n }\n defaultRequestHandler(req, res, (err) => {\n if (err) {\n return next(err)\n }\n if (utils.isFunction(config[method].response)) {\n config[method].response(req, res, next)\n } else {\n defaultResponseHandler(req, res, next)\n }\n })\n })\n }\n}\n\n/**\n * A middleware method invoked on all requests\n *\n * @typedef RequestHandler\n * @type function\n * @param {object} req HTTP(S) Request Object\n * @param {object} res HTTP(S) Response Object\n * @param {function} next Express `next()` callback to continue the chain\n */\n\n/**\n * A method that handles all responses\n *\n * @typedef ResponseHandler\n * @type function\n * @param {object} req HTTP(S) Request Object\n * @param {object} res HTTP(S) Response Object\n * @param {function} next Express `next()` callback to continue the chain\n */\n\n/**\n * Custom defined method that retrieves data/results for an endpoint\n *\n * @typedef ActionHandler\n * @type function\n * @param {object} component Instance of `Mapper`, `Container`, `SimpleStore`,\n * or `DataStore`.\n * @param {object} req HTTP(S) Request Object\n *\n * @example A custom action\n * (component, req) => {\n * return new Promise((resolve, reject) => {\n * // ..some logic\n * return resolve(results)\n * })\n * }\n *\n * @returns {Promise} Promise that resolves with the result.\n */\n\n/**\n * @typedef Serializer\n * @type function\n * @param {object} component Instance of `Mapper`, `Container`, `SimpleStore`,\n * or `DataStore`.\n * @param {object} result The result of the endpoint's {@link ActionHandler}.\n * @param {object} opts Configuration options.\n * @returns {object|array|undefined} The serialized result.\n */\n\n/**\n * create action configs\n *\n * @typedef CreateConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * createMany action configs\n *\n * @typedef CreateManyConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * destroy action configs\n *\n * @typedef DestroyConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * destroyAll action configs\n *\n * @typedef DestroyAllConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * find action configs\n *\n * @typedef FindConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * findAll action configs\n *\n * @typedef FindAllConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * update action configs\n *\n * @typedef UpdateConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * UpdateAllConfig action configs\n *\n * @typedef UpdateAllConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * updateMany action configs\n *\n * @typedef UpdateManyConfig\n * @type object\n * @property {ActionHandler} [action] Custom action to retrieve data results\n * @property {number} [statusCode] The status code to return with the response\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n */\n\n/**\n * Define endpoint path with custom logic\n *\n * @typedef Endpoint\n * @type function\n * @param {Object} mapper Component Mapper object\n */\n\n/**\n * Configuration options for endpoints, actions, & request/response\n *\n * @typedef Config\n * @type object\n * @property {Endpoint} [getEndpoint] Define endpoints with custom method\n * @property {CreateConfig} [create] create action configs\n * @property {CreateManyConfig} [createMany] createMany action configs\n * @property {DestroyConfig} [destroy] destroy action configs\n * @property {DestroyAllConfig} [destroyAll] destroyAll action configs\n * @property {FindConfig} [find] find action configs\n * @property {FindAllConfig} [findAll] findAll action configs\n * @property {Serializer|boolean} [toJSON] Define custom toJSON method for response results\n * @property {UpdateConfig} [update] update action configs\n * @property {UpdateAllConfig} [updateAll] updateAll action configs\n * @property {UpdateManyConfig} [updateMany] updateMany action configs\n */\n\n/**\n * @class Router\n *\n * @param {object} component Instance of `Mapper`, `Container`, `SimpleStore`,\n * or `DataStore`.\n * @param {Config} [config] Optional configuration.\n *\n */\nexport function Router (component, config = {}) {\n if (!(component instanceof Mapper) && !(component instanceof Container)) {\n throw new Error('You must provide an instance of JSData.Container, JSData.DataStore, or JSData.Mapper!')\n }\n\n const router = this.router = express.Router()\n router.use(bodyParser.json())\n router.use(bodyParser.urlencoded({\n extended: true\n }))\n\n if (utils.isFunction(config.request)) {\n router.use(config.request)\n config.request = undefined\n }\n\n if (component instanceof Container) {\n utils.forOwn(component._mappers, (mapper, name) => {\n let endpoint = `/${mapper.endpoint || name}`\n if (utils.isFunction(config.getEndpoint)) {\n endpoint = config.getEndpoint(mapper)\n }\n router.use(endpoint, new Router(mapper, config).router)\n })\n } else if (component instanceof Mapper) {\n const createManyHandler = makeHandler('createMany', component, config)\n const createHandler = makeHandler('create', component, config)\n const updateManyHandler = makeHandler('updateMany', component, config)\n const updateAllHandler = makeHandler('updateAll', component, config)\n\n router.route('/')\n // GET /:resource\n .get(makeHandler('findAll', component, config))\n // POST /:resource\n .post(function (req, res, next) {\n if (utils.isArray(req.body)) {\n createManyHandler(req, res, next)\n } else {\n createHandler(req, res, next)\n }\n })\n // PUT /:resource\n .put(function (req, res, next) {\n if (utils.isArray(req.body)) {\n updateManyHandler(req, res, next)\n } else {\n updateAllHandler(req, res, next)\n }\n })\n // DELETE /:resource\n .delete(makeHandler('destroyAll', component, config))\n\n router.route('/:id')\n // GET /:resource/:id\n .get(makeHandler('find', component, config))\n // PUT /:resource/:id\n .put(makeHandler('update', component, config))\n // DELETE /:resource/:id\n .delete(makeHandler('destroy', component, config))\n }\n}\n\nComponent.extend({\n constructor: Router\n})\n\n/**\n * Convenience method that mounts {@link queryParser} and a store.\n *\n * @example Mount queryParser and store at \"/\"\n * import express from 'express';\n * import { mount, queryParser, Router } from 'js-data-express';\n * import { Container } from 'js-data';\n *\n * const app = express();\n * const store = new Container();\n * const UserMapper = store.defineMapper('user');\n * const CommentMapper = store.defineMapper('comment');\n * mount(app, store);\n *\n * @example Mount queryParser and store at \"/api\"\n * mount(app, store, '/api');\n *\n * @name module:js-data-express.mount\n * @method\n * @param {*} app\n * @param {object} store Instance of `Mapper`, `Container`, `SimpleStore`,\n * or `DataStore`.\n * @param {Config|string} [config] Configuration options.\n */\nexport function mount (app, store, config = {}) {\n if (!(store instanceof Container)) {\n throw new Error('You must provide an instance of JSData.Container or JSData.DataStore!')\n }\n if (utils.isString(config)) {\n config = { path: config }\n }\n config.path || (config.path = '/')\n\n app.use(config.path, queryParser)\n app.use(config.path, new Router(store, config).router)\n}\n\n/**\n * Details of the current version of the `js-data-express` module.\n *\n * @example ES2015 modules import\n * import { version } from 'js-data-express';\n * console.log(version.full);\n *\n * @example CommonJS import\n * var version = require('js-data-express').version;\n * console.log(version.full);\n *\n * @name module:js-data-express.version\n * @type {object}\n * @property {string} version.full The full semver value.\n * @property {number} version.major The major version number.\n * @property {number} version.minor The minor version number.\n * @property {number} version.patch The patch version number.\n * @property {(string|boolean)} version.alpha The alpha version value,\n * otherwise `false` if the current version is not alpha.\n * @property {(string|boolean)} version.beta The beta version value,\n * otherwise `false` if the current version is not beta.\n */\nexport const version = '<%= version %>'\n\n/**\n * {@link Router} class.\n *\n * @example ES2015 modules import\n * import { Router } from 'js-data-express';\n * const adapter = new Router();\n *\n * @example CommonJS import\n * var Router = require('js-data-express').Router;\n * var adapter = new Router();\n *\n * @name module:js-data-express.Router\n * @see Router\n * @type {Constructor}\n */\n\n/**\n * Registered as `js-data-express` in NPM.\n *\n * @example Install from NPM\n * npm i --save js-data-express@rc js-data@rc\n *\n * @example ES2015 modules import\n * import { Router } from 'js-data-express';\n * const adapter = new Router();\n *\n * @example CommonJS import\n * var Router = require('js-data-express').Router;\n * var adapter = new Router();\n *\n * @module js-data-express\n */\n"],"names":["parseQuery","query","where","JSON","parse","err","orderBy","sort","error","Array","isArray","map","clause","indexOf","undefined","queryParser","req","res","next","jsdataOpts","with","DEFAULTS","component","create","body","createMany","destroy","params","id","destroyAll","find","findAll","update","updateAll","updateMany","makeRequestHandler","method","config","action","then","result","jsdataResult","catch","makeResponseHandler","methodConfig","statusCode","toJSON","utils","isFunction","opts","status","send","end","handlerNoop","makeHandler","userRequestHandler","request","defaultRequestHandler","handlers","defaultResponseHandler","response","Router","Mapper","Container","Error","router","express","use","bodyParser","json","urlencoded","forOwn","_mappers","mapper","name","endpoint","getEndpoint","createManyHandler","createHandler","updateManyHandler","updateAllHandler","route","get","post","put","delete","Component","extend","mount","app","store","isString","path","version"],"mappings":"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"} \ No newline at end of file