UNPKG

@data-client/normalizr

Version:

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

79 lines (76 loc) 11 kB
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: { ...entities }, indexes: { ...indexes }, entityMeta: { ...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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhZGRFbnRpdGllcyIsImdldFZpc2l0IiwiY3JlYXRlR2V0RW50aXR5Iiwibm9ybWFsaXplIiwic2NoZW1hIiwiaW5wdXQiLCJhcmdzIiwiZW50aXRpZXMiLCJpbmRleGVzIiwiZW50aXR5TWV0YSIsImVtcHR5U3RvcmUiLCJtZXRhIiwiZmV0Y2hlZEF0IiwiZGF0ZSIsIkRhdGUiLCJub3ciLCJleHBpcmVzQXQiLCJJbmZpbml0eSIsInVuZGVmaW5lZCIsInJlc3VsdCIsInNjaGVtYVR5cGUiLCJleHBlY3RlZFNjaGVtYVR5cGUiLCJrZXkiLCJwayIsInByb2Nlc3MiLCJlbnYiLCJOT0RFX0VOViIsInBhcnNlV29ya3MiLCJKU09OIiwicGFyc2UiLCJlIiwiRXJyb3IiLCJzdHJpbmdpZnkiLCJuZXdFbnRpdGllcyIsIk1hcCIsIm5ld0luZGV4ZXMiLCJyZXQiLCJhZGRFbnRpdHkiLCJ2aXNpdCIsImluY2x1ZGVzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL25vcm1hbGl6ci9ub3JtYWxpemUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYWRkRW50aXRpZXMgfSBmcm9tICcuL2FkZEVudGl0aWVzLmpzJztcbmltcG9ydCB7IGdldFZpc2l0IH0gZnJvbSAnLi9nZXRWaXNpdC5qcyc7XG5pbXBvcnQgdHlwZSB7IFNjaGVtYSwgTm9ybWFsaXplZEluZGV4IH0gZnJvbSAnLi4vaW50ZXJmYWNlLmpzJztcbmltcG9ydCB7IGNyZWF0ZUdldEVudGl0eSB9IGZyb20gJy4uL21lbW8vTWVtb0NhY2hlLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgTm9ybWFsaXplTWV0YSxcbiAgTm9ybWFsaXplTnVsbGFibGUsXG4gIE5vcm1hbGl6ZWRTY2hlbWEsXG4gIFN0b3JlRGF0YSxcbn0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5leHBvcnQgY29uc3Qgbm9ybWFsaXplID0gPFxuICBTIGV4dGVuZHMgU2NoZW1hID0gU2NoZW1hLFxuICBFIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYW55PiB8IHVuZGVmaW5lZD4gPSBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIFJlY29yZDxzdHJpbmcsIGFueT5cbiAgPixcbiAgUiA9IE5vcm1hbGl6ZU51bGxhYmxlPFM+LFxuPihcbiAgc2NoZW1hOiBTIHwgdW5kZWZpbmVkLFxuICBpbnB1dDogYW55LFxuICBhcmdzOiByZWFkb25seSBhbnlbXSA9IFtdLFxuICB7IGVudGl0aWVzLCBpbmRleGVzLCBlbnRpdHlNZXRhIH06IFN0b3JlRGF0YTxFPiA9IGVtcHR5U3RvcmUsXG4gIG1ldGE6IE5vcm1hbGl6ZU1ldGEgPSB7IGZldGNoZWRBdDogMCwgZGF0ZTogRGF0ZS5ub3coKSwgZXhwaXJlc0F0OiBJbmZpbml0eSB9LFxuKTogTm9ybWFsaXplZFNjaGVtYTxFLCBSPiA9PiB7XG4gIC8vIG5vIHNjaGVtYSBtZWFucyB3ZSBkb24ndCBwcm9jZXNzIGF0IGFsbFxuICBpZiAoc2NoZW1hID09PSB1bmRlZmluZWQgfHwgc2NoZW1hID09PSBudWxsKVxuICAgIHJldHVybiB7XG4gICAgICByZXN1bHQ6IGlucHV0LFxuICAgICAgZW50aXRpZXMsXG4gICAgICBpbmRleGVzLFxuICAgICAgZW50aXR5TWV0YSxcbiAgICB9O1xuXG4gIGNvbnN0IHNjaGVtYVR5cGUgPSBleHBlY3RlZFNjaGVtYVR5cGUoc2NoZW1hKTtcbiAgaWYgKFxuICAgIGlucHV0ID09PSBudWxsIHx8XG4gICAgKHR5cGVvZiBpbnB1dCAhPT0gc2NoZW1hVHlwZSAmJlxuICAgICAgLy8gd2Ugd2lsbCBhbGxvdyBhIERlbGV0ZSBzY2hlbWEgdG8gYmUgYSBzdHJpbmcgb3Igb2JqZWN0XG4gICAgICAhKFxuICAgICAgICAoc2NoZW1hIGFzIGFueSkua2V5ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgKHNjaGVtYSBhcyBhbnkpLnBrID09PSB1bmRlZmluZWQgJiZcbiAgICAgICAgdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJ1xuICAgICAgKSlcbiAgKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgY29uc3QgcGFyc2VXb3JrcyA9IChpbnB1dDogc3RyaW5nKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIHR5cGVvZiBKU09OLnBhcnNlKGlucHV0KSAhPT0gJ3N0cmluZyc7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyAmJiBwYXJzZVdvcmtzKGlucHV0KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vcm1hbGl6aW5nIGEgc3RyaW5nLCBidXQgdGhpcyBkb2VzIG1hdGNoIHNjaGVtYS5cblxuUGFyc2luZyB0aGlzIGlucHV0IHN0cmluZyBhcyBKU09OIHdvcmtlZC4gVGhpcyBsaWtlbHkgaW5kaWNhdGVzIGZldGNoIGZ1bmN0aW9uIGRpZCBub3QgcGFyc2VcbnRoZSBKU09OLiBCeSBkZWZhdWx0LCB0aGlzIG9ubHkgaGFwcGVucyBpZiBcImNvbnRlbnQtdHlwZVwiIGhlYWRlciBpbmNsdWRlcyBcImpzb25cIi5cblNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vcmVzdC9hcGkvUmVzdEVuZHBvaW50I3BhcnNlUmVzcG9uc2UgZm9yIG1vcmUgaW5mb3JtYXRpb25cblxuICBTY2hlbWE6ICR7SlNPTi5zdHJpbmdpZnkoc2NoZW1hLCB1bmRlZmluZWQsIDIpfVxuICBJbnB1dDogXCIke2lucHV0fVwiYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFVuZXhwZWN0ZWQgaW5wdXQgZ2l2ZW4gdG8gbm9ybWFsaXplLiBFeHBlY3RlZCB0eXBlIHRvIGJlIFwiJHtzY2hlbWFUeXBlfVwiLCBmb3VuZCBcIiR7XG4gICAgICAgICAgICBpbnB1dCA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiBpbnB1dFxuICAgICAgICAgIH1cIi5cblxuICAgICAgICAgIFNjaGVtYTogJHtKU09OLnN0cmluZ2lmeShzY2hlbWEsIHVuZGVmaW5lZCwgMil9XG4gICAgICAgICAgSW5wdXQ6IFwiJHtpbnB1dH1cImAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFVuZXhwZWN0ZWQgaW5wdXQgZ2l2ZW4gdG8gbm9ybWFsaXplLiBFeHBlY3RlZCB0eXBlIHRvIGJlIFwiJHtzY2hlbWFUeXBlfVwiLCBmb3VuZCBcIiR7XG4gICAgICAgICAgaW5wdXQgPT09IG51bGwgPyAnbnVsbCcgOiB0eXBlb2YgaW5wdXRcbiAgICAgICAgfVwiLmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5ld0VudGl0aWVzID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIGFueT4+KCk7XG4gIGNvbnN0IG5ld0luZGV4ZXMgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgYW55Pj4oKTtcbiAgY29uc3QgcmV0OiBOb3JtYWxpemVkU2NoZW1hPEUsIFI+ID0ge1xuICAgIHJlc3VsdDogJycgYXMgYW55LFxuICAgIGVudGl0aWVzOiB7IC4uLmVudGl0aWVzIH0sXG4gICAgaW5kZXhlczogeyAuLi5pbmRleGVzIH0sXG4gICAgZW50aXR5TWV0YTogeyAuLi5lbnRpdHlNZXRhIH0sXG4gIH07XG4gIGNvbnN0IGFkZEVudGl0eSA9IGFkZEVudGl0aWVzKFxuICAgIG5ld0VudGl0aWVzLFxuICAgIG5ld0luZGV4ZXMsXG4gICAgcmV0LmVudGl0aWVzLFxuICAgIHJldC5pbmRleGVzLFxuICAgIHJldC5lbnRpdHlNZXRhLFxuICAgIG1ldGEsXG4gICk7XG5cbiAgY29uc3QgdmlzaXQgPSBnZXRWaXNpdChhZGRFbnRpdHksIGNyZWF0ZUdldEVudGl0eShlbnRpdGllcykpO1xuICByZXQucmVzdWx0ID0gdmlzaXQoc2NoZW1hLCBpbnB1dCwgaW5wdXQsIHVuZGVmaW5lZCwgYXJncyk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBleHBlY3RlZFNjaGVtYVR5cGUoc2NoZW1hOiBTY2hlbWEpIHtcbiAgcmV0dXJuIFsnb2JqZWN0JywgJ2Z1bmN0aW9uJ10uaW5jbHVkZXModHlwZW9mIHNjaGVtYSkgPyAnb2JqZWN0JyA6IChcbiAgICAgIHR5cGVvZiBzY2hlbWFcbiAgICApO1xufVxuXG5jb25zdCBlbXB0eVN0b3JlOiBTdG9yZURhdGE8YW55PiA9IHtcbiAgZW50aXRpZXM6IHt9LFxuICBpbmRleGVzOiB7fSxcbiAgZW50aXR5TWV0YToge30sXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxXQUFXLFFBQVEsa0JBQWtCO0FBQzlDLFNBQVNDLFFBQVEsUUFBUSxlQUFlO0FBRXhDLFNBQVNDLGVBQWUsUUFBUSxzQkFBc0I7QUFRdEQsT0FBTyxNQUFNQyxTQUFTLEdBQUdBLENBUXZCQyxNQUFxQixFQUNyQkMsS0FBVSxFQUNWQyxJQUFvQixHQUFHLEVBQUUsRUFDekI7RUFBRUMsUUFBUTtFQUFFQyxPQUFPO0VBQUVDO0FBQXlCLENBQUMsR0FBR0MsVUFBVSxFQUM1REMsSUFBbUIsR0FBRztFQUFFQyxTQUFTLEVBQUUsQ0FBQztFQUFFQyxJQUFJLEVBQUVDLElBQUksQ0FBQ0MsR0FBRyxDQUFDLENBQUM7RUFBRUMsU0FBUyxFQUFFQztBQUFTLENBQUMsS0FDbEQ7RUFDM0I7RUFDQSxJQUFJYixNQUFNLEtBQUtjLFNBQVMsSUFBSWQsTUFBTSxLQUFLLElBQUksRUFDekMsT0FBTztJQUNMZSxNQUFNLEVBQUVkLEtBQUs7SUFDYkUsUUFBUTtJQUNSQyxPQUFPO0lBQ1BDO0VBQ0YsQ0FBQztFQUVILE1BQU1XLFVBQVUsR0FBR0Msa0JBQWtCLENBQUNqQixNQUFNLENBQUM7RUFDN0MsSUFDRUMsS0FBSyxLQUFLLElBQUksSUFDYixPQUFPQSxLQUFLLEtBQUtl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