Skip to content

Commit bc2e06c

Browse files
committed
fix(nodes, accessors): fix validations with $ref nodes
Allow usage of readOnly and WriteOnly tags on $ref nodes fix stoplightio#34
1 parent 8300b12 commit bc2e06c

File tree

4 files changed

+74
-4
lines changed

4 files changed

+74
-4
lines changed

Diff for: src/accessors/__tests__/getValidations.spec.ts

+46
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ describe('getValidations util', () => {
1212
multipleOf: 2,
1313
},
1414
[SchemaNodeKind.Integer],
15+
{},
1516
),
1617
).toStrictEqual({
1718
exclusiveMaximum: true,
@@ -20,4 +21,49 @@ describe('getValidations util', () => {
2021
multipleOf: 2,
2122
});
2223
});
24+
it('should support $ref visibility', () => {
25+
expect(
26+
getValidations(
27+
{
28+
readOnly: true,
29+
},
30+
[SchemaNodeKind.Object],
31+
{
32+
writeOnly: true,
33+
},
34+
),
35+
).toStrictEqual({
36+
writeOnly: true,
37+
});
38+
39+
expect(
40+
getValidations(
41+
{
42+
writeOnly: true,
43+
},
44+
[SchemaNodeKind.Object],
45+
{
46+
readOnly: true,
47+
},
48+
),
49+
).toStrictEqual({
50+
readOnly: true,
51+
});
52+
53+
expect(
54+
getValidations({}, [SchemaNodeKind.Object], {
55+
readOnly: true,
56+
}),
57+
).toStrictEqual({
58+
readOnly: true,
59+
});
60+
61+
expect(
62+
getValidations({}, [SchemaNodeKind.Object], {
63+
writeOnly: true,
64+
}),
65+
).toStrictEqual({
66+
writeOnly: true,
67+
});
68+
});
2369
});

Diff for: src/accessors/getValidations.ts

+25-2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,34 @@ function getTypeValidations(types: SchemaNodeKind[]): (keyof SchemaFragment)[] |
3030
return extraValidations;
3131
}
3232

33-
export function getValidations(fragment: SchemaFragment, types: SchemaNodeKind[] | null): Dictionary<unknown> {
33+
export function getValidations(
34+
fragment: SchemaFragment,
35+
types: SchemaNodeKind[] | null,
36+
originalFragment: SchemaFragment | null = null,
37+
): Dictionary<unknown> {
3438
const extraValidations = types === null ? null : getTypeValidations(types);
3539

40+
const fragmentValidations: Dictionary<unknown> = pick(fragment, COMMON_VALIDATION_TYPES);
41+
42+
if (originalFragment) {
43+
const originalValidations: Dictionary<unknown> = pick(originalFragment, COMMON_VALIDATION_TYPES);
44+
45+
if (originalValidations.readOnly as boolean) {
46+
fragmentValidations.readOnly = true;
47+
if (fragmentValidations.writeOnly as boolean) {
48+
delete fragmentValidations.writeOnly;
49+
}
50+
}
51+
if (originalValidations.writeOnly as boolean) {
52+
fragmentValidations.writeOnly = true;
53+
if (fragmentValidations.readOnly as boolean) {
54+
delete fragmentValidations.readOnly;
55+
}
56+
}
57+
}
58+
3659
return {
37-
...pick(fragment, COMMON_VALIDATION_TYPES),
60+
...fragmentValidations,
3861
...(extraValidations !== null ? pick(fragment, extraValidations) : null),
3962
};
4063
}

Diff for: src/nodes/RegularNode.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ export class RegularNode extends BaseNode {
4747
this.title = unwrapStringOrNull(fragment.title);
4848

4949
this.annotations = getAnnotations(fragment);
50-
this.validations = getValidations(fragment, this.types);
5150
this.originalFragment = context?.originalFragment ?? fragment;
51+
this.validations = getValidations(fragment, this.types, this.originalFragment);
5252

5353
this.children = void 0;
5454
}

Diff for: src/nodes/mirrored/MirroredRegularNode.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Dictionary } from '@stoplight/types';
22

3+
import { getValidations } from '../../accessors/getValidations';
34
import { isReferenceNode, isRegularNode } from '../../guards';
45
import type { SchemaFragment } from '../../types';
56
import { isNonNullable } from '../../utils';
@@ -39,7 +40,7 @@ export class MirroredRegularNode extends BaseNode implements RegularNode {
3940
super();
4041
this.fragment = mirroredNode.fragment;
4142
this.originalFragment = context?.originalFragment ?? mirroredNode.originalFragment;
42-
43+
this.validations = getValidations(this.fragment, null, this.originalFragment);
4344
this.cache = new WeakMap();
4445

4546
this._this = new Proxy(this, {

0 commit comments

Comments
 (0)