Skip to content

Commit

Permalink
feat: add ObjectSchema
Browse files Browse the repository at this point in the history
  • Loading branch information
ASafaeirad committed Apr 13, 2024
1 parent c458d87 commit de998bf
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/Schema/ObjectSchema.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { NumberSchema } from './NumberSchema';
import { ObjectSchema } from './ObjectSchema';

describe('Object Schema', () => {
it('should throw error when there is an error in object keys', () => {
const schema = new ObjectSchema({
foo: new NumberSchema(),
}).setValue({ foo: '3000' });
schema.key = 'key';

expect(() => schema.validate()).toThrow(
new TypeError(
'Invalid configuration: The "key.foo" expected to be "number" but a "string" was provided',
),
);
});

it('should throw validate nested schema', () => {
const schema = new ObjectSchema({
foo: new ObjectSchema({
bar: new NumberSchema(),
}),
}).setValue({ foo: '3000' });
schema.key = 'key';

expect(() => schema.validate()).toThrow(
new TypeError(
'Invalid configuration: The "key.foo" expected to be "object" but a "string" was provided',
),
);

schema.setValue({ foo: { bar: '3000' } });

expect(() => schema.validate()).toThrow(
new TypeError(
'Invalid configuration: The "key.foo.bar" expected to be "number" but a "string" was provided',
),
);

schema.setValue({});

expect(() => schema.validate()).toThrow(
new TypeError(
'Invalid configuration: The "key.foo" is required but the given value is "undefined"',
),
);
});
});
31 changes: 31 additions & 0 deletions src/Schema/ObjectSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Guard } from '../Guard';
import { Schema } from './Schema';

class ObjectGuard implements Guard<Record<string, Schema>> {
constructor(private schema: Record<string, Schema>) {}

validate(input: Record<string, unknown>, key: string) {
if (!input) return;

Object.entries(this.schema).forEach(([subKey, schema]) => {
schema.key = `${key}.${subKey}`;
schema.value = input[subKey];

schema.validate();
});
}
}

export class ObjectSchema<TInput = any> extends Schema<
TInput,
Record<string, unknown>
> {
constructor(schema: Record<string, Schema>) {
super({
typeConstructor: x => x as Record<string, unknown>,
type: 'object',
});
this.require();
this.guards.push(new ObjectGuard(schema));
}
}

0 comments on commit de998bf

Please sign in to comment.