Skip to content

Commit

Permalink
feat: BaseDBEntity now has all fields required (id/created/updated)
Browse files Browse the repository at this point in the history
Same as what SavedDBEntity was before.
  • Loading branch information
kirillgroshkov committed Jan 21, 2024
1 parent a600a97 commit fcb1fac
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 59 deletions.
6 changes: 6 additions & 0 deletions src/json-schema/__snapshots__/jsonSchemaBuilder.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ exports[`addressBMJsonSchema 1`] = `
"address1",
"city",
"countryCode",
"created",
"id",
"updated",
"zip",
],
"type": "object",
Expand Down Expand Up @@ -94,6 +97,9 @@ exports[`addressDBMJsonSchema 1`] = `
"address1",
"city",
"countryCode",
"created",
"id",
"updated",
"zip",
],
"type": "object",
Expand Down
6 changes: 3 additions & 3 deletions src/json-schema/jsonSchemaBuilder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ const addressDBMJsonSchema2 = baseDBEntityJsonSchema.extend(addressJsonSchema)
// alternative 2
const addressBMJsonSchema3 = addressJsonSchema.extend(
jsonSchema.object<BaseDBEntity>({
id: jsonSchema.string().optional(),
created: jsonSchema.unixTimestamp2000().optional(),
updated: jsonSchema.unixTimestamp2000().optional(),
id: jsonSchema.string(),
created: jsonSchema.unixTimestamp2000(),
updated: jsonSchema.unixTimestamp2000(),
}),
)

Expand Down
7 changes: 1 addition & 6 deletions src/json-schema/jsonSchemaBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type {
JsonSchemaArray,
JsonSchemaOneOf,
JsonSchemaTuple,
SavedDBEntity,
AnyObject,
} from '../index'
import { mergeJsonSchemaObjects, _deepCopy, _sortObject } from '../index'
Expand Down Expand Up @@ -375,11 +374,7 @@ export class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyB
updated: { type: 'number', format: 'unixTimestamp2000' },
})

return this
}

savedDBEntity(): JsonSchemaObjectBuilder<T & SavedDBEntity> {
return this.baseDBEntity().addRequired(['id', 'created', 'updated']) as any
return this.addRequired(['id', 'created', 'updated']) as any
}

extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2> {
Expand Down
14 changes: 7 additions & 7 deletions src/json-schema/jsonSchemas.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { BaseDBEntity, SavedDBEntity } from '../types'
import type { BaseDBEntity } from '../types'
import { jsonSchema } from './jsonSchemaBuilder'

export const baseDBEntityJsonSchema = jsonSchema.object<BaseDBEntity>({
id: jsonSchema.string().optional(),
created: jsonSchema.unixTimestamp2000().optional(),
updated: jsonSchema.unixTimestamp2000().optional(),
})

export const savedDBEntityJsonSchema = jsonSchema.object<SavedDBEntity>({
id: jsonSchema.string(),
created: jsonSchema.unixTimestamp2000(),
updated: jsonSchema.unixTimestamp2000(),
})

// export const savedDBEntityJsonSchema = jsonSchema.object<SavedDBEntity>({
// id: jsonSchema.string(),
// created: jsonSchema.unixTimestamp2000(),
// updated: jsonSchema.unixTimestamp2000(),
// })
7 changes: 3 additions & 4 deletions src/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type {
Reviver,
StringMap,
BaseDBEntity,
Saved,
Unsaved,
UnsavedId,
AnyObject,
Expand All @@ -29,7 +28,7 @@ interface Item extends BaseDBEntity {
a?: number
}

interface ItemDBM extends Saved<Item> {}
interface ItemDBM extends Item {}

const _ym: MonthId = '2021-01'

Expand All @@ -44,7 +43,7 @@ test('saved/unsaved', () => {
a: number
}>()

const item: Item = {}
const item = {} as Unsaved<Item>
delete item.a
delete item.id
delete item.created
Expand Down Expand Up @@ -177,7 +176,7 @@ test('_typeCast', () => {
})

test('_objectAssign', () => {
const item: Item = {}
const item = {} as Item

// No TypeScript error here
Object.assign(item, {
Expand Down
27 changes: 3 additions & 24 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export interface AnyObjectWithId extends AnyObject, ObjectWithId {}
* Base interface for any Entity that was saved to DB.
*/
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type SavedDBEntity = {
export type BaseDBEntity = {
id: string

/**
Expand All @@ -61,31 +61,10 @@ export type SavedDBEntity = {
updated: UnixTimestampNumber
}

/**
* Base interface for any Entity that can be saved to DB.
* This interface fits when entity was NOT YET saved to DB,
* hence `id`, `created` and `updated` fields CAN BE undefined (yet).
* When it's known to be saved - `SavedDBEntity` interface can be used instead.
*/
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type BaseDBEntity = {
id?: string

/**
* unixTimestamp of when the entity was first created (in the DB).
*/
created?: UnixTimestampNumber

/**
* unixTimestamp of when the entity was last updated (in the DB).
*/
updated?: UnixTimestampNumber
}

export type Saved<T> = T & SavedDBEntity
export type Saved<T> = T & BaseDBEntity

export type Unsaved<T> = T extends AnyObject
? Omit<T, 'id' | 'created' | 'updated'> & BaseDBEntity
? Omit<T, 'id' | 'created' | 'updated'> & Partial<BaseDBEntity>
: T

export type UnsavedId<T> = Omit<T, 'id'> & {
Expand Down
8 changes: 4 additions & 4 deletions src/zod/zod.shared.schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ export const zSlug = z

export const zBaseDBEntity = z
.object({
id: z.string().optional(),
created: zUnixTimestamp2000.optional(),
updated: zUnixTimestamp2000.optional(),
id: z.string(),
created: zUnixTimestamp2000,
updated: zUnixTimestamp2000,
})
.describe('BaseDBEntity')

export const zSavedDBEntity = zBaseDBEntity.required().describe('SavedDBEntity')
// export const zSavedDBEntity = zBaseDBEntity.required().describe('SavedDBEntity')
22 changes: 11 additions & 11 deletions src/zod/zod.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { _expectedError } from '../error/try'
import { zBaseDBEntity, zEmail, zIsoDateString, zSavedDBEntity } from './zod.shared.schemas'
import { zBaseDBEntity, zEmail, zIsoDateString } from './zod.shared.schemas'
import { ZodValidationError, zSafeValidate, zValidate } from './zod.util'

test('basic', () => {
const err = _expectedError(() => zValidate({} as any, zSavedDBEntity), ZodValidationError)
const err = _expectedError(() => zValidate({} as any, zBaseDBEntity), ZodValidationError)
expect(err).toBeInstanceOf(Error)
expect(err).toBeInstanceOf(ZodValidationError)
expect(err.name).toBe('ZodError')
expect(err.annotate()).toBe(err.message)
expect(err.toString()).toBe(err.message)
expect(err.stack!.split('\n')[0]).toMatchInlineSnapshot(`"ZodError: Invalid SavedDBEntity"`)
expect(err.stack!.split('\n')[0]).toMatchInlineSnapshot(`"ZodError: Invalid BaseDBEntity"`)
expect(err.message).toMatchInlineSnapshot(`
"Invalid SavedDBEntity
"Invalid BaseDBEntity
Input:
{}
Input:
{}
3 issues:
id: Required
created: Required
updated: Required"
`)
3 issues:
id: Required
created: Required
updated: Required"
`)

expect(zSafeValidate(' a' as any, zBaseDBEntity).error!.message).toMatchInlineSnapshot(`
"Invalid BaseDBEntity
Expand Down

0 comments on commit fcb1fac

Please sign in to comment.