Skip to content

Commit 212f09b

Browse files
authored
fix: do not mutate combiner child (#59)
1 parent a3e9eae commit 212f09b

File tree

4 files changed

+32
-15
lines changed

4 files changed

+32
-15
lines changed

src/utils/__tests__/__snapshots__/renderSchema.spec.ts.snap

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,13 @@ Array [
2525
"type": "string",
2626
},
2727
},
28-
"type": "object",
2928
},
3029
Object {
3130
"properties": Object {
3231
"bar": Object {
3332
"type": "string",
3433
},
3534
},
36-
"type": "object",
3735
},
3836
],
3937
"type": "object",
@@ -63,15 +61,13 @@ Array [
6361
"type": "string",
6462
},
6563
},
66-
"type": "object",
6764
},
6865
Object {
6966
"properties": Object {
7067
"bar": Object {
7168
"type": "string",
7269
},
7370
},
74-
"type": "object",
7571
},
7672
],
7773
"type": "object",

src/utils/__tests__/renderSchema.spec.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,36 @@ jest.mock('../generateId', () => ({
1010

1111
describe('renderSchema util', () => {
1212
it.each([
13-
['default-schema.json', ''],
14-
['ref/original.json', 'ref/resolved.json'],
15-
['combiner-schema.json', ''],
16-
['array-of-objects.json', ''],
17-
['array-of-refs.json', ''],
18-
['array-of-allofs.json', ''],
19-
['tickets.schema.json', ''],
20-
])('should match %s', (schema, dereferenced) => {
13+
'default-schema.json',
14+
'ref/original.json',
15+
'combiner-schema.json',
16+
'array-of-objects.json',
17+
'array-of-refs.json',
18+
'array-of-allofs.json',
19+
'tickets.schema.json',
20+
])('should match %s', schema => {
2121
expect(
2222
Array.from(renderSchema(JSON.parse(fs.readFileSync(path.resolve(BASE_PATH, schema), 'utf8')))),
2323
).toMatchSnapshot();
2424
});
2525

26+
it.each([
27+
'default-schema.json',
28+
'ref/original.json',
29+
'combiner-schema.json',
30+
'array-of-objects.json',
31+
'array-of-refs.json',
32+
'array-of-allofs.json',
33+
'tickets.schema.json',
34+
])('should not mutate original object %s', schema => {
35+
const content = fs.readFileSync(path.resolve(BASE_PATH, schema), 'utf8');
36+
const input = JSON.parse(content);
37+
38+
Array.from(renderSchema(input));
39+
40+
expect(input).toStrictEqual(JSON.parse(content));
41+
});
42+
2643
it('given schema with complex types, throws', () => {
2744
expect(() =>
2845
Array.from(

src/utils/renderSchema.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,13 @@ export const renderSchema: Walker = function*(schema, level = 0, meta = { path:
104104
if (node.properties !== undefined) {
105105
for (const [i, property] of node.properties.entries()) {
106106
if ('type' in node) {
107-
property.type = property.type || node.type;
107+
node.properties[i] = {
108+
...property,
109+
type: property.type || node.type,
110+
};
108111
}
109112

110-
yield* renderSchema(property, level + 1, {
113+
yield* renderSchema(node.properties[i], level + 1, {
111114
...(i !== 0 && { divider: DIVIDERS[node.combiner] }),
112115
path: [...path, node.combiner, i],
113116
});

src/utils/walk.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ function processNode(node: JSONSchema4): SchemaNode | void {
2727
const type = node.type || inferType(node);
2828

2929
if (combiner) {
30+
const properties = node[combiner];
3031
return {
3132
id: generateId(),
3233
combiner,
33-
properties: node[combiner],
34+
properties: Array.isArray(properties) ? properties.slice() : properties,
3435
annotations: getAnnotations(node),
3536
...(type !== undefined && { type }),
3637
} as ICombinerNode;

0 commit comments

Comments
 (0)