@zenstackhq/orm 3.5.2 → 3.5.4
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.cjs +261 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -4
- package/dist/index.d.ts +21 -4
- package/dist/index.js +140 -15
- package/dist/index.js.map +1 -1
- package/package.json +19 -9
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _zenstackhq_schema from '@zenstackhq/schema';
|
|
2
|
-
import { SchemaDef, GetModels, ScalarFields, ForeignKeyFields, GetModelFields, FieldHasDefault, GetModelFieldType, ModelFieldIsOptional, GetModelField, NonRelationFields, GetModel, ProcedureDef, BuiltinType, FieldDef, ModelDef, DataSourceProviderType, IsDelegateModel, RelationFields, FieldIsArray, RelationFieldType, FieldIsRelation, GetEnums, GetEnum, GetTypeDefs, GetTypeDefFields, GetTypeDefField, TypeDefFieldIsOptional, GetTypeDefFieldType, TypeDefFieldIsArray, UpdatedAtInfo, FieldIsDelegateDiscriminator, FieldType, RelationInfo, Expression as Expression$1, LiteralExpression, ArrayExpression, FieldExpression, MemberExpression, BinaryExpression, UnaryExpression, CallExpression, BindingExpression, ThisExpression, NullExpression } from '@zenstackhq/schema';
|
|
2
|
+
import { SchemaDef, GetModels, ScalarFields, ForeignKeyFields, GetModelFields, FieldHasDefault, GetModelFieldType, ModelFieldIsOptional, GetModelField, NonRelationFields, GetModel, ProcedureDef, BuiltinType, FieldDef, ModelDef, DataSourceProviderType, IsDelegateModel, RelationFields, FieldIsArray, RelationFieldType, FieldIsRelation, GetEnums, GetEnum, GetTypeDefs, GetTypeDefFields, GetTypeDefField, TypeDefFieldIsOptional, GetTypeDefFieldType, TypeDefFieldIsArray, GetModelDiscriminator, GetSubModels, UpdatedAtInfo, FieldIsDelegateDiscriminator, FieldType, RelationInfo, Expression as Expression$1, LiteralExpression, ArrayExpression, FieldExpression, MemberExpression, BinaryExpression, UnaryExpression, CallExpression, BindingExpression, ThisExpression, NullExpression } from '@zenstackhq/schema';
|
|
3
3
|
import * as kysely from 'kysely';
|
|
4
4
|
import { Kysely, OperationNodeVisitor, OperationNode, SelectQueryNode, SelectionNode, ColumnNode, AliasNode, TableNode, FromNode, ReferenceNode, AndNode, OrNode, ValueListNode, ParensNode, JoinNode, RawNode, WhereNode, InsertQueryNode, DeleteQueryNode, ReturningNode, CreateTableNode, AddColumnNode, ColumnDefinitionNode, DropTableNode, OrderByNode, OrderByItemNode, GroupByNode, GroupByItemNode, UpdateQueryNode, ColumnUpdateNode, LimitNode, OffsetNode, OnConflictNode, OnDuplicateKeyNode, CheckConstraintNode, DataTypeNode, SelectAllNode, IdentifierNode, SchemableIdentifierNode, ValueNode, PrimitiveValueListNode, OperatorNode, CreateIndexNode, DropIndexNode, ListNode, PrimaryKeyConstraintNode, UniqueConstraintNode, ReferencesNode, WithNode, CommonTableExpressionNode, CommonTableExpressionNameNode, HavingNode, CreateSchemaNode, DropSchemaNode, AlterTableNode, DropColumnNode, RenameColumnNode, AlterColumnNode, ModifyColumnNode, AddConstraintNode, DropConstraintNode, ForeignKeyConstraintNode, CreateViewNode, DropViewNode, GeneratedNode, DefaultValueNode, OnNode, ValuesNode, SelectModifierNode, CreateTypeNode, DropTypeNode, ExplainNode, DefaultInsertValueNode, AggregateFunctionNode, OverNode, PartitionByNode, PartitionByItemNode, SetOperationNode, BinaryOperationNode, UnaryOperationNode, UsingNode, FunctionNode, CaseNode, WhenNode, JSONReferenceNode, JSONPathNode, JSONPathLegNode, JSONOperatorChainNode, TupleNode, MergeQueryNode, MatchedNode, AddIndexNode, CastNode, FetchNode, TopNode, OutputNode, RenameConstraintNode, RefreshMaterializedViewNode, OrActionNode, CollateNode, Generated, QueryId, RootOperationNode, QueryResult, UnknownRow, Dialect, ExpressionBuilder, Expression, KyselyConfig, OperandExpression, SelectQueryBuilder, SqlBool, AliasableExpression, ExpressionWrapper } from 'kysely';
|
|
5
5
|
import Decimal from 'decimal.js';
|
|
@@ -908,6 +908,10 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
908
908
|
* Builds a VALUES table and select all fields from it.
|
|
909
909
|
*/
|
|
910
910
|
abstract buildValuesTableSelect(fields: FieldDef[], rows: unknown[][]): SelectQueryBuilder<any, any, any>;
|
|
911
|
+
/**
|
|
912
|
+
* Builds a binary comparison expression between two operands.
|
|
913
|
+
*/
|
|
914
|
+
buildComparison(left: Expression<unknown>, _leftFieldDef: FieldDef | undefined, op: string, right: Expression<unknown>, _rightFieldDef: FieldDef | undefined): Expression<SqlBool>;
|
|
911
915
|
/**
|
|
912
916
|
* Builds a JSON path selection expression.
|
|
913
917
|
*/
|
|
@@ -1099,13 +1103,26 @@ type GetAllFieldsExcludedFilterKinds<FieldsConfig> = '$all' extends keyof Fields
|
|
|
1099
1103
|
excludedFilterKinds: readonly (infer EFK)[];
|
|
1100
1104
|
} ? EFK : never : never;
|
|
1101
1105
|
|
|
1102
|
-
type DefaultModelResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Omit = undefined, Options extends QueryOptions<Schema> = QueryOptions<Schema>, Optional = false, Array = false> = WrapType<
|
|
1103
|
-
[Key in NonRelationFields<Schema, Model> as ShouldOmitField<Schema, Model, Options, Key, Omit> extends true ? never : Key]: MapModelFieldType<Schema, Model, Key>;
|
|
1104
|
-
}, Optional, Array>;
|
|
1106
|
+
type DefaultModelResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Omit = undefined, Options extends QueryOptions<Schema> = QueryOptions<Schema>, Optional = false, Array = false, IsGenericModel = [string] extends [Model] ? true : false> = WrapType<IsGenericModel extends true ? FlatModelResult<Schema, Model, Omit, Options> : IsDelegateModel<Schema, Model> extends true ? DelegateUnionResult<Schema, Model, Options, GetSubModels<Schema, Model>, Omit> : FlatModelResult<Schema, Model, Omit, Options>, Optional, Array>;
|
|
1105
1107
|
type ShouldOmitField<Schema extends SchemaDef, Model extends GetModels<Schema>, Options extends QueryOptions<Schema>, Field extends GetModelFields<Schema, Model>, Omit> = QueryLevelOmit<Schema, Model, Field, Omit> extends boolean ? QueryLevelOmit<Schema, Model, Field, Omit> : OptionsLevelOmit<Schema, Model, Field, Options> extends boolean ? OptionsLevelOmit<Schema, Model, Field, Options> : SchemaLevelOmit<Schema, Model, Field>;
|
|
1106
1108
|
type QueryLevelOmit<Schema extends SchemaDef, Model extends GetModels<Schema>, Field extends GetModelFields<Schema, Model>, Omit> = Field extends keyof Omit ? (Omit[Field] extends boolean ? Omit[Field] : undefined) : undefined;
|
|
1107
1109
|
type OptionsLevelOmit<Schema extends SchemaDef, Model extends GetModels<Schema>, Field extends GetModelFields<Schema, Model>, Options extends QueryOptions<Schema>> = Uncapitalize<Model> extends keyof Options['omit'] ? Field extends keyof Options['omit'][Uncapitalize<Model>] ? Options['omit'][Uncapitalize<Model>][Field] extends boolean ? Options['omit'][Uncapitalize<Model>][Field] : undefined : undefined : undefined;
|
|
1108
1110
|
type SchemaLevelOmit<Schema extends SchemaDef, Model extends GetModels<Schema>, Field extends GetModelFields<Schema, Model>> = GetModelField<Schema, Model, Field>['omit'] extends true ? true : false;
|
|
1111
|
+
type FlatModelResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Omit, Options extends QueryOptions<Schema>> = {
|
|
1112
|
+
[Key in NonRelationFields<Schema, Model> as ShouldOmitField<Schema, Model, Options, Key, Omit> extends true ? never : Key]: MapModelFieldType<Schema, Model, Key>;
|
|
1113
|
+
};
|
|
1114
|
+
type DelegateUnionResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Options extends QueryOptions<Schema>, SubModel extends GetModels<Schema>, Omit = undefined, Depth extends readonly 0[] = []> = Depth['length'] extends 10 ? SubModel extends string ? FlatModelResult<Schema, SubModel, Omit, Options> & {
|
|
1115
|
+
[K in GetModelDiscriminator<Schema, Model>]: SubModel;
|
|
1116
|
+
} : never : SubModel extends string ? IsDelegateModel<Schema, SubModel> extends true ? // sub-model is itself a delegate — recurse into its own sub-models so all
|
|
1117
|
+
DelegateUnionResult<Schema, SubModel, Options, GetSubModels<Schema, SubModel>, Omit, [
|
|
1118
|
+
...Depth,
|
|
1119
|
+
0
|
|
1120
|
+
]> & {
|
|
1121
|
+
[K in GetModelDiscriminator<Schema, Model>]: SubModel;
|
|
1122
|
+
} : // leaf model — produce a flat scalar result and fix the discriminator
|
|
1123
|
+
FlatModelResult<Schema, SubModel, Omit, Options> & {
|
|
1124
|
+
[K in GetModelDiscriminator<Schema, Model>]: SubModel;
|
|
1125
|
+
} : never;
|
|
1109
1126
|
type ModelSelectResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Select, Omit, Options extends QueryOptions<Schema>, ExtResult extends ExtResultBase<Schema> = {}> = {
|
|
1110
1127
|
[Key in keyof Select as Select[Key] extends false | undefined ? never : Key extends keyof ExtractExtResult<ExtResult, Model & string> ? never : Key extends '_count' ? Select[Key] extends SelectCount<Schema, Model, Options> ? Key : never : Key extends keyof Omit ? Omit[Key] extends true ? never : Key : Key]: Key extends '_count' ? SelectCountResult<Schema, Model, Select[Key]> : Key extends NonRelationFields<Schema, Model> ? MapModelFieldType<Schema, Model, Key> : Key extends RelationFields<Schema, Model> ? ModelResult<Schema, RelationFieldType<Schema, Model, Key>, Select[Key], Options, ModelFieldIsOptional<Schema, Model, Key>, FieldIsArray<Schema, Model, Key>, ExtResult> : never;
|
|
1111
1128
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _zenstackhq_schema from '@zenstackhq/schema';
|
|
2
|
-
import { SchemaDef, GetModels, ScalarFields, ForeignKeyFields, GetModelFields, FieldHasDefault, GetModelFieldType, ModelFieldIsOptional, GetModelField, NonRelationFields, GetModel, ProcedureDef, BuiltinType, FieldDef, ModelDef, DataSourceProviderType, IsDelegateModel, RelationFields, FieldIsArray, RelationFieldType, FieldIsRelation, GetEnums, GetEnum, GetTypeDefs, GetTypeDefFields, GetTypeDefField, TypeDefFieldIsOptional, GetTypeDefFieldType, TypeDefFieldIsArray, UpdatedAtInfo, FieldIsDelegateDiscriminator, FieldType, RelationInfo, Expression as Expression$1, LiteralExpression, ArrayExpression, FieldExpression, MemberExpression, BinaryExpression, UnaryExpression, CallExpression, BindingExpression, ThisExpression, NullExpression } from '@zenstackhq/schema';
|
|
2
|
+
import { SchemaDef, GetModels, ScalarFields, ForeignKeyFields, GetModelFields, FieldHasDefault, GetModelFieldType, ModelFieldIsOptional, GetModelField, NonRelationFields, GetModel, ProcedureDef, BuiltinType, FieldDef, ModelDef, DataSourceProviderType, IsDelegateModel, RelationFields, FieldIsArray, RelationFieldType, FieldIsRelation, GetEnums, GetEnum, GetTypeDefs, GetTypeDefFields, GetTypeDefField, TypeDefFieldIsOptional, GetTypeDefFieldType, TypeDefFieldIsArray, GetModelDiscriminator, GetSubModels, UpdatedAtInfo, FieldIsDelegateDiscriminator, FieldType, RelationInfo, Expression as Expression$1, LiteralExpression, ArrayExpression, FieldExpression, MemberExpression, BinaryExpression, UnaryExpression, CallExpression, BindingExpression, ThisExpression, NullExpression } from '@zenstackhq/schema';
|
|
3
3
|
import * as kysely from 'kysely';
|
|
4
4
|
import { Kysely, OperationNodeVisitor, OperationNode, SelectQueryNode, SelectionNode, ColumnNode, AliasNode, TableNode, FromNode, ReferenceNode, AndNode, OrNode, ValueListNode, ParensNode, JoinNode, RawNode, WhereNode, InsertQueryNode, DeleteQueryNode, ReturningNode, CreateTableNode, AddColumnNode, ColumnDefinitionNode, DropTableNode, OrderByNode, OrderByItemNode, GroupByNode, GroupByItemNode, UpdateQueryNode, ColumnUpdateNode, LimitNode, OffsetNode, OnConflictNode, OnDuplicateKeyNode, CheckConstraintNode, DataTypeNode, SelectAllNode, IdentifierNode, SchemableIdentifierNode, ValueNode, PrimitiveValueListNode, OperatorNode, CreateIndexNode, DropIndexNode, ListNode, PrimaryKeyConstraintNode, UniqueConstraintNode, ReferencesNode, WithNode, CommonTableExpressionNode, CommonTableExpressionNameNode, HavingNode, CreateSchemaNode, DropSchemaNode, AlterTableNode, DropColumnNode, RenameColumnNode, AlterColumnNode, ModifyColumnNode, AddConstraintNode, DropConstraintNode, ForeignKeyConstraintNode, CreateViewNode, DropViewNode, GeneratedNode, DefaultValueNode, OnNode, ValuesNode, SelectModifierNode, CreateTypeNode, DropTypeNode, ExplainNode, DefaultInsertValueNode, AggregateFunctionNode, OverNode, PartitionByNode, PartitionByItemNode, SetOperationNode, BinaryOperationNode, UnaryOperationNode, UsingNode, FunctionNode, CaseNode, WhenNode, JSONReferenceNode, JSONPathNode, JSONPathLegNode, JSONOperatorChainNode, TupleNode, MergeQueryNode, MatchedNode, AddIndexNode, CastNode, FetchNode, TopNode, OutputNode, RenameConstraintNode, RefreshMaterializedViewNode, OrActionNode, CollateNode, Generated, QueryId, RootOperationNode, QueryResult, UnknownRow, Dialect, ExpressionBuilder, Expression, KyselyConfig, OperandExpression, SelectQueryBuilder, SqlBool, AliasableExpression, ExpressionWrapper } from 'kysely';
|
|
5
5
|
import Decimal from 'decimal.js';
|
|
@@ -908,6 +908,10 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
908
908
|
* Builds a VALUES table and select all fields from it.
|
|
909
909
|
*/
|
|
910
910
|
abstract buildValuesTableSelect(fields: FieldDef[], rows: unknown[][]): SelectQueryBuilder<any, any, any>;
|
|
911
|
+
/**
|
|
912
|
+
* Builds a binary comparison expression between two operands.
|
|
913
|
+
*/
|
|
914
|
+
buildComparison(left: Expression<unknown>, _leftFieldDef: FieldDef | undefined, op: string, right: Expression<unknown>, _rightFieldDef: FieldDef | undefined): Expression<SqlBool>;
|
|
911
915
|
/**
|
|
912
916
|
* Builds a JSON path selection expression.
|
|
913
917
|
*/
|
|
@@ -1099,13 +1103,26 @@ type GetAllFieldsExcludedFilterKinds<FieldsConfig> = '$all' extends keyof Fields
|
|
|
1099
1103
|
excludedFilterKinds: readonly (infer EFK)[];
|
|
1100
1104
|
} ? EFK : never : never;
|
|
1101
1105
|
|
|
1102
|
-
type DefaultModelResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Omit = undefined, Options extends QueryOptions<Schema> = QueryOptions<Schema>, Optional = false, Array = false> = WrapType<
|
|
1103
|
-
[Key in NonRelationFields<Schema, Model> as ShouldOmitField<Schema, Model, Options, Key, Omit> extends true ? never : Key]: MapModelFieldType<Schema, Model, Key>;
|
|
1104
|
-
}, Optional, Array>;
|
|
1106
|
+
type DefaultModelResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Omit = undefined, Options extends QueryOptions<Schema> = QueryOptions<Schema>, Optional = false, Array = false, IsGenericModel = [string] extends [Model] ? true : false> = WrapType<IsGenericModel extends true ? FlatModelResult<Schema, Model, Omit, Options> : IsDelegateModel<Schema, Model> extends true ? DelegateUnionResult<Schema, Model, Options, GetSubModels<Schema, Model>, Omit> : FlatModelResult<Schema, Model, Omit, Options>, Optional, Array>;
|
|
1105
1107
|
type ShouldOmitField<Schema extends SchemaDef, Model extends GetModels<Schema>, Options extends QueryOptions<Schema>, Field extends GetModelFields<Schema, Model>, Omit> = QueryLevelOmit<Schema, Model, Field, Omit> extends boolean ? QueryLevelOmit<Schema, Model, Field, Omit> : OptionsLevelOmit<Schema, Model, Field, Options> extends boolean ? OptionsLevelOmit<Schema, Model, Field, Options> : SchemaLevelOmit<Schema, Model, Field>;
|
|
1106
1108
|
type QueryLevelOmit<Schema extends SchemaDef, Model extends GetModels<Schema>, Field extends GetModelFields<Schema, Model>, Omit> = Field extends keyof Omit ? (Omit[Field] extends boolean ? Omit[Field] : undefined) : undefined;
|
|
1107
1109
|
type OptionsLevelOmit<Schema extends SchemaDef, Model extends GetModels<Schema>, Field extends GetModelFields<Schema, Model>, Options extends QueryOptions<Schema>> = Uncapitalize<Model> extends keyof Options['omit'] ? Field extends keyof Options['omit'][Uncapitalize<Model>] ? Options['omit'][Uncapitalize<Model>][Field] extends boolean ? Options['omit'][Uncapitalize<Model>][Field] : undefined : undefined : undefined;
|
|
1108
1110
|
type SchemaLevelOmit<Schema extends SchemaDef, Model extends GetModels<Schema>, Field extends GetModelFields<Schema, Model>> = GetModelField<Schema, Model, Field>['omit'] extends true ? true : false;
|
|
1111
|
+
type FlatModelResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Omit, Options extends QueryOptions<Schema>> = {
|
|
1112
|
+
[Key in NonRelationFields<Schema, Model> as ShouldOmitField<Schema, Model, Options, Key, Omit> extends true ? never : Key]: MapModelFieldType<Schema, Model, Key>;
|
|
1113
|
+
};
|
|
1114
|
+
type DelegateUnionResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Options extends QueryOptions<Schema>, SubModel extends GetModels<Schema>, Omit = undefined, Depth extends readonly 0[] = []> = Depth['length'] extends 10 ? SubModel extends string ? FlatModelResult<Schema, SubModel, Omit, Options> & {
|
|
1115
|
+
[K in GetModelDiscriminator<Schema, Model>]: SubModel;
|
|
1116
|
+
} : never : SubModel extends string ? IsDelegateModel<Schema, SubModel> extends true ? // sub-model is itself a delegate — recurse into its own sub-models so all
|
|
1117
|
+
DelegateUnionResult<Schema, SubModel, Options, GetSubModels<Schema, SubModel>, Omit, [
|
|
1118
|
+
...Depth,
|
|
1119
|
+
0
|
|
1120
|
+
]> & {
|
|
1121
|
+
[K in GetModelDiscriminator<Schema, Model>]: SubModel;
|
|
1122
|
+
} : // leaf model — produce a flat scalar result and fix the discriminator
|
|
1123
|
+
FlatModelResult<Schema, SubModel, Omit, Options> & {
|
|
1124
|
+
[K in GetModelDiscriminator<Schema, Model>]: SubModel;
|
|
1125
|
+
} : never;
|
|
1109
1126
|
type ModelSelectResult<Schema extends SchemaDef, Model extends GetModels<Schema>, Select, Omit, Options extends QueryOptions<Schema>, ExtResult extends ExtResultBase<Schema> = {}> = {
|
|
1110
1127
|
[Key in keyof Select as Select[Key] extends false | undefined ? never : Key extends keyof ExtractExtResult<ExtResult, Model & string> ? never : Key extends '_count' ? Select[Key] extends SelectCount<Schema, Model, Options> ? Key : never : Key extends keyof Omit ? Omit[Key] extends true ? never : Key : Key]: Key extends '_count' ? SelectCountResult<Schema, Model, Select[Key]> : Key extends NonRelationFields<Schema, Model> ? MapModelFieldType<Schema, Model, Key> : Key extends RelationFields<Schema, Model> ? ModelResult<Schema, RelationFieldType<Schema, Model, Key>, Select[Key], Options, ModelFieldIsOptional<Schema, Model, Key>, FieldIsArray<Schema, Model, Key>, ExtResult> : never;
|
|
1111
1128
|
};
|
package/dist/index.js
CHANGED
|
@@ -82,6 +82,7 @@ __reExport(schema_exports, schema_star);
|
|
|
82
82
|
import * as schema_star from "@zenstackhq/schema";
|
|
83
83
|
|
|
84
84
|
// src/utils/object-utils.ts
|
|
85
|
+
import { isPlainObject } from "@zenstackhq/common-helpers";
|
|
85
86
|
function extractFields(obj, fields) {
|
|
86
87
|
return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
|
|
87
88
|
}
|
|
@@ -93,6 +94,10 @@ function fieldsToSelectObject(fields) {
|
|
|
93
94
|
]));
|
|
94
95
|
}
|
|
95
96
|
__name(fieldsToSelectObject, "fieldsToSelectObject");
|
|
97
|
+
function isEmptyObject(x) {
|
|
98
|
+
return isPlainObject(x) && Object.keys(x).length === 0;
|
|
99
|
+
}
|
|
100
|
+
__name(isEmptyObject, "isEmptyObject");
|
|
96
101
|
|
|
97
102
|
// src/client/executor/error-processor.ts
|
|
98
103
|
function getDbErrorCode(error) {
|
|
@@ -605,7 +610,7 @@ __name(tmpAlias, "tmpAlias");
|
|
|
605
610
|
|
|
606
611
|
// src/client/crud/operations/base.ts
|
|
607
612
|
import { createId as cuid2 } from "@paralleldrive/cuid2";
|
|
608
|
-
import { clone, enumerate as enumerate2, invariant as invariant7, isPlainObject as
|
|
613
|
+
import { clone, enumerate as enumerate2, invariant as invariant7, isPlainObject as isPlainObject3 } from "@zenstackhq/common-helpers";
|
|
609
614
|
import { default as cuid1 } from "cuid";
|
|
610
615
|
import { createQueryId, expressionBuilder as expressionBuilder5, sql as sql5 } from "kysely";
|
|
611
616
|
import { nanoid } from "nanoid";
|
|
@@ -729,7 +734,7 @@ var AnyNull = new AnyNullClass();
|
|
|
729
734
|
import { invariant as invariant3 } from "@zenstackhq/common-helpers";
|
|
730
735
|
|
|
731
736
|
// src/client/crud/dialects/base-dialect.ts
|
|
732
|
-
import { enumerate, invariant as invariant2, isPlainObject, lowerCaseFirst } from "@zenstackhq/common-helpers";
|
|
737
|
+
import { enumerate, invariant as invariant2, isPlainObject as isPlainObject2, lowerCaseFirst } from "@zenstackhq/common-helpers";
|
|
733
738
|
import { expressionBuilder, sql } from "kysely";
|
|
734
739
|
import { match as match2, P } from "ts-pattern";
|
|
735
740
|
var BaseCrudDialect = class {
|
|
@@ -857,7 +862,31 @@ var BaseCrudDialect = class {
|
|
|
857
862
|
return LOGICAL_COMBINATORS.includes(key);
|
|
858
863
|
}
|
|
859
864
|
buildCompositeFilter(model, modelAlias, key, payload) {
|
|
860
|
-
|
|
865
|
+
const normalizedPayload = enumerate(payload).filter((el) => {
|
|
866
|
+
if (typeof el === "object" && el !== null && !Array.isArray(el)) {
|
|
867
|
+
const entries = Object.entries(el);
|
|
868
|
+
return entries.some(([, v]) => v !== void 0);
|
|
869
|
+
} else {
|
|
870
|
+
return true;
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
const normalizedFilters = normalizedPayload.map((el) => this.buildFilter(model, modelAlias, el));
|
|
874
|
+
return match2(key).with("AND", () => {
|
|
875
|
+
if (normalizedFilters.length === 0) {
|
|
876
|
+
return this.true();
|
|
877
|
+
}
|
|
878
|
+
return this.and(...normalizedFilters);
|
|
879
|
+
}).with("OR", () => {
|
|
880
|
+
if (normalizedFilters.length === 0) {
|
|
881
|
+
return this.false();
|
|
882
|
+
}
|
|
883
|
+
return this.or(...normalizedFilters);
|
|
884
|
+
}).with("NOT", () => {
|
|
885
|
+
if (normalizedFilters.length === 0) {
|
|
886
|
+
return this.true();
|
|
887
|
+
}
|
|
888
|
+
return this.not(...normalizedFilters);
|
|
889
|
+
}).exhaustive();
|
|
861
890
|
}
|
|
862
891
|
buildRelationFilter(model, modelAlias, field, fieldDef, payload) {
|
|
863
892
|
if (!fieldDef.array) {
|
|
@@ -1198,7 +1227,7 @@ var BaseCrudDialect = class {
|
|
|
1198
1227
|
return this.eb(lhs, "=", this.transformInput(rhs, type, false));
|
|
1199
1228
|
}
|
|
1200
1229
|
buildStandardFilter(type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
|
|
1201
|
-
if (payload === null || !
|
|
1230
|
+
if (payload === null || !isPlainObject2(payload)) {
|
|
1202
1231
|
return {
|
|
1203
1232
|
conditions: [
|
|
1204
1233
|
this.buildValueFilter(lhs, type, payload)
|
|
@@ -1215,6 +1244,9 @@ var BaseCrudDialect = class {
|
|
|
1215
1244
|
if (excludeKeys.includes(op)) {
|
|
1216
1245
|
continue;
|
|
1217
1246
|
}
|
|
1247
|
+
if (value === void 0) {
|
|
1248
|
+
continue;
|
|
1249
|
+
}
|
|
1218
1250
|
const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
|
|
1219
1251
|
const condition = match2(op).with("equals", () => rhs === null ? this.eb(lhs, "is", null) : this.eb(lhs, "=", rhs)).with("in", () => {
|
|
1220
1252
|
invariant2(Array.isArray(rhs), "right hand side must be an array");
|
|
@@ -1272,6 +1304,9 @@ var BaseCrudDialect = class {
|
|
|
1272
1304
|
if (key === "mode" || consumedKeys.includes(key)) {
|
|
1273
1305
|
continue;
|
|
1274
1306
|
}
|
|
1307
|
+
if (value === void 0) {
|
|
1308
|
+
continue;
|
|
1309
|
+
}
|
|
1275
1310
|
invariant2(typeof value === "string", `${key} value must be a string`);
|
|
1276
1311
|
const escapedValue = this.escapeLikePattern(value);
|
|
1277
1312
|
const condition = match2(key).with("contains", () => this.buildStringLike(fieldRef, `%${escapedValue}%`, mode === "insensitive")).with("startsWith", () => this.buildStringLike(fieldRef, `${escapedValue}%`, mode === "insensitive")).with("endsWith", () => this.buildStringLike(fieldRef, `%${escapedValue}`, mode === "insensitive")).otherwise(() => {
|
|
@@ -1597,6 +1632,12 @@ var BaseCrudDialect = class {
|
|
|
1597
1632
|
buildExistsExpression(innerQuery) {
|
|
1598
1633
|
return this.eb.exists(innerQuery);
|
|
1599
1634
|
}
|
|
1635
|
+
/**
|
|
1636
|
+
* Builds a binary comparison expression between two operands.
|
|
1637
|
+
*/
|
|
1638
|
+
buildComparison(left, _leftFieldDef, op, right, _rightFieldDef) {
|
|
1639
|
+
return this.eb(left, op, right);
|
|
1640
|
+
}
|
|
1600
1641
|
};
|
|
1601
1642
|
|
|
1602
1643
|
// src/client/crud/dialects/lateral-join-dialect-base.ts
|
|
@@ -2031,6 +2072,33 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2031
2072
|
Bytes: "bytea",
|
|
2032
2073
|
Json: "jsonb"
|
|
2033
2074
|
};
|
|
2075
|
+
// Maps @db.* attribute names to PostgreSQL SQL types for use in VALUES table casts
|
|
2076
|
+
static dbAttributeToSqlTypeMap = {
|
|
2077
|
+
"@db.Uuid": "uuid",
|
|
2078
|
+
"@db.Citext": "citext",
|
|
2079
|
+
"@db.Inet": "inet",
|
|
2080
|
+
"@db.Bit": "bit",
|
|
2081
|
+
"@db.VarBit": "varbit",
|
|
2082
|
+
"@db.Xml": "xml",
|
|
2083
|
+
"@db.Json": "json",
|
|
2084
|
+
"@db.JsonB": "jsonb",
|
|
2085
|
+
"@db.ByteA": "bytea",
|
|
2086
|
+
"@db.Text": "text",
|
|
2087
|
+
"@db.Char": "bpchar",
|
|
2088
|
+
"@db.VarChar": "varchar",
|
|
2089
|
+
"@db.Date": "date",
|
|
2090
|
+
"@db.Time": "time",
|
|
2091
|
+
"@db.Timetz": "timetz",
|
|
2092
|
+
"@db.Timestamp": "timestamp",
|
|
2093
|
+
"@db.Timestamptz": "timestamptz",
|
|
2094
|
+
"@db.SmallInt": "smallint",
|
|
2095
|
+
"@db.Integer": "integer",
|
|
2096
|
+
"@db.BigInt": "bigint",
|
|
2097
|
+
"@db.Real": "real",
|
|
2098
|
+
"@db.DoublePrecision": "double precision",
|
|
2099
|
+
"@db.Decimal": "decimal",
|
|
2100
|
+
"@db.Boolean": "boolean"
|
|
2101
|
+
};
|
|
2034
2102
|
constructor(schema, options) {
|
|
2035
2103
|
super(schema, options);
|
|
2036
2104
|
this.overrideTypeParsers();
|
|
@@ -2295,13 +2363,55 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2295
2363
|
receiver
|
|
2296
2364
|
]).as("$items")).select(this.eb.lit(1).as("_")).where(buildFilter(this.eb.ref("$items.value"))));
|
|
2297
2365
|
}
|
|
2298
|
-
getSqlType(zmodelType) {
|
|
2366
|
+
getSqlType(zmodelType, attributes) {
|
|
2367
|
+
if (attributes) {
|
|
2368
|
+
for (const attr of attributes) {
|
|
2369
|
+
const mapped = _PostgresCrudDialect.dbAttributeToSqlTypeMap[attr.name];
|
|
2370
|
+
if (mapped) {
|
|
2371
|
+
return mapped;
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2299
2375
|
if (isEnum(this.schema, zmodelType)) {
|
|
2300
2376
|
return "text";
|
|
2301
2377
|
} else {
|
|
2302
2378
|
return this.zmodelToSqlTypeMap[zmodelType] ?? "text";
|
|
2303
2379
|
}
|
|
2304
2380
|
}
|
|
2381
|
+
// Resolves the effective SQL type for a field: the native type from any @db.* attribute,
|
|
2382
|
+
// or the base ZModel SQL type if no attribute is present, or undefined if the field is unknown.
|
|
2383
|
+
resolveFieldSqlType(fieldDef) {
|
|
2384
|
+
if (!fieldDef) {
|
|
2385
|
+
return {
|
|
2386
|
+
sqlType: void 0,
|
|
2387
|
+
hasDbOverride: false
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2390
|
+
const dbAttr = fieldDef.attributes?.find((a) => a.name.startsWith("@db."));
|
|
2391
|
+
if (dbAttr) {
|
|
2392
|
+
return {
|
|
2393
|
+
sqlType: _PostgresCrudDialect.dbAttributeToSqlTypeMap[dbAttr.name],
|
|
2394
|
+
hasDbOverride: true
|
|
2395
|
+
};
|
|
2396
|
+
}
|
|
2397
|
+
return {
|
|
2398
|
+
sqlType: this.getSqlType(fieldDef.type),
|
|
2399
|
+
hasDbOverride: false
|
|
2400
|
+
};
|
|
2401
|
+
}
|
|
2402
|
+
buildComparison(left, leftFieldDef, op, right, rightFieldDef) {
|
|
2403
|
+
const leftResolved = this.resolveFieldSqlType(leftFieldDef);
|
|
2404
|
+
const rightResolved = this.resolveFieldSqlType(rightFieldDef);
|
|
2405
|
+
if (leftResolved.sqlType !== rightResolved.sqlType && (leftResolved.hasDbOverride || rightResolved.hasDbOverride)) {
|
|
2406
|
+
if (leftResolved.hasDbOverride) {
|
|
2407
|
+
left = this.eb.cast(left, sql3.raw(this.getSqlType(leftFieldDef.type)));
|
|
2408
|
+
}
|
|
2409
|
+
if (rightResolved.hasDbOverride) {
|
|
2410
|
+
right = this.eb.cast(right, sql3.raw(this.getSqlType(rightFieldDef.type)));
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
return super.buildComparison(left, leftFieldDef, op, right, rightFieldDef);
|
|
2414
|
+
}
|
|
2305
2415
|
getStringCasingBehavior() {
|
|
2306
2416
|
return {
|
|
2307
2417
|
supportsILike: true,
|
|
@@ -2323,7 +2433,7 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2323
2433
|
}
|
|
2324
2434
|
const eb = expressionBuilder3();
|
|
2325
2435
|
return eb.selectFrom(sql3`(VALUES ${sql3.join(rows.map((row) => sql3`(${sql3.join(row.map((v) => sql3.val(v)))})`), sql3.raw(", "))})`.as("$values")).select(fields.map((f, i) => {
|
|
2326
|
-
const mappedType = this.getSqlType(f.type);
|
|
2436
|
+
const mappedType = this.getSqlType(f.type, f.attributes);
|
|
2327
2437
|
const castType = f.array ? sql3`${sql3.raw(mappedType)}[]` : sql3.raw(mappedType);
|
|
2328
2438
|
return this.eb.cast(sql3.ref(`$values.column${i + 1}`), castType).as(f.name);
|
|
2329
2439
|
}));
|
|
@@ -3351,7 +3461,7 @@ var BaseOperationHandler = class {
|
|
|
3351
3461
|
throw createInvalidInputError("data must be an object");
|
|
3352
3462
|
}
|
|
3353
3463
|
const parentWhere = await this.buildUpdateParentRelationFilter(kysely, fromRelation);
|
|
3354
|
-
let combinedWhere = where ??
|
|
3464
|
+
let combinedWhere = where ?? true;
|
|
3355
3465
|
if (Object.keys(parentWhere).length > 0) {
|
|
3356
3466
|
combinedWhere = Object.keys(combinedWhere).length > 0 ? {
|
|
3357
3467
|
AND: [
|
|
@@ -3624,7 +3734,7 @@ var BaseOperationHandler = class {
|
|
|
3624
3734
|
throw createNotSupportedError("Updating with a limit is not supported for polymorphic models");
|
|
3625
3735
|
}
|
|
3626
3736
|
const parentWhere = await this.buildUpdateParentRelationFilter(kysely, fromRelation);
|
|
3627
|
-
let combinedWhere = where ??
|
|
3737
|
+
let combinedWhere = where ?? true;
|
|
3628
3738
|
if (Object.keys(parentWhere).length > 0) {
|
|
3629
3739
|
combinedWhere = Object.keys(combinedWhere).length > 0 ? {
|
|
3630
3740
|
AND: [
|
|
@@ -3816,11 +3926,11 @@ var BaseOperationHandler = class {
|
|
|
3816
3926
|
break;
|
|
3817
3927
|
}
|
|
3818
3928
|
case "delete": {
|
|
3819
|
-
await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, true);
|
|
3929
|
+
await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, true, true);
|
|
3820
3930
|
break;
|
|
3821
3931
|
}
|
|
3822
3932
|
case "deleteMany": {
|
|
3823
|
-
await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, false);
|
|
3933
|
+
await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, false, false);
|
|
3824
3934
|
break;
|
|
3825
3935
|
}
|
|
3826
3936
|
default: {
|
|
@@ -3908,6 +4018,10 @@ var BaseOperationHandler = class {
|
|
|
3908
4018
|
true
|
|
3909
4019
|
];
|
|
3910
4020
|
}
|
|
4021
|
+
} else if (isEmptyObject(data)) {
|
|
4022
|
+
disconnectConditions = [
|
|
4023
|
+
true
|
|
4024
|
+
];
|
|
3911
4025
|
} else {
|
|
3912
4026
|
disconnectConditions = this.normalizeRelationManipulationInput(model, data);
|
|
3913
4027
|
if (disconnectConditions.length === 0) {
|
|
@@ -4030,9 +4144,9 @@ var BaseOperationHandler = class {
|
|
|
4030
4144
|
}
|
|
4031
4145
|
}
|
|
4032
4146
|
}
|
|
4033
|
-
async deleteRelation(kysely, model, data, fromRelation, throwForNotFound) {
|
|
4147
|
+
async deleteRelation(kysely, model, data, fromRelation, uniqueDelete, throwForNotFound) {
|
|
4034
4148
|
let deleteConditions = [];
|
|
4035
|
-
let expectedDeleteCount;
|
|
4149
|
+
let expectedDeleteCount = -1;
|
|
4036
4150
|
if (typeof data === "boolean") {
|
|
4037
4151
|
if (data === false) {
|
|
4038
4152
|
return;
|
|
@@ -4040,6 +4154,15 @@ var BaseOperationHandler = class {
|
|
|
4040
4154
|
deleteConditions = [
|
|
4041
4155
|
true
|
|
4042
4156
|
];
|
|
4157
|
+
if (uniqueDelete) {
|
|
4158
|
+
expectedDeleteCount = 1;
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
} else if (isEmptyObject(data)) {
|
|
4162
|
+
deleteConditions = [
|
|
4163
|
+
true
|
|
4164
|
+
];
|
|
4165
|
+
if (uniqueDelete) {
|
|
4043
4166
|
expectedDeleteCount = 1;
|
|
4044
4167
|
}
|
|
4045
4168
|
} else {
|
|
@@ -4047,7 +4170,9 @@ var BaseOperationHandler = class {
|
|
|
4047
4170
|
if (deleteConditions.length === 0) {
|
|
4048
4171
|
return;
|
|
4049
4172
|
}
|
|
4050
|
-
|
|
4173
|
+
if (uniqueDelete) {
|
|
4174
|
+
expectedDeleteCount = deleteConditions.length;
|
|
4175
|
+
}
|
|
4051
4176
|
}
|
|
4052
4177
|
let deleteResult;
|
|
4053
4178
|
let deleteFromModel;
|
|
@@ -4107,7 +4232,7 @@ var BaseOperationHandler = class {
|
|
|
4107
4232
|
});
|
|
4108
4233
|
}
|
|
4109
4234
|
}
|
|
4110
|
-
if (throwForNotFound && expectedDeleteCount > (deleteResult.numAffectedRows ?? 0)) {
|
|
4235
|
+
if (throwForNotFound && expectedDeleteCount >= 0 && expectedDeleteCount > (deleteResult.numAffectedRows ?? 0)) {
|
|
4111
4236
|
throw createNotFoundError(deleteFromModel);
|
|
4112
4237
|
}
|
|
4113
4238
|
}
|
|
@@ -4242,7 +4367,7 @@ var BaseOperationHandler = class {
|
|
|
4242
4367
|
for (const [key, value] of Object.entries(args)) {
|
|
4243
4368
|
if (value === void 0) {
|
|
4244
4369
|
delete args[key];
|
|
4245
|
-
} else if (value &&
|
|
4370
|
+
} else if (value && isPlainObject3(value)) {
|
|
4246
4371
|
this.doNormalizeArgs(value);
|
|
4247
4372
|
}
|
|
4248
4373
|
}
|