Skip to content

Commit 0bedc20

Browse files
authored
Add script to help convert JS to Yaml (mongodb#15)
1 parent d8898ce commit 0bedc20

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

generator/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ To run the generator, you need to have PHP 8.1+ installed and Composer.
1616
## Configuration
1717

1818
The `generator/config/*.yaml` files contains the list of operators and stages that are supported by the library.
19+
20+
To add new test cases to operators, you can get inspiration from the official MongoDB documentation and use
21+
the `generator/js2yaml.html` web page to manually convert a pipeline array from JS to Yaml.

generator/js2yaml.html

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<style>
2+
body {
3+
font-family: system-ui, sans-serif;
4+
}
5+
h1 {
6+
font-size: 1.1em;
7+
font-weight: bold;
8+
}
9+
textarea {
10+
width: 100%;
11+
height: 300px;
12+
font-family: monospace;
13+
}
14+
</style>
15+
16+
<h1>Convert JS examples into Yaml</h1>
17+
18+
<div>
19+
<label for="input">Input JS code:</label>
20+
<textarea id="input">
21+
[
22+
// First Stage
23+
{
24+
$bucket: {
25+
groupBy: "$year_born", // Field to group by
26+
boundaries: [ 1840, 1850, 1860, 1870, 1880 ], // Boundaries for the buckets
27+
default: "Other", // Bucket ID for documents which do not fall into a bucket
28+
output: { // Output for each bucket
29+
"count": { $sum: 1 },
30+
"artists" :
31+
{
32+
$push: {
33+
"name": { $concat: [ "$first_name", " ", "$last_name"] },
34+
"year_born": "$year_born"
35+
}
36+
}
37+
}
38+
}
39+
},
40+
// Second Stage
41+
{
42+
$match: { count: {$gt: 3} }
43+
}
44+
]
45+
</textarea>
46+
</div>
47+
48+
<div>
49+
<label for="output">Output YAML code:</label>
50+
<textarea id="output"></textarea>
51+
</div>
52+
53+
54+
<script>
55+
function convert(jsString) {
56+
try {
57+
return toYaml(eval(jsString), 1);
58+
} catch (e) {
59+
return e.toString();
60+
}
61+
}
62+
63+
function toYaml(object, indent = 0) {
64+
const newline = '\n' + (' '.repeat(indent + 1));
65+
if (object === null) {
66+
return ' ~';
67+
}
68+
69+
if (Array.isArray(object)) {
70+
return newline + '-' + object.map((item) => toYaml(item, indent + 1)).join(newline + '-');
71+
}
72+
73+
switch (typeof object) {
74+
case 'boolean':
75+
return object ? ' true' : ' false';
76+
case 'string':
77+
return " '" + object.replace(/'/g, "\\'") + "'";
78+
case 'number':
79+
return ' ' + object.toString();
80+
case 'object':
81+
var dump = [];
82+
for (var key in object) {
83+
dump.push(key + ':' + toYaml(object[key], indent + 1));
84+
}
85+
return newline + dump.join(newline);
86+
case 'function':
87+
return toYaml({
88+
$code: object.toString()
89+
.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '')
90+
.replace(/\s+/g, ' ')
91+
}, indent)
92+
default:
93+
return 'Unsupported type: ' + typeof object;
94+
}
95+
}
96+
97+
const input = document.getElementById('input');
98+
const output = document.getElementById('output');
99+
100+
output.value = convert(input.value);
101+
102+
input.addEventListener('keyup', function () {
103+
output.value = convert(input.value);
104+
});
105+
</script>

0 commit comments

Comments
 (0)