@apisr/drizzle-model 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.turbo/turbo-check-types.log +2 -0
  2. package/ROADMAP.md +1 -0
  3. package/TODO.md +64 -0
  4. package/drizzle.config.ts +11 -0
  5. package/package.json +35 -0
  6. package/src/index.ts +1 -0
  7. package/src/model/builder.ts +46 -0
  8. package/src/model/config.ts +35 -0
  9. package/src/model/core/joins.ts +279 -0
  10. package/src/model/core/projection.ts +47 -0
  11. package/src/model/core/runtime.ts +249 -0
  12. package/src/model/core/thenable.ts +85 -0
  13. package/src/model/core/transform.ts +45 -0
  14. package/src/model/core/where.ts +183 -0
  15. package/src/model/core/with.ts +28 -0
  16. package/src/model/dialect.ts +11 -0
  17. package/src/model/foreigns.ts +31 -0
  18. package/src/model/format.ts +19 -0
  19. package/src/model/index.ts +1 -0
  20. package/src/model/methods/exclude.ts +32 -0
  21. package/src/model/methods/include.ts +3 -0
  22. package/src/model/methods/insert.ts +16 -0
  23. package/src/model/methods/levels.ts +2 -0
  24. package/src/model/methods/query/where.ts +48 -0
  25. package/src/model/methods/return.ts +39 -0
  26. package/src/model/methods/select.ts +38 -0
  27. package/src/model/methods/update.ts +4 -0
  28. package/src/model/methods/upsert.ts +54 -0
  29. package/src/model/methods/with.ts +40 -0
  30. package/src/model/model.ts +148 -0
  31. package/src/model/options.ts +64 -0
  32. package/src/model/query/operations.ts +170 -0
  33. package/src/model/relation.ts +121 -0
  34. package/src/model/result.ts +91 -0
  35. package/src/model/shape.ts +8 -0
  36. package/src/model/table.ts +127 -0
  37. package/src/types.ts +16 -0
  38. package/tests/builder-v2-mysql.type-test.ts +40 -0
  39. package/tests/builder-v2.type-test.ts +343 -0
  40. package/tests/builder.test.ts +63 -0
  41. package/tests/db.ts +25 -0
  42. package/tests/find.test.ts +155 -0
  43. package/tests/insert.test.ts +233 -0
  44. package/tests/relations.ts +38 -0
  45. package/tests/schema.ts +49 -0
  46. package/tsconfig.json +36 -0
  47. package/tsdown.config.ts +12 -0
@@ -0,0 +1,16 @@
1
+ // import type { DrizzleInsertValues, IsDrizzleTable } from "@/types";
2
+ import type { RelationsRecord, TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relations";
3
+ import type { IsTable, NormalizeTable, TableInsertValues } from "../table.ts";
4
+
5
+ export type MethodInsertValue<TTable extends TableRelationalConfig> = TableInsertValues<
6
+ NormalizeTable<TTable>
7
+ >;
8
+
9
+ export type MethodWithInsertValue<
10
+ TSchema extends TablesRelationalConfig,
11
+ TRelations extends RelationsRecord,
12
+ > = {
13
+ [Key in keyof TRelations]?: TableInsertValues<IsTable<
14
+ TSchema[TRelations[Key]["targetTableName"]]["table"]
15
+ >>
16
+ };
@@ -0,0 +1,2 @@
1
+ export type ModelFirstLevelMethods = "$insert";
2
+ export type ModelLevelMethods = "$findMany" | "$findFirst" | "$insert" | "$update" | "$delete" | "$with";
@@ -0,0 +1,48 @@
1
+ import type { SQL } from "drizzle-orm/sql";
2
+ import type { ModelIdentifier } from "../../model.ts";
3
+ import type { TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relations";
4
+ import type { TableColumn, TableColumns, TableOneRelationsTableName } from "../../table.ts";
5
+ import type { MethodIncludeIdentifier } from "../include.ts";
6
+ import type { ColumnValue } from "../../query/operations.ts";
7
+
8
+ export type MethodWhereValue<
9
+ TSchema extends TablesRelationalConfig,
10
+ TTable extends TableRelationalConfig,
11
+ TValue = ModelIdentifier<TableOneRelationsTableName<TTable>> | SQL | MethodWhereColumns<TTable> | MethodWhereRelations<TSchema, TTable> | MethodIncludeIdentifier<any>
12
+ > =
13
+ // Is result of .include fn?
14
+ TValue extends MethodIncludeIdentifier<true>
15
+ ? never
16
+ : (
17
+ // Is SQL?
18
+ TValue extends SQL
19
+ ? TValue
20
+ // Is model?
21
+ : (TValue extends ModelIdentifier<TableOneRelationsTableName<TTable>>
22
+ ? TValue
23
+ // Is columns where clauses?
24
+ : (TValue extends MethodWhereColumns<TTable>
25
+ ? TValue
26
+ // Is relations
27
+ : (TValue extends MethodWhereRelations<TSchema, TTable>
28
+ ? TValue
29
+ : never)
30
+ )
31
+ )
32
+ );
33
+
34
+ export type MethodWhereRelations<TSchema extends TablesRelationalConfig, TTable extends TableRelationalConfig> = {
35
+ [TableName in keyof TTable["relations"]as TTable["relations"][TableName]["relationType"] extends "many" ? never : TableName]?: RelationWhere<
36
+ // Table
37
+ TSchema[
38
+ // Table name
39
+ TTable["relations"][TableName & string]["targetTableName"]
40
+ ]
41
+ >;
42
+ };
43
+
44
+ export type RelationWhere<TTable extends TableRelationalConfig> = MethodWhereColumns<TTable>;
45
+
46
+ export type MethodWhereColumns<TTable extends TableRelationalConfig> = {
47
+ [ColumnName in keyof TableColumns<TTable>]?: ColumnValue<TableColumn<ColumnName & string, TTable>>
48
+ };
@@ -0,0 +1,39 @@
1
+ import type { ReturningIdDialects } from "../dialect.ts";
2
+ import type { InferModelFromColumns } from "drizzle-orm/table";
3
+ import type { Column } from "drizzle-orm";
4
+ import type { ModelConfig } from "../config.ts";
5
+ import type { ModelFormatValue } from "../format.ts";
6
+
7
+ // export type GetPrimarySerialOrDefaultKeys<TTable extends TableRelationalConfig, T extends IsDrizzleTable<TTable["table"]>["_"]["columns"] = IsDrizzleTable<TTable["table"]>["_"]["columns"]> = {
8
+ // [K in keyof T]: T[K]['_']['isPrimaryKey'] extends true
9
+ // ? (T[K]['_']['isAutoincrement'] extends true
10
+ // ? K
11
+ // : (T[K]['_']['hasRuntimeDefault'] extends true
12
+ // ? (T[K]['_']['isPrimaryKey'] extends true
13
+ // ? K
14
+ // : never)
15
+ // : never))
16
+ // : ((T[K]['_']['hasRuntimeDefault'] extends true
17
+ // ? (T[K]['_']['isPrimaryKey'] extends true
18
+ // ? K
19
+ // : never)
20
+ // : never));
21
+ // };
22
+
23
+ export type PrimaryKeyKeys<T extends Record<string, Column>> = {
24
+ [K in keyof T]: T[K]['_']['isPrimaryKey'] extends true ? K : never;
25
+ }[keyof T];
26
+
27
+ export type GetPrimarySerialOrDefaultKeys<T extends Record<string, Column>> = {
28
+ [K in PrimaryKeyKeys<T>]: T[K];
29
+ };
30
+
31
+ export type MethodReturnResult<
32
+ TResultType extends string,
33
+ TConfig extends ModelConfig,
34
+ > =
35
+ TConfig["dialect"] extends ReturningIdDialects
36
+ ? InferModelFromColumns<GetPrimarySerialOrDefaultKeys<TConfig["tableColumns"]>>
37
+ : (TResultType extends "many"
38
+ ? ModelFormatValue<TConfig["tableOutput"], TConfig["optionsFormat"]>[]
39
+ : ModelFormatValue<TConfig["tableOutput"], TConfig["optionsFormat"]>);
@@ -0,0 +1,38 @@
1
+ import type { UnwrapArray } from "@/types.ts";
2
+
3
+ export type ResolveMethodSelectValue<
4
+ TValue extends Record<string, any>,
5
+ TResult extends Record<string, any>,
6
+ > = {
7
+ [Key in keyof TValue]: TValue[Key] extends object
8
+ ? TResult[Key & string] extends (infer RItem)[]
9
+ ? RItem extends Record<string, any>
10
+ ? ResolveMethodSelectValue<TValue[Key], RItem>[]
11
+ : never
12
+ : TResult[Key & string] extends Record<string, any>
13
+ ? ResolveMethodSelectValue<TValue[Key], TResult[Key & string]>
14
+ : never
15
+ : TResult[Key & string];
16
+ };
17
+
18
+ export type MethodSelectResult<
19
+ TValue extends Record<string, any>,
20
+ TResult extends Record<string, any> | any[],
21
+ > = TResult extends any[]
22
+ ? TResult extends (infer RItem)[]
23
+ ? RItem extends Record<string, any>
24
+ ? ResolveMethodSelectValue<TValue, RItem>[]
25
+ : ResolveMethodSelectValue<TValue, TResult>[]
26
+ : ResolveMethodSelectValue<TValue, TResult>
27
+ : ResolveMethodSelectValue<TValue, TResult>;
28
+
29
+ export type MethodSelectValue<TResult extends object> =
30
+ TResult extends readonly (infer U)[]
31
+ ? U extends object
32
+ ? MethodSelectValue<U>
33
+ : never
34
+ : {
35
+ [Key in keyof TResult]?: UnwrapArray<TResult[Key]> extends object
36
+ ? MethodSelectValue<UnwrapArray<TResult[Key]>> | boolean
37
+ : boolean;
38
+ };
@@ -0,0 +1,4 @@
1
+ import type { TableRelationalConfig } from "drizzle-orm/relations";
2
+ import type { IsTable, TableInsertValues } from "../table.ts";
3
+
4
+ export type MethodUpdateValue<TTable extends TableRelationalConfig> = Partial<TableInsertValues<IsTable<TTable["table"]>>>;
@@ -0,0 +1,54 @@
1
+ import type { TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relations";
2
+ import type { ModelConfig } from "../config.ts";
3
+ import type { MethodInsertValue } from "./insert.ts";
4
+ import type { MethodUpdateValue } from "./update.ts";
5
+ import type { GetPrimarySerialOrDefaultKeys } from "./return.ts";
6
+ import type { MethodWhereValue } from "./query/where.ts";
7
+ import type { SQL } from "drizzle-orm";
8
+ import type { Column } from "drizzle-orm";
9
+ import type { IsTable } from "../table.ts";
10
+ import type { AddUnionToValues } from "@/types.ts";
11
+
12
+ export type MethodUpsertValue<
13
+ TConfig extends ModelConfig,
14
+ TSchema extends TablesRelationalConfig = TConfig["schema"],
15
+ TTable extends TableRelationalConfig = TConfig["table"]
16
+ > = {
17
+ insert: MethodInsertValue<TTable>;
18
+ update: MethodUpsertUpdate<TTable>;
19
+
20
+ target?:
21
+ | (TConfig["primaryKeys"])
22
+ | (TConfig["primaryKeys"])[]
23
+ | Column
24
+ | Column[];
25
+ updateWhere?: MethodUpsertUpdateWhere<TSchema, TTable>;
26
+ };
27
+
28
+ export type MethodUpsertContext<
29
+ TTable extends TableRelationalConfig,
30
+ TFields extends string = (keyof IsTable<TTable["table"]>["_"]["columns"] & string)
31
+ > = {
32
+ excluded: (field: TFields) => SQL;
33
+ inserted: (field: TFields) => SQL;
34
+ };
35
+
36
+ export type MethodUpsertContextFunction<TTable extends TableRelationalConfig, R> =
37
+ (c: MethodUpsertContext<TTable>) => R;
38
+
39
+ export type MethodUpsertUpdateValue<
40
+ TTable extends TableRelationalConfig,
41
+ > = AddUnionToValues<
42
+ MethodUpdateValue<TTable>,
43
+ SQL
44
+ >;
45
+
46
+ export type MethodUpsertUpdate<
47
+ TTable extends TableRelationalConfig,
48
+ > =
49
+ MethodUpsertUpdateValue<TTable> | MethodUpsertContextFunction<TTable, MethodUpsertUpdateValue<TTable>>;
50
+
51
+ export type MethodUpsertUpdateWhere<
52
+ TSchema extends TablesRelationalConfig,
53
+ TTable extends TableRelationalConfig
54
+ > = MethodUpsertContextFunction<TTable, MethodWhereValue<TSchema, TTable>>;
@@ -0,0 +1,40 @@
1
+ import type {
2
+ FindTargetTableInRelationalConfig,
3
+ RelationsRecord,
4
+ TableRelationalConfig,
5
+ TablesRelationalConfig,
6
+ } from "drizzle-orm/relations";
7
+ import type { ResolveRelationSelection } from "../relation.ts";
8
+
9
+ /**
10
+ * Recursive type structure for defining nested relation selections in the .with() method.
11
+ *
12
+ * It maps relation keys to either a boolean (for simple inclusion) or a nested selection object.
13
+ *
14
+ * @typeParam TSchema - Full relational schema
15
+ * @typeParam TRelations - Record of relations for the current level
16
+ */
17
+ export type MethodWithValue<
18
+ TSchema extends TablesRelationalConfig,
19
+ TRelations extends RelationsRecord,
20
+ > = {
21
+ [Key in keyof TRelations]?:
22
+ | boolean
23
+ | MethodWithValue<
24
+ TSchema,
25
+ FindTargetTableInRelationalConfig<TSchema, TRelations[Key]>["relations"]
26
+ >
27
+ | object;
28
+ };
29
+
30
+ export type MethodWithResult<
31
+ TValue extends Record<string, any>,
32
+ TResult extends Record<string, any>,
33
+ TSchema extends TablesRelationalConfig,
34
+ TTable extends TableRelationalConfig,
35
+ TOutput = ResolveRelationSelection<TValue, TSchema, TTable>,
36
+ > = TResult extends any[]
37
+ ? TResult extends (infer RItem)[]
38
+ ? (TOutput & RItem)[]
39
+ : TOutput & TResult
40
+ : TOutput & TResult;
@@ -0,0 +1,148 @@
1
+ import type {
2
+ TableRelationalConfig,
3
+ TablesRelationalConfig,
4
+ } from "drizzle-orm/relations";
5
+ import type { MethodWithValue } from "./methods/with.ts";
6
+ import type { MethodInsertValue } from "./methods/insert.ts";
7
+ import type { ModelQueryResult, ModelMutateResult } from "./result.ts";
8
+ import type { MethodUpdateValue } from "./methods/update.ts";
9
+ import type { ModelDialect } from "./dialect.ts";
10
+ import type { MethodWhereValue } from "./methods/query/where.ts";
11
+ import type { ComposeModelOptions, ModelOptions, ResolveOptionsFormat, ResolveOptionsMethods } from "./options.ts";
12
+ import type { ModelConfig } from "./config.ts";
13
+ import type { Replace } from "../types.ts";
14
+ import type { MethodUpsertValue } from "./methods/upsert.ts";
15
+
16
+ /**
17
+ * Interface defining standard query methods available on a model.
18
+ *
19
+ * @typeParam TSchema - Full relational schema
20
+ * @typeParam TTable - Relational configuration for the current table
21
+ */
22
+ export interface ModelMethods<
23
+ TConfig extends ModelConfig,
24
+ TSchema extends TablesRelationalConfig = TConfig["schema"],
25
+ TTable extends TableRelationalConfig = TConfig["table"],
26
+ TDialect extends ModelDialect = TConfig["dialect"]
27
+ > {
28
+ /**
29
+ * Fetches all rows for the current model query.
30
+ */
31
+ findMany(): ModelQueryResult<
32
+ TConfig["tableOutput"][],
33
+ TConfig
34
+ >;
35
+ /**
36
+ * Fetches the first matching row for the current model query.
37
+ */
38
+ findFirst(): ModelQueryResult<
39
+ TConfig["tableOutput"],
40
+ TConfig
41
+ >,
42
+
43
+ /**
44
+ * Adds a where clause to the current model query.
45
+ *
46
+ * @param value - Where conditions for the model query
47
+ */
48
+ where(value: MethodWhereValue<TConfig["schema"], TConfig["table"]>): Model<TConfig>;
49
+
50
+ /**
51
+ * Inserts one or many rows into the model table.
52
+ *
53
+ * @param value - Insert payload or batch payload
54
+ */
55
+ insert<TValue extends MethodInsertValue<TTable>>(value: TValue): ModelMutateResult<void, TConfig, TValue extends any[] ? "many" : "one">;
56
+ /**
57
+ * Updates rows that match the current model query.
58
+ *
59
+ * @param value - Update payload
60
+ */
61
+ update<TValue extends MethodUpdateValue<TTable>>(value: TValue): ModelMutateResult<void, TConfig, "many">;
62
+ /**
63
+ * Deletes rows that match the current model query.
64
+ */
65
+ delete(): ModelMutateResult<void, TConfig, "many">;
66
+
67
+ /**
68
+ * Inserts or updates rows based on conflict criteria.
69
+ *
70
+ * @param value - Upsert payload or batch payload
71
+ */
72
+ upsert<TValue extends MethodUpsertValue<TConfig>>(value: TValue): ModelMutateResult<void, TConfig, TValue["insert"] extends any[] ? "many" : "one">;
73
+
74
+ /**
75
+ * Includes related entities in the current model query.
76
+ *
77
+ * @param value - Include configuration for relations
78
+ */
79
+ include<TValue extends MethodWithValue<TSchema, TTable["relations"]>>(
80
+ value: TValue,
81
+ ): TValue;
82
+ }
83
+
84
+ export interface ModelQueryMethods<
85
+ TConfig extends ModelConfig
86
+ > {
87
+ /**
88
+ * Extends the current model with additional options.
89
+ *
90
+ * @param config - Options to merge into the model
91
+ */
92
+ extend<
93
+ TOptions extends ModelOptions<TConfig["schema"], TConfig["table"], TConfig["dialect"]>
94
+ >(config: TOptions): Model<
95
+ Replace<
96
+ TConfig,
97
+ {
98
+ options: ComposeModelOptions<
99
+ TOptions,
100
+ TConfig["options"]
101
+ >;
102
+ }
103
+ >
104
+ >;
105
+
106
+ /**
107
+ * Binds a database client to the model.
108
+ *
109
+ * @param db - Database client instance
110
+ */
111
+ db(db: any): Model<TConfig>;
112
+ }
113
+
114
+ /**
115
+ * Just base represenation of model. This type JUST made for more clearer types, not more...
116
+ */
117
+ export type ModelBase<
118
+ TConfig extends ModelConfig
119
+ > = ModelMethods<TConfig>
120
+ & ModelQueryMethods<TConfig>;
121
+
122
+ /**
123
+ * Main model interface for a table.
124
+ *
125
+ * Each column of the table is exposed as a strongly-typed field setter,
126
+ * allowing type-safe assignment of values when building or mutating models.
127
+ *
128
+ * This type is intended to be extended with query helpers and other
129
+ * model-level utilities.
130
+ *
131
+ * @typeParam TConfig - Config that includes all related information about tables, relations and etc...
132
+ */
133
+ export type Model<
134
+ TConfig extends ModelConfig,
135
+ > = ModelIdentifier<TConfig["table"]["name"]>
136
+ & ModelBase<TConfig>
137
+ & ResolveOptionsMethods<TConfig["options"]["methods"]>
138
+ & {
139
+ $format: TConfig["options"]["format"];
140
+ $formatValue: ResolveOptionsFormat<TConfig["options"]["format"]>;
141
+
142
+ $$config: TConfig;
143
+ };
144
+
145
+ export type ModelIdentifier<ModelName> = {
146
+ $model: "model";
147
+ $modelName: ModelName;
148
+ };
@@ -0,0 +1,64 @@
1
+ import type { TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relations";
2
+ import type { ModelDialect } from "./dialect.ts";
3
+ import type { TableOutput } from "./table.ts";
4
+ import type { Fallback } from "../types.ts";
5
+ import type { MethodWhereValue } from "./methods/query/where.ts";
6
+
7
+ /**
8
+ * Options to define a model
9
+ */
10
+ export interface ModelOptions<
11
+ TSchema extends TablesRelationalConfig = TablesRelationalConfig,
12
+ TTable extends TableRelationalConfig = TableRelationalConfig,
13
+ TDialect extends ModelDialect = ModelDialect,
14
+ TSelf extends ModelOptions<any, any, any, TSelf> = ModelOptions<TSchema, TTable, TDialect, any>
15
+ > {
16
+ format?: ModelOptionFormat<TTable>;
17
+ where?: MethodWhereValue<TSchema, TTable>;
18
+
19
+ // TODO: Make zod schemas
20
+ // insertSchema?: any;
21
+ // updateSchema?: any;
22
+
23
+ // TODO: Maybe planned for future releases
24
+ // select?: MethodSelectValue<TableOutput<TTable>>;
25
+ // exclude?: MethodExcludeValue<TableOutput<TTable>>;
26
+
27
+ methods?: ModelMethodsFactory;
28
+ }
29
+
30
+ export type ComposeModelOptions<
31
+ O1 extends ModelOptions,
32
+ O2 extends ModelOptions
33
+ > = Omit<O1, "format" | "methods"> & {
34
+ format: Fallback<O1["format"], O2["format"]>;
35
+ methods: MergeModelOptionsMethods<O1["methods"], O2["methods"]>;
36
+ };
37
+
38
+ export type ModelOptionFormat<TTable extends TableRelationalConfig> = {
39
+ bivarianceHack(output: TableOutput<TTable>): any;
40
+ }["bivarianceHack"];
41
+ // export type ModelMethodsFactory = {
42
+ // bivarianceHack(): Record<string, any>;
43
+ // }["bivarianceHack"];
44
+ export type ModelMethodsFactory = Record<string, any>;
45
+
46
+ export type ResolveOptionsMethods<TFactory extends ModelMethodsFactory | undefined> =
47
+ (TFactory extends ModelMethodsFactory
48
+ ? TFactory
49
+ : {});
50
+
51
+ export type ResolveOptionsFormat<TFormat> =
52
+ TFormat extends (...args: any[]) => any
53
+ ? ReturnType<TFormat>
54
+ : undefined;
55
+
56
+ export type MergeModelOptionsMethods<
57
+ M1 extends ModelMethodsFactory | undefined,
58
+ M2 extends ModelMethodsFactory | undefined
59
+ > =
60
+ M1 extends ModelMethodsFactory
61
+ ? M2 extends ModelMethodsFactory
62
+ ? Omit<M2, keyof M1> & M1
63
+ : M1
64
+ : M2;
@@ -0,0 +1,170 @@
1
+ import type { Column, SQL } from "drizzle-orm";
2
+
3
+ export type DrizzleColumnDataType<TColumn extends Column> = TColumn["_"]["data"];
4
+
5
+ export type EscapedValue<T> =
6
+ | {
7
+ equal: T;
8
+ }
9
+ | {
10
+ __kind: "esc-op";
11
+ op: {
12
+ bivarianceHack(column: any, value: T): any;
13
+ }["bivarianceHack"];
14
+ value: T;
15
+ };
16
+
17
+ type OpValue<T> = T | SQL | EscapedValue<T>;
18
+
19
+ export type ColumnOpsBase<T> = {
20
+ eq?: OpValue<T>;
21
+ equal?: OpValue<T>;
22
+ not?: OpValue<T>;
23
+ in?: OpValue<T>[];
24
+ nin?: OpValue<T>[];
25
+ isNull?: boolean;
26
+ };
27
+
28
+ export type NumberOps = {
29
+ gt?: OpValue<number>;
30
+ gte?: OpValue<number>;
31
+ lt?: OpValue<number>;
32
+ lte?: OpValue<number>;
33
+ between?: [OpValue<number>, OpValue<number>];
34
+ notBetween?: [OpValue<number>, OpValue<number>];
35
+ };
36
+
37
+ export type StringOps = {
38
+ like?: OpValue<string>;
39
+ ilike?: OpValue<string>;
40
+ startsWith?: OpValue<string>;
41
+ endsWith?: OpValue<string>;
42
+ contains?: OpValue<string>;
43
+ regex?: OpValue<string>;
44
+ notRegex?: OpValue<string>;
45
+ length?: NumberOps;
46
+ };
47
+
48
+ export type BoolOps = {
49
+ isTrue?: boolean;
50
+ isFalse?: boolean;
51
+ };
52
+
53
+ export type DateOps = {
54
+ before?: OpValue<Date | string>;
55
+ after?: OpValue<Date | string>;
56
+ on?: OpValue<Date | string>;
57
+ notOn?: OpValue<Date | string>;
58
+ between?: [OpValue<Date | string>, OpValue<Date | string>];
59
+ };
60
+
61
+ export type JsonOps<T> = {
62
+ has?: T;
63
+ hasAny?: T[];
64
+ hasAll?: T[];
65
+ len?: NumberOps;
66
+ };
67
+
68
+ export type LogicalOps<TColumn extends Column> = {
69
+ or?: ColumnValue<TColumn>[];
70
+ and?: ColumnValue<TColumn>[];
71
+ };
72
+
73
+ export type TypeOps<T> = T extends number
74
+ ? NumberOps
75
+ : T extends string
76
+ ? StringOps
77
+ : T extends boolean
78
+ ? BoolOps
79
+ : T extends Date
80
+ ? DateOps
81
+ : T extends any[]
82
+ ? JsonOps<T[number]>
83
+ : {};
84
+
85
+ export type ColumnOps<
86
+ TColumn extends Column,
87
+ TDataType extends DrizzleColumnDataType<TColumn>,
88
+ > = ColumnOpsBase<TDataType> & TypeOps<TDataType> & LogicalOps<TColumn>;
89
+
90
+ export type ColumnValue<
91
+ TColumn extends Column,
92
+ TDataType extends
93
+ DrizzleColumnDataType<TColumn> = DrizzleColumnDataType<TColumn>,
94
+ > = ColumnOps<TColumn, TDataType> | EscapedValue<TDataType>;
95
+
96
+ /**
97
+ * Escapes a value from the query DSL and forces it to be compiled using
98
+ * a specific comparison operator.
99
+ *
100
+ * This function exists as an explicit escape hatch for cases where:
101
+ * - the default DSL operators are insufficient
102
+ * - Drizzle ORM operators should be used directly
103
+ * - complex types (e.g. Date, objects, custom classes) need safe handling
104
+ *
105
+ * There are two supported forms:
106
+ *
107
+ * 1) Implicit equality (default behavior):
108
+ * ```ts
109
+ * where({ name: esc("Alex") })
110
+ * ```
111
+ * Compiles to:
112
+ * ```ts
113
+ * {
114
+ * eq: "Alex"
115
+ * }
116
+ * // In drizzle: eq(column, "Alex")
117
+ * ```
118
+ *
119
+ * 2) Explicit operator (Drizzle-style):
120
+ * ```ts
121
+ * where({ age: esc(gte, 18) })
122
+ * ```
123
+ * Compiles to:
124
+ * ```ts
125
+ * gte(column, 18)
126
+ * ```
127
+ *
128
+ * The column is injected later during query compilation.
129
+ * `esc` does NOT execute the operator immediately.
130
+ *
131
+ * @typeParam T - The value type being compared against the column
132
+ *
133
+ * @param value - Value to compare using implicit equality
134
+ *
135
+ * @returns An internal escaped descriptor consumed by the query compiler
136
+ */
137
+ export function esc<T>(value: T): EscapedValue<T>;
138
+
139
+ /**
140
+ * Escapes a value from the query DSL and forces it to be compiled using
141
+ * the provided binary operator.
142
+ *
143
+ * This overload allows reuse of Drizzle ORM operators that normally
144
+ * require the column as the first argument.
145
+ *
146
+ * @typeParam T - The value type expected by the operator
147
+ *
148
+ * @param op - A binary comparison operator (e.g. eq, gte, ilike)
149
+ * @param value - Value to pass as the operator's right-hand side
150
+ *
151
+ * @returns An internal escaped descriptor consumed by the query compiler
152
+ */
153
+ export function esc<T>(
154
+ op: (column: any, value: T) => any,
155
+ value: T
156
+ ): EscapedValue<T>;
157
+
158
+ export function esc<T>(arg1: any, arg2?: any): EscapedValue<T> {
159
+ if (typeof arg1 === "function") {
160
+ return {
161
+ __kind: "esc-op",
162
+ op: arg1 as (column: any, value: T) => any,
163
+ value: arg2 as T,
164
+ };
165
+ }
166
+
167
+ return {
168
+ equal: arg1,
169
+ };
170
+ }