@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/CHANGELOG.md +4 -1
- package/README.md +280 -37
- package/ROADMAP.md +3 -0
- package/dist/core/dialect.mjs +56 -0
- package/dist/core/query/joins.mjs +334 -0
- package/dist/core/query/projection.mjs +78 -0
- package/dist/core/query/where.mjs +265 -0
- package/dist/core/result.mjs +215 -0
- package/dist/core/runtime.mjs +393 -0
- package/dist/core/transform.mjs +83 -0
- package/dist/index.d.mts +4 -4
- package/dist/model/builder.mjs +22 -2
- package/dist/model/config.d.mts +6 -6
- package/dist/model/format.d.mts +6 -2
- package/dist/model/index.d.mts +2 -2
- package/dist/model/methods/exclude.d.mts +1 -1
- package/dist/model/methods/return.d.mts +2 -2
- package/dist/model/methods/select.d.mts +1 -1
- package/dist/model/model.d.mts +10 -12
- package/dist/model/query/error.d.mts +4 -0
- package/dist/model/query/operations.d.mts +89 -39
- package/dist/model/query/operations.mjs +12 -0
- package/dist/model/result.d.mts +26 -10
- package/dist/types.d.mts +16 -1
- package/package.json +1 -1
- package/tests/snippets/x-2.ts +2 -0
- package/dist/model/core/joins.mjs +0 -184
- package/dist/model/core/projection.mjs +0 -28
- package/dist/model/core/runtime.mjs +0 -198
- package/dist/model/core/thenable.mjs +0 -64
- package/dist/model/core/transform.mjs +0 -39
- package/dist/model/core/where.mjs +0 -130
- package/dist/model/core/with.mjs +0 -19
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 {
|
|
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,
|
|
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 };
|
package/dist/model/builder.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
|
package/dist/model/config.d.mts
CHANGED
|
@@ -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
|
-
|
|
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 };
|
package/dist/model/format.d.mts
CHANGED
|
@@ -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
|
|
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 {
|
|
8
|
+
export { ModelFormatResult, ResolveFormatCustomFields };
|
package/dist/model/index.d.mts
CHANGED
|
@@ -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 {
|
|
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>> =
|
|
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 {
|
|
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<
|
|
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
|
|
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 };
|
package/dist/model/model.d.mts
CHANGED
|
@@ -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,
|
|
8
|
-
import {
|
|
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"]
|
|
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():
|
|
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):
|
|
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):
|
|
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):
|
|
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
|
-
|
|
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 };
|
|
@@ -12,53 +12,53 @@ type EscapedValue<T> = {
|
|
|
12
12
|
value: T;
|
|
13
13
|
};
|
|
14
14
|
type OpValue<T> = T | SQL | EscapedValue<T>;
|
|
15
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
38
|
-
|
|
33
|
+
endsWith?: OpValue<string>;
|
|
34
|
+
ilike?: OpValue<string>;
|
|
39
35
|
length?: NumberOps;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
46
|
-
|
|
43
|
+
isTrue?: boolean;
|
|
44
|
+
}
|
|
45
|
+
interface DateOps {
|
|
47
46
|
after?: OpValue<Date | string>;
|
|
48
|
-
|
|
49
|
-
notOn?: OpValue<Date | string>;
|
|
47
|
+
before?: OpValue<Date | string>;
|
|
50
48
|
between?: [OpValue<Date | string>, OpValue<Date | string>];
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
*
|
|
85
|
+
*
|
|
86
|
+
* 3) Chainable operator methods (recommended):
|
|
93
87
|
* ```ts
|
|
94
|
-
*
|
|
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 };
|
package/dist/model/result.d.mts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { ReturningIdDialects } from "./dialect.mjs";
|
|
2
|
-
import {
|
|
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 {
|
|
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
|
|
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
|
|
26
|
-
raw<TExcludeKeys extends string = TExcludedKeys | "raw">(): ModelQueryResult<TResult, TConfig, TExcludeKeys, TSchema, TTable, undefined>;
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
31
|
-
|
|
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
package/tests/snippets/x-2.ts
CHANGED
|
@@ -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%"),
|