devstar插件
This commit is contained in:
173
node_modules/superjson/dist/plainer.js
generated
vendored
Normal file
173
node_modules/superjson/dist/plainer.js
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
import { isArray, isEmptyObject, isMap, isPlainObject, isPrimitive, isSet, } from './is.js';
|
||||
import { escapeKey, stringifyPath } from './pathstringifier.js';
|
||||
import { isInstanceOfRegisteredClass, transformValue, untransformValue, } from './transformer.js';
|
||||
import { includes, forEach } from './util.js';
|
||||
import { parsePath } from './pathstringifier.js';
|
||||
import { getDeep, setDeep } from './accessDeep.js';
|
||||
function traverse(tree, walker, origin = []) {
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
if (!isArray(tree)) {
|
||||
forEach(tree, (subtree, key) => traverse(subtree, walker, [...origin, ...parsePath(key)]));
|
||||
return;
|
||||
}
|
||||
const [nodeValue, children] = tree;
|
||||
if (children) {
|
||||
forEach(children, (child, key) => {
|
||||
traverse(child, walker, [...origin, ...parsePath(key)]);
|
||||
});
|
||||
}
|
||||
walker(nodeValue, origin);
|
||||
}
|
||||
export function applyValueAnnotations(plain, annotations, superJson) {
|
||||
traverse(annotations, (type, path) => {
|
||||
plain = setDeep(plain, path, v => untransformValue(v, type, superJson));
|
||||
});
|
||||
return plain;
|
||||
}
|
||||
export function applyReferentialEqualityAnnotations(plain, annotations) {
|
||||
function apply(identicalPaths, path) {
|
||||
const object = getDeep(plain, parsePath(path));
|
||||
identicalPaths.map(parsePath).forEach(identicalObjectPath => {
|
||||
plain = setDeep(plain, identicalObjectPath, () => object);
|
||||
});
|
||||
}
|
||||
if (isArray(annotations)) {
|
||||
const [root, other] = annotations;
|
||||
root.forEach(identicalPath => {
|
||||
plain = setDeep(plain, parsePath(identicalPath), () => plain);
|
||||
});
|
||||
if (other) {
|
||||
forEach(other, apply);
|
||||
}
|
||||
}
|
||||
else {
|
||||
forEach(annotations, apply);
|
||||
}
|
||||
return plain;
|
||||
}
|
||||
const isDeep = (object, superJson) => isPlainObject(object) ||
|
||||
isArray(object) ||
|
||||
isMap(object) ||
|
||||
isSet(object) ||
|
||||
isInstanceOfRegisteredClass(object, superJson);
|
||||
function addIdentity(object, path, identities) {
|
||||
const existingSet = identities.get(object);
|
||||
if (existingSet) {
|
||||
existingSet.push(path);
|
||||
}
|
||||
else {
|
||||
identities.set(object, [path]);
|
||||
}
|
||||
}
|
||||
export function generateReferentialEqualityAnnotations(identitites, dedupe) {
|
||||
const result = {};
|
||||
let rootEqualityPaths = undefined;
|
||||
identitites.forEach(paths => {
|
||||
if (paths.length <= 1) {
|
||||
return;
|
||||
}
|
||||
// if we're not deduping, all of these objects continue existing.
|
||||
// putting the shortest path first makes it easier to parse for humans
|
||||
// if we're deduping though, only the first entry will still exist, so we can't do this optimisation.
|
||||
if (!dedupe) {
|
||||
paths = paths
|
||||
.map(path => path.map(String))
|
||||
.sort((a, b) => a.length - b.length);
|
||||
}
|
||||
const [representativePath, ...identicalPaths] = paths;
|
||||
if (representativePath.length === 0) {
|
||||
rootEqualityPaths = identicalPaths.map(stringifyPath);
|
||||
}
|
||||
else {
|
||||
result[stringifyPath(representativePath)] = identicalPaths.map(stringifyPath);
|
||||
}
|
||||
});
|
||||
if (rootEqualityPaths) {
|
||||
if (isEmptyObject(result)) {
|
||||
return [rootEqualityPaths];
|
||||
}
|
||||
else {
|
||||
return [rootEqualityPaths, result];
|
||||
}
|
||||
}
|
||||
else {
|
||||
return isEmptyObject(result) ? undefined : result;
|
||||
}
|
||||
}
|
||||
export const walker = (object, identities, superJson, dedupe, path = [], objectsInThisPath = [], seenObjects = new Map()) => {
|
||||
const primitive = isPrimitive(object);
|
||||
if (!primitive) {
|
||||
addIdentity(object, path, identities);
|
||||
const seen = seenObjects.get(object);
|
||||
if (seen) {
|
||||
// short-circuit result if we've seen this object before
|
||||
return dedupe
|
||||
? {
|
||||
transformedValue: null,
|
||||
}
|
||||
: seen;
|
||||
}
|
||||
}
|
||||
if (!isDeep(object, superJson)) {
|
||||
const transformed = transformValue(object, superJson);
|
||||
const result = transformed
|
||||
? {
|
||||
transformedValue: transformed.value,
|
||||
annotations: [transformed.type],
|
||||
}
|
||||
: {
|
||||
transformedValue: object,
|
||||
};
|
||||
if (!primitive) {
|
||||
seenObjects.set(object, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (includes(objectsInThisPath, object)) {
|
||||
// prevent circular references
|
||||
return {
|
||||
transformedValue: null,
|
||||
};
|
||||
}
|
||||
const transformationResult = transformValue(object, superJson);
|
||||
const transformed = transformationResult?.value ?? object;
|
||||
const transformedValue = isArray(transformed) ? [] : {};
|
||||
const innerAnnotations = {};
|
||||
forEach(transformed, (value, index) => {
|
||||
if (index === '__proto__' ||
|
||||
index === 'constructor' ||
|
||||
index === 'prototype') {
|
||||
throw new Error(`Detected property ${index}. This is a prototype pollution risk, please remove it from your object.`);
|
||||
}
|
||||
const recursiveResult = walker(value, identities, superJson, dedupe, [...path, index], [...objectsInThisPath, object], seenObjects);
|
||||
transformedValue[index] = recursiveResult.transformedValue;
|
||||
if (isArray(recursiveResult.annotations)) {
|
||||
innerAnnotations[index] = recursiveResult.annotations;
|
||||
}
|
||||
else if (isPlainObject(recursiveResult.annotations)) {
|
||||
forEach(recursiveResult.annotations, (tree, key) => {
|
||||
innerAnnotations[escapeKey(index) + '.' + key] = tree;
|
||||
});
|
||||
}
|
||||
});
|
||||
const result = isEmptyObject(innerAnnotations)
|
||||
? {
|
||||
transformedValue,
|
||||
annotations: !!transformationResult
|
||||
? [transformationResult.type]
|
||||
: undefined,
|
||||
}
|
||||
: {
|
||||
transformedValue,
|
||||
annotations: !!transformationResult
|
||||
? [transformationResult.type, innerAnnotations]
|
||||
: innerAnnotations,
|
||||
};
|
||||
if (!primitive) {
|
||||
seenObjects.set(object, result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
//# sourceMappingURL=plainer.js.map
|
Reference in New Issue
Block a user