Skip to content

Commit

Permalink
initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
Yury Dymov committed Dec 22, 2016
1 parent 102a414 commit 7f950f1
Show file tree
Hide file tree
Showing 10 changed files with 521 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .babelrc
@@ -0,0 +1,7 @@
{
"presets": [
"es2015",
"react",
"stage-0"
]
}
4 changes: 4 additions & 0 deletions .eslintrc
@@ -0,0 +1,4 @@
{
"extends": "airbnb",
"parser": "babel-eslint"
}
9 changes: 9 additions & 0 deletions .npmignore
@@ -0,0 +1,9 @@
coverage
demo
docs
src
test
.babelrc
.eslintrc
.travis.yml
webpack.config.js
14 changes: 14 additions & 0 deletions .travis.yml
@@ -0,0 +1,14 @@
language: node_js
node_js:
- "6"
- "5"
- "4"
- "node"
env:
- CXX=g++-4.8
before_install:
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo apt-get -qq update
- sudo apt-get -qq install g++-4.8
install: "npm install && npm run build"
after_success: "npm install -g coveralls && npm run coverage && cat ./coverage/lcov.info | coveralls"
5 changes: 5 additions & 0 deletions README.md
@@ -0,0 +1,5 @@
# json-api-normalizer
Utility to normalize JSON API data for redux applications

# Description
TBD
1 change: 1 addition & 0 deletions dist/bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions package.json
@@ -0,0 +1,52 @@
{
"name": "json-api-normalizer",
"version": "0.0.1",
"description": "JSON API response normaliser",
"main": "dist/bundle.js",
"scripts": {
"build": "NODE_ENV=production webpack -p",
"clean": "rimraf dist coverage lib",
"coverage": "NODE_ENV=production webpack && istanbul cover _mocha -- --compilers js:babel-core/register && NODE_ENV=production webpack -p",
"lint": "eslint src --ext .js",
"test": "mocha --compilers js:babel-core/register"
},
"repository": {
"type": "git",
"url": "git+https://github.com/yury-dymov/json-api-normalizer.git"
},
"keywords": [
"JSON",
"API",
"normalize",
"redux"
],
"author": "Yury Dymov",
"license": "MIT",
"bugs": {
"url": "https://github.com/yury-dymov/json-api-normalizer/issues"
},
"homepage": "https://github.com/yury-dymov/json-api-normalizer#readme",
"devDependencies": {
"babel-core": "^6.21.0",
"babel-eslint": "^7.1.1",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-0": "^6.16.0",
"chai": "^3.5.0",
"eslint": "^3.12.2",
"eslint-config-airbnb": "^13.0.0",
"eslint-loader": "^1.6.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.8.0",
"istanbul": "^1.1.0-alpha.1",
"mocha": "^3.2.0",
"rimraf": "^2.5.4",
"webpack": "^1.14.0",
"webpack-node-externals": "^1.5.4"
},
"dependencies": {
"lodash": "^4.17.2"
}
}
96 changes: 96 additions & 0 deletions src/normalize.js
@@ -0,0 +1,96 @@
import isArray from 'lodash/isArray';
import join from 'lodash/join';
import keys from 'lodash/keys';
import merge from 'lodash/merge';

function wrap(json) {
if (isArray(json)) {
return json;
}

return [json];
}

function extract(json) {
const ret = {};

wrap(json).forEach((elem) => {
ret[elem.type] = ret[elem.type] || {};
ret[elem.type][elem.id] = ret[elem.type][elem.id] || {};
ret[elem.type][elem.id].attributes = elem.attributes;

if (elem.relationships) {
wrap(elem.relationships).forEach((relationship) => {
const ids = [];

let type;

wrap(relationship).forEach((object) => {
keys(object).forEach((key) => {
ids.push(object[key].data.id);
type = object[key].data.type;
});
});

ret[elem.type][elem.id].relationships = {};
ret[elem.type][elem.id].relationships[type] = join(ids, ',');
});
}
});

return ret;
}

function doFilterEndpoint(endpoint) {
return endpoint.replace(/\?.*$/, '');
}

function extractMetaData(json, endpoint) {
const ret = {};

ret.meta = {};
ret.meta[endpoint] = {};
ret.meta[endpoint].data = {};

if (json.data) {
const ids = {};

wrap(json.data).forEach((object) => {
ids[object.type] = ids[object.type] || [];
ids[object.type].push(object.id);
});

keys(ids).forEach(type => ids[type] = join(ids[type], ','));

ret.meta[endpoint].data = ids;

if (json.links) {
ret.meta[endpoint].links = json.links;
}
}

return ret;
}

export default function normalize(json, endpoint = null, opts = {}) {
const ret = {};
let { filterEndpoint } = opts;

if (typeof filterEndpoint === 'undefined') {
filterEndpoint = true;
}

if (json.data) {
merge(ret, extract(json.data));
}

if (json.included) {
merge(ret, extract(json.included));
}

if (endpoint) {
merge(ret, extractMetaData(json, filterEndpoint ? doFilterEndpoint(endpoint) : endpoint));
}

return ret;
}

0 comments on commit 7f950f1

Please sign in to comment.