UNPKG

@data-client/normalizr

Version:

Normalizes and denormalizes JSON according to schema for Redux and Flux applications

70 lines (67 loc) 10 kB
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