Skip to content
This repository has been archived by the owner on Oct 31, 2024. It is now read-only.

feat: option noAdditionalProperties #39

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,23 @@ isSubset(
```
<hr/>
You can find more examples in the unit tests.

### Options
#### noAdditionalProperties
Add `additionalProperties=false` to all object types
```ts
import { createSchema } from 'genson-js';
const schema = createSchema({ one: 1, two: 'second' }, { noAdditionalProperties: true });
```
The following schema will be created:
```ts
{
type: 'object',
additionalProperties: false,
properties: { one: { type: 'integer' }, two: { type: 'string' } },
required: [
"one",
"two",
]
}
```
21 changes: 21 additions & 0 deletions src/schema-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ function createSchemaForArray(arr: Array<any>, options?: SchemaGenOptions): Sche
}
const elementSchemas = arr.map((value) => createSchemaFor(value, options));
const items = combineSchemas(elementSchemas);
if(options?.noAdditionalProperties){
addNoAddtionalProperties(items);
}
return { type: ValueType.Array, items };
}

Expand All @@ -47,6 +50,9 @@ function createSchemaForObject(obj: Object, options?: SchemaGenOptions): Schema
if (!options?.noRequired) {
schema.required = keys;
}
if(options?.noAdditionalProperties){
addNoAddtionalProperties(schema);
}
return schema;
}

Expand Down Expand Up @@ -251,3 +257,18 @@ export function createCompoundSchema(values: any[], options?: SchemaGenOptions):
const schemas = values.map((value) => createSchema(value, options));
return mergeSchemas(schemas, options);
}


function addNoAddtionalProperties(schema: Schema) {
if (schema.type == 'object') {
schema.additionalProperties = false;
const keys = Object.keys(schema.properties);
schema.properties = keys.reduce((properties, key) => {
properties[key] = addNoAddtionalProperties(schema.properties[key]);
return properties;
}, schema.properties);
} else if (schema.type == 'array') {
schema.items = addNoAddtionalProperties(schema.items);
}
return schema;
}
4 changes: 3 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ export type Schema = {
properties?: Record<string, Schema>;
required?: string[];
anyOf?: Array<Schema>;
additionalProperties?: boolean;
};

export type SchemaGenOptions = {
noRequired: boolean;
noRequired?: boolean;
noAdditionalProperties?: boolean;
};

export type SchemaComparisonOptions = {
Expand Down
60 changes: 60 additions & 0 deletions tests/schema-builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ describe('SchemaBuilder', () => {
properties: { one: { type: 'integer' }, two: { type: 'string' } },
});
});
it('it should generate schema for object with additionalProperties=false ', () => {
const schema = createSchema({ one: 1, two: 'second' }, { noAdditionalProperties: true });
expect(schema).toEqual({
type: 'object',
additionalProperties: false,
properties: { one: { type: 'integer' }, two: { type: 'string' } },
required: [
"one",
"two",
]
});
});
});

describe('nested array', () => {
Expand Down Expand Up @@ -254,6 +266,54 @@ describe('SchemaBuilder', () => {
});
});

it('should consider value with additionalProperties=false in all objects', async () => {
const val = [
{
arr: [
{
prop1: 'test string',
},
{
prop2: 'test string',
},
],
},
{
arr: [
{
prop1: 'test',
},
],
},
];
const schema = createSchema(val, { noAdditionalProperties: true });
expect(schema).toEqual({
type: 'array',
items: {
type: 'object',
additionalProperties: false,
properties: {
arr: {
type: 'array',
items: {
type: 'object',
additionalProperties: false,
properties: {
prop1: {
type: 'string',
},
prop2: {
type: 'string',
},
},
},
},
},
required: ['arr'],
},
});
});

it('should generate schema for array of objects w/o required', () => {
const schema = createSchema(
[
Expand Down