@dipscope/type-manager
Version:
Transform JSON strings or plain objects into JS class instances.
70 lines • 2.86 kB
JavaScript
export class JsonPathReferenceHandler {
constructor() {
this.arrayKeyRegExp = new RegExp('\\[\\\'?([^\\\'\\[\\]]+)\\\'?\\]', 'g');
}
define(serializerContext, referenceKey, referenceValueGetter) {
const referenceMap = serializerContext.referenceMap;
const referencePath = referenceMap.get(referenceKey);
if (referencePath === undefined) {
referenceMap.set(referenceKey, serializerContext.jsonPath);
const value = referenceValueGetter();
return value;
}
return { $ref: referencePath };
}
restore(serializerContext, referenceKey, referenceValueGetter) {
const referenceMap = serializerContext.referenceMap;
const referenceTarget = this.defineReferenceTarget(serializerContext, referenceKey);
const referenceValue = referenceMap.get(referenceTarget);
if (referenceValue === undefined) {
referenceMap.set(referenceTarget, referenceTarget);
const value = referenceValueGetter();
referenceMap.set(referenceTarget, value);
serializerContext.resolveReferenceCallbacks(referenceTarget);
return value;
}
if (referenceTarget !== referenceKey) {
serializerContext.pushReferenceCallback(referenceTarget, () => {
serializerContext.resolveReferenceCallbacks(referenceKey);
});
}
if (referenceTarget === referenceValue) {
serializerContext.registerReferenceCallback(referenceTarget);
return undefined;
}
return referenceValue;
}
defineReferenceTarget(serializerContext, referenceKey) {
const $ = serializerContext.$;
const referencePath = referenceKey.$ref;
if (typeof referencePath !== 'string' || typeof $ !== 'object') {
return referenceKey;
}
if (referencePath === '$') {
return $;
}
const referencePathArray = this.convertReferencePathToArray(referencePath);
referencePathArray.shift();
let referenceTarget = $;
for (let i = 0; i < referencePathArray.length; i++) {
referenceTarget = referenceTarget[referencePathArray[i]];
}
return referenceTarget;
}
convertReferencePathToArray(referencePath) {
const array = new Array();
const parts = referencePath.split('.');
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
const keys = part.split(this.arrayKeyRegExp);
for (let j = 0; j < keys.length; j++) {
const key = keys[j];
if (key.length > 0) {
array.push(key);
}
}
}
return array;
}
}
//# sourceMappingURL=json-path-reference-handler.js.map