@data-client/normalizr
Version:
Normalizes and denormalizes JSON according to schema for Redux and Flux applications
70 lines (67 loc) • 10 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { getVisit } from './getVisit.js';
import { NormalizeDelegate } from './NormalizeDelegate.js';
export const normalize = (schema, input, args = [], {
entities,
indexes,
entitiesMeta
} = 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,
entitiesMeta
};
const schemaType = expectedSchemaType(schema);
if (input === null || typeof input !== schemaType &&
// we will allow a Invalidate 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 ret = {
result: '',
entities: _extends({}, entities),
indexes: _extends({}, indexes),
entitiesMeta: _extends({}, entitiesMeta)
};
const visit = getVisit(new NormalizeDelegate(ret, meta));
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: {},
entitiesMeta: {}
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJnZXRWaXNpdCIsIk5vcm1hbGl6ZURlbGVnYXRlIiwibm9ybWFsaXplIiwic2NoZW1hIiwiaW5wdXQiLCJhcmdzIiwiZW50aXRpZXMiLCJpbmRleGVzIiwiZW50aXRpZXNNZXRhIiwiZW1wdHlTdG9yZSIsIm1ldGEiLCJmZXRjaGVkQXQiLCJkYXRlIiwiRGF0ZSIsIm5vdyIsImV4cGlyZXNBdCIsIkluZmluaXR5IiwidW5kZWZpbmVkIiwicmVzdWx0Iiwic2NoZW1hVHlwZSIsImV4cGVjdGVkU2NoZW1hVHlwZSIsImtleSIsInBrIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwicGFyc2VXb3JrcyIsIkpTT04iLCJwYXJzZSIsImUiLCJFcnJvciIsInN0cmluZ2lmeSIsInJldCIsIl9leHRlbmRzIiwidmlzaXQiLCJpbmNsdWRlcyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ub3JtYWxpemUvbm9ybWFsaXplLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldFZpc2l0IH0gZnJvbSAnLi9nZXRWaXNpdC5qcyc7XG5pbXBvcnQgdHlwZSB7IFNjaGVtYSB9IGZyb20gJy4uL2ludGVyZmFjZS5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIE5vcm1hbGl6ZU1ldGEsXG4gIE5vcm1hbGl6ZU51bGxhYmxlLFxuICBOb3JtYWxpemVkU2NoZW1hLFxuICBTdG9yZURhdGEsXG59IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCB7IE5vcm1hbGl6ZURlbGVnYXRlIH0gZnJvbSAnLi9Ob3JtYWxpemVEZWxlZ2F0ZS5qcyc7XG5cbmV4cG9ydCBjb25zdCBub3JtYWxpemUgPSA8XG4gIFMgZXh0ZW5kcyBTY2hlbWEgPSBTY2hlbWEsXG4gIEUgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgdW5kZWZpbmVkPiA9IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgUmVjb3JkPHN0cmluZywgYW55PlxuICA+LFxuICBSID0gTm9ybWFsaXplTnVsbGFibGU8Uz4sXG4+KFxuICBzY2hlbWE6IFMgfCB1bmRlZmluZWQsXG4gIGlucHV0OiBhbnksXG4gIGFyZ3M6IHJlYWRvbmx5IGFueVtdID0gW10sXG4gIHsgZW50aXRpZXMsIGluZGV4ZXMsIGVudGl0aWVzTWV0YSB9OiBTdG9yZURhdGE8RT4gPSBlbXB0eVN0b3JlLFxuICBtZXRhOiBOb3JtYWxpemVNZXRhID0geyBmZXRjaGVkQXQ6IDAsIGRhdGU6IERhdGUubm93KCksIGV4cGlyZXNBdDogSW5maW5pdHkgfSxcbik6IE5vcm1hbGl6ZWRTY2hlbWE8RSwgUj4gPT4ge1xuICAvLyBubyBzY2hlbWEgbWVhbnMgd2UgZG9uJ3QgcHJvY2VzcyBhdCBhbGxcbiAgaWYgKHNjaGVtYSA9PT0gdW5kZWZpbmVkIHx8IHNjaGVtYSA9PT0gbnVsbClcbiAgICByZXR1cm4ge1xuICAgICAgcmVzdWx0OiBpbnB1dCxcbiAgICAgIGVudGl0aWVzLFxuICAgICAgaW5kZXhlcyxcbiAgICAgIGVudGl0aWVzTWV0YSxcbiAgICB9O1xuXG4gIGNvbnN0IHNjaGVtYVR5cGUgPSBleHBlY3RlZFNjaGVtYVR5cGUoc2NoZW1hKTtcbiAgaWYgKFxuICAgIGlucHV0ID09PSBudWxsIHx8XG4gICAgKHR5cGVvZiBpbnB1dCAhPT0gc2NoZW1hVHlwZSAmJlxuICAgICAgLy8gd2Ugd2lsbCBhbGxvdyBhIEludmFsaWRhdGUgc2NoZW1hIHRvIGJlIGEgc3RyaW5nIG9yIG9iamVjdFxuICAgICAgIShcbiAgICAgICAgKHNjaGVtYSBhcyBhbnkpLmtleSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgIChzY2hlbWEgYXMgYW55KS5wayA9PT0gdW5kZWZpbmVkICYmXG4gICAgICAgIHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZydcbiAgICAgICkpXG4gICkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGNvbnN0IHBhcnNlV29ya3MgPSAoaW5wdXQ6IHN0cmluZykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiB0eXBlb2YgSlNPTi5wYXJzZShpbnB1dCkgIT09ICdzdHJpbmcnO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgJiYgcGFyc2VXb3JrcyhpbnB1dCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBOb3JtYWxpemluZyBhIHN0cmluZywgYnV0IHRoaXMgZG9lcyBtYXRjaCBzY2hlbWEuXG5cblBhcnNpbmcgdGhpcyBpbnB1dCBzdHJpbmcgYXMgSlNPTiB3b3JrZWQuIFRoaXMgbGlrZWx5IGluZGljYXRlcyBmZXRjaCBmdW5jdGlvbiBkaWQgbm90IHBhcnNlXG50aGUgSlNPTi4gQnkgZGVmYXVsdCwgdGhpcyBvbmx5IGhhcHBlbnMgaWYgXCJjb250ZW50LXR5cGVcIiBoZWFkZXIgaW5jbHVkZXMgXCJqc29uXCIuXG5TZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL3Jlc3QvYXBpL1Jlc3RFbmRwb2ludCNwYXJzZVJlc3BvbnNlIGZvciBtb3JlIGluZm9ybWF0aW9uXG5cbiAgU2NoZW1hOiAke0pTT04uc3RyaW5naWZ5KHNjaGVtYSwgdW5kZWZpbmVkLCAyKX1cbiAgSW5wdXQ6IFwiJHtpbnB1dH1cImApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBVbmV4cGVjdGVkIGlucHV0IGdpdmVuIHRvIG5vcm1hbGl6ZS4gRXhwZWN0ZWQgdHlwZSB0byBiZSBcIiR7c2NoZW1hVHlwZX1cIiwgZm91bmQgXCIke1xuICAgICAgICAgICAgaW5wdXQgPT09IG51bGwgPyAnbnVsbCcgOiB0eXBlb2YgaW5wdXRcbiAgICAgICAgICB9XCIuXG5cbiAgICAgICAgICBTY2hlbWE6ICR7SlNPTi5zdHJpbmdpZnkoc2NoZW1hLCB1bmRlZmluZWQsIDIpfVxuICAgICAgICAgIElucHV0OiBcIiR7aW5wdXR9XCJgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBVbmV4cGVjdGVkIGlucHV0IGdpdmVuIHRvIG5vcm1hbGl6ZS4gRXhwZWN0ZWQgdHlwZSB0byBiZSBcIiR7c2NoZW1hVHlwZX1cIiwgZm91bmQgXCIke1xuICAgICAgICAgIGlucHV0ID09PSBudWxsID8gJ251bGwnIDogdHlwZW9mIGlucHV0XG4gICAgICAgIH1cIi5gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCByZXQ6IE5vcm1hbGl6ZWRTY2hlbWE8RSwgUj4gPSB7XG4gICAgcmVzdWx0OiAnJyBhcyBhbnksXG4gICAgZW50aXRpZXM6IHsgLi4uZW50aXRpZXMgfSxcbiAgICBpbmRleGVzOiB7IC4uLmluZGV4ZXMgfSxcbiAgICBlbnRpdGllc01ldGE6IHsgLi4uZW50aXRpZXNNZXRhIH0sXG4gIH07XG4gIGNvbnN0IHZpc2l0ID0gZ2V0VmlzaXQobmV3IE5vcm1hbGl6ZURlbGVnYXRlKHJldCwgbWV0YSkpO1xuICByZXQucmVzdWx0ID0gdmlzaXQoc2NoZW1hLCBpbnB1dCwgaW5wdXQsIHVuZGVmaW5lZCwgYXJncyk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBleHBlY3RlZFNjaGVtYVR5cGUoc2NoZW1hOiBTY2hlbWEpIHtcbiAgcmV0dXJuIFsnb2JqZWN0JywgJ2Z1bmN0aW9uJ10uaW5jbHVkZXModHlwZW9mIHNjaGVtYSkgPyAnb2JqZWN0JyA6IChcbiAgICAgIHR5cGVvZiBzY2hlbWFcbiAgICApO1xufVxuXG5jb25zdCBlbXB0eVN0b3JlOiBTdG9yZURhdGE8YW55PiA9IHtcbiAgZW50aXRpZXM6IHt9LFxuICBpbmRleGVzOiB7fSxcbiAgZW50aXRpZXNNZXRhOiB7fSxcbn07XG4iXSwibWFwcGluZ3MiOiI7QUFBQSxTQUFTQSxRQUFRLFFBQVEsZUFBZTtBQVF4QyxTQUFTQyxpQkFBaUIsUUFBUSx3QkFBd0I7QUFFMUQsT0FBTyxNQUFNQyxTQUFTLEdBQUdBLENBUXZCQyxNQUFxQixFQUNyQkMsS0FBVSxFQUNWQyxJQUFvQixHQUFHLEVBQUUsRUFDekI7RUFBRUMsUUFBUTtFQUFFQyxPQUFPO0VBQUVDO0FBQTJCLENBQUMsR0FBR0MsVUFBVSxFQUM5REMsSUFBbUIsR0FBRztFQUFFQyxTQUFTLEVBQUUsQ0FBQztFQUFFQyxJQUFJLEVBQUVDLElBQUksQ0FBQ0MsR0FBRyxDQUFDLENBQUM7RUFBRUMsU0FBUyxFQUFFQztBQUFTLENBQUMsS0FDbEQ7RUFDM0I7RUFDQSxJQUFJYixNQUFNLEtBQUtjLFNBQVMsSUFBSWQsTUFBTSxLQUFLLElBQUksRUFDekMsT0FBTztJQUNMZSxNQUFNLEVBQUVkLEtBQUs7SUFDYkUsUUFBUTtJQUNSQyxPQUFPO0lBQ1BDO0VBQ0YsQ0FBQztFQUVILE1BQU1XLFVBQVUsR0FBR0Msa0JBQWtCLENBQUNqQixNQUFNLENBQUM7RUFDN0MsSUFDRUMsS0FBSyxLQUFLLElBQUksSUFDYixPQUFPQSxLQUFLLEtBQUtlLFVBQVU7RUFDMUI7RUFDQSxFQUNHaEIsTUFBTSxDQUFTa0IsR0FBRyxLQUFLSixTQUFTLElBQ2hDZCxNQUFNLENBQVNtQixFQUFFLEtBQUtMLFNBQVMsSUFDaEMsT0FBT2IsS0FBSyxLQUFLLFFBQVEsQ0FDekIsRUFDSjtJQUNBO0lBQ0EsSUFBSW1CLE9BQU8sQ0FBQ0MsR0FBRyxDQUFDQyxRQUFRLEtBQUssWUFBWSxFQUFFO01BQ3pDLE1BQU1DLFVBQVUsR0FBSXRCLEtBQWEsSUFBSztRQUNwQyxJQUFJO1VBQ0YsT0FBTyxPQUFPdUIsSUFBSSxDQUFDQyxLQUFLLENBQUN4QixLQUFLLENBQUMsS0FBSyxRQUFRO1FBQzlDLENBQUMsQ0FBQyxPQUFPeUIsQ0FBQyxFQUFFO1VBQ1YsT0FBTyxLQUFLO1FBQ2Q7TUFDRixDQUFDO01BQ0QsSUFBSSxPQUFPekIsS0FBSyxLQUFLLFFBQVEsSUFBSXNCLFVBQVUsQ0FBQ3RCLEtBQUssQ0FBQyxFQUFFO1FBQ2xELE1BQU0sSUFBSTBCLEtBQUssQ0FBQztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWUgsSUFBSSxDQUFDSSxTQUFTLENBQUM1QixNQUFNLEVBQUVjLFNBQVMsRUFBRSxDQUFDLENBQUM7QUFDaEQsWUFBWWIsS0FBSyxHQUFHLENBQUM7TUFDZixDQUFDLE1BQU07UUFDTCxNQUFNLElBQUkwQixLQUFLLENBQ2IsNkRBQTZEWCxVQUFVLGFBQ3JFZixLQUFLLEtBQUssSUFBSSxHQUFHLE1BQU0sR0FBRyxPQUFPQSxLQUFLO0FBQ2xEO0FBQ0Esb0JBQ29CdUIsSUFBSSxDQUFDSSxTQUFTLENBQUM1QixNQUFNLEVBQUVjLFNBQVMsRUFBRSxDQUFDLENBQUM7QUFDeEQsb0JBQW9CYixLQUFLLEdBQ2pCLENBQUM7TUFDSDtJQUNGLENBQUMsTUFBTTtNQUNMLE1BQU0sSUFBSTBCLEtBQUssQ0FDYiw2REFBNkRYLFVBQVUsYUFDckVmLEtBQUssS0FBSyxJQUFJLEdBQUcsTUFBTSxHQUFHLE9BQU9BLEtBQUssSUFFMUMsQ0FBQztJQUNIO0VBQ0Y7RUFFQSxNQUFNNEIsR0FBMkIsR0FBRztJQUNsQ2QsTUFBTSxFQUFFLEVBQVM7SUFDakJaLFFBQVEsRUFBQTJCLFFBQUEsS0FBTzNCLFFBQVEsQ0FBRTtJQUN6QkMsT0FBTyxFQUFBMEIsUUFBQSxLQUFPMUIsT0FBTyxDQUFFO0lBQ3ZCQyxZQUFZLEVBQUF5QixRQUFBLEtBQU96QixZQUFZO0VBQ2pDLENBQUM7RUFDRCxNQUFNMEIsS0FBSyxHQUFHbEMsUUFBUSxDQUFDLElBQUlDLGlCQUFpQixDQUFDK0IsR0FBRyxFQUFFdEIsSUFBSSxDQUFDLENBQUM7RUFDeERzQixHQUFHLENBQUNkLE1BQU0sR0FBR2dCLEtBQUssQ0FBQy9CLE1BQU0sRUFBRUMsS0FBSyxFQUFFQSxLQUFLLEVBQUVhLFNBQVMsRUFBRVosSUFBSSxDQUFDO0VBQ3pELE9BQU8yQixHQUFHO0FBQ1osQ0FBQztBQUVELFNBQVNaLGtCQUFrQkEsQ0FBQ2pCLE1BQWMsRUFBRTtFQUMxQyxPQUFPLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDZ0MsUUFBUSxDQUFDLE9BQU9oQyxNQUFNLENBQUMsR0FBRyxRQUFRLEdBQzVELE9BQU9BLE1BQ1I7QUFDTDtBQUVBLE1BQU1NLFVBQTBCLEdBQUc7RUFDakNILFFBQVEsRUFBRSxDQUFDLENBQUM7RUFDWkMsT0FBTyxFQUFFLENBQUMsQ0FBQztFQUNYQyxZQUFZLEVBQUUsQ0FBQztBQUNqQixDQUFDIiwiaWdub3JlTGlzdCI6W119