@apisr/drizzle-model 2.0.2 → 2.0.3

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.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CockroachDbDialect, ModelDialect, MssqlDialect, MySqlDialect, PgDialect, ReturningIdDialects, SingleStoreDialect, SqlLiteDialect, UnknownDialect } from "./model/dialect.mjs";
2
- import { AddToValues, AddUnionToValues, Compose, Fallback, RecursiveBooleanRecord, Replace, UnwrapArray } from "./types.mjs";
2
+ import { AddToValues, AddUnionToValues, ApplyArrayIf, ApplyArrayIfArray, Compose, Fallback, InferArrayItem, MergeExclusive, RecursiveBooleanRecord, Replace, Simplify, UnwrapArray } from "./types.mjs";
3
3
  import { IsTable, NormalizeTable, TableColumn, TableColumns, TableInsertModel, TableInsertValues, TableOneRelationsTableName, TableOutput, TableRelationsTableName } from "./model/table.mjs";
4
4
  import { MethodInsertValue, MethodWithInsertValue } from "./model/methods/insert.mjs";
5
5
  import { MethodUpdateValue } from "./model/methods/update.mjs";
@@ -7,11 +7,11 @@ import { MethodUpsertContext, MethodUpsertContextFunction, MethodUpsertUpdate, M
7
7
  import { ApplyRelationCardinality, RelationKind, RelationMeta, RelationTargetRow, ResolveRelationSelection, ResolveSingleRelation, TargetTable } from "./model/relation.mjs";
8
8
  import { MethodWithResult, MethodWithValue } from "./model/methods/with.mjs";
9
9
  import { ComposeModelOptions, MergeModelOptionsMethods, ModelMethodsFactory, ModelOptionFormat, ModelOptions, ResolveOptionsFormat, ResolveOptionsMethods } from "./model/options.mjs";
10
- import { ModelFormatValue } from "./model/format.mjs";
10
+ import { ModelFormatResult, ResolveFormatCustomFields } from "./model/format.mjs";
11
11
  import { MethodSelectResult, MethodSelectValue, ResolveMethodSelectValue } from "./model/methods/select.mjs";
12
12
  import { MethodExcludeResult, MethodExcludeValue, ResolveMethodExcludeValue } from "./model/methods/exclude.mjs";
13
13
  import { GetPrimarySerialOrDefaultKeys, MethodReturnResult, PrimaryKeyKeys } from "./model/methods/return.mjs";
14
- import { ModelMutateResult, ModelQueryResult } from "./model/result.mjs";
14
+ import { ApplySafeResultIf, ModelInMutableResult, ModelMutateResult, ModelQueryResult, SafeResult } from "./model/result.mjs";
15
15
  import { Model, ModelBase, ModelIdentifier, ModelMethods, ModelQueryMethods } from "./model/model.mjs";
16
16
  import { BoolOps, ColumnOps, ColumnOpsBase, ColumnValue, DateOps, DrizzleColumnDataType, EscapedValue, JsonOps, LogicalOps, NumberOps, StringOps, TypeOps, esc } from "./model/query/operations.mjs";
17
17
  import { MethodIncludeIdentifier } from "./model/methods/include.mjs";
@@ -22,4 +22,4 @@ import { ModelForegins } from "./model/foreigns.mjs";
22
22
  import { ModelFirstLevelMethods, ModelLevelMethods } from "./model/methods/levels.mjs";
23
23
  import { ModelShape } from "./model/shape.mjs";
24
24
  import "./model/index.mjs";
25
- export { AddToValues, AddUnionToValues, ApplyRelationCardinality, BoolOps, CockroachDbDialect, ColumnOps, ColumnOpsBase, ColumnValue, Compose, ComposeModelOptions, DateOps, DrizzleColumnDataType, EscapedValue, Fallback, GetPrimarySerialOrDefaultKeys, IsTable, JsonOps, LogicalOps, MergeModelOptionsMethods, MethodExcludeResult, MethodExcludeValue, MethodIncludeIdentifier, MethodInsertValue, MethodReturnResult, MethodSelectResult, MethodSelectValue, MethodUpdateValue, MethodUpsertContext, MethodUpsertContextFunction, MethodUpsertUpdate, MethodUpsertUpdateValue, MethodUpsertUpdateWhere, MethodUpsertValue, MethodWhereColumns, MethodWhereRelations, MethodWhereValue, MethodWithInsertValue, MethodWithResult, MethodWithValue, Model, ModelBase, ModelConfig, ModelDialect, ModelFirstLevelMethods, ModelForegins, ModelFormatValue, ModelIdentifier, ModelLevelMethods, ModelMethods, ModelMethodsFactory, ModelMutateResult, ModelOptionFormat, ModelOptions, ModelQueryMethods, ModelQueryResult, ModelShape, MssqlDialect, MySqlDialect, NormalizeTable, NumberOps, PgDialect, PrimaryKeyKeys, RecursiveBooleanRecord, RelationKind, RelationMeta, RelationTargetRow, RelationWhere, Replace, ResolveMethodExcludeValue, ResolveMethodSelectValue, ResolveOptionsFormat, ResolveOptionsMethods, ResolveRelationSelection, ResolveSingleRelation, ReturningIdDialects, SingleStoreDialect, SqlLiteDialect, StringOps, TableColumn, TableColumns, TableInsertModel, TableInsertValues, TableOneRelationsTableName, TableOutput, TableRelationsTableName, TargetTable, TypeOps, UnknownDialect, UnwrapArray, esc, modelBuilder };
25
+ export { AddToValues, AddUnionToValues, ApplyArrayIf, ApplyArrayIfArray, ApplyRelationCardinality, ApplySafeResultIf, BoolOps, CockroachDbDialect, ColumnOps, ColumnOpsBase, ColumnValue, Compose, ComposeModelOptions, DateOps, DrizzleColumnDataType, EscapedValue, Fallback, GetPrimarySerialOrDefaultKeys, InferArrayItem, IsTable, JsonOps, LogicalOps, MergeExclusive, MergeModelOptionsMethods, MethodExcludeResult, MethodExcludeValue, MethodIncludeIdentifier, MethodInsertValue, MethodReturnResult, MethodSelectResult, MethodSelectValue, MethodUpdateValue, MethodUpsertContext, MethodUpsertContextFunction, MethodUpsertUpdate, MethodUpsertUpdateValue, MethodUpsertUpdateWhere, MethodUpsertValue, MethodWhereColumns, MethodWhereRelations, MethodWhereValue, MethodWithInsertValue, MethodWithResult, MethodWithValue, Model, ModelBase, ModelConfig, ModelDialect, ModelFirstLevelMethods, ModelForegins, ModelFormatResult, ModelIdentifier, ModelInMutableResult, ModelLevelMethods, ModelMethods, ModelMethodsFactory, ModelMutateResult, ModelOptionFormat, ModelOptions, ModelQueryMethods, ModelQueryResult, ModelShape, MssqlDialect, MySqlDialect, NormalizeTable, NumberOps, PgDialect, PrimaryKeyKeys, RecursiveBooleanRecord, RelationKind, RelationMeta, RelationTargetRow, RelationWhere, Replace, ResolveFormatCustomFields, ResolveMethodExcludeValue, ResolveMethodSelectValue, ResolveOptionsFormat, ResolveOptionsMethods, ResolveRelationSelection, ResolveSingleRelation, ReturningIdDialects, SafeResult, Simplify, SingleStoreDialect, SqlLiteDialect, StringOps, TableColumn, TableColumns, TableInsertModel, TableInsertValues, TableOneRelationsTableName, TableOutput, TableRelationsTableName, TargetTable, TypeOps, UnknownDialect, UnwrapArray, esc, modelBuilder };
@@ -1,9 +1,9 @@
1
- import { makeModelRuntime } from "./core/runtime.mjs";
1
+ import { ModelRuntime } from "../core/runtime.mjs";
2
2
 
3
3
  //#region src/model/builder.ts
4
4
  function modelBuilder({ db, relations, schema, dialect }) {
5
5
  return (table, options) => {
6
- return makeModelRuntime({
6
+ const runtime = new ModelRuntime({
7
7
  db,
8
8
  relations,
9
9
  schema,
@@ -11,6 +11,26 @@ function modelBuilder({ db, relations, schema, dialect }) {
11
11
  dialect,
12
12
  options: options ?? {}
13
13
  });
14
+ const target = {};
15
+ for (const key of Object.getOwnPropertyNames(Object.getPrototypeOf(runtime))) {
16
+ if (key === "constructor") continue;
17
+ const value = runtime[key];
18
+ if (typeof value === "function") target[key] = value.bind(runtime);
19
+ }
20
+ Object.defineProperty(target, "$model", {
21
+ get: () => runtime.$model,
22
+ enumerable: true
23
+ });
24
+ Object.defineProperty(target, "$modelName", {
25
+ get: () => runtime.$modelName,
26
+ enumerable: true
27
+ });
28
+ Object.defineProperty(target, "$format", {
29
+ get: () => runtime.$format,
30
+ enumerable: true
31
+ });
32
+ runtime.attachMethods(target);
33
+ return target;
14
34
  };
15
35
  }
16
36
 
@@ -7,17 +7,17 @@ import { MethodWhereValue } from "./methods/query/where.mjs";
7
7
  import { TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relations";
8
8
 
9
9
  //#region src/model/config.d.ts
10
- type ModelConfig<TSchema extends TablesRelationalConfig = TablesRelationalConfig, TTable extends TableRelationalConfig = TableRelationalConfig, TDialect extends ModelDialect = ModelDialect, TOptions extends ModelOptions<any> = ModelOptions<any>> = {
11
- schema: TSchema;
12
- table: TTable;
10
+ interface ModelConfig<TSchema extends TablesRelationalConfig = TablesRelationalConfig, TTable extends TableRelationalConfig = TableRelationalConfig, TDialect extends ModelDialect = ModelDialect, TOptions extends ModelOptions<any> = ModelOptions<any>> {
13
11
  dialect: TDialect;
14
12
  options: TOptions;
15
- tableOutput: TableOutput<TTable>;
16
- tableColumns: IsTable<TTable["table"]>["_"]["columns"];
17
13
  optionsFormat: ResolveOptionsFormat<TOptions["format"]>;
18
14
  primaryKeys: keyof GetPrimarySerialOrDefaultKeys<IsTable<TTable["table"]>["_"]["columns"]>;
19
15
  primaryKeysWithDataType: { [TKey in keyof GetPrimarySerialOrDefaultKeys<IsTable<TTable["table"]>["_"]["columns"]>]: DrizzleColumnDataType<IsTable<TTable["table"]>["_"]["columns"][TKey]> };
16
+ schema: TSchema;
17
+ table: TTable;
18
+ tableColumns: IsTable<TTable["table"]>["_"]["columns"];
19
+ tableOutput: TableOutput<TTable>;
20
20
  whereValue: MethodWhereValue<TSchema, TTable>;
21
- };
21
+ }
22
22
  //#endregion
23
23
  export { ModelConfig };
@@ -1,4 +1,8 @@
1
+ import { TableRelationalConfig } from "drizzle-orm/relations";
2
+ import { TableColumns } from "dist/index.mjs";
3
+
1
4
  //#region src/model/format.d.ts
2
- type ModelFormatValue<TValue extends Record<string, any>, TFormat extends Record<string, any> | undefined> = TFormat extends undefined ? TValue : TValue extends (infer TItem)[] ? TItem extends Record<string, any> ? ModelFormatValue<TItem, TFormat>[] : TValue : Omit<TValue, keyof TFormat> & TFormat;
5
+ type ModelFormatResult<TResult extends Record<string, any>, TFormat extends Record<string, any> | undefined, TTable extends TableRelationalConfig> = TFormat extends undefined ? TResult : Pick<TResult, keyof TFormat & string> & ResolveFormatCustomFields<Exclude<TFormat, undefined>, TTable>;
6
+ type ResolveFormatCustomFields<TFormat extends Record<string, any>, TTable extends TableRelationalConfig> = { [TKey in keyof TFormat as TableColumns<TTable>[TKey & string] extends never ? never : TKey & string]: TFormat[TKey & string] };
3
7
  //#endregion
4
- export { ModelFormatValue };
8
+ export { ModelFormatResult, ResolveFormatCustomFields };
@@ -6,11 +6,11 @@ import { MethodUpsertContext, MethodUpsertContextFunction, MethodUpsertUpdate, M
6
6
  import { ApplyRelationCardinality, RelationKind, RelationMeta, RelationTargetRow, ResolveRelationSelection, ResolveSingleRelation, TargetTable } from "./relation.mjs";
7
7
  import { MethodWithResult, MethodWithValue } from "./methods/with.mjs";
8
8
  import { ComposeModelOptions, MergeModelOptionsMethods, ModelMethodsFactory, ModelOptionFormat, ModelOptions, ResolveOptionsFormat, ResolveOptionsMethods } from "./options.mjs";
9
- import { ModelFormatValue } from "./format.mjs";
9
+ import { ModelFormatResult, ResolveFormatCustomFields } from "./format.mjs";
10
10
  import { MethodSelectResult, MethodSelectValue, ResolveMethodSelectValue } from "./methods/select.mjs";
11
11
  import { MethodExcludeResult, MethodExcludeValue, ResolveMethodExcludeValue } from "./methods/exclude.mjs";
12
12
  import { GetPrimarySerialOrDefaultKeys, MethodReturnResult, PrimaryKeyKeys } from "./methods/return.mjs";
13
- import { ModelMutateResult, ModelQueryResult } from "./result.mjs";
13
+ import { ApplySafeResultIf, ModelInMutableResult, ModelMutateResult, ModelQueryResult, SafeResult } from "./result.mjs";
14
14
  import { Model, ModelBase, ModelIdentifier, ModelMethods, ModelQueryMethods } from "./model.mjs";
15
15
  import { BoolOps, ColumnOps, ColumnOpsBase, ColumnValue, DateOps, DrizzleColumnDataType, EscapedValue, JsonOps, LogicalOps, NumberOps, StringOps, TypeOps, esc } from "./query/operations.mjs";
16
16
  import { MethodIncludeIdentifier } from "./methods/include.mjs";
@@ -2,7 +2,7 @@ import { MethodSelectValue } from "./select.mjs";
2
2
 
3
3
  //#region src/model/methods/exclude.d.ts
4
4
  type ResolveMethodExcludeValue<TValue extends Record<string, any>, TResult extends Record<string, any>> = { [Key in keyof TResult as TValue[Key & string] extends true ? never : Key]: TValue[Key & string] extends object ? TResult[Key & string] extends (infer RItem)[] ? RItem extends Record<string, any> ? ResolveMethodExcludeValue<TValue[Key & string], RItem>[] : never : TResult[Key & string] extends Record<string, any> ? ResolveMethodExcludeValue<TValue[Key & string], TResult[Key & string]> : never : TResult[Key & string] };
5
- type MethodExcludeResult<TValue extends Record<string, any>, TResult extends Record<string, any>> = TResult extends any[] ? TResult extends (infer RItem)[] ? RItem extends Record<string, any> ? ResolveMethodExcludeValue<TValue, RItem>[] : ResolveMethodExcludeValue<TValue, TResult>[] : ResolveMethodExcludeValue<TValue, TResult> : ResolveMethodExcludeValue<TValue, TResult>;
5
+ type MethodExcludeResult<TValue extends Record<string, any>, TResult extends Record<string, any>> = ResolveMethodExcludeValue<TValue, TResult>;
6
6
  type MethodExcludeValue<TResult extends Record<string, any>> = MethodSelectValue<TResult>;
7
7
  //#endregion
8
8
  export { MethodExcludeResult, MethodExcludeValue, ResolveMethodExcludeValue };
@@ -1,5 +1,5 @@
1
1
  import { ReturningIdDialects } from "../dialect.mjs";
2
- import { ModelFormatValue } from "../format.mjs";
2
+ import { ModelFormatResult } from "../format.mjs";
3
3
  import { ModelConfig } from "../config.mjs";
4
4
  import { Column } from "drizzle-orm";
5
5
  import { InferModelFromColumns } from "drizzle-orm/table";
@@ -7,6 +7,6 @@ import { InferModelFromColumns } from "drizzle-orm/table";
7
7
  //#region src/model/methods/return.d.ts
8
8
  type PrimaryKeyKeys<T extends Record<string, Column>> = { [K in keyof T]: T[K]["_"]["isPrimaryKey"] extends true ? K : never }[keyof T];
9
9
  type GetPrimarySerialOrDefaultKeys<T extends Record<string, Column>> = { [K in PrimaryKeyKeys<T>]: T[K] };
10
- type MethodReturnResult<TResultType extends string, TConfig extends ModelConfig> = TConfig["dialect"] extends ReturningIdDialects ? InferModelFromColumns<GetPrimarySerialOrDefaultKeys<TConfig["tableColumns"]>> : TResultType extends "many" ? ModelFormatValue<TConfig["tableOutput"], TConfig["optionsFormat"]>[] : ModelFormatValue<TConfig["tableOutput"], TConfig["optionsFormat"]>;
10
+ type MethodReturnResult<TConfig extends ModelConfig> = TConfig["dialect"] extends ReturningIdDialects ? InferModelFromColumns<GetPrimarySerialOrDefaultKeys<TConfig["tableColumns"]>> : ModelFormatResult<TConfig["tableOutput"], TConfig["optionsFormat"], TConfig["table"]>;
11
11
  //#endregion
12
12
  export { GetPrimarySerialOrDefaultKeys, MethodReturnResult, PrimaryKeyKeys };
@@ -2,7 +2,7 @@ import { UnwrapArray } from "../../types.mjs";
2
2
 
3
3
  //#region src/model/methods/select.d.ts
4
4
  type ResolveMethodSelectValue<TValue extends Record<string, any>, TResult extends Record<string, any>> = { [Key in keyof TValue]: TValue[Key] extends object ? TResult[Key & string] extends (infer RItem)[] ? RItem extends Record<string, any> ? ResolveMethodSelectValue<TValue[Key], RItem>[] : never : TResult[Key & string] extends Record<string, any> ? ResolveMethodSelectValue<TValue[Key], TResult[Key & string]> : never : TResult[Key & string] };
5
- type MethodSelectResult<TValue extends Record<string, any>, TResult extends Record<string, any> | any[]> = TResult extends any[] ? TResult extends (infer RItem)[] ? RItem extends Record<string, any> ? ResolveMethodSelectValue<TValue, RItem>[] : ResolveMethodSelectValue<TValue, TResult>[] : ResolveMethodSelectValue<TValue, TResult> : ResolveMethodSelectValue<TValue, TResult>;
5
+ type MethodSelectResult<TValue extends Record<string, any>, TResult extends Record<string, any>> = ResolveMethodSelectValue<TValue, TResult>;
6
6
  type MethodSelectValue<TResult extends object> = TResult extends readonly (infer U)[] ? U extends object ? MethodSelectValue<U> : never : { [Key in keyof TResult]?: UnwrapArray<TResult[Key]> extends object ? MethodSelectValue<UnwrapArray<TResult[Key]>> | boolean : boolean };
7
7
  //#endregion
8
8
  export { MethodSelectResult, MethodSelectValue, ResolveMethodSelectValue };
@@ -1,11 +1,10 @@
1
- import { ModelDialect } from "./dialect.mjs";
2
1
  import { Replace } from "../types.mjs";
3
2
  import { MethodInsertValue } from "./methods/insert.mjs";
4
3
  import { MethodUpdateValue } from "./methods/update.mjs";
5
4
  import { MethodUpsertValue } from "./methods/upsert.mjs";
6
5
  import { MethodWithValue } from "./methods/with.mjs";
7
- import { ComposeModelOptions, ModelOptions, ResolveOptionsFormat, ResolveOptionsMethods } from "./options.mjs";
8
- import { ModelMutateResult, ModelQueryResult } from "./result.mjs";
6
+ import { ComposeModelOptions, ModelOptions, ResolveOptionsMethods } from "./options.mjs";
7
+ import { ModelInMutableResult, ModelQueryResult } from "./result.mjs";
9
8
  import { MethodWhereValue } from "./methods/query/where.mjs";
10
9
  import { ModelConfig } from "./config.mjs";
11
10
  import { TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relations";
@@ -17,11 +16,12 @@ import { TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relat
17
16
  * @typeParam TSchema - Full relational schema
18
17
  * @typeParam TTable - Relational configuration for the current table
19
18
  */
20
- interface ModelMethods<TConfig extends ModelConfig, TSchema extends TablesRelationalConfig = TConfig["schema"], TTable extends TableRelationalConfig = TConfig["table"], TDialect extends ModelDialect = TConfig["dialect"]> {
19
+ interface ModelMethods<TConfig extends ModelConfig, TSchema extends TablesRelationalConfig = TConfig["schema"], TTable extends TableRelationalConfig = TConfig["table"]> {
20
+ count(): Promise<number>;
21
21
  /**
22
22
  * Deletes rows that match the current model query.
23
23
  */
24
- delete(): ModelMutateResult<void, TConfig, "many">;
24
+ delete(): ModelInMutableResult<never, TConfig>;
25
25
  /**
26
26
  * Fetches the first matching row for the current model query.
27
27
  */
@@ -41,19 +41,19 @@ interface ModelMethods<TConfig extends ModelConfig, TSchema extends TablesRelati
41
41
  *
42
42
  * @param value - Insert payload or batch payload
43
43
  */
44
- insert<TValue extends MethodInsertValue<TTable>>(value: TValue): ModelMutateResult<void, TConfig, TValue extends any[] ? "many" : "one">;
44
+ insert<TValue extends MethodInsertValue<TTable>>(value: TValue): ModelInMutableResult<never, TConfig>;
45
45
  /**
46
46
  * Updates rows that match the current model query.
47
47
  *
48
48
  * @param value - Update payload
49
49
  */
50
- update<TValue extends MethodUpdateValue<TTable>>(value: TValue): ModelMutateResult<void, TConfig, "many">;
50
+ update<TValue extends MethodUpdateValue<TTable>>(value: TValue): ModelInMutableResult<never, TConfig>;
51
51
  /**
52
52
  * Inserts or updates rows based on conflict criteria.
53
53
  *
54
54
  * @param value - Upsert payload or batch payload
55
55
  */
56
- upsert<TValue extends MethodUpsertValue<TConfig>>(value: TValue): ModelMutateResult<void, TConfig, TValue["insert"] extends any[] ? "many" : "one">;
56
+ upsert<TValue extends MethodUpsertValue<TConfig>>(value: TValue): ModelInMutableResult<never, TConfig>;
57
57
  /**
58
58
  * Adds a where clause to the current model query.
59
59
  *
@@ -93,13 +93,11 @@ type ModelBase<TConfig extends ModelConfig> = ModelMethods<TConfig> & ModelQuery
93
93
  * @typeParam TConfig - Config that includes all related information about tables, relations and etc...
94
94
  */
95
95
  type Model<TConfig extends ModelConfig> = ModelIdentifier<TConfig["table"]["name"]> & ModelBase<TConfig> & ResolveOptionsMethods<TConfig["options"]["methods"]> & {
96
- $format: TConfig["options"]["format"];
97
- $formatValue: ResolveOptionsFormat<TConfig["options"]["format"]>;
98
96
  $$config: TConfig;
99
97
  };
100
- type ModelIdentifier<ModelName> = {
98
+ interface ModelIdentifier<ModelName> {
101
99
  $model: "model";
102
100
  $modelName: ModelName;
103
- };
101
+ }
104
102
  //#endregion
105
103
  export { Model, ModelBase, ModelIdentifier, ModelMethods, ModelQueryMethods };
@@ -0,0 +1,4 @@
1
+ //#region src/model/query/error.d.ts
2
+ interface QueryError extends Error {}
3
+ //#endregion
4
+ export { QueryError };
@@ -12,53 +12,53 @@ type EscapedValue<T> = {
12
12
  value: T;
13
13
  };
14
14
  type OpValue<T> = T | SQL | EscapedValue<T>;
15
- type ColumnOpsBase<T> = {
15
+ interface ColumnOpsBase<T> {
16
16
  eq?: OpValue<T>;
17
17
  equal?: OpValue<T>;
18
- not?: OpValue<T>;
19
18
  in?: OpValue<T>[];
20
- nin?: OpValue<T>[];
21
19
  isNull?: boolean;
22
- };
23
- type NumberOps = {
20
+ nin?: OpValue<T>[];
21
+ not?: OpValue<T>;
22
+ }
23
+ interface NumberOps {
24
+ between?: [OpValue<number>, OpValue<number>];
24
25
  gt?: OpValue<number>;
25
26
  gte?: OpValue<number>;
26
27
  lt?: OpValue<number>;
27
28
  lte?: OpValue<number>;
28
- between?: [OpValue<number>, OpValue<number>];
29
29
  notBetween?: [OpValue<number>, OpValue<number>];
30
- };
31
- type StringOps = {
32
- like?: OpValue<string>;
33
- ilike?: OpValue<string>;
34
- startsWith?: OpValue<string>;
35
- endsWith?: OpValue<string>;
30
+ }
31
+ interface StringOps {
36
32
  contains?: OpValue<string>;
37
- regex?: OpValue<string>;
38
- notRegex?: OpValue<string>;
33
+ endsWith?: OpValue<string>;
34
+ ilike?: OpValue<string>;
39
35
  length?: NumberOps;
40
- };
41
- type BoolOps = {
42
- isTrue?: boolean;
36
+ like?: OpValue<string>;
37
+ notRegex?: OpValue<string>;
38
+ regex?: OpValue<string>;
39
+ startsWith?: OpValue<string>;
40
+ }
41
+ interface BoolOps {
43
42
  isFalse?: boolean;
44
- };
45
- type DateOps = {
46
- before?: OpValue<Date | string>;
43
+ isTrue?: boolean;
44
+ }
45
+ interface DateOps {
47
46
  after?: OpValue<Date | string>;
48
- on?: OpValue<Date | string>;
49
- notOn?: OpValue<Date | string>;
47
+ before?: OpValue<Date | string>;
50
48
  between?: [OpValue<Date | string>, OpValue<Date | string>];
51
- };
52
- type JsonOps<T> = {
49
+ notOn?: OpValue<Date | string>;
50
+ on?: OpValue<Date | string>;
51
+ }
52
+ interface JsonOps<T> {
53
53
  has?: T;
54
- hasAny?: T[];
55
54
  hasAll?: T[];
55
+ hasAny?: T[];
56
56
  len?: NumberOps;
57
- };
58
- type LogicalOps<TColumn extends Column> = {
59
- or?: ColumnValue<TColumn>[];
57
+ }
58
+ interface LogicalOps<TColumn extends Column> {
60
59
  and?: ColumnValue<TColumn>[];
61
- };
60
+ or?: ColumnValue<TColumn>[];
61
+ }
62
62
  type TypeOps<T> = T extends number ? NumberOps : T extends string ? StringOps : T extends boolean ? BoolOps : T extends Date ? DateOps : T extends any[] ? JsonOps<T[number]> : {};
63
63
  type ColumnOps<TColumn extends Column, TDataType extends DrizzleColumnDataType<TColumn>> = ColumnOpsBase<TDataType> & TypeOps<TDataType> & LogicalOps<TColumn>;
64
64
  type ColumnValue<TColumn extends Column, TDataType extends DrizzleColumnDataType<TColumn> = DrizzleColumnDataType<TColumn>> = ColumnOps<TColumn, TDataType> | EscapedValue<TDataType>;
@@ -71,29 +71,40 @@ type ColumnValue<TColumn extends Column, TDataType extends DrizzleColumnDataType
71
71
  * - Drizzle ORM operators should be used directly
72
72
  * - complex types (e.g. Date, objects, custom classes) need safe handling
73
73
  *
74
- * There are two supported forms:
74
+ * There are three supported forms:
75
75
  *
76
76
  * 1) Implicit equality (default behavior):
77
77
  * ```ts
78
78
  * where({ name: esc("Alex") })
79
79
  * ```
80
- * Compiles to:
81
- * ```ts
82
- * {
83
- * eq: "Alex"
84
- * }
85
- * // In drizzle: eq(column, "Alex")
86
- * ```
87
80
  *
88
81
  * 2) Explicit operator (Drizzle-style):
89
82
  * ```ts
90
83
  * where({ age: esc(gte, 18) })
91
84
  * ```
92
- * Compiles to:
85
+ *
86
+ * 3) Chainable operator methods (recommended):
93
87
  * ```ts
94
- * gte(column, 18)
88
+ * where({ name: esc.like("%Alex%") })
89
+ * where({ age: esc.gte(18) })
90
+ * where({ status: esc.in(["active", "pending"]) })
91
+ * where({ price: esc.between(10, 100) })
95
92
  * ```
96
93
  *
94
+ * Available chainable methods:
95
+ * - `esc.eq(value)` — equality
96
+ * - `esc.not(value)` — inequality
97
+ * - `esc.gt(value)` — greater than
98
+ * - `esc.gte(value)` — greater than or equal
99
+ * - `esc.lt(value)` — less than
100
+ * - `esc.lte(value)` — less than or equal
101
+ * - `esc.like(pattern)` — SQL LIKE pattern matching
102
+ * - `esc.ilike(pattern)` — case-insensitive LIKE
103
+ * - `esc.in(values)` — value in array
104
+ * - `esc.nin(values)` — value not in array
105
+ * - `esc.between(min, max)` — value between range
106
+ * - `esc.notBetween(min, max)` — value not between range
107
+ *
97
108
  * The column is injected later during query compilation.
98
109
  * `esc` does NOT execute the operator immediately.
99
110
  *
@@ -119,5 +130,44 @@ declare function esc<T>(value: T): EscapedValue<T>;
119
130
  * @returns An internal escaped descriptor consumed by the query compiler
120
131
  */
121
132
  declare function esc<T>(op: (column: any, value: T) => any, value: T): EscapedValue<T>;
133
+ declare namespace esc {
134
+ export var eq: <T>(value: T) => {
135
+ eq: T;
136
+ };
137
+ export var not: <T>(value: T) => {
138
+ not: T;
139
+ };
140
+ export var gt: <T>(value: T) => {
141
+ gt: T;
142
+ };
143
+ export var gte: <T>(value: T) => {
144
+ gte: T;
145
+ };
146
+ export var lt: <T>(value: T) => {
147
+ lt: T;
148
+ };
149
+ export var lte: <T>(value: T) => {
150
+ lte: T;
151
+ };
152
+ export var like: (pattern: string) => {
153
+ like: string;
154
+ };
155
+ export var ilike: (pattern: string) => {
156
+ ilike: string;
157
+ };
158
+ var _a: <T>(values: T[]) => {
159
+ in: T[];
160
+ };
161
+ export var nin: <T>(values: T[]) => {
162
+ nin: T[];
163
+ };
164
+ export var between: <T>(min: T, max: T) => {
165
+ between: [T, T];
166
+ };
167
+ export var notBetween: <T>(min: T, max: T) => {
168
+ notBetween: [T, T];
169
+ };
170
+ export { _a as in };
171
+ }
122
172
  //#endregion
123
173
  export { BoolOps, ColumnOps, ColumnOpsBase, ColumnValue, DateOps, DrizzleColumnDataType, EscapedValue, JsonOps, LogicalOps, NumberOps, StringOps, TypeOps, esc };
@@ -7,6 +7,18 @@ function esc(arg1, arg2) {
7
7
  };
8
8
  return { equal: arg1 };
9
9
  }
10
+ esc.eq = (value) => ({ eq: value });
11
+ esc.not = (value) => ({ not: value });
12
+ esc.gt = (value) => ({ gt: value });
13
+ esc.gte = (value) => ({ gte: value });
14
+ esc.lt = (value) => ({ lt: value });
15
+ esc.lte = (value) => ({ lte: value });
16
+ esc.like = (pattern) => ({ like: pattern });
17
+ esc.ilike = (pattern) => ({ ilike: pattern });
18
+ esc.in = (values) => ({ in: values });
19
+ esc.nin = (values) => ({ nin: values });
20
+ esc.between = (min, max) => ({ between: [min, max] });
21
+ esc.notBetween = (min, max) => ({ notBetween: [min, max] });
10
22
 
11
23
  //#endregion
12
24
  export { esc };
@@ -1,13 +1,15 @@
1
1
  import { ReturningIdDialects } from "./dialect.mjs";
2
- import { TableOutput } from "./table.mjs";
2
+ import { ApplyArrayIfArray, InferArrayItem, MergeExclusive, Simplify } from "../types.mjs";
3
3
  import { MethodWithResult, MethodWithValue } from "./methods/with.mjs";
4
4
  import { ResolveOptionsFormat } from "./options.mjs";
5
- import { ModelFormatValue } from "./format.mjs";
5
+ import { ModelFormatResult } from "./format.mjs";
6
6
  import { MethodSelectResult, MethodSelectValue } from "./methods/select.mjs";
7
7
  import { MethodExcludeResult, MethodExcludeValue } from "./methods/exclude.mjs";
8
8
  import { MethodReturnResult } from "./methods/return.mjs";
9
+ import { QueryError } from "./query/error.mjs";
9
10
  import { ModelConfig } from "./config.mjs";
10
11
  import { TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relations";
12
+ import { SimplifyDeep } from "type-fest";
11
13
 
12
14
  //#region src/model/result.d.ts
13
15
  /**
@@ -20,15 +22,29 @@ import { TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm/relat
20
22
  * @typeParam TSchema - Full relational schema
21
23
  * @typeParam TTable - Relational configuration for the current table
22
24
  */
23
- interface ModelQueryResult<TResult extends Record<string, any>, TConfig extends ModelConfig, TExcludedKeys extends string = string, TSchema extends TablesRelationalConfig = TConfig["schema"], TTable extends TableRelationalConfig = TConfig["table"], TFormat extends Record<string, any> | undefined = ResolveOptionsFormat<TConfig["options"]["format"]>> extends Promise<ModelFormatValue<TResult, TFormat>> {
25
+ interface ModelQueryResult<TResult extends Record<string, any> | any[], TConfig extends ModelConfig, TExcludedKeys extends string = string, TSchema extends TablesRelationalConfig = TConfig["schema"], TTable extends TableRelationalConfig = TConfig["table"], TFormat extends Record<string, any> | undefined = ResolveOptionsFormat<TConfig["options"]["format"]>, TWithSafe extends true | false = false> extends Promise<ApplySafeResultIf<TWithSafe, ApplyArrayIfArray<TResult, SimplifyDeep<ModelFormatResult<InferArrayItem<TResult>, TFormat, TTable>>>>> {
26
+ $format: TFormat;
24
27
  debug(): any;
25
- exclude<TValue extends MethodExcludeValue<TResult>, TExcludeKeys extends string = TExcludedKeys | "exclude">(value: TValue): ModelQueryResult<MethodExcludeResult<TValue, TResult>, TConfig, TExcludeKeys>;
26
- raw<TExcludeKeys extends string = TExcludedKeys | "raw">(): ModelQueryResult<TResult, TConfig, TExcludeKeys, TSchema, TTable, undefined>;
27
- select<TValue extends MethodSelectValue<TResult>, TExcludeKeys extends string = TExcludedKeys | "select">(value: TValue): ModelQueryResult<MethodSelectResult<TValue, TResult>, TConfig, TExcludeKeys>;
28
- with<TValue extends MethodWithValue<TSchema, TTable["relations"]>, TExcludeKeys extends string = TExcludedKeys | "with">(value: TValue): ModelQueryResult<MethodWithResult<TValue, TResult, TSchema, TTable>, TConfig, TExcludeKeys>;
28
+ exclude<TValue extends MethodExcludeValue<TResult>, TExcludeKeys extends string = TExcludedKeys | "exclude">(value: TValue): ModelQueryResult<ApplyArrayIfArray<TResult, MethodExcludeResult<TValue, InferArrayItem<TResult>>>, TConfig, TExcludeKeys, TSchema, TTable, TFormat, TWithSafe>;
29
+ raw<TExcludeKeys extends string = TExcludedKeys | "raw">(): ModelQueryResult<TResult, TConfig, TExcludeKeys, TSchema, TTable, undefined, TWithSafe>;
30
+ safe(): ModelQueryResult<TResult, TConfig, TExcludedKeys | "safe", TSchema, TTable, TFormat, true>;
31
+ select<TValue extends MethodSelectValue<TResult>, TExcludeKeys extends string = TExcludedKeys | "select">(value: TValue): ModelQueryResult<ApplyArrayIfArray<TResult, MethodSelectResult<TValue, InferArrayItem<TResult>>>, TConfig, TExcludeKeys, TSchema, TTable, TFormat, TWithSafe>;
32
+ with<TValue extends MethodWithValue<TSchema, TTable["relations"]>, TExcludeKeys extends string = TExcludedKeys | "with">(value: TValue): ModelQueryResult<MethodWithResult<TValue, TResult, TSchema, TTable>, TConfig, TExcludeKeys, TSchema, TTable, TFormat, TWithSafe>;
29
33
  }
30
- interface ModelMutateResult<TBaseResult extends Record<string, any> | void, TConfig extends ModelConfig, TResultType extends string = "one"> extends Promise<TBaseResult> {
31
- return<TValue extends MethodSelectValue<TableOutput<TConfig["table"]>> | undefined, TReturnResult extends MethodReturnResult<TResultType, TConfig> = MethodReturnResult<TResultType, TConfig>, TResult extends Record<string, any> = (TValue extends undefined ? TReturnResult : MethodSelectResult<Exclude<TValue, undefined>, TReturnResult>)>(value?: TConfig["dialect"] extends ReturningIdDialects ? never : TValue): Omit<ModelMutateResult<TResult, TConfig, TResultType>, "with">;
34
+ interface ModelInMutableResult<TBaseResult extends Record<string, any> | any[] | never, TConfig extends ModelConfig> extends Promise<Simplify<TBaseResult>> {
35
+ omit<TValue extends MethodExcludeValue<TConfig["tableOutput"]>>(value: TValue): ModelInMutableResult<ApplyArrayIfArray<TConfig["tableOutput"], MethodExcludeResult<TValue, InferArrayItem<TConfig["tableOutput"]>>>, TConfig>;
36
+ return<TValue extends MethodSelectValue<TConfig["tableOutput"]> | undefined, TReturnResult extends MethodReturnResult<TConfig> = MethodReturnResult<TConfig>, TResult extends Record<string, any> = (undefined extends TValue ? TReturnResult : MethodSelectResult<Exclude<TValue, undefined>, TReturnResult>)>(value?: TConfig["dialect"] extends ReturningIdDialects ? never : TValue): ModelMutateResult<Simplify<TResult>[], TConfig>;
37
+ returnFirst<TValue extends MethodSelectValue<TConfig["tableOutput"]> | undefined, TReturnResult extends MethodReturnResult<TConfig> = MethodReturnResult<TConfig>, TResult extends Record<string, any> = (undefined extends TValue ? TReturnResult : MethodSelectResult<Exclude<TValue, undefined>, TReturnResult>)>(value?: TConfig["dialect"] extends ReturningIdDialects ? never : TValue): ModelMutateResult<Simplify<TResult>, TConfig>;
32
38
  }
39
+ interface ModelMutateResult<TResult extends Record<string, any> | any[] | never, TConfig extends ModelConfig, TExcludedKeys extends string = string, TWithSafe extends true | false = false> extends Promise<ApplySafeResultIf<TWithSafe, TResult>> {
40
+ omit<TValue extends MethodExcludeValue<TResult>, TExcludeKeys extends string = TExcludedKeys | "omit">(value: TValue): ModelMutateResult<ApplyArrayIfArray<TResult, Simplify<MethodExcludeResult<TValue, InferArrayItem<TResult>>>>, TConfig, TExcludeKeys>;
41
+ safe(): ModelMutateResult<TResult, TConfig, TExcludedKeys, true>;
42
+ }
43
+ type SafeResult<TResult> = MergeExclusive<{
44
+ error: QueryError;
45
+ }, {
46
+ data: TResult;
47
+ }>;
48
+ type ApplySafeResultIf<TCondition extends true | false, TResult> = TCondition extends true ? SafeResult<TResult> : TResult;
33
49
  //#endregion
34
- export { ModelMutateResult, ModelQueryResult };
50
+ export { ApplySafeResultIf, ModelInMutableResult, ModelMutateResult, ModelQueryResult, SafeResult };
package/dist/types.d.mts CHANGED
@@ -8,5 +8,20 @@ type AddUnionToValues<T extends Record<PropertyKey, any>, A> = { [K in keyof T]:
8
8
  interface RecursiveBooleanRecord {
9
9
  [key: string]: boolean | RecursiveBooleanRecord;
10
10
  }
11
+ type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
12
+ type Without<FirstType, SecondType> = { [KeyType in Exclude<keyof FirstType, keyof SecondType>]?: never };
13
+ type MergeExclusive<FirstType, SecondType> = FirstType | SecondType extends object ? (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) : FirstType | SecondType;
14
+ /**
15
+ * Infer item of Array<>. If not Array<> return type.
16
+ */
17
+ type InferArrayItem<T extends any | any[]> = T extends any[] ? T extends (infer Item)[] ? Item : T : T;
18
+ /**
19
+ * Applies Array<> to T if condition is true, otherwise return T as non array.
20
+ */
21
+ type ApplyArrayIf<TCondition extends true | false, T> = TCondition extends true ? T[] : T;
22
+ /**
23
+ * Applies Array<> to T if TArray is Array<>, if not return T as non array.
24
+ */
25
+ type ApplyArrayIfArray<TArray extends any | any[], T> = ApplyArrayIf<TArray extends any[] ? true : false, T>;
11
26
  //#endregion
12
- export { AddToValues, AddUnionToValues, Compose, Fallback, RecursiveBooleanRecord, Replace, UnwrapArray };
27
+ export { AddToValues, AddUnionToValues, ApplyArrayIf, ApplyArrayIfArray, Compose, Fallback, InferArrayItem, MergeExclusive, RecursiveBooleanRecord, Replace, Simplify, UnwrapArray };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apisr/drizzle-model",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "lint": "eslint . --max-warnings 0",
@@ -13,6 +13,7 @@ const model = modelBuilder({
13
13
  // create model
14
14
  const userModel = model("user", {});
15
15
 
16
+ // #1 syntax
16
17
  await userModel
17
18
  .where({
18
19
  name: {
@@ -21,6 +22,7 @@ await userModel
21
22
  })
22
23
  .findFirst();
23
24
 
25
+ // #2 syntax
24
26
  await userModel
25
27
  .where({
26
28
  name: esc.like("A%"),