UNPKG

@orbit/records

Version:

A flexible data access and synchronization layer.

102 lines 15.8 kB
import { Assertion, Orbit } from '@orbit/core'; import { clone } from '@orbit/utils'; import { cloneRecordIdentity, isRecordIdentity } from './record'; import { KeyNotDefined, ModelNotDefined } from './record-exceptions'; const { assert, deprecate } = Orbit; export class StandardRecordNormalizer { constructor(settings) { const { schema, keyMap, cloneInputs, validateInputs } = settings; assert("StandardRecordNormalizer's `schema` must be specified in the `settings.schema` constructor argument", !!schema); this.schema = schema; this.keyMap = keyMap; this.cloneInputs = cloneInputs; this.validateInputs = validateInputs; } normalizeRecordType(type) { if (this.validateInputs) { if (typeof type !== 'string') { throw new Assertion('StandardRecordNormalizer expects record types to be strings'); } if (!this.schema.hasModel(type)) { throw new ModelNotDefined(type); } } return type; } normalizeRecordIdentity(identity) { const { schema, keyMap, cloneInputs, validateInputs } = this; const { type } = identity; if (validateInputs && !schema.hasModel(type)) { throw new ModelNotDefined(type); } if (isRecordIdentity(identity)) { return cloneInputs ? this.cloneRecordIdentity(identity) : identity; } else { if (keyMap === undefined) { throw new Assertion("StandardRecordNormalizer's `keyMap` must be specified in order to lookup an `id` from a `key`"); } const { key, value } = identity; if (typeof key !== 'string' || typeof value !== 'string') { throw new Assertion('StandardRecordNormalizer expects record identities in the form `{ type: string, id: string }` or `{ type: string, key: string, value: string }`'); } if (validateInputs && !schema.hasKey(type, key)) { throw new KeyNotDefined(type, key); } let id = keyMap.keyToId(type, key, value); if (id === undefined) { id = this.schema.generateId(type); keyMap.pushRecord({ type, id, keys: { [key]: value } }); } return { type, id }; } } normalizeRecord(record) { const { keyMap, schema, cloneInputs, validateInputs } = this; const { type } = record; if (validateInputs && !schema.hasModel(type)) { throw new ModelNotDefined(type); } let result = cloneInputs ? this.cloneRecord(record) : record; // If `initializeRecord` has been defined on the schema, continue to call it // but issue a deprecation warning. // TODO: Remove in v0.18 if (schema.initializeRecord !== undefined) { deprecate("RecordSchema's `initializeRecord` method should NOT be defined. Instead override `normalizeRecord` on the RecordNormalizer to initialize records."); result = schema.initializeRecord(result); } if (result.id === undefined) { const { keys } = result; // Lookup id from keys if possible if (keyMap !== undefined && keys !== undefined) { if (validateInputs) { Object.keys(keys).forEach((key) => { if (!schema.hasKey(type, key)) { throw new KeyNotDefined(type, key); } }); } const id = keyMap.idFromKeys(result.type, keys); if (id) { result.id = id; } } // Generate an id if one has still not been assigned if (result.id === undefined) { result.id = schema.generateId(result.type); // Register any generated ids in the keyMap, if present if (keyMap && result.keys !== undefined) { keyMap.pushRecord(result); } } } return result; } cloneRecordIdentity(rid) { return cloneRecordIdentity(rid); } cloneRecord(record) { return clone(record); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmQtcmVjb3JkLW5vcm1hbGl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhbmRhcmQtcmVjb3JkLW5vcm1hbGl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDL0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyQyxPQUFPLEVBQ0wsbUJBQW1CLEVBRW5CLGdCQUFnQixFQUlqQixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBS3JFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBU3BDLE1BQU0sT0FBTyx3QkFBd0I7SUFZbkMsWUFBWSxRQUEwQztRQUNwRCxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLEdBQUcsUUFBUSxDQUFDO1FBRWpFLE1BQU0sQ0FDSixxR0FBcUcsRUFDckcsQ0FBQyxDQUFDLE1BQU0sQ0FDVCxDQUFDO1FBRUYsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7SUFDdkMsQ0FBQztJQUVELG1CQUFtQixDQUFDLElBQVk7UUFDOUIsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO1lBQ3ZCLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFO2dCQUM1QixNQUFNLElBQUksU0FBUyxDQUNqQiw2REFBNkQsQ0FDOUQsQ0FBQzthQUNIO1lBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFD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LCBPcmJpdCB9IGZyb20gJ0BvcmJpdC9jb3JlJztcbmltcG9ydCB7IGNsb25lIH0gZnJvbSAnQG9yYml0L3V0aWxzJztcbmltcG9ydCB7XG4gIGNsb25lUmVjb3JkSWRlbnRpdHksXG4gIEluaXRpYWxpemVkUmVjb3JkLFxuICBpc1JlY29yZElkZW50aXR5LFxuICBSZWNvcmRJZGVudGl0eSxcbiAgUmVjb3JkS2V5VmFsdWUsXG4gIFVuaW5pdGlhbGl6ZWRSZWNvcmRcbn0gZnJvbSAnLi9yZWNvcmQnO1xuaW1wb3J0IHsgS2V5Tm90RGVmaW5lZCwgTW9kZWxOb3REZWZpbmVkIH0gZnJvbSAnLi9yZWNvcmQtZXhjZXB0aW9ucyc7XG5pbXBvcnQgeyBSZWNvcmRLZXlNYXAgfSBmcm9tICcuL3JlY29yZC1rZXktbWFwJztcbmltcG9ydCB7IFJlY29yZE5vcm1hbGl6ZXIgfSBmcm9tICcuL3JlY29yZC1ub3JtYWxpemVyJztcbmltcG9ydCB7IFJlY29yZFNjaGVtYSB9IGZyb20gJy4vcmVjb3JkLXNjaGVtYSc7XG5cbmNvbnN0IHsgYXNzZXJ0LCBkZXByZWNhdGUgfSA9IE9yYml0O1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YW5kYXJkUmVjb3JkTm9ybWFsaXplclNldHRpbmdzIHtcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWE7XG4gIGtleU1hcD86IFJlY29yZEtleU1hcDtcbiAgY2xvbmVJbnB1dHM/OiBib29sZWFuO1xuICB2YWxpZGF0ZUlucHV0cz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBTdGFuZGFyZFJlY29yZE5vcm1hbGl6ZXJcbiAgaW1wbGVtZW50c1xuICAgIFJlY29yZE5vcm1hbGl6ZXI8XG4gICAgICBzdHJpbmcsXG4gICAgICBSZWNvcmRJZGVudGl0eSB8IFJlY29yZEtleVZhbHVlLFxuICAgICAgVW5pbml0aWFsaXplZFJlY29yZFxuICAgID4ge1xuICBzY2hlbWE6IFJlY29yZFNjaGVtYTtcbiAga2V5TWFwPzogUmVjb3JkS2V5TWFwO1xuICBjbG9uZUlucHV0cz86IGJvb2xlYW47XG4gIHZhbGlkYXRlSW5wdXRzPzogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihzZXR0aW5nczogU3RhbmRhcmRSZWNvcmROb3JtYWxpemVyU2V0dGluZ3MpIHtcbiAgICBjb25zdCB7IHNjaGVtYSwga2V5TWFwLCBjbG9uZUlucHV0cywgdmFsaWRhdGVJbnB1dHMgfSA9IHNldHRpbmdzO1xuXG4gICAgYXNzZXJ0KFxuICAgICAgXCJTdGFuZGFyZFJlY29yZE5vcm1hbGl6ZXIncyBgc2NoZW1hYCBtdXN0IGJlIHNwZWNpZmllZCBpbiB0aGUgYHNldHRpbmdzLnNjaGVtYWAgY29uc3RydWN0b3IgYXJndW1lbnRcIixcbiAgICAgICEhc2NoZW1hXG4gICAgKTtcblxuICAgIHRoaXMuc2NoZW1hID0gc2NoZW1hO1xuICAgIHRoaXMua2V5TWFwID0ga2V5TWFwO1xuICAgIHRoaXMuY2xvbmVJbnB1dHMgPSBjbG9uZUlucHV0cztcbiAgICB0aGlzLnZhbGlkYXRlSW5wdXRzID0gdmFsaWRhdGVJbnB1dHM7XG4gIH1cblxuICBub3JtYWxpemVSZWNvcmRUeXBlKHR5cGU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMudmFsaWRhdGVJbnB1dHMpIHtcbiAgICAgIGlmICh0eXBlb2YgdHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbihcbiAgICAgICAgICAnU3RhbmRhcmRSZWNvcmROb3JtYWxpemVyIGV4cGVjdHMgcmVjb3JkIHR5cGVzIHRvIGJlIHN0cmluZ3MnXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5zY2hlbWEuaGFzTW9kZWwodHlwZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IE1vZGVsTm90RGVmaW5lZCh0eXBlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIG5vcm1hbGl6ZVJlY29yZElkZW50aXR5KFxuICAgIGlkZW50aXR5OiBSZWNvcmRJZGVudGl0eSB8IFJlY29yZEtleVZhbHVlXG4gICk6IFJlY29yZElkZW50aXR5IHtcbiAgICBjb25zdCB7IHNjaGVtYSwga2V5TWFwLCBjbG9uZUlucHV0cywgdmFsaWRhdGVJbnB1dHMgfSA9IHRoaXM7XG4gICAgY29uc3QgeyB0eXBlIH0gPSBpZGVudGl0eTtcblxuICAgIGlmICh2YWxpZGF0ZUlucHV0cyAmJiAhc2NoZW1hLmhhc01vZGVsKHR5cGUpKSB7XG4gICAgICB0aHJvdyBuZXcgTW9kZWxOb3REZWZpbmVkKHR5cGUpO1xuICAgIH1cblxuICAgIGlmIChpc1JlY29yZElkZW50aXR5KGlkZW50aXR5KSkge1xuICAgICAgcmV0dXJuIGNsb25lSW5wdXRzID8gdGhpcy5jbG9uZVJlY29yZElkZW50aXR5KGlkZW50aXR5KSA6IGlkZW50aXR5O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoa2V5TWFwID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbihcbiAgICAgICAgICBcIlN0YW5kYXJkUmVjb3JkTm9ybWFsaXplcidzIGBrZXlNYXBgIG11c3QgYmUgc3BlY2lmaWVkIGluIG9yZGVyIHRvIGxvb2t1cCBhbiBgaWRgIGZyb20gYSBga2V5YFwiXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsga2V5LCB2YWx1ZSB9ID0gaWRlbnRpdHk7XG5cbiAgICAgIGlmICh0eXBlb2Yga2V5ICE9PSAnc3RyaW5nJyB8fCB0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBBc3NlcnRpb24oXG4gICAgICAgICAgJ1N0YW5kYXJkUmVjb3JkTm9ybWFsaXplciBleHBlY3RzIHJlY29yZCBpZGVudGl0aWVzIGluIHRoZSBmb3JtIGB7IHR5cGU6IHN0cmluZywgaWQ6IHN0cmluZyB9YCBvciBgeyB0eXBlOiBzdHJpbmcsIGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIH1gJ1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAodmFsaWRhdGVJbnB1dHMgJiYgIXNjaGVtYS5oYXNLZXkodHlwZSwga2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgS2V5Tm90RGVmaW5lZCh0eXBlLCBrZXkpO1xuICAgICAgfVxuXG4gICAgICBsZXQgaWQgPSBrZXlNYXAua2V5VG9JZCh0eXBlLCBrZXksIHZhbHVlKTtcblxuICAgICAgaWYgKGlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWQgPSB0aGlzLnNjaGVtYS5nZW5lcmF0ZUlkKHR5cGUpO1xuICAgICAgICBrZXlNYXAucHVzaFJlY29yZCh7IHR5cGUsIGlkLCBrZXlzOiB7IFtrZXldOiB2YWx1ZSB9IH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyB0eXBlLCBpZCB9O1xuICAgIH1cbiAgfVxuXG4gIG5vcm1hbGl6ZVJlY29yZChyZWNvcmQ6IFVuaW5pdGlhbGl6ZWRSZWNvcmQpOiBJbml0aWFsaXplZFJlY29yZCB7XG4gICAgY29uc3QgeyBrZXlNYXAsIHNjaGVtYSwgY2xvbmVJbnB1dHMsIHZhbGlkYXRlSW5wdXRzIH0gPSB0aGlzO1xuICAgIGNvbnN0IHsgdHlwZSB9ID0gcmVjb3JkO1xuXG4gICAgaWYgKHZhbGlkYXRlSW5wdXRzICYmICFzY2hlbWEuaGFzTW9kZWwodHlwZSkpIHtcbiAgICAgIHRocm93IG5ldyBNb2RlbE5vdERlZmluZWQodHlwZSk7XG4gICAgfVxuXG4gICAgbGV0IHJlc3VsdCA9IGNsb25lSW5wdXRzID8gdGhpcy5jbG9uZVJlY29yZChyZWNvcmQpIDogcmVjb3JkO1xuXG4gICAgLy8gSWYgYGluaXRpYWxpemVSZWNvcmRgIGhhcyBiZWVuIGRlZmluZWQgb24gdGhlIHNjaGVtYSwgY29udGludWUgdG8gY2FsbCBpdFxuICAgIC8vIGJ1dCBpc3N1ZSBhIGRlcHJlY2F0aW9uIHdhcm5pbmcuXG4gICAgLy8gVE9ETzogUmVtb3ZlIGluIHYwLjE4XG4gICAgaWYgKChzY2hlbWEgYXMgYW55KS5pbml0aWFsaXplUmVjb3JkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlcHJlY2F0ZShcbiAgICAgICAgXCJSZWNvcmRTY2hlbWEncyBgaW5pdGlhbGl6ZVJlY29yZGAgbWV0aG9kIHNob3VsZCBOT1QgYmUgZGVmaW5lZC4gSW5zdGVhZCBvdmVycmlkZSBgbm9ybWFsaXplUmVjb3JkYCBvbiB0aGUgUmVjb3JkTm9ybWFsaXplciB0byBpbml0aWFsaXplIHJlY29yZHMuXCJcbiAgICAgICk7XG4gICAgICByZXN1bHQgPSAoc2NoZW1hIGFzIGFueSkuaW5pdGlhbGl6ZVJlY29yZChyZXN1bHQpO1xuICAgIH1cblxuICAgIGlmIChyZXN1bHQuaWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgeyBrZXlzIH0gPSByZXN1bHQ7XG5cbiAgICAgIC8vIExvb2t1cCBpZCBmcm9tIGtleXMgaWYgcG9zc2libGVcbiAgICAgIGlmIChrZXlNYXAgIT09IHVuZGVmaW5lZCAmJiBrZXlzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHZhbGlkYXRlSW5wdXRzKSB7XG4gICAgICAgICAgT2JqZWN0LmtleXMoa2V5cykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXNjaGVtYS5oYXNLZXkodHlwZSwga2V5KSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgS2V5Tm90RGVmaW5lZCh0eXBlLCBrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaWQgPSBrZXlNYXAuaWRGcm9tS2V5cyhyZXN1bHQudHlwZSwga2V5cyk7XG4gICAgICAgIGlmIChpZCkge1xuICAgICAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEdlbmVyYXRlIGFuIGlkIGlmIG9uZSBoYXMgc3RpbGwgbm90IGJlZW4gYXNzaWduZWRcbiAgICAgIGlmIChyZXN1bHQuaWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXN1bHQuaWQgPSBzY2hlbWEuZ2VuZXJhdGVJZChyZXN1bHQudHlwZSk7XG5cbiAgICAgICAgLy8gUmVnaXN0ZXIgYW55IGdlbmVyYXRlZCBpZHMgaW4gdGhlIGtleU1hcCwgaWYgcHJlc2VudFxuICAgICAgICBpZiAoa2V5TWFwICYmIHJlc3VsdC5rZXlzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBrZXlNYXAucHVzaFJlY29yZChyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdCBhcyBJbml0aWFsaXplZFJlY29yZDtcbiAgfVxuXG4gIHByb3RlY3RlZCBjbG9uZVJlY29yZElkZW50aXR5KHJpZDogUmVjb3JkSWRlbnRpdHkpOiBSZWNvcmRJZGVudGl0eSB7XG4gICAgcmV0dXJuIGNsb25lUmVjb3JkSWRlbnRpdHkocmlkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjbG9uZVJlY29yZChyZWNvcmQ6IFVuaW5pdGlhbGl6ZWRSZWNvcmQpOiBVbmluaXRpYWxpemVkUmVjb3JkIHtcbiAgICByZXR1cm4gY2xvbmUocmVjb3JkKTtcbiAgfVxufVxuIl19