Skip to content

Commit

Permalink
fix(nodes, accessors): fix validations with $ref nodes
Browse files Browse the repository at this point in the history
Allow usage of readOnly and WriteOnly tags on $ref nodes

fix stoplightio#34
  • Loading branch information
CptKirk committed Mar 18, 2024
1 parent 8300b12 commit bc2e06c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
46 changes: 46 additions & 0 deletions src/accessors/__tests__/getValidations.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe('getValidations util', () => {
multipleOf: 2,
},
[SchemaNodeKind.Integer],
{},
),
).toStrictEqual({
exclusiveMaximum: true,
Expand All @@ -20,4 +21,49 @@ describe('getValidations util', () => {
multipleOf: 2,
});
});
it('should support $ref visibility', () => {
expect(
getValidations(
{
readOnly: true,
},
[SchemaNodeKind.Object],
{
writeOnly: true,
},
),
).toStrictEqual({
writeOnly: true,
});

expect(
getValidations(
{
writeOnly: true,
},
[SchemaNodeKind.Object],
{
readOnly: true,
},
),
).toStrictEqual({
readOnly: true,
});

expect(
getValidations({}, [SchemaNodeKind.Object], {
readOnly: true,
}),
).toStrictEqual({
readOnly: true,
});

expect(
getValidations({}, [SchemaNodeKind.Object], {
writeOnly: true,
}),
).toStrictEqual({
writeOnly: true,
});
});
});
27 changes: 25 additions & 2 deletions src/accessors/getValidations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,34 @@ function getTypeValidations(types: SchemaNodeKind[]): (keyof SchemaFragment)[] |
return extraValidations;
}

export function getValidations(fragment: SchemaFragment, types: SchemaNodeKind[] | null): Dictionary<unknown> {
export function getValidations(
fragment: SchemaFragment,
types: SchemaNodeKind[] | null,
originalFragment: SchemaFragment | null = null,
): Dictionary<unknown> {
const extraValidations = types === null ? null : getTypeValidations(types);

const fragmentValidations: Dictionary<unknown> = pick(fragment, COMMON_VALIDATION_TYPES);

if (originalFragment) {
const originalValidations: Dictionary<unknown> = pick(originalFragment, COMMON_VALIDATION_TYPES);

if (originalValidations.readOnly as boolean) {
fragmentValidations.readOnly = true;
if (fragmentValidations.writeOnly as boolean) {
delete fragmentValidations.writeOnly;
}
}
if (originalValidations.writeOnly as boolean) {
fragmentValidations.writeOnly = true;
if (fragmentValidations.readOnly as boolean) {
delete fragmentValidations.readOnly;
}
}
}

return {
...pick(fragment, COMMON_VALIDATION_TYPES),
...fragmentValidations,
...(extraValidations !== null ? pick(fragment, extraValidations) : null),
};
}
2 changes: 1 addition & 1 deletion src/nodes/RegularNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export class RegularNode extends BaseNode {
this.title = unwrapStringOrNull(fragment.title);

this.annotations = getAnnotations(fragment);
this.validations = getValidations(fragment, this.types);
this.originalFragment = context?.originalFragment ?? fragment;
this.validations = getValidations(fragment, this.types, this.originalFragment);

this.children = void 0;
}
Expand Down
3 changes: 2 additions & 1 deletion src/nodes/mirrored/MirroredRegularNode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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';
Expand Down Expand Up @@ -39,7 +40,7 @@ export class MirroredRegularNode extends BaseNode implements RegularNode {
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, {
Expand Down

0 comments on commit bc2e06c

Please sign in to comment.