Skip to content

Commit

Permalink
feat: adding support to dates
Browse files Browse the repository at this point in the history
  • Loading branch information
yUnreal committed May 25, 2024
1 parent 5eb7923 commit 840dacd
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 2 deletions.
12 changes: 11 additions & 1 deletion lib/structs/Document.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import isPlainObject from 'is-plain-obj';
import { AnyObject } from '../types/utils';
import { Model } from './Model';
import { Schema } from './schema/Schema';
Expand All @@ -6,7 +7,16 @@ export class Document<T extends AnyObject & { id?: string }> {
public constructor(
public data: T,
public model: Model<Schema<T>>
) {}
) {
for (const [key, value] of Object.entries(data)) {
const DATE_KEY = '$date';

if (isPlainObject(value) && value[DATE_KEY])
Object.defineProperty(data, key, {
value: new Date(<number>value[DATE_KEY]),
});
}
}

public fetch() {
return this.model.findById(this.id);
Expand Down
8 changes: 8 additions & 0 deletions lib/structs/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ export class Model<S extends Schema<AnyObject>> {

this.schema.parse(data);

for (const [key, value] of Object.entries(data)) {
if (value instanceof Date)
Object.defineProperty(data, key, {
value: { $date: value.getTime() },
enumerable: true,
});
}

data.id ??= uuid();

this.driver.update((crrData) =>
Expand Down
24 changes: 24 additions & 0 deletions lib/structs/schema/DateSchemaKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Expression, Types } from '../../types/schema';
import { SchemaKey } from './SchemaKey';

export class DateSchemaKey extends SchemaKey<Types.Date> {
public min(
date: Date,
message = `${Expression.Key} must be older than ${date.toISOString()}`
) {
return this.effect(
(crrData) => crrData.getTime() > date.getTime(),
message
);
}

public max(
date: Date,
message = `${Expression.Key} must be newer than ${date.toISOString()}`
) {
return this.effect(
(crrData) => crrData.getTime() < date.getTime(),
message
);
}
}
5 changes: 5 additions & 0 deletions lib/structs/schema/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { StringSchemaKey } from './StringSchemaKey';
import { NumberSchemaKey } from './NumberSchemaKey';
import { BooleanSchemaKey } from './BooleanSchemaKey';
import { BigIntSchemaKey } from './BigIntSchemaKey';
import { DateSchemaKey } from './DateSchemaKey';

export class Schema<S extends AnyObject> {
public constructor(public shape: Required<InferShape<S>>) {}
Expand All @@ -25,6 +26,10 @@ export class Schema<S extends AnyObject> {
return new BigIntSchemaKey({ type: Types.BigInt, flags: [] });
}

public static date() {
return new DateSchemaKey({ type: Types.Date, flags: [] });
}

public parse<O>(object: O) {
if (!isPlainObject(object))
throw new Error('Invalid value when parsing schema');
Expand Down
8 changes: 7 additions & 1 deletion lib/types/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BigIntSchemaKey } from '../structs/schema/BigIntSchemaKey';
import { BooleanSchemaKey } from '../structs/schema/BooleanSchemaKey';
import { DateSchemaKey } from '../structs/schema/DateSchemaKey';
import { NumberSchemaKey } from '../structs/schema/NumberSchemaKey';
import { Schema } from '../structs/schema/Schema';
import { StringSchemaKey } from '../structs/schema/StringSchemaKey';
Expand All @@ -10,6 +11,7 @@ export enum Types {
Number,
Boolean,
BigInt,
Date,
}

export type SchemaDefinition = {
Expand All @@ -31,13 +33,15 @@ export interface MappedSchemaTypes {
[Types.Number]: number;
[Types.Boolean]: boolean;
[Types.BigInt]: bigint;
[Types.Date]: Date;
}

export interface MappedSchemaKeys {
[Types.String]: StringSchemaKey;
[Types.Number]: NumberSchemaKey;
[Types.Boolean]: BooleanSchemaKey;
[Types.BigInt]: BigIntSchemaKey;
[Types.Date]: DateSchemaKey;
}

export type InferShape<S extends AnyObject> = {
Expand All @@ -52,7 +56,9 @@ export type ExtractType<S> = S extends string
? Types.Boolean
: S extends bigint
? Types.BigInt
: never;
: S extends Date
? Types.Date
: never;

export interface Constraint<Type extends Types> {
effect(value: MappedSchemaTypes[Type]): unknown;
Expand Down
2 changes: 2 additions & 0 deletions lib/utils/getType.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Types } from '../types/schema';

export const getType = (value: unknown) => {
if (value instanceof Date) return Types.Date;

switch (typeof value) {
case 'number':
return Types.Number;
Expand Down

0 comments on commit 840dacd

Please sign in to comment.