From 5f5228b36ecb48d83dda67cb649faf0b2475af0e Mon Sep 17 00:00:00 2001 From: Mario564 Date: Fri, 7 Feb 2025 08:46:16 -0800 Subject: [PATCH 1/4] Export (almost) everything from validator packages --- drizzle-typebox/src/index.ts | 5 ++++- drizzle-valibot/src/index.ts | 5 ++++- drizzle-zod/src/index.ts | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drizzle-typebox/src/index.ts b/drizzle-typebox/src/index.ts index 26230f99a1..225d3e880f 100644 --- a/drizzle-typebox/src/index.ts +++ b/drizzle-typebox/src/index.ts @@ -1,3 +1,6 @@ +export { bufferSchema, jsonSchema, literalSchema } from './column.ts'; +export * from './column.types.ts'; export * from './schema.ts'; -export type { BuildSchema } from './schema.types.internal.ts'; +export * from './schema.types.internal.ts'; export * from './schema.types.ts'; +export * from './utils.ts'; diff --git a/drizzle-valibot/src/index.ts b/drizzle-valibot/src/index.ts index 26230f99a1..225d3e880f 100644 --- a/drizzle-valibot/src/index.ts +++ b/drizzle-valibot/src/index.ts @@ -1,3 +1,6 @@ +export { bufferSchema, jsonSchema, literalSchema } from './column.ts'; +export * from './column.types.ts'; export * from './schema.ts'; -export type { BuildSchema } from './schema.types.internal.ts'; +export * from './schema.types.internal.ts'; export * from './schema.types.ts'; +export * from './utils.ts'; diff --git a/drizzle-zod/src/index.ts b/drizzle-zod/src/index.ts index 26230f99a1..225d3e880f 100644 --- a/drizzle-zod/src/index.ts +++ b/drizzle-zod/src/index.ts @@ -1,3 +1,6 @@ +export { bufferSchema, jsonSchema, literalSchema } from './column.ts'; +export * from './column.types.ts'; export * from './schema.ts'; -export type { BuildSchema } from './schema.types.internal.ts'; +export * from './schema.types.internal.ts'; export * from './schema.types.ts'; +export * from './utils.ts'; From 30e14dfbaada439e1a6e871cd0d188ebbaea308d Mon Sep 17 00:00:00 2001 From: Mario564 Date: Mon, 10 Feb 2025 09:48:18 -0800 Subject: [PATCH 2/4] Support infinitely recursive types in JSON columns --- drizzle-typebox/package.json | 1 + drizzle-typebox/src/column.types.ts | 10 +- drizzle-typebox/tests/mysql.test.ts | 19 +- drizzle-typebox/tests/pg.test.ts | 21 +- drizzle-typebox/tests/singlestore.test.ts | 21 +- drizzle-typebox/tests/sqlite.test.ts | 21 +- drizzle-valibot/package.json | 1 + drizzle-valibot/src/column.types.ts | 4 +- drizzle-valibot/tests/mysql.test.ts | 15 +- drizzle-valibot/tests/pg.test.ts | 17 ++ drizzle-valibot/tests/singlestore.test.ts | 15 +- drizzle-valibot/tests/sqlite.test.ts | 17 +- drizzle-zod/package.json | 3 +- drizzle-zod/src/column.types.ts | 10 +- drizzle-zod/src/schema.types.internal.ts | 1 + drizzle-zod/tests/mysql.test.ts | 15 +- drizzle-zod/tests/pg.test.ts | 19 ++ drizzle-zod/tests/singlestore.test.ts | 15 +- drizzle-zod/tests/sqlite.test.ts | 17 +- pnpm-lock.yaml | 231 +++++++++++++--------- 20 files changed, 360 insertions(+), 113 deletions(-) diff --git a/drizzle-typebox/package.json b/drizzle-typebox/package.json index 0c986c0a1b..f663210400 100644 --- a/drizzle-typebox/package.json +++ b/drizzle-typebox/package.json @@ -64,6 +64,7 @@ "@types/node": "^18.15.10", "cpy": "^10.1.0", "drizzle-orm": "link:../drizzle-orm/dist", + "json-rules-engine": "^7.3.0", "rimraf": "^5.0.0", "rollup": "^3.20.7", "vite-tsconfig-paths": "^4.3.2", diff --git a/drizzle-typebox/src/column.types.ts b/drizzle-typebox/src/column.types.ts index 2644946c15..1fe66d03d9 100644 --- a/drizzle-typebox/src/column.types.ts +++ b/drizzle-typebox/src/column.types.ts @@ -1,4 +1,4 @@ -import type * as t from '@sinclair/typebox'; +import * as t from '@sinclair/typebox'; import type { Assume, Column } from 'drizzle-orm'; import type { ArrayHasAtLeastOneValue, BufferSchema, ColumnIsGeneratedAlwaysAs, IsNever, JsonSchema } from './utils.ts'; @@ -13,6 +13,10 @@ export type GetBaseColumn = TColumn['_'] extends { baseC export type EnumValuesToEnum = { [K in TEnumValues[number]]: K }; +export interface GenericSchema extends t.TSchema { + static: T; +} + export type GetTypeboxType< TData, TDataType extends string, @@ -61,7 +65,9 @@ export type GetTypeboxType< : TDataType extends 'array' ? t.TArray[number], string, string, undefined, undefined>> : TData extends infer TDict extends Record - ? t.TObject<{ [K in keyof TDict]: GetTypeboxType }> + ? TColumnType extends 'PgJson' | 'PgJsonb' | 'MySqlJson' | 'SingleStoreJson' | 'SQLiteTextJson' | 'SQLiteBlobJson' + ? GenericSchema + : t.TObject<{ [K in keyof TDict]: GetTypeboxType }> : TDataType extends 'json' ? JsonSchema : TData extends number ? t.TNumber : TData extends bigint ? t.TBigInt diff --git a/drizzle-typebox/tests/mysql.test.ts b/drizzle-typebox/tests/mysql.test.ts index 8863f0fb99..8b01255f4d 100644 --- a/drizzle-typebox/tests/mysql.test.ts +++ b/drizzle-typebox/tests/mysql.test.ts @@ -1,10 +1,11 @@ -import { Type as t } from '@sinclair/typebox'; +import { type Static, Type as t } from '@sinclair/typebox'; import { type Equal, sql } from 'drizzle-orm'; -import { customType, int, mysqlSchema, mysqlTable, mysqlView, serial, text } from 'drizzle-orm/mysql-core'; +import { customType, int, json, mysqlSchema, mysqlTable, mysqlView, serial, text } from 'drizzle-orm/mysql-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import { test } from 'vitest'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; -import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; +import { createInsertSchema, createSelectSchema, createUpdateSchema, type GenericSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; const intSchema = t.Integer({ @@ -460,6 +461,18 @@ test('all data types', (tc) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: GenericSchema = t.Any() as any; + const table = mysqlTable('test', { + json: json().$type(), + }); + const result = createSelectSchema(table); + const expected = t.Object({ + json: t.Union([TopLevelCondition, t.Null()]), + }); + Expect, Static>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = mysqlTable('test', { id: int() }); // @ts-expect-error diff --git a/drizzle-typebox/tests/pg.test.ts b/drizzle-typebox/tests/pg.test.ts index 8fd8148d87..7b05a04353 100644 --- a/drizzle-typebox/tests/pg.test.ts +++ b/drizzle-typebox/tests/pg.test.ts @@ -1,8 +1,10 @@ -import { Type as t } from '@sinclair/typebox'; +import { type Static, Type as t } from '@sinclair/typebox'; import { type Equal, sql } from 'drizzle-orm'; import { customType, integer, + json, + jsonb, pgEnum, pgMaterializedView, pgSchema, @@ -11,10 +13,11 @@ import { serial, text, } from 'drizzle-orm/pg-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import { test } from 'vitest'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; -import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; +import { createInsertSchema, createSelectSchema, createUpdateSchema, type GenericSchema } from '../src'; import { Expect, expectEnumValues, expectSchemaShape } from './utils.ts'; const integerSchema = t.Integer({ minimum: CONSTANTS.INT32_MIN, maximum: CONSTANTS.INT32_MAX }); @@ -499,6 +502,20 @@ test('all data types', (tc) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: GenericSchema = t.Any() as any; + const table = pgTable('test', { + json: json().$type().notNull(), + jsonb: jsonb().$type(), + }); + const result = createSelectSchema(table); + const expected = t.Object({ + json: TopLevelCondition, + jsonb: t.Union([TopLevelCondition, t.Null()]), + }); + Expect, Static>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = pgTable('test', { id: integer() }); // @ts-expect-error diff --git a/drizzle-typebox/tests/singlestore.test.ts b/drizzle-typebox/tests/singlestore.test.ts index f643ab3b74..13a1a673c6 100644 --- a/drizzle-typebox/tests/singlestore.test.ts +++ b/drizzle-typebox/tests/singlestore.test.ts @@ -1,10 +1,11 @@ -import { Type as t } from '@sinclair/typebox'; -import { type Equal, sql } from 'drizzle-orm'; -import { customType, int, serial, singlestoreSchema, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; +import { type Static, Type as t } from '@sinclair/typebox'; +import { type Equal } from 'drizzle-orm'; +import { customType, int, json, serial, singlestoreSchema, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import { test } from 'vitest'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; -import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; +import { createInsertSchema, createSelectSchema, createUpdateSchema, type GenericSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; const intSchema = t.Integer({ @@ -462,6 +463,18 @@ test('all data types', (tc) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: GenericSchema = t.Any() as any; + const table = singlestoreTable('test', { + json: json().$type(), + }); + const result = createSelectSchema(table); + const expected = t.Object({ + json: t.Union([TopLevelCondition, t.Null()]), + }); + Expect, Static>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = singlestoreTable('test', { id: int() }); // @ts-expect-error diff --git a/drizzle-typebox/tests/sqlite.test.ts b/drizzle-typebox/tests/sqlite.test.ts index 2b5083b922..b4db9b90ec 100644 --- a/drizzle-typebox/tests/sqlite.test.ts +++ b/drizzle-typebox/tests/sqlite.test.ts @@ -1,10 +1,11 @@ -import { Type as t } from '@sinclair/typebox'; +import { type Static, Type as t } from '@sinclair/typebox'; import { type Equal, sql } from 'drizzle-orm'; -import { customType, int, sqliteTable, sqliteView, text } from 'drizzle-orm/sqlite-core'; +import { blob, customType, int, sqliteTable, sqliteView, text } from 'drizzle-orm/sqlite-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import { test } from 'vitest'; import { bufferSchema, jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; -import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; +import { createInsertSchema, createSelectSchema, createUpdateSchema, type GenericSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; const intSchema = t.Integer({ minimum: Number.MIN_SAFE_INTEGER, maximum: Number.MAX_SAFE_INTEGER }); @@ -354,6 +355,20 @@ test('all data types', (tc) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: GenericSchema = t.Any() as any; + const table = sqliteTable('test', { + json1: text({ mode: 'json' }).$type().notNull(), + json2: blob({ mode: 'json' }).$type(), + }); + const result = createSelectSchema(table); + const expected = t.Object({ + json1: TopLevelCondition, + json2: t.Union([TopLevelCondition, t.Null()]), + }); + Expect, Static>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = sqliteTable('test', { id: int() }); // @ts-expect-error diff --git a/drizzle-valibot/package.json b/drizzle-valibot/package.json index 7818dae311..267685c9b4 100644 --- a/drizzle-valibot/package.json +++ b/drizzle-valibot/package.json @@ -63,6 +63,7 @@ "@types/node": "^18.15.10", "cpy": "^10.1.0", "drizzle-orm": "link:../drizzle-orm/dist", + "json-rules-engine": "^7.3.0", "rimraf": "^5.0.0", "rollup": "^3.20.7", "valibot": "1.0.0-beta.7", diff --git a/drizzle-valibot/src/column.types.ts b/drizzle-valibot/src/column.types.ts index 2b30cb60aa..7107edf4a6 100644 --- a/drizzle-valibot/src/column.types.ts +++ b/drizzle-valibot/src/column.types.ts @@ -87,7 +87,9 @@ export type GetValibotType< GetValibotType[number], string, string, undefined, undefined, { noPipe: true }>, undefined > - : TData extends infer TDict extends Record ? v.ObjectSchema< + : TData extends infer TDict extends Record + ? TColumnType extends 'PgJson' | 'PgJsonb' | 'MySqlJson' | 'SingleStoreJson' | 'SQLiteTextJson' | 'SQLiteBlobJson' ? v.GenericSchema + : v.ObjectSchema< { readonly [K in keyof TDict]: GetValibotType }, undefined > diff --git a/drizzle-valibot/tests/mysql.test.ts b/drizzle-valibot/tests/mysql.test.ts index 6578729a44..581307095b 100644 --- a/drizzle-valibot/tests/mysql.test.ts +++ b/drizzle-valibot/tests/mysql.test.ts @@ -1,11 +1,12 @@ import { type Equal, sql } from 'drizzle-orm'; -import { customType, int, mysqlSchema, mysqlTable, mysqlView, serial, text } from 'drizzle-orm/mysql-core'; +import { customType, int, json, mysqlSchema, mysqlTable, mysqlView, serial, text } from 'drizzle-orm/mysql-core'; import * as v from 'valibot'; import { test } from 'vitest'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; +import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = v.pipe( v.number(), @@ -463,6 +464,18 @@ test('all data types', (t) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: v.GenericSchema = v.custom(() => true); + const table = mysqlTable('test', { + json: json().$type(), + }); + const result = createSelectSchema(table); + const expected = v.object({ + json: v.nullable(TopLevelCondition), + }); + Expect, v.InferOutput>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = mysqlTable('test', { id: int() }); // @ts-expect-error diff --git a/drizzle-valibot/tests/pg.test.ts b/drizzle-valibot/tests/pg.test.ts index ea2bf2dd09..4983926aef 100644 --- a/drizzle-valibot/tests/pg.test.ts +++ b/drizzle-valibot/tests/pg.test.ts @@ -2,6 +2,8 @@ import { type Equal, sql } from 'drizzle-orm'; import { customType, integer, + json, + jsonb, pgEnum, pgMaterializedView, pgSchema, @@ -16,6 +18,7 @@ import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectEnumValues, expectSchemaShape } from './utils.ts'; +import type { TopLevelCondition } from 'json-rules-engine'; const integerSchema = v.pipe(v.number(), v.minValue(CONSTANTS.INT32_MIN), v.maxValue(CONSTANTS.INT32_MAX), v.integer()); const textSchema = v.string(); @@ -505,6 +508,20 @@ test('all data types', (t) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: v.GenericSchema = v.custom(() => true); + const table = pgTable('test', { + json: json().$type().notNull(), + jsonb: jsonb().$type(), + }); + const result = createSelectSchema(table); + const expected = v.object({ + json: TopLevelCondition, + jsonb: v.nullable(TopLevelCondition), + }); + Expect, v.InferOutput>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = pgTable('test', { id: integer() }); // @ts-expect-error diff --git a/drizzle-valibot/tests/singlestore.test.ts b/drizzle-valibot/tests/singlestore.test.ts index 0827ba7a19..9fe4ea8fcd 100644 --- a/drizzle-valibot/tests/singlestore.test.ts +++ b/drizzle-valibot/tests/singlestore.test.ts @@ -1,11 +1,12 @@ import { type Equal } from 'drizzle-orm'; -import { customType, int, serial, singlestoreSchema, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; +import { customType, int, json, serial, singlestoreSchema, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; import * as v from 'valibot'; import { test } from 'vitest'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; +import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = v.pipe( v.number(), @@ -465,6 +466,18 @@ test('all data types', (t) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: v.GenericSchema = v.custom(() => true); + const table = singlestoreTable('test', { + json: json().$type(), + }); + const result = createSelectSchema(table); + const expected = v.object({ + json: v.nullable(TopLevelCondition), + }); + Expect, v.InferOutput>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = singlestoreTable('test', { id: int() }); // @ts-expect-error diff --git a/drizzle-valibot/tests/sqlite.test.ts b/drizzle-valibot/tests/sqlite.test.ts index 14e6b4bd63..be87bc1c2e 100644 --- a/drizzle-valibot/tests/sqlite.test.ts +++ b/drizzle-valibot/tests/sqlite.test.ts @@ -1,11 +1,12 @@ import { type Equal, sql } from 'drizzle-orm'; -import { customType, int, sqliteTable, sqliteView, text } from 'drizzle-orm/sqlite-core'; +import { blob, customType, int, sqliteTable, sqliteView, text } from 'drizzle-orm/sqlite-core'; import * as v from 'valibot'; import { test } from 'vitest'; import { bufferSchema, jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; +import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = v.pipe( v.number(), @@ -355,6 +356,20 @@ test('all data types', (t) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: v.GenericSchema = v.custom(() => true); + const table = sqliteTable('test', { + json1: text({ mode: 'json' }).$type().notNull(), + json2: blob({ mode: 'json' }).$type(), + }); + const result = createSelectSchema(table); + const expected = v.object({ + json1: TopLevelCondition, + json2: v.nullable(TopLevelCondition), + }); + Expect, v.InferOutput>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = sqliteTable('test', { id: int() }); // @ts-expect-error diff --git a/drizzle-zod/package.json b/drizzle-zod/package.json index ce6ece3d42..b0880da960 100644 --- a/drizzle-zod/package.json +++ b/drizzle-zod/package.json @@ -72,11 +72,12 @@ "@types/node": "^18.15.10", "cpy": "^10.1.0", "drizzle-orm": "link:../drizzle-orm/dist", + "json-rules-engine": "^7.3.0", "rimraf": "^5.0.0", "rollup": "^3.20.7", "vite-tsconfig-paths": "^4.3.2", "vitest": "^1.6.0", - "zod": "^3.20.2", + "zod": "^3.24.1", "zx": "^7.2.2" } } diff --git a/drizzle-zod/src/column.types.ts b/drizzle-zod/src/column.types.ts index 49c12cdbb7..d61f07b4c4 100644 --- a/drizzle-zod/src/column.types.ts +++ b/drizzle-zod/src/column.types.ts @@ -14,24 +14,27 @@ export type GetBaseColumn = TColumn['_'] extends { baseC export type GetZodType< TData, TDataType extends string, + TColumnType extends string, TEnumValues extends [string, ...string[]] | undefined, TBaseColumn extends Column | undefined, > = TBaseColumn extends Column ? z.ZodArray< GetZodType< TBaseColumn['_']['data'], TBaseColumn['_']['dataType'], + TBaseColumn['_']['columnType'], GetEnumValuesFromColumn, GetBaseColumn > > : ArrayHasAtLeastOneValue extends true ? z.ZodEnum> : TData extends infer TTuple extends [any, ...any[]] - ? z.ZodTuple }, [any, ...any[]]>> + ? z.ZodTuple }, [any, ...any[]]>> : TData extends Date ? z.ZodDate : TData extends Buffer ? z.ZodType - : TDataType extends 'array' ? z.ZodArray[number], string, undefined, undefined>> + : TDataType extends 'array' ? z.ZodArray[number], string, string, undefined, undefined>> : TData extends infer TDict extends Record - ? z.ZodObject<{ [K in keyof TDict]: GetZodType }, 'strip'> + ? TColumnType extends 'PgJson' | 'PgJsonb' | 'MySqlJson' | 'SingleStoreJson' | 'SQLiteTextJson' | 'SQLiteBlobJson' ? z.ZodType + : z.ZodObject<{ [K in keyof TDict]: GetZodType }, 'strip'> : TDataType extends 'json' ? z.ZodType : TData extends number ? z.ZodNumber : TData extends bigint ? z.ZodBigInt @@ -66,6 +69,7 @@ export type HandleColumn< > = GetZodType< TColumn['_']['data'], TColumn['_']['dataType'], + TColumn['_']['columnType'], GetEnumValuesFromColumn, GetBaseColumn > extends infer TSchema extends z.ZodTypeAny ? TSchema extends z.ZodAny ? z.ZodAny diff --git a/drizzle-zod/src/schema.types.internal.ts b/drizzle-zod/src/schema.types.internal.ts index 8b89187f22..ae7b433d5c 100644 --- a/drizzle-zod/src/schema.types.internal.ts +++ b/drizzle-zod/src/schema.types.internal.ts @@ -17,6 +17,7 @@ export type BuildRefineColumns< [K in keyof TColumns]: TColumns[K] extends infer TColumn extends Column ? GetZodType< TColumn['_']['data'], TColumn['_']['dataType'], + TColumn['_']['columnType'], GetEnumValuesFromColumn, GetBaseColumn > extends infer TSchema extends z.ZodTypeAny ? TSchema diff --git a/drizzle-zod/tests/mysql.test.ts b/drizzle-zod/tests/mysql.test.ts index 314631b6e9..8f0478a3c1 100644 --- a/drizzle-zod/tests/mysql.test.ts +++ b/drizzle-zod/tests/mysql.test.ts @@ -1,11 +1,12 @@ import { type Equal, sql } from 'drizzle-orm'; -import { customType, int, mysqlSchema, mysqlTable, mysqlView, serial, text } from 'drizzle-orm/mysql-core'; +import { customType, int, json, mysqlSchema, mysqlTable, mysqlView, serial, text } from 'drizzle-orm/mysql-core'; import { test } from 'vitest'; import { z } from 'zod'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSchemaFactory, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; +import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = z.number().min(CONSTANTS.INT32_MIN).max(CONSTANTS.INT32_MAX).int(); const serialNumberModeSchema = z.number().min(0).max(Number.MAX_SAFE_INTEGER).int(); @@ -507,6 +508,18 @@ test('type coercion - mixed', (t) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: z.ZodType = z.custom().superRefine(() => {}); + const table = mysqlTable('test', { + json: json().$type(), + }); + const result = createSelectSchema(table); + const expected = z.object({ + json: z.nullable(TopLevelCondition), + }); + Expect, z.infer>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = mysqlTable('test', { id: int() }); // @ts-expect-error diff --git a/drizzle-zod/tests/pg.test.ts b/drizzle-zod/tests/pg.test.ts index 4f82afc2d0..eb293ee351 100644 --- a/drizzle-zod/tests/pg.test.ts +++ b/drizzle-zod/tests/pg.test.ts @@ -2,6 +2,8 @@ import { type Equal, sql } from 'drizzle-orm'; import { customType, integer, + json, + jsonb, pgEnum, pgMaterializedView, pgSchema, @@ -16,6 +18,7 @@ import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSchemaFactory, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectEnumValues, expectSchemaShape } from './utils.ts'; +import type { TopLevelCondition } from 'json-rules-engine'; const integerSchema = z.number().min(CONSTANTS.INT32_MIN).max(CONSTANTS.INT32_MAX).int(); const textSchema = z.string(); @@ -496,6 +499,8 @@ test('all data types', (t) => { array2: z.array(z.array(integerSchema).length(2)), array3: z.array(z.array(z.string().max(10)).length(2)), }); + result.shape.json + expected.shape.json expectSchemaShape(t, expected).from(result); Expect>(); }); @@ -553,6 +558,20 @@ test('type coercion - mixed', (t) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: z.ZodType = z.custom().superRefine(() => {}); + const table = pgTable('test', { + json: json().$type().notNull(), + jsonb: jsonb().$type(), + }); + const result = createSelectSchema(table); + const expected = z.object({ + json: TopLevelCondition, + jsonb: z.nullable(TopLevelCondition), + }); + Expect, z.infer>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = pgTable('test', { id: integer() }); // @ts-expect-error diff --git a/drizzle-zod/tests/singlestore.test.ts b/drizzle-zod/tests/singlestore.test.ts index c736efa4c8..849193f213 100644 --- a/drizzle-zod/tests/singlestore.test.ts +++ b/drizzle-zod/tests/singlestore.test.ts @@ -1,11 +1,12 @@ import type { Equal } from 'drizzle-orm'; -import { customType, int, serial, singlestoreSchema, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; +import { customType, int, json, serial, singlestoreSchema, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; import { test } from 'vitest'; import { z } from 'zod'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSchemaFactory, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; +import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = z.number().min(CONSTANTS.INT32_MIN).max(CONSTANTS.INT32_MAX).int(); const serialNumberModeSchema = z.number().min(0).max(Number.MAX_SAFE_INTEGER).int(); @@ -509,6 +510,18 @@ test('type coercion - mixed', (t) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: z.ZodType = z.custom().superRefine(() => {}); + const table = singlestoreTable('test', { + json: json().$type(), + }); + const result = createSelectSchema(table); + const expected = z.object({ + json: z.nullable(TopLevelCondition), + }); + Expect, z.infer>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = singlestoreTable('test', { id: int() }); // @ts-expect-error diff --git a/drizzle-zod/tests/sqlite.test.ts b/drizzle-zod/tests/sqlite.test.ts index 5950f6efec..1c6e534b36 100644 --- a/drizzle-zod/tests/sqlite.test.ts +++ b/drizzle-zod/tests/sqlite.test.ts @@ -1,11 +1,12 @@ import { type Equal, sql } from 'drizzle-orm'; -import { customType, int, sqliteTable, sqliteView, text } from 'drizzle-orm/sqlite-core'; +import { blob, customType, int, sqliteTable, sqliteView, text } from 'drizzle-orm/sqlite-core'; import { test } from 'vitest'; import { z } from 'zod'; import { bufferSchema, jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSchemaFactory, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; +import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = z.number().min(Number.MIN_SAFE_INTEGER).max(Number.MAX_SAFE_INTEGER).int(); const textSchema = z.string(); @@ -400,6 +401,20 @@ test('type coercion - mixed', (t) => { Expect>(); }); +/* Infinitely recursive type */ { + const TopLevelCondition: z.ZodType = z.custom().superRefine(() => {}); + const table = sqliteTable('test', { + json1: text({ mode: 'json' }).$type().notNull(), + json2: blob({ mode: 'json' }).$type(), + }); + const result = createSelectSchema(table); + const expected = z.object({ + json1: TopLevelCondition, + json2: z.nullable(TopLevelCondition), + }); + Expect, z.infer>>(); +} + /* Disallow unknown keys in table refinement - select */ { const table = sqliteTable('test', { id: int() }); // @ts-expect-error diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 430c60b266..2eb9767b87 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -517,6 +517,9 @@ importers: drizzle-orm: specifier: link:../drizzle-orm/dist version: link:../drizzle-orm/dist + json-rules-engine: + specifier: ^7.3.0 + version: 7.3.0 rimraf: specifier: ^5.0.0 version: 5.0.0 @@ -547,6 +550,9 @@ importers: drizzle-orm: specifier: link:../drizzle-orm/dist version: link:../drizzle-orm/dist + json-rules-engine: + specifier: ^7.3.0 + version: 7.3.0 rimraf: specifier: ^5.0.0 version: 5.0.0 @@ -580,6 +586,9 @@ importers: drizzle-orm: specifier: link:../drizzle-orm/dist version: link:../drizzle-orm/dist + json-rules-engine: + specifier: ^7.3.0 + version: 7.3.0 rimraf: specifier: ^5.0.0 version: 5.0.0 @@ -593,8 +602,8 @@ importers: specifier: ^1.6.0 version: 1.6.0(@types/node@18.15.10)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) zod: - specifier: ^3.20.2 - version: 3.21.4 + specifier: ^3.24.1 + version: 3.24.1 zx: specifier: ^7.2.2 version: 7.2.2 @@ -3194,6 +3203,18 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@jsep-plugin/assignment@1.3.0': + resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@jsep-plugin/regex@1.0.4': + resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + '@libsql/client-wasm@0.10.0': resolution: {integrity: sha512-xSlpGdBGEr4mRtjCnDejTqtDpct2ng8cqHUQs+S4xG1yv0h+hLdzOtQJSY9JV9T/2MWWDfdCiEntPs2SdErSJA==} bundledDependencies: @@ -6238,6 +6259,9 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + exec-async@2.2.0: resolution: {integrity: sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==} @@ -6752,6 +6776,9 @@ packages: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} + hash-it@6.0.0: + resolution: {integrity: sha512-KHzmSFx1KwyMPw0kXeeUD752q/Kfbzhy6dAZrjXV9kAIXGqzGvv8vhkUqj+2MGZldTo0IBpw6v7iWE7uxsvH0w==} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -7239,6 +7266,10 @@ packages: peerDependencies: '@babel/preset-env': ^7.1.6 + jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} + engines: {node: '>= 10.16.0'} + jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true @@ -7270,6 +7301,10 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-rules-engine@7.3.0: + resolution: {integrity: sha512-Ng8Nq9sXID2h92gk3gTCB6bYK6GvQOPgxHLOIl6dEL+PE4+jvTltSOKtfYkVScTR2wL/+ts5gaQqoBFl0zK4/g==} + engines: {node: '>=18.0.0'} + json-schema-deref-sync@0.13.0: resolution: {integrity: sha512-YBOEogm5w9Op337yb6pAT6ZXDqlxAsQCanM3grid8lMWNxRJO/zWEJi3ZzqDL8boWfwhTFym5EFrNgWwpqcBRg==} engines: {node: '>=6.0.0'} @@ -7299,6 +7334,11 @@ packages: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} + jsonpath-plus@10.2.0: + resolution: {integrity: sha512-T9V+8iNYKFL2n2rF+w02LBOT2JjDnTjioaNFrxRy0Bv1y/hNsqR/EBK7Ojy2ythRHwmz2cRIls+9JitQGZC/sw==} + engines: {node: '>=18.0.0'} + hasBin: true + jsonstream-next@3.0.0: resolution: {integrity: sha512-aAi6oPhdt7BKyQn1SrIIGZBt0ukKuOUE1qV6kJ3GgioSOYzsRc8z9Hfr1BVmacA/jLe9nARfmgMGgn68BqIAgg==} engines: {node: '>=10'} @@ -7365,10 +7405,12 @@ packages: libsql@0.3.19: resolution: {integrity: sha512-Aj5cQ5uk/6fHdmeW0TiXK42FqUlwx7ytmMLPSaUQPin5HKKKuUPD62MAbN4OEweGBBI7q1BekoEN4gPUEL6MZA==} + cpu: [x64, arm64, wasm32] os: [darwin, linux, win32] libsql@0.4.1: resolution: {integrity: sha512-qZlR9Yu1zMBeLChzkE/cKfoKV3Esp9cn9Vx5Zirn4AVhDWPcjYhKwbtJcMuHehgk3mH+fJr9qW+3vesBWbQpBg==} + cpu: [x64, arm64, wasm32] os: [darwin, linux, win32] lighthouse-logger@1.4.2: @@ -10467,12 +10509,12 @@ packages: youch@3.3.3: resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} - zod@3.21.4: - resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} - zod@3.23.7: resolution: {integrity: sha512-NBeIoqbtOiUMomACV/y+V3Qfs9+Okr18vR5c/5pHClPpufWOrsx8TENboDPe265lFdfewX2yBtNTLPvnmCxwog==} + zod@3.24.1: + resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} + zx@7.2.2: resolution: {integrity: sha512-50Gjicd6ijTt7Zcz5fNX+rHrmE0uVqC+X6lYKhf2Cu8wIxDpNIzXwTmzchNdW+JY3LFsRcU43B1lHE4HBMmKgQ==} engines: {node: '>= 16.0.0'} @@ -10767,9 +10809,9 @@ snapshots: dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.583.0 + '@aws-sdk/client-sts': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/core': 3.582.0 - '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)) '@aws-sdk/middleware-host-header': 3.577.0 '@aws-sdk/middleware-logger': 3.577.0 '@aws-sdk/middleware-recursion-detection': 3.577.0 @@ -10808,52 +10850,6 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.583.0 - '@aws-sdk/core': 3.582.0 - '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.583.0) - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.583.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.583.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.8.1 - transitivePeerDependencies: - - '@aws-sdk/client-sts' - - aws-crt - '@aws-sdk/client-sso@3.478.0': dependencies: '@aws-crypto/sha256-browser': 3.0.0 @@ -11122,9 +11118,54 @@ snapshots: dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.583.0(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/client-sso-oidc': 3.583.0 + '@aws-sdk/core': 3.582.0 + '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/middleware-host-header': 3.577.0 + '@aws-sdk/middleware-logger': 3.577.0 + '@aws-sdk/middleware-recursion-detection': 3.577.0 + '@aws-sdk/middleware-user-agent': 3.583.0 + '@aws-sdk/region-config-resolver': 3.577.0 + '@aws-sdk/types': 3.577.0 + '@aws-sdk/util-endpoints': 3.583.0 + '@aws-sdk/util-user-agent-browser': 3.577.0 + '@aws-sdk/util-user-agent-node': 3.577.0 + '@smithy/config-resolver': 3.0.0 + '@smithy/core': 2.0.1 + '@smithy/fetch-http-handler': 3.0.1 + '@smithy/hash-node': 3.0.0 + '@smithy/invalid-dependency': 3.0.0 + '@smithy/middleware-content-length': 3.0.0 + '@smithy/middleware-endpoint': 3.0.0 + '@smithy/middleware-retry': 3.0.1 + '@smithy/middleware-serde': 3.0.0 + '@smithy/middleware-stack': 3.0.0 + '@smithy/node-config-provider': 3.0.0 + '@smithy/node-http-handler': 3.0.0 + '@smithy/protocol-http': 4.0.0 + '@smithy/smithy-client': 3.0.1 + '@smithy/types': 3.0.0 + '@smithy/url-parser': 3.0.0 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.1 + '@smithy/util-defaults-mode-node': 3.0.1 + '@smithy/util-endpoints': 2.0.0 + '@smithy/util-middleware': 3.0.0 + '@smithy/util-retry': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)': + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/client-sso-oidc': 3.583.0 '@aws-sdk/core': 3.582.0 - '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/credential-provider-node': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)) '@aws-sdk/middleware-host-header': 3.577.0 '@aws-sdk/middleware-logger': 3.577.0 '@aws-sdk/middleware-recursion-detection': 3.577.0 @@ -11161,6 +11202,7 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.8.1 transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' - aws-crt '@aws-sdk/core@3.477.0': @@ -11313,13 +11355,13 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-ini@3.583.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.583.0)': + '@aws-sdk/credential-provider-ini@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0))': dependencies: - '@aws-sdk/client-sts': 3.583.0 + '@aws-sdk/client-sts': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/credential-provider-env': 3.577.0 '@aws-sdk/credential-provider-process': 3.577.0 - '@aws-sdk/credential-provider-sso': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/credential-provider-sso': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) + '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)) '@aws-sdk/types': 3.577.0 '@smithy/credential-provider-imds': 3.0.0 '@smithy/property-provider': 3.0.0 @@ -11420,14 +11462,14 @@ snapshots: - '@aws-sdk/client-sts' - aws-crt - '@aws-sdk/credential-provider-node@3.583.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.583.0)': + '@aws-sdk/credential-provider-node@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0))': dependencies: '@aws-sdk/credential-provider-env': 3.577.0 '@aws-sdk/credential-provider-http': 3.582.0 - '@aws-sdk/credential-provider-ini': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/credential-provider-ini': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)) '@aws-sdk/credential-provider-process': 3.577.0 - '@aws-sdk/credential-provider-sso': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.583.0) + '@aws-sdk/credential-provider-sso': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) + '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)) '@aws-sdk/types': 3.577.0 '@smithy/credential-provider-imds': 3.0.0 '@smithy/property-provider': 3.0.0 @@ -11520,19 +11562,6 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-sso@3.583.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))': - dependencies: - '@aws-sdk/client-sso': 3.583.0 - '@aws-sdk/token-providers': 3.577.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)) - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.8.1 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - '@aws-sdk/credential-provider-sso@3.583.0(@aws-sdk/client-sso-oidc@3.583.0)': dependencies: '@aws-sdk/client-sso': 3.583.0 @@ -11569,6 +11598,14 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 + '@aws-sdk/credential-provider-web-identity@3.577.0(@aws-sdk/client-sts@3.583.0(@aws-sdk/client-sso-oidc@3.583.0))': + dependencies: + '@aws-sdk/client-sts': 3.583.0(@aws-sdk/client-sso-oidc@3.583.0) + '@aws-sdk/types': 3.577.0 + '@smithy/property-provider': 3.0.0 + '@smithy/types': 3.0.0 + tslib: 2.8.1 + '@aws-sdk/credential-provider-web-identity@3.577.0(@aws-sdk/client-sts@3.583.0)': dependencies: '@aws-sdk/client-sts': 3.583.0 @@ -11779,15 +11816,6 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@aws-sdk/token-providers@3.577.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))': - dependencies: - '@aws-sdk/client-sso-oidc': 3.583.0(@aws-sdk/client-sts@3.583.0) - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.8.1 - '@aws-sdk/token-providers@3.577.0(@aws-sdk/client-sso-oidc@3.583.0)': dependencies: '@aws-sdk/client-sso-oidc': 3.583.0 @@ -13899,6 +13927,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 + '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/regex@1.0.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + '@libsql/client-wasm@0.10.0': dependencies: '@libsql/core': 0.10.0 @@ -15761,7 +15797,7 @@ snapshots: pathe: 1.1.2 picocolors: 1.0.1 sirv: 2.0.4 - vitest: 1.6.0(@types/node@18.19.33)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) + vitest: 1.6.0(@types/node@18.15.10)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) optional: true '@vitest/ui@1.6.0(vitest@2.1.2)': @@ -17826,6 +17862,8 @@ snapshots: event-target-shim@5.0.1: {} + eventemitter2@6.4.9: {} + exec-async@2.2.0: {} execa@1.0.0: @@ -18483,6 +18521,8 @@ snapshots: dependencies: function-bind: 1.1.1 + hash-it@6.0.0: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -18955,6 +18995,8 @@ snapshots: transitivePeerDependencies: - supports-color + jsep@1.4.0: {} + jsesc@0.5.0: {} jsesc@2.5.2: {} @@ -18979,6 +19021,13 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-rules-engine@7.3.0: + dependencies: + clone: 2.1.2 + eventemitter2: 6.4.9 + hash-it: 6.0.0 + jsonpath-plus: 10.2.0 + json-schema-deref-sync@0.13.0: dependencies: clone: 2.1.2 @@ -19012,6 +19061,12 @@ snapshots: jsonparse@1.3.1: {} + jsonpath-plus@10.2.0: + dependencies: + '@jsep-plugin/assignment': 1.3.0(jsep@1.4.0) + '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) + jsep: 1.4.0 + jsonstream-next@3.0.0: dependencies: jsonparse: 1.3.1 @@ -22687,10 +22742,10 @@ snapshots: mustache: 4.2.0 stacktracey: 2.1.8 - zod@3.21.4: {} - zod@3.23.7: {} + zod@3.24.1: {} + zx@7.2.2: dependencies: '@types/fs-extra': 11.0.4 From f6b563edb447082fde5888f144873644f9cd0571 Mon Sep 17 00:00:00 2001 From: Mario564 Date: Mon, 10 Feb 2025 09:50:29 -0800 Subject: [PATCH 3/4] Fix import --- drizzle-typebox/src/column.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drizzle-typebox/src/column.types.ts b/drizzle-typebox/src/column.types.ts index 1fe66d03d9..6db65e5c97 100644 --- a/drizzle-typebox/src/column.types.ts +++ b/drizzle-typebox/src/column.types.ts @@ -1,4 +1,4 @@ -import * as t from '@sinclair/typebox'; +import type * as t from '@sinclair/typebox'; import type { Assume, Column } from 'drizzle-orm'; import type { ArrayHasAtLeastOneValue, BufferSchema, ColumnIsGeneratedAlwaysAs, IsNever, JsonSchema } from './utils.ts'; From c1c8e1660bf671f166c8d5fcfa8eb8feada249d7 Mon Sep 17 00:00:00 2001 From: Mario564 Date: Mon, 10 Feb 2025 10:07:02 -0800 Subject: [PATCH 4/4] Format --- drizzle-valibot/src/column.types.ts | 5 +++-- drizzle-valibot/tests/mysql.test.ts | 2 +- drizzle-valibot/tests/pg.test.ts | 2 +- drizzle-valibot/tests/singlestore.test.ts | 2 +- drizzle-valibot/tests/sqlite.test.ts | 2 +- drizzle-zod/src/column.types.ts | 11 +++++++---- drizzle-zod/tests/mysql.test.ts | 2 +- drizzle-zod/tests/pg.test.ts | 6 +++--- drizzle-zod/tests/singlestore.test.ts | 2 +- drizzle-zod/tests/sqlite.test.ts | 2 +- 10 files changed, 20 insertions(+), 16 deletions(-) diff --git a/drizzle-valibot/src/column.types.ts b/drizzle-valibot/src/column.types.ts index 7107edf4a6..17eccadbd8 100644 --- a/drizzle-valibot/src/column.types.ts +++ b/drizzle-valibot/src/column.types.ts @@ -87,8 +87,9 @@ export type GetValibotType< GetValibotType[number], string, string, undefined, undefined, { noPipe: true }>, undefined > - : TData extends infer TDict extends Record - ? TColumnType extends 'PgJson' | 'PgJsonb' | 'MySqlJson' | 'SingleStoreJson' | 'SQLiteTextJson' | 'SQLiteBlobJson' ? v.GenericSchema + : TData extends infer TDict extends Record + ? TColumnType extends 'PgJson' | 'PgJsonb' | 'MySqlJson' | 'SingleStoreJson' | 'SQLiteTextJson' | 'SQLiteBlobJson' + ? v.GenericSchema : v.ObjectSchema< { readonly [K in keyof TDict]: GetValibotType }, undefined diff --git a/drizzle-valibot/tests/mysql.test.ts b/drizzle-valibot/tests/mysql.test.ts index 581307095b..a01f53de56 100644 --- a/drizzle-valibot/tests/mysql.test.ts +++ b/drizzle-valibot/tests/mysql.test.ts @@ -1,12 +1,12 @@ import { type Equal, sql } from 'drizzle-orm'; import { customType, int, json, mysqlSchema, mysqlTable, mysqlView, serial, text } from 'drizzle-orm/mysql-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import * as v from 'valibot'; import { test } from 'vitest'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; -import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = v.pipe( v.number(), diff --git a/drizzle-valibot/tests/pg.test.ts b/drizzle-valibot/tests/pg.test.ts index 4983926aef..a0ff08a605 100644 --- a/drizzle-valibot/tests/pg.test.ts +++ b/drizzle-valibot/tests/pg.test.ts @@ -12,13 +12,13 @@ import { serial, text, } from 'drizzle-orm/pg-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import * as v from 'valibot'; import { test } from 'vitest'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectEnumValues, expectSchemaShape } from './utils.ts'; -import type { TopLevelCondition } from 'json-rules-engine'; const integerSchema = v.pipe(v.number(), v.minValue(CONSTANTS.INT32_MIN), v.maxValue(CONSTANTS.INT32_MAX), v.integer()); const textSchema = v.string(); diff --git a/drizzle-valibot/tests/singlestore.test.ts b/drizzle-valibot/tests/singlestore.test.ts index 9fe4ea8fcd..1ddb5e8563 100644 --- a/drizzle-valibot/tests/singlestore.test.ts +++ b/drizzle-valibot/tests/singlestore.test.ts @@ -1,12 +1,12 @@ import { type Equal } from 'drizzle-orm'; import { customType, int, json, serial, singlestoreSchema, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import * as v from 'valibot'; import { test } from 'vitest'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; -import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = v.pipe( v.number(), diff --git a/drizzle-valibot/tests/sqlite.test.ts b/drizzle-valibot/tests/sqlite.test.ts index be87bc1c2e..e0af4bd462 100644 --- a/drizzle-valibot/tests/sqlite.test.ts +++ b/drizzle-valibot/tests/sqlite.test.ts @@ -1,12 +1,12 @@ import { type Equal, sql } from 'drizzle-orm'; import { blob, customType, int, sqliteTable, sqliteView, text } from 'drizzle-orm/sqlite-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import * as v from 'valibot'; import { test } from 'vitest'; import { bufferSchema, jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; -import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = v.pipe( v.number(), diff --git a/drizzle-zod/src/column.types.ts b/drizzle-zod/src/column.types.ts index d61f07b4c4..2d6663b8c5 100644 --- a/drizzle-zod/src/column.types.ts +++ b/drizzle-zod/src/column.types.ts @@ -27,13 +27,16 @@ export type GetZodType< > > : ArrayHasAtLeastOneValue extends true ? z.ZodEnum> - : TData extends infer TTuple extends [any, ...any[]] - ? z.ZodTuple }, [any, ...any[]]>> + : TData extends infer TTuple extends [any, ...any[]] ? z.ZodTuple< + Assume<{ [K in keyof TTuple]: GetZodType }, [any, ...any[]]> + > : TData extends Date ? z.ZodDate : TData extends Buffer ? z.ZodType - : TDataType extends 'array' ? z.ZodArray[number], string, string, undefined, undefined>> + : TDataType extends 'array' + ? z.ZodArray[number], string, string, undefined, undefined>> : TData extends infer TDict extends Record - ? TColumnType extends 'PgJson' | 'PgJsonb' | 'MySqlJson' | 'SingleStoreJson' | 'SQLiteTextJson' | 'SQLiteBlobJson' ? z.ZodType + ? TColumnType extends 'PgJson' | 'PgJsonb' | 'MySqlJson' | 'SingleStoreJson' | 'SQLiteTextJson' | 'SQLiteBlobJson' + ? z.ZodType : z.ZodObject<{ [K in keyof TDict]: GetZodType }, 'strip'> : TDataType extends 'json' ? z.ZodType : TData extends number ? z.ZodNumber diff --git a/drizzle-zod/tests/mysql.test.ts b/drizzle-zod/tests/mysql.test.ts index 8f0478a3c1..e0e5986602 100644 --- a/drizzle-zod/tests/mysql.test.ts +++ b/drizzle-zod/tests/mysql.test.ts @@ -1,12 +1,12 @@ import { type Equal, sql } from 'drizzle-orm'; import { customType, int, json, mysqlSchema, mysqlTable, mysqlView, serial, text } from 'drizzle-orm/mysql-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import { test } from 'vitest'; import { z } from 'zod'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSchemaFactory, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; -import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = z.number().min(CONSTANTS.INT32_MIN).max(CONSTANTS.INT32_MAX).int(); const serialNumberModeSchema = z.number().min(0).max(Number.MAX_SAFE_INTEGER).int(); diff --git a/drizzle-zod/tests/pg.test.ts b/drizzle-zod/tests/pg.test.ts index eb293ee351..dcba9979de 100644 --- a/drizzle-zod/tests/pg.test.ts +++ b/drizzle-zod/tests/pg.test.ts @@ -12,13 +12,13 @@ import { serial, text, } from 'drizzle-orm/pg-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import { test } from 'vitest'; import { z } from 'zod'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSchemaFactory, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectEnumValues, expectSchemaShape } from './utils.ts'; -import type { TopLevelCondition } from 'json-rules-engine'; const integerSchema = z.number().min(CONSTANTS.INT32_MIN).max(CONSTANTS.INT32_MAX).int(); const textSchema = z.string(); @@ -499,8 +499,8 @@ test('all data types', (t) => { array2: z.array(z.array(integerSchema).length(2)), array3: z.array(z.array(z.string().max(10)).length(2)), }); - result.shape.json - expected.shape.json + result.shape.json; + expected.shape.json; expectSchemaShape(t, expected).from(result); Expect>(); }); diff --git a/drizzle-zod/tests/singlestore.test.ts b/drizzle-zod/tests/singlestore.test.ts index 849193f213..a62b98fdf5 100644 --- a/drizzle-zod/tests/singlestore.test.ts +++ b/drizzle-zod/tests/singlestore.test.ts @@ -1,12 +1,12 @@ import type { Equal } from 'drizzle-orm'; import { customType, int, json, serial, singlestoreSchema, singlestoreTable, text } from 'drizzle-orm/singlestore-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import { test } from 'vitest'; import { z } from 'zod'; import { jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSchemaFactory, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; -import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = z.number().min(CONSTANTS.INT32_MIN).max(CONSTANTS.INT32_MAX).int(); const serialNumberModeSchema = z.number().min(0).max(Number.MAX_SAFE_INTEGER).int(); diff --git a/drizzle-zod/tests/sqlite.test.ts b/drizzle-zod/tests/sqlite.test.ts index 1c6e534b36..838d521854 100644 --- a/drizzle-zod/tests/sqlite.test.ts +++ b/drizzle-zod/tests/sqlite.test.ts @@ -1,12 +1,12 @@ import { type Equal, sql } from 'drizzle-orm'; import { blob, customType, int, sqliteTable, sqliteView, text } from 'drizzle-orm/sqlite-core'; +import type { TopLevelCondition } from 'json-rules-engine'; import { test } from 'vitest'; import { z } from 'zod'; import { bufferSchema, jsonSchema } from '~/column.ts'; import { CONSTANTS } from '~/constants.ts'; import { createInsertSchema, createSchemaFactory, createSelectSchema, createUpdateSchema } from '../src'; import { Expect, expectSchemaShape } from './utils.ts'; -import type { TopLevelCondition } from 'json-rules-engine'; const intSchema = z.number().min(Number.MIN_SAFE_INTEGER).max(Number.MAX_SAFE_INTEGER).int(); const textSchema = z.string();