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 #8 from dantothefuture/dev
Browse files Browse the repository at this point in the history
Add support for "minProperties", "maxProperties" and "multipleOf"
  • Loading branch information
pheekus authored Sep 3, 2019
2 parents a589164 + 527409a commit 3facb1a
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ The code we generated in the previous step exposes `isValid($id: string): boolea

```
match /apples/{appleId} {
allow write: isValid("Apple");
allow write: if isValid("Apple");
}
```

Expand Down
5 changes: 1 addition & 4 deletions docs/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ Features on this list are not currently supported, but planned for the future re

|Type|Features|
|--|--|
|`object`|`minProperties`, `maxProperties`, `dependencies`|
|`string`|`format`|
|`integer`|`multipleOf`|
|`number`|`multipleOf`|
|`object`|`dependencies`|
|`other`|`allOf`, `$ref`|

## Under consideration
Expand Down
2 changes: 1 addition & 1 deletion src/compile/cel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type CELOperator = '&&'|'||'|'>'|'<'|'=='|'>='|'<=';
export type CELOperator = '&&'|'||'|'>'|'<'|'=='|'>='|'<='|'%';
export type CELKeyword = 'is'|'in';
export type CELPrimitive = null|number|string|boolean;
export type CELLiteral = CELPrimitive|CELPrimitive[];
Expand Down
5 changes: 4 additions & 1 deletion src/compile/compile-type/compile-numeric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export default function(schema: JSONSchema7, ref: string): string {
guard = cel.calc(guard, '&&', exMaxGuard);
}

// TODO: multipleOf
if (typeof schema.multipleOf === 'number') {
const multipleOfGuard = cel.calc(cel.calc(ref, '%', cel.val(schema.multipleOf)), '==', cel.val(0));
guard = cel.calc(guard, '&&', multipleOfGuard);
}

return guard;
}
16 changes: 12 additions & 4 deletions src/compile/compile-type/compile-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ export default function(schema: JSONSchema7, ref: string, strictRef: string): st
const properties = schema.properties || {};
const requiredProperties = new Set(schema.required || []);
const allProperties = Object.keys(properties);
const actualKeys = cel.ref(cel.call(cel.ref(ref, 'keys')));
const actualKeysSize = cel.call(cel.ref(actualKeys, 'size'));

let guard = cel.calc(ref, 'is', cel.ref('map'));

if (allProperties.length > 0) {
const expectedKeys = cel.val(allProperties);
const actualKeys = cel.ref(cel.call(cel.ref(ref, 'keys')));

guard = cel.calc(guard, '&&', cel.call(cel.ref(actualKeys, 'hasOnly'), expectedKeys));
}

Expand All @@ -40,8 +40,16 @@ export default function(schema: JSONSchema7, ref: string, strictRef: string): st
}
});

// TODO: minProperties
// TODO: maxProperties
if (typeof schema.minProperties === 'number') {
const minPropertiesGuard = cel.calc(actualKeysSize, '>=', cel.val(schema.minProperties));
guard = cel.calc(guard, '&&', minPropertiesGuard);
}

if (typeof schema.maxProperties === 'number') {
const maxPropertiesGuard = cel.calc(actualKeysSize, '<=', cel.val(schema.maxProperties));
guard = cel.calc(guard, '&&', maxPropertiesGuard);
}

// TODO: propertyNames
// TODO: dependencies
// TODO: patternProperties
Expand Down
21 changes: 21 additions & 0 deletions test/compile-type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ describe('type compilers', () => {
'(((ref is int)||(ref is float))&&(ref<0))'
);
});

it('supports "multipleOf"', () => {
assert.equal(
compileNumeric({ type: 'integer', multipleOf: 2 }, 'ref'),
'((ref is int)&&((ref%2)==0))'
);
});
});

describe('object', () => {
Expand All @@ -203,6 +210,20 @@ describe('type compilers', () => {
);
});

it('supports "minProperties"', () => {
assert.equal(
compileObject({ type: 'object', minProperties: 0 }, 'ref', 's'),
'((ref is map)&&(ref.keys().size()>=0))'
);
});

it('supports "maxProperties"', () => {
assert.equal(
compileObject({ type: 'object', maxProperties: 0 }, 'ref', 's'),
'((ref is map)&&(ref.keys().size()<=0))'
);
});

it('supports "required"', () => {
assert.equal(
compileObject({ type: 'object', properties: { a: { type: 'boolean' }}, required: ['a']}, 'ref', 's'),
Expand Down

0 comments on commit 3facb1a

Please sign in to comment.