Skip to content

Commit

Permalink
feat: add IsUnknown decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbash committed Feb 14, 2023
1 parent 2a37ad7 commit ec77cdf
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This library contains the following decorators
| IsNumber | numbers |
| IsObject | typed plain js objects |
| IsString | strings |
| IsUnknown | any json value |

All of the decorators support the following parameters:

Expand Down
66 changes: 66 additions & 0 deletions src/decorators/is-unknown.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Result } from 'true-myth';

import { generateSchemas, input, make, output } from '../../tests/helpers';
import { IsUnknown } from '../nestjs-swagger-dto';

describe('IsUnknown', () => {
describe('single', () => {
class Test {
@IsUnknown()
unknownField!: unknown;
}

it('generates correct schema', async () => {
expect(await generateSchemas([Test])).toStrictEqual({
Test: {
type: 'object',
properties: {
unknownField: {
oneOf: [
{ type: 'string' },
{ type: 'number' },
{ type: 'integer' },
{ type: 'boolean' },
{ type: 'array' },
{ type: 'object' },
],
},
},
required: ['unknownField'],
},
});
});

it('accepts anything except null and undefined', async () => {
expect(await input(Test, { unknownField: false })).toStrictEqual(
Result.ok(make(Test, { unknownField: false }))
);
expect(await input(Test, { unknownField: 123 })).toStrictEqual(
Result.ok(make(Test, { unknownField: 123 }))
);
expect(await input(Test, { unknownField: 'abc' })).toStrictEqual(
Result.ok(make(Test, { unknownField: 'abc' }))
);
expect(await input(Test, { unknownField: [] })).toStrictEqual(
Result.ok(make(Test, { unknownField: [] }))
);
expect(await input(Test, { unknownField: {} })).toStrictEqual(
Result.ok(make(Test, { unknownField: {} }))
);
});

it('transforms to plain', async () => {
const dto = make(Test, { unknownField: true });
expect(output(dto)).toStrictEqual({ unknownField: true });
});

it('rejects null and undefined by default', async () => {
expect(await input(Test, { unknownField: null })).toStrictEqual(
Result.err('unknownField should not be null or undefined')
);
expect(await input(Test, {})).toStrictEqual(
Result.err('unknownField should not be null or undefined')
);
});
});
});
24 changes: 24 additions & 0 deletions src/decorators/is-unknown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { IsDefined } from 'class-validator';

import { BasePropertyOptions, compose } from '../core';

export const IsUnknown = ({
...base
}: BasePropertyOptions & {
example?: unknown;
default?: unknown;
} = {}): PropertyDecorator =>
compose(
{
oneOf: [
{ type: 'string' },
{ type: 'number' },
{ type: 'integer' },
{ type: 'boolean' },
{ type: 'array' },
{ type: 'object' },
],
},
base,
IsDefined()
);
1 change: 1 addition & 0 deletions src/nestjs-swagger-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export * from './decorators/is-nested';
export * from './decorators/is-number';
export * from './decorators/is-object';
export * from './decorators/is-string';
export * from './decorators/is-unknown';
export * from './decorators/typed-headers.decorator';

0 comments on commit ec77cdf

Please sign in to comment.