@ts-common/source-map
Version:
263 lines • 8.23 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAllDirectives = exports.getDescendantFilePosition = exports.getChildFilePosition = exports.getFilePosition = exports.cloneDeepWithInfo = exports.cloneDeep = exports.getPath = exports.getRootObjectInfo = exports.propertySetMap = exports.stringMapMerge = exports.stringMapMap = exports.arrayMap = exports.copyDataInfo = exports.copyInfo = exports.getInfo = exports.getInfoFunc = exports.setInfo = exports.setInfoFunc = exports.objectInfoSymbol = exports.createChildObjectInfo = exports.createRootObjectInfo = void 0;
const tslib_1 = require("tslib");
const sm = tslib_1.__importStar(require("@ts-common/string-map"));
const _ = tslib_1.__importStar(require("@ts-common/iterator"));
const propertySet = tslib_1.__importStar(require("@ts-common/property-set"));
const json = tslib_1.__importStar(require("@ts-common/json"));
exports.createRootObjectInfo = (position, url, primitiveProperties) => ({
isChild: false,
position,
url,
primitiveProperties
});
exports.createChildObjectInfo = (position, parent, property, primitiveProperties) => ({
isChild: true,
position,
parent,
property,
primitiveProperties
});
exports.objectInfoSymbol = Symbol.for("@ts-common/source-map/object-info");
exports.setInfoFunc = (value, infoFunc) => {
const result = value;
if (result[exports.objectInfoSymbol] === undefined) {
result[exports.objectInfoSymbol] = infoFunc;
}
return result;
};
exports.setInfo = (value, info) => exports.setInfoFunc(value, () => info);
exports.getInfoFunc = (value) => {
if (value === undefined) {
return undefined;
}
const withInfo = value;
return withInfo[exports.objectInfoSymbol];
};
exports.getInfo = (value) => {
const f = exports.getInfoFunc(value);
return f === undefined ? undefined : f();
};
exports.copyInfo = (source, dest) => {
const info = exports.getInfoFunc(source);
if (info !== undefined) {
exports.setInfoFunc(dest, info);
}
return dest;
};
exports.copyDataInfo = (source, dest) => {
const destJson = dest;
if (source !== null &&
typeof source === "object" &&
destJson !== null &&
typeof destJson === "object") {
exports.copyInfo(source, destJson);
}
return dest;
};
exports.arrayMap = (source, f) => {
if (source === undefined) {
return [];
}
const result = source.map((v, i) => exports.copyDataInfo(v, f(v, i)));
if (_.isEqual(source, result)) {
return source;
}
exports.copyInfo(source, result);
return result;
};
/**
* Transform an object.
*
* @param source
* @param f
*/
exports.stringMapMap = (source, f) => {
if (source === undefined) {
return {};
}
const result = sm.map(source, (v, k) => {
const r = f(v, k);
exports.copyDataInfo(v, r);
return r;
});
if (sm.isEqual(source, result)) {
return source;
}
exports.copyInfo(source, result);
return result;
};
/**
* Merge objects
*
* @param array
*/
exports.stringMapMerge = (...array) => {
if (array.length === 0) {
return {};
}
const result = sm.merge(...array);
const source = array[0];
if (source === undefined) {
return result;
}
if (sm.isEqual(source, result)) {
return source;
}
exports.copyInfo(source, result);
return result;
};
exports.propertySetMap = (source, f) => {
const result = propertySet.copyCreate(source, f);
if (sm.isEqual(sm.toStringMap(source), sm.toStringMap(result))) {
return source;
}
propertySet.forEach(result, (v, k) => {
const sourceValue = source[k];
const vv = v;
if (sourceValue !== undefined && vv !== undefined) {
exports.copyDataInfo(sourceValue, vv);
}
});
exports.copyInfo(source, result);
return result;
};
exports.getRootObjectInfo = (info) => !info.isChild ? info : exports.getRootObjectInfo(info.parent[exports.objectInfoSymbol]());
const getReversedInfoIterator = function* (info) {
while (info.isChild) {
yield info;
info = info.parent[exports.objectInfoSymbol]();
}
yield info;
};
exports.getPath = (info) => _.reverse(_.filterMap(getReversedInfoIterator(info), i => i.isChild ? i.property : undefined));
/**
* Returns a deep clone of `source` and set a source-map for each member.
*
* @param source an original object
* @param getInfoFunctOptional the function should return an object info of a provided member.
* If the function is not provided the algorithm extract information from the provided member.
*/
exports.cloneDeep = (source, getInfoFuncOptional) => {
const get = getInfoFuncOptional === undefined ? exports.getInfoFunc : getInfoFuncOptional;
const clone = (data) => {
if (data === null ||
typeof data === "boolean" ||
typeof data === "number" ||
typeof data === "string") {
return data;
}
const result = _.isArray(data) ?
data.map(clone) :
sm.map(data, clone);
const infoFunc = get(data);
if (infoFunc !== undefined) {
exports.setInfoFunc(result, infoFunc);
}
return result;
};
return clone(source);
};
/**
* Returns a deep clone of `source`. Each member of the returned object will contain the provided
* source-map information.
*
* @param source
* @param infoFunc
*/
exports.cloneDeepWithInfo = (source, infoFunc) => exports.cloneDeep(source, () => infoFunc);
/**
* Get a file position
*
* @param value
*/
exports.getFilePosition = (value) => {
const info = exports.getInfo(value);
return info !== undefined ? info.position : undefined;
};
/**
* Get a position of a child.
*
* @param data
* @param index
*/
exports.getChildFilePosition = (data, index) => {
if (data === undefined) {
return undefined;
}
if (index === undefined) {
return exports.getFilePosition(data);
}
const child = data[index];
if (child === undefined) {
return undefined;
}
if (json.isPrimitive(child)) {
const info = exports.getInfo(data);
if (info === undefined) {
return undefined;
}
return info.primitiveProperties[index];
}
return exports.getFilePosition(child);
};
/**
* Returns a data reference corresponding to the given path.
*
* @param object
* @param path
*/
const getDataRef = (object, path) => {
if (path === undefined) {
return { parent: object, index: undefined };
}
let index = undefined;
// preserve the last index.
for (const i of path) {
if (index !== undefined) {
const newObject = object[index];
if (newObject === null || typeof newObject !== "object") {
return { parent: undefined, index: undefined };
}
object = newObject;
}
index = i;
}
return { parent: object, index };
};
/**
* Get a file position of a descendant by path.
*
* @param object
* @param path
*/
exports.getDescendantFilePosition = (object, path) => {
const dataRef = getDataRef(object, path);
return exports.getChildFilePosition(dataRef.parent, dataRef.index);
};
const getReversedFilePositions = function* (dataRef) {
const parent = dataRef.parent;
if (parent === undefined) {
return;
}
if (dataRef.index !== undefined) {
const filePosition = exports.getChildFilePosition(parent, dataRef.index);
if (filePosition !== undefined) {
yield filePosition;
}
}
let i = exports.getInfo(parent);
if (i === undefined) {
return;
}
yield* _.map(getReversedInfoIterator(i), v => v.position);
};
exports.getAllDirectives = (object, path) => {
const dataRef = getDataRef(object, path);
const reversedFilePositions = getReversedFilePositions(dataRef);
const reversedDirectives = _.filterMap(reversedFilePositions, v => v.directives);
const directives = _.reverse(reversedDirectives);
return sm.merge(...directives);
};
//# sourceMappingURL=index.js.map
;