-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathhelpers.ts
101 lines (96 loc) · 2.91 KB
/
helpers.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
import * as nunjucks from 'nunjucks';
import { ProvideMetadata } from './interfaces';
export const generateMetadata = (providers: ProvideMetadata[]) => {
const metadata = providers.reduce((currentMetadata, provider) => {
currentMetadata[provider.metadataName] = provider.getMetadata();
return currentMetadata;
}, {} as Record<string, any>);
return metadata;
};
export const walkAst = (
root: nunjucks.nodes.Node,
visitors: ((node: nunjucks.nodes.Node) => void)[]
): void => {
visitors.forEach((visitor) => visitor(root));
visitChildren(root, (node) => walkAst(node, visitors));
};
export type VisitChildCallback = (
node: nunjucks.nodes.Node,
replaceFunc: ReplaceChildFunc
) => void;
export type ReplaceChildFunc = (
/** Provide the node you want to replace, or null if you want to delete this child */
replaceNode:
| nunjucks.nodes.NodeList
| nunjucks.nodes.CallExtension
| nunjucks.nodes.Node
| null
) => void;
export const visitChildren = (
root: nunjucks.nodes.Node,
callBack: VisitChildCallback
) => {
if (root instanceof nunjucks.nodes.NodeList) {
const indexToRemove: number[] = [];
root.children.forEach((node, index) => {
callBack(node, (replaced) => {
if (replaced) {
root.children[index] = replaced;
} else {
indexToRemove.push(index);
}
});
});
// Must delete in reverse order
for (let index = indexToRemove.length - 1; index >= 0; index--) {
root.children.splice(indexToRemove[index], 1);
}
} else if (root instanceof nunjucks.nodes.CallExtension) {
if (root.args) {
callBack(root.args, (replaced) => {
if (!replaced) {
root.args = new nunjucks.nodes.NodeList(
root.args.lineno,
root.args.colno
);
} else if (replaced instanceof nunjucks.nodes.NodeList) {
root.args = replaced;
} else {
root.args = new nunjucks.nodes.NodeList(
root.args.lineno,
root.args.colno
);
root.args.addChild(replaced);
}
});
}
if (root.contentArgs) {
const indexToRemove: number[] = [];
root.contentArgs.forEach((node, index) => {
callBack(node, (replaced) => {
if (replaced && root.contentArgs) {
root.contentArgs[index] = replaced;
} else {
indexToRemove.push(index);
}
});
});
// Must delete in reverse order
for (let index = indexToRemove.length - 1; index >= 0; index--) {
root.contentArgs.splice(indexToRemove[index], 1);
}
}
} else {
root.iterFields((node, fieldName) => {
if (node instanceof nunjucks.nodes.Node) {
callBack(node, (replaced) => {
if (replaced) {
(root as any)[fieldName] = replaced;
} else {
delete (root as any)[fieldName];
}
});
}
});
}
};