@data-client/normalizr
Version:
Normalizes and denormalizes JSON according to schema for Redux and Flux applications
74 lines (71 loc) • 11.1 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { addEntities } from './addEntities.js';
import { getVisit } from './getVisit.js';
import { createGetEntity } from '../memo/MemoCache.js';
export const normalize = (schema, input, args = [], {
entities,
indexes,
entityMeta
} = emptyStore, meta = {
fetchedAt: 0,
date: Date.now(),
expiresAt: Infinity
}) => {
// no schema means we don't process at all
if (schema === undefined || schema === null) return {
result: input,
entities,
indexes,
entityMeta
};
const schemaType = expectedSchemaType(schema);
if (input === null || typeof input !== schemaType &&
// we will allow a Delete schema to be a string or object
!(schema.key !== undefined && schema.pk === undefined && typeof input === 'string')) {
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
const parseWorks = input => {
try {
return typeof JSON.parse(input) !== 'string';
} catch (e) {
return false;
}
};
if (typeof input === 'string' && parseWorks(input)) {
throw new Error(`Normalizing a string, but this does match schema.
Parsing this input string as JSON worked. This likely indicates fetch function did not parse
the JSON. By default, this only happens if "content-type" header includes "json".
See https://dataclient.io/rest/api/RestEndpoint#parseResponse for more information
Schema: ${JSON.stringify(schema, undefined, 2)}
Input: "${input}"`);
} else {
throw new Error(`Unexpected input given to normalize. Expected type to be "${schemaType}", found "${input === null ? 'null' : typeof input}".
Schema: ${JSON.stringify(schema, undefined, 2)}
Input: "${input}"`);
}
} else {
throw new Error(`Unexpected input given to normalize. Expected type to be "${schemaType}", found "${input === null ? 'null' : typeof input}".`);
}
}
const newEntities = new Map();
const newIndexes = new Map();
const ret = {
result: '',
entities: _extends({}, entities),
indexes: _extends({}, indexes),
entityMeta: _extends({}, entityMeta)
};
const addEntity = addEntities(newEntities, newIndexes, ret.entities, ret.indexes, ret.entityMeta, meta);
const visit = getVisit(addEntity, createGetEntity(entities));
ret.result = visit(schema, input, input, undefined, args);
return ret;
};
function expectedSchemaType(schema) {
return ['object', 'function'].includes(typeof schema) ? 'object' : typeof schema;
}
const emptyStore = {
entities: {},
indexes: {},
entityMeta: {}
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhZGRFbnRpdGllcyIsImdldFZpc2l0IiwiY3JlYXRlR2V0RW50aXR5Iiwibm9ybWFsaXplIiwic2NoZW1hIiwiaW5wdXQiLCJhcmdzIiwiZW50aXRpZXMiLCJpbmRleGVzIiwiZW50aXR5TWV0YSIsImVtcHR5U3RvcmUiLCJtZXRhIiwiZmV0Y2hlZEF0IiwiZGF0ZSIsIkRhdGUiLCJub3ciLCJleHBpcmVzQXQiLCJJbmZpbml0eSIsInVuZGVmaW5lZCIsInJlc3VsdCIsInNjaGVtYVR5cGUiLCJleHBlY3RlZFNjaGVtYVR5cGUiLCJrZXkiLCJwayIsInByb2Nlc3MiLCJlbnYiLCJOT0RFX0VOViIsInBhcnNlV29ya3MiLCJKU09OIiwicGFyc2UiLCJlIiwiRXJyb3IiLCJzdHJpbmdpZnkiLCJuZXdFbnRpdGllcyIsIk1hcCIsIm5ld0luZGV4ZXMiLCJyZXQiLCJfZXh0ZW5kcyIsImFkZEVudGl0eSIsInZpc2l0IiwiaW5jbHVkZXMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbm9ybWFsaXpyL25vcm1hbGl6ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhZGRFbnRpdGllcyB9IGZyb20gJy4vYWRkRW50aXRpZXMuanMnO1xuaW1wb3J0IHsgZ2V0VmlzaXQgfSBmcm9tICcuL2dldFZpc2l0LmpzJztcbmltcG9ydCB0eXBlIHsgU2NoZW1hLCBOb3JtYWxpemVkSW5kZXggfSBmcm9tICcuLi9pbnRlcmZhY2UuanMnO1xuaW1wb3J0IHsgY3JlYXRlR2V0RW50aXR5IH0gZnJvbSAnLi4vbWVtby9NZW1vQ2FjaGUuanMnO1xuaW1wb3J0IHR5cGUge1xuICBOb3JtYWxpemVNZXRhLFxuICBOb3JtYWxpemVOdWxsYWJsZSxcbiAgTm9ybWFsaXplZFNjaGVtYSxcbiAgU3RvcmVEYXRhLFxufSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBjb25zdCBub3JtYWxpemUgPSA8XG4gIFMgZXh0ZW5kcyBTY2hlbWEgPSBTY2hlbWEsXG4gIEUgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgdW5kZWZpbmVkPiA9IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgUmVjb3JkPHN0cmluZywgYW55PlxuICA+LFxuICBSID0gTm9ybWFsaXplTnVsbGFibGU8Uz4sXG4+KFxuICBzY2hlbWE6IFMgfCB1bmRlZmluZWQsXG4gIGlucHV0OiBhbnksXG4gIGFyZ3M6IHJlYWRvbmx5IGFueVtdID0gW10sXG4gIHsgZW50aXRpZXMsIGluZGV4ZXMsIGVudGl0eU1ldGEgfTogU3RvcmVEYXRhPEU+ID0gZW1wdHlTdG9yZSxcbiAgbWV0YTogTm9ybWFsaXplTWV0YSA9IHsgZmV0Y2hlZEF0OiAwLCBkYXRlOiBEYXRlLm5vdygpLCBleHBpcmVzQXQ6IEluZmluaXR5IH0sXG4pOiBOb3JtYWxpemVkU2NoZW1hPEUsIFI+ID0+IHtcbiAgLy8gbm8gc2NoZW1hIG1lYW5zIHdlIGRvbid0IHByb2Nlc3MgYXQgYWxsXG4gIGlmIChzY2hlbWEgPT09IHVuZGVmaW5lZCB8fCBzY2hlbWEgPT09IG51bGwpXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlc3VsdDogaW5wdXQsXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGluZGV4ZXMsXG4gICAgICBlbnRpdHlNZXRhLFxuICAgIH07XG5cbiAgY29uc3Qgc2NoZW1hVHlwZSA9IGV4cGVjdGVkU2NoZW1hVHlwZShzY2hlbWEpO1xuICBpZiAoXG4gICAgaW5wdXQgPT09IG51bGwgfHxcbiAgICAodHlwZW9mIGlucHV0ICE9PSBzY2hlbWFUeXBlICYmXG4gICAgICAvLyB3ZSB3aWxsIGFsbG93IGEgRGVsZXRlIHNjaGVtYSB0byBiZSBhIHN0cmluZyBvciBvYmplY3RcbiAgICAgICEoXG4gICAgICAgIChzY2hlbWEgYXMgYW55KS5rZXkgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAoc2NoZW1hIGFzIGFueSkucGsgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICB0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnXG4gICAgICApKVxuICApIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBjb25zdCBwYXJzZVdvcmtzID0gKGlucHV0OiBzdHJpbmcpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gdHlwZW9mIEpTT04ucGFyc2UoaW5wdXQpICE9PSAnc3RyaW5nJztcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnICYmIHBhcnNlV29ya3MoaW5wdXQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm9ybWFsaXppbmcgYSBzdHJpbmcsIGJ1dCB0aGlzIGRvZXMgbWF0Y2ggc2NoZW1hLlxuXG5QYXJzaW5nIHRoaXMgaW5wdXQgc3RyaW5nIGFzIEpTT04gd29ya2VkLiBUaGlzIGxpa2VseSBpbmRpY2F0ZXMgZmV0Y2ggZnVuY3Rpb24gZGlkIG5vdCBwYXJzZVxudGhlIEpTT04uIEJ5IGRlZmF1bHQsIHRoaXMgb25seSBoYXBwZW5zIGlmIFwiY29udGVudC10eXBlXCIgaGVhZGVyIGluY2x1ZGVzIFwianNvblwiLlxuU2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9yZXN0L2FwaS9SZXN0RW5kcG9pbnQjcGFyc2VSZXNwb25zZSBmb3IgbW9yZSBpbmZvcm1hdGlvblxuXG4gIFNjaGVtYTogJHtKU09OLnN0cmluZ2lmeShzY2hlbWEsIHVuZGVmaW5lZCwgMil9XG4gIElucHV0OiBcIiR7aW5wdXR9XCJgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgVW5leHBlY3RlZCBpbnB1dCBnaXZlbiB0byBub3JtYWxpemUuIEV4cGVjdGVkIHR5cGUgdG8gYmUgXCIke3NjaGVtYVR5cGV9XCIsIGZvdW5kIFwiJHtcbiAgICAgICAgICAgIGlucHV0ID09PSBudWxsID8gJ251bGwnIDogdHlwZW9mIGlucHV0XG4gICAgICAgICAgfVwiLlxuXG4gICAgICAgICAgU2NoZW1hOiAke0pTT04uc3RyaW5naWZ5KHNjaGVtYSwgdW5kZWZpbmVkLCAyKX1cbiAgICAgICAgICBJbnB1dDogXCIke2lucHV0fVwiYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVW5leHBlY3RlZCBpbnB1dCBnaXZlbiB0byBub3JtYWxpemUuIEV4cGVjdGVkIHR5cGUgdG8gYmUgXCIke3NjaGVtYVR5cGV9XCIsIGZvdW5kIFwiJHtcbiAgICAgICAgICBpbnB1dCA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiBpbnB1dFxuICAgICAgICB9XCIuYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgbmV3RW50aXRpZXMgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgYW55Pj4oKTtcbiAgY29uc3QgbmV3SW5kZXhlcyA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBhbnk+PigpO1xuICBjb25zdCByZXQ6IE5vcm1hbGl6ZWRTY2hlbWE8RSwgUj4gPSB7XG4gICAgcmVzdWx0OiAnJyBhcyBhbnksXG4gICAgZW50aXRpZXM6IHsgLi4uZW50aXRpZXMgfSxcbiAgICBpbmRleGVzOiB7IC4uLmluZGV4ZXMgfSxcbiAgICBlbnRpdHlNZXRhOiB7IC4uLmVudGl0eU1ldGEgfSxcbiAgfTtcbiAgY29uc3QgYWRkRW50aXR5ID0gYWRkRW50aXRpZXMoXG4gICAgbmV3RW50aXRpZXMsXG4gICAgbmV3SW5kZXhlcyxcbiAgICByZXQuZW50aXRpZXMsXG4gICAgcmV0LmluZGV4ZXMsXG4gICAgcmV0LmVudGl0eU1ldGEsXG4gICAgbWV0YSxcbiAgKTtcblxuICBjb25zdCB2aXNpdCA9IGdldFZpc2l0KGFkZEVudGl0eSwgY3JlYXRlR2V0RW50aXR5KGVudGl0aWVzKSk7XG4gIHJldC5yZXN1bHQgPSB2aXNpdChzY2hlbWEsIGlucHV0LCBpbnB1dCwgdW5kZWZpbmVkLCBhcmdzKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIGV4cGVjdGVkU2NoZW1hVHlwZShzY2hlbWE6IFNjaGVtYSkge1xuICByZXR1cm4gWydvYmplY3QnLCAnZnVuY3Rpb24nXS5pbmNsdWRlcyh0eXBlb2Ygc2NoZW1hKSA/ICdvYmplY3QnIDogKFxuICAgICAgdHlwZW9mIHNjaGVtYVxuICAgICk7XG59XG5cbmNvbnN0IGVtcHR5U3RvcmU6IFN0b3JlRGF0YTxhbnk+ID0ge1xuICBlbnRpdGllczoge30sXG4gIGluZGV4ZXM6IHt9LFxuICBlbnRpdHlNZXRhOiB7fSxcbn07XG4iXSwibWFwcGluZ3MiOiI7QUFBQSxTQUFTQSxXQUFXLFFBQVEsa0JBQWtCO0FBQzlDLFNBQVNDLFFBQVEsUUFBUSxlQUFlO0FBRXhDLFNBQVNDLGVBQWUsUUFBUSxzQkFBc0I7QUFRdEQsT0FBTyxNQUFNQyxTQUFTLEdBQUdBLENBUXZCQyxNQUFxQixFQUNyQkMsS0FBVSxFQUNWQyxJQUFvQixHQUFHLEVBQUUsRUFDekI7RUFBRUMsUUFBUTtFQUFFQyxPQUFPO0VBQUVDO0FBQXlCLENBQUMsR0FBR0MsVUFBVSxFQUM1REMsSUFBbUIsR0FBRztFQUFFQyxTQUFTLEVBQUUsQ0FBQztFQUFFQyxJQUFJLEVBQUVDLElBQUksQ0FBQ0MsR0FBRyxDQUFDLENBQUM7RUFBRUMsU0FBUyxFQUFFQztBQUFTLENBQUMsS0FDbEQ7RUFDM0I7RUFDQSxJQUFJYixNQUFNLEtBQUtjLFNBQVMsSUFBSWQsTUFBTSxLQUFLLElBQUksRUFDekMsT0FBTztJQUNMZSxNQUFNLEVBQUVkLEtBQUs7SUFDYkUsUUFBUTtJQUNSQyxPQUFPO0lBQ1BDO0VBQ0YsQ0FBQztFQUVILE1BQU1XLFVBQVUsR0FBR0Msa0JBQWtCLENBQUNqQixNQUFNLENBQUM7RUFDN0MsSUFDRUMsS0FBSyxLQUFLLElBQUksSUFDYixPQUFP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