-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathMirroredRegularNode.ts
108 lines (86 loc) · 3.54 KB
/
MirroredRegularNode.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import type { Dictionary } from '@stoplight/types';
import { getValidations } from '../../accessors/getValidations';
import { isReferenceNode, isRegularNode } from '../../guards';
import type { SchemaFragment } from '../../types';
import { isNonNullable } from '../../utils';
import { BaseNode } from '../BaseNode';
import { BooleanishNode } from '../BooleanishNode';
import type { ReferenceNode } from '../ReferenceNode';
import type { RegularNode } from '../RegularNode';
import type { SchemaAnnotations, SchemaCombinerName, SchemaNodeKind } from '../types';
import { MirroredReferenceNode } from './MirroredReferenceNode';
export class MirroredRegularNode extends BaseNode implements RegularNode {
public readonly fragment: SchemaFragment;
public readonly $id!: string | null;
public readonly types!: SchemaNodeKind[] | null;
public readonly primaryType!: SchemaNodeKind | null;
public readonly combiners!: SchemaCombinerName[] | null;
public readonly required!: string[] | null;
public readonly enum!: unknown[] | null;
public readonly format!: string | null;
public readonly title!: string | null;
public readonly deprecated!: boolean;
public readonly annotations!: Readonly<Partial<Dictionary<unknown, SchemaAnnotations>>>;
public readonly validations!: Readonly<Dictionary<unknown>>;
public readonly originalFragment!: SchemaFragment;
public readonly simple!: boolean;
public readonly unknown!: boolean;
private readonly cache: WeakMap<
RegularNode | BooleanishNode | ReferenceNode,
MirroredRegularNode | BooleanishNode | MirroredReferenceNode
>;
constructor(public readonly mirroredNode: RegularNode, context?: { originalFragment?: SchemaFragment }) {
super();
this.fragment = mirroredNode.fragment;
this.originalFragment = context?.originalFragment ?? mirroredNode.originalFragment;
this.validations = getValidations(this.fragment, null, this.originalFragment);
this.cache = new WeakMap();
this._this = new Proxy(this, {
get(target, key) {
if (key in target) {
return target[key];
}
if (key in mirroredNode) {
return Reflect.get(mirroredNode, key, mirroredNode);
}
return;
},
has(target, key) {
return key in target || key in mirroredNode;
},
});
return this._this;
}
private readonly _this: MirroredRegularNode;
private _children?: (MirroredRegularNode | BooleanishNode | MirroredReferenceNode)[];
public get children(): (MirroredRegularNode | BooleanishNode | MirroredReferenceNode)[] | null | undefined {
const referencedChildren = this.mirroredNode.children;
if (!isNonNullable(referencedChildren)) {
return referencedChildren;
}
if (this._children === void 0) {
this._children = [];
} else {
this._children.length = 0;
}
const children: (MirroredRegularNode | BooleanishNode | MirroredReferenceNode)[] = this._children;
for (const child of referencedChildren) {
// this is to avoid pointing at nested mirroring
const cached = this.cache.get(child);
if (cached !== void 0) {
children.push(cached);
continue;
}
const mirroredChild = isRegularNode(child)
? new MirroredRegularNode(child)
: isReferenceNode(child)
? new MirroredReferenceNode(child)
: new BooleanishNode(child.fragment);
mirroredChild.parent = this._this;
mirroredChild.subpath = child.subpath;
this.cache.set(child, mirroredChild);
children.push(mirroredChild);
}
return children;
}
}