Skip to content
This repository has been archived by the owner on Dec 12, 2022. It is now read-only.

Commit

Permalink
chore(global): merge pull request #9 from dantothefuture/dev
Browse files Browse the repository at this point in the history
Add support for "allOf", "anyOf" and "not"
  • Loading branch information
pheekus authored Sep 3, 2019
2 parents 3facb1a + b5fe4ed commit 2e4365e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
4 changes: 2 additions & 2 deletions docs/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Features on this list are not currently supported, but planned for the future re
|Type|Features|
|--|--|
|`object`|`dependencies`|
|`other`|`allOf`, `$ref`|
|`other`|`$ref`|

## Under consideration

Expand All @@ -19,7 +19,7 @@ JSON Schema features listed below may be implemented in future releases, but are
|Type|Features|
|--|--|
|`string`|`format`|
|`other`|`anyOf`, `oneOf`, `not`, `if`, `then`, `else`|
|`other`|`oneOf`, `if`, `then`, `else`|

## Not planned

Expand Down
29 changes: 29 additions & 0 deletions src/compile/compile-type/compile-generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
} from 'json-schema';

import cel from '../cel';
import compileType from './';

function createEnumValueGuard(schema: JSONSchema7Type, ref: string): string {
if (typeof schema === 'object' && schema !== null) {
Expand Down Expand Up @@ -34,5 +35,33 @@ export default function(schema: JSONSchema7, ref: string, strictRef: string) {
if (typeof schema.const !== 'undefined') guard = createEnumGuard([schema.const], ref);
if (typeof schema.enum !== 'undefined') guard = cel.calc(guard, '&&', createEnumGuard(schema.enum, ref));

if (Array.isArray(schema.allOf)) {
const allOfGuard = schema.allOf.reduce((partialGuard, variant) => {
if (typeof variant === 'boolean') return partialGuard;
if (!variant.hasOwnProperty('type')) variant.type = schema.type;

return cel.calc(partialGuard, '&&', compileType(variant, ref, strictRef));
}, '');

guard = cel.calc(guard, '&&', allOfGuard);
}

if (Array.isArray(schema.anyOf)) {
const anyOfGuard = schema.anyOf.reduce((partialGuard, variant) => {
if (typeof variant === 'boolean') return partialGuard;
if (!variant.hasOwnProperty('type')) variant.type = schema.type;

return cel.calc(partialGuard, '||', compileType(variant, ref, strictRef));
}, '');

guard = cel.calc(guard, '&&', anyOfGuard);
}

if (typeof schema.not === 'object') {
if (!schema.not.hasOwnProperty('type')) schema.not.type = schema.type;
const notGuard = cel.calc(compileType(schema.not, 'ref', 's'), '==', cel.val(false));
guard = cel.calc(guard, '&&', notGuard);
}

return guard;
}
31 changes: 31 additions & 0 deletions test/compile-type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,37 @@ describe('type compilers', () => {
'(((((ref[0]==0)&&(ref[1]=="1"))&&(ref[2]==true))&&(ref[3]==false))&&(ref[4]==null))'
);
});

it('supports "allOf"', () => {
assert.equal(
compileGeneric({ type: 'integer', allOf: [true, { maximum: 1 }] }, 'ref', 's'),
'((ref is int)&&(ref<=1))'
);

assert.equal(
compileGeneric({ type: 'integer', allOf: [{ minimum: 0 }, { maximum: 1 }] }, 'ref', 's'),
'(((ref is int)&&(ref>=0))&&((ref is int)&&(ref<=1)))'
);
});

it('supports "anyOf"', () => {
assert.equal(
compileGeneric({ type: 'integer', anyOf: [true, { maximum: 1 }] }, 'ref', 's'),
'((ref is int)&&(ref<=1))'
);

assert.equal(
compileGeneric({ type: 'integer', anyOf: [{ minimum: 0 }, { maximum: 1 }] }, 'ref', 's'),
'(((ref is int)&&(ref>=0))||((ref is int)&&(ref<=1)))'
);
});

it('supports "not"', () => {
assert.equal(
compileGeneric({ type: 'integer', not: { minimum: 0 }}, 'ref', 's'),
'(((ref is int)&&(ref>=0))==false)'
);
});
});

describe('null', () => {
Expand Down

0 comments on commit 2e4365e

Please sign in to comment.