diff --git a/README.md b/README.md index bad4620..e220120 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,19 @@ This is a [Sails JS](http://sailsjs.org) hook for creating an API which conforms Just lift your app as normal, and your api responses will be formatted in accordance with [jsonapi.org](http://jsonapi.org/format/). +If you need to serialize data for other reasons (eg. send data trough sockets), you can use the serializeData method like this `serializedData = sails.hooks.jsonapi.serializeData(model,data);`. +This method takes 2 arguments +* *model:* The name of the model that you wish to serialize ('model' must be defined on the sails models). +* *data:* The data to be serialized. + #### Options Create a `jsonapi.js` file inside the `config/` directory of your app, and you can set the following options: | Option | Default | Description | |---------------|:---------:|---------------| | `compoundDoc` | `true` | When set to 'true' (default), response will be a [compound document](http://jsonapi.org/format/#document-compound-documents) including related resources. | +| `keyForAttribute` | `dash-case` | A function or string to customize attributes. Functions are passed the attribute as a single argument and expect a string to be returned. Strings are aliases for inbuilt functions for common case conversions. Options include: dash-case (default), lisp-case, spinal-case, kebab-case, underscore_case, snake_case, camelCase, CamelCase. | +| `pluralizeType` | `true` | When set to 'true' (default), the type is pluralized. | ### Known Limitations @@ -45,4 +52,4 @@ This is unfinished. So far, the following are not yet implemented: - [ ] Updating relationships - [ ] Deleting relationships -There may be more. Please submit issue reports. Or better yet, pull requests. +There may be more. Please submit issue reports. Or better yet, pull requests. \ No newline at end of file diff --git a/lib/hook.js b/lib/hook.js index 54882f0..e6919f3 100644 --- a/lib/hook.js +++ b/lib/hook.js @@ -2,6 +2,7 @@ module.exports = function jsonApiHook(sails) { var moduleUtils = require('./utils/module-utils'); + var serializer = require('./serializer'); var _ = require('lodash'); var normalizeQueryParams = require('./requests/query-params'); var normalizePayload = require('./requests/payload'); @@ -16,7 +17,7 @@ module.exports = function jsonApiHook(sails) { * @param {Function} next [description] * @api private */ - var addResponseMethods = function (req, res) { + function addResponseMethods(req, res) { // Attach custom responses to `res` object // Provide access to `req` and `res` in each of their `this` contexts. _.each(sails.middleware.jsonapi.responses, function eachMethod(responseFn, name) { @@ -26,10 +27,10 @@ module.exports = function jsonApiHook(sails) { res: res, }); }); - }; + } // binds PATCH routes - var bindPatchRoutes = function () { + let bindPatchRoutes = function () { // https://github.com/balderdashy/sails/blob/v0.12.2-0/lib/hooks/blueprints/index.js#L157-L370 _.each(sails.middleware.controllers, function eachController(controller, controllerId) { var _getRestRoute; @@ -103,9 +104,11 @@ module.exports = function jsonApiHook(sails) { defaults: { __configKey__: { - _hookTimeout: 10000, // wait 10 seconds before timing out - compoundDoc : true, - included : true, + _hookTimeout : 10000, // wait 10 seconds before timing out + compoundDoc : true, + included : true, + pluralizeType : true, + keyForAttribute: 'dash-case', } }, @@ -124,6 +127,10 @@ module.exports = function jsonApiHook(sails) { }); }, + serializeData: function (type, data) { + return serializer(type, data); + }, + /** * Shadow route bindings * @type {Object} @@ -132,17 +139,20 @@ module.exports = function jsonApiHook(sails) { before: { 'all /*': function (req, res, next) { + if (req.isSocket) return next(); addResponseMethods(req, res); next(); }, 'GET /*': function (req, res, next) { + if (req.isSocket) return next(); addResponseMethods(req, res); normalizeQueryParams(req, res); next(); }, 'POST /*': function (req, res, next) { + if (req.isSocket) return next(); addResponseMethods(req, res); normalizePayload(req, next); }, @@ -150,6 +160,7 @@ module.exports = function jsonApiHook(sails) { 'PATCH /*': function (req, res, next) { addResponseMethods(req, res); normalizePayload(req, next); + next(); } } } diff --git a/lib/responses/json.js b/lib/responses/ok.js similarity index 91% rename from lib/responses/json.js rename to lib/responses/ok.js index 66cfb3e..da53621 100644 --- a/lib/responses/json.js +++ b/lib/responses/ok.js @@ -24,12 +24,12 @@ function normalizeResArgs( args ) { }; if (isNumeric(args[0])) { return { - statusCode: args[0], + statusCode: args[0], other: args[1] }; } else return { - statusCode: args[1], + statusCode: args[1], other: args[0] }; } @@ -62,7 +62,9 @@ module.exports = function json() { sails.log.verbose('[jsonapi] modelName ::', modelName); Model = sails.models[modelName]; opts = { - attributes: modelUtils.getAttributes(Model) + attributes : modelUtils.getAttributes(Model), + keyForAttribute: sails.config.jsonapi.keyForAttribute, + pluralizeType : sails.config.jsonapi.pluralizeType }; // Add related model data relationships = modelUtils.getRelationships(req); @@ -73,7 +75,9 @@ module.exports = function json() { Model = sails.models[collection]; // Related model attributes opts[alias] = { - attributes: modelUtils.getOwnAttributes(Model) + attributes : modelUtils.getOwnAttributes(Model), + keyForAttribute: sails.config.jsonapi.keyForAttribute, + pluralizeType : sails.config.jsonapi.pluralizeType }; // add models as relationships if (modelUtils.isPopulatedRelationship(data, relationship)) { diff --git a/lib/serializer.js b/lib/serializer.js new file mode 100644 index 0000000..0f961d5 --- /dev/null +++ b/lib/serializer.js @@ -0,0 +1,41 @@ +'use strict'; + +var JSONAPISerializer = require('jsonapi-serializer').Serializer; + +module.exports = function (modelName, data) { + let sails = this.req._sails; + let sailsModel = sails.models[modelName]; + console.log(sailsModel); + console.log('------------'); + console.log(modelName); + try { + if (!sailsModel || typeof sailsModel === 'undefined') { + throw new Error(`Looks like the model '${modelName}', does not exist.`); + } + } catch (err) { + // throw 1; + console.error(err); + return {}; + } + + let attributes = []; + Object.keys(sailsModel.definition).forEach(function (key) { + if (!sailsModel.definition[key].primaryKey && !sailsModel.definition[key].alias) { + attributes.push(key); + } + }); + let Serializer = new JSONAPISerializer(modelName, { + attributes, + + keyForAttribute: sails.config.jsonapi.keyForAttribute, + pluralizeType : sails.config.jsonapi.pluralizeType + }); + try { + data = JSON.parse(JSON.stringify(data)); + return Serializer.serialize(data); + } catch (err) { + console.error(`Unable to parse '${data}' for model '${modelName}', rerurning empty object \n + Attributes: ${attributes}`); + return {}; + } +}; diff --git a/lib/utils/norm-utils.js b/lib/utils/norm-utils.js index 761e88f..29ed488 100644 --- a/lib/utils/norm-utils.js +++ b/lib/utils/norm-utils.js @@ -1,5 +1,11 @@ 'use strict'; exports.normalizeData = function (data) { - return JSON.parse(JSON.stringify(data)); + try { + data = JSON.parse(JSON.stringify(data)); + return data; + } catch (err) { + console.error(`Unable to parse '${data}', returning empty object`); + return {}; + } }; diff --git a/package.json b/package.json index 9e28a02..47ebeca 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,8 @@ }, "dependencies": { "jsonapi-serializer": "^3.3.0", - "lodash": "^4.5.0", - "pluralize": "^1.1.2", + "lodash": "^4.13.1", + "pluralize": "^1.2.1", "sails-build-dictionary": "^0.10.1" }, "devDependencies": {