@danielhritcu/zenstack-orm 3.5.4 → 3.5.6

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.cts CHANGED
@@ -234,6 +234,19 @@ declare const FILTER_PROPERTY_TO_KIND: {
234
234
  */
235
235
  type FilterPropertyToKind = typeof FILTER_PROPERTY_TO_KIND;
236
236
 
237
+ type SearchMode = 'contains' | 'startsWith' | 'equals';
238
+ type SearchStrategy = 'all' | 'any';
239
+ interface SearchFieldMap {
240
+ [key: string]: true | SearchFieldMap;
241
+ }
242
+ interface SearchPayload {
243
+ q: string;
244
+ fields?: SearchFieldMap;
245
+ profile?: string;
246
+ mode?: SearchMode;
247
+ strategy?: SearchStrategy;
248
+ }
249
+
237
250
  type ToKyselySchema<Schema extends SchemaDef> = {
238
251
  [Model in GetModels<Schema>]: ToKyselyTable<Schema, Model>;
239
252
  };
@@ -637,6 +650,13 @@ type FieldSlicingOptions = {
637
650
  */
638
651
  excludedFilterKinds?: readonly FilterKind[];
639
652
  };
653
+ /**
654
+ * Configuration for default where clauses applied to all queries.
655
+ * `$all` applies to every model. Model-specific keys override `$all`.
656
+ */
657
+ type DefaultWhereConfig = {
658
+ $all?: Record<string, unknown>;
659
+ } & Record<string, Record<string, unknown> | undefined>;
640
660
  /**
641
661
  * Partial ORM client options that defines customizable behaviors.
642
662
  */
@@ -659,6 +679,17 @@ type QueryOptions<Schema extends SchemaDef> = {
659
679
  * ZenStack client options.
660
680
  */
661
681
  type ClientOptions<Schema extends SchemaDef> = QueryOptions<Schema> & {
682
+ /**
683
+ * Default query options applied to all operations.
684
+ */
685
+ default?: {
686
+ /**
687
+ * Default where clauses merged into every query. `$all` applies to all models.
688
+ * Model-specific keys override `$all`. Accepts a static object or a function
689
+ * for request-scoped values.
690
+ */
691
+ where?: DefaultWhereConfig | (() => DefaultWhereConfig);
692
+ };
662
693
  /**
663
694
  * Kysely dialect.
664
695
  */
@@ -1154,6 +1185,7 @@ type WhereInput<Schema extends SchemaDef, Model extends GetModels<Schema>, Optio
1154
1185
  [Key in GetModelFields<Schema, Model> as ScalarOnly extends true ? Key extends RelationFields<Schema, Model> ? never : Key : Key]?: FieldFilter<Schema, Model, Key, Options, WithAggregations>;
1155
1186
  } & {
1156
1187
  $expr?: (eb: ExpressionBuilder<ToKyselySchema<Schema>, Model>) => OperandExpression<SqlBool>;
1188
+ search?: SearchPayload;
1157
1189
  } & {
1158
1190
  AND?: OrArray<WhereInput<Schema, Model, Options, ScalarOnly>>;
1159
1191
  OR?: WhereInput<Schema, Model, Options, ScalarOnly>[];
@@ -3374,4 +3406,4 @@ declare namespace schemaUtils {
3374
3406
  export { schemaUtils_ExpressionVisitor as ExpressionVisitor, schemaUtils_MatchingExpressionVisitor as MatchingExpressionVisitor, type schemaUtils_VisitResult as VisitResult };
3375
3407
  }
3376
3408
 
3377
- export { type AfterEntityMutationCallback, type AggregateArgs, type AggregateResult, AllCrudOperations, type AllModelOperations, AllReadOperations, AnyNull, AnyNullClass, type AnyPlugin, type AuthType, BaseCrudDialect, type BatchResult, type BeforeEntityMutationCallback, type BooleanFilter, type BytesFilter, CRUD, CRUD_EXT, type ClientConstructor, type ClientContract, type ClientOptions, type ComputedFieldsOptions, CoreCreateOperations, CoreCrudOperations, CoreDeleteOperations, CoreReadOperations, CoreUpdateOperations, CoreWriteOperations, type CountArgs, type CountResult, type CreateArgs, type CreateInput, type CreateManyAndReturnArgs, type CreateManyArgs, type CreateManyInput, type DateTimeFilter, DbNull, DbNullClass, type DefaultModelResult, type DeleteArgs, type DeleteManyArgs, type EntityMutationHooksDef, type ExistsArgs, type ExtClientMembersBase, type ExtQueryArgsBase, type ExtResultBase, type ExtResultInferenceArgs, type ExtResultSelectOmitFields, type ExtractExtResult, type FilterKind, type FindArgs, type FindFirstArgs, type FindManyArgs, type FindUniqueArgs, type GetAllIncludedOperations, type GetIncludedOperations, type GetProcedure, type GetProcedureNames, type GetProcedureParams, type GetQueryOptions, type GetSlicedFilterKindsForField, type GetSlicedModels, type GetSlicedOperations, type GetSlicedProcedures, type GroupByArgs, type GroupByResult, type HasComputedFields, type HasProcedures, type IncludeInput, InputValidator, type JsonArray, type JsonFilter, JsonNull, JsonNullClass, type JsonNullValues, type JsonObject, type JsonValue, kyselyUtils as KyselyUtils, LOGICAL_COMBINATORS, type MapModelFieldType, type ModelAllowsCreate, type ModelHasRequiredUnsupportedField, type ModelOperations, type ModelResult, type ModelSlicingOptions, type NullsOrder, type NumberFilter, ORMError, ORMErrorReason, type OmitConfig, type OmitInput, type OnKyselyQueryArgs, type OnKyselyQueryCallback, type OnProcedureHookContext, type OperationsRequiringCreate, type OrderBy, type PluginAfterEntityMutationArgs, type PluginBeforeEntityMutationArgs, type ProcedureEnvelope, type ProcedureFunc, type ProcedureHandlerFunc, type ProcedureOperations, type ProceduresOptions, type ProceedKyselyQueryFunction, type QueryOptions, queryUtils as QueryUtils, RejectedByPolicyReason, type RuntimePlugin, schemaUtils as SchemaUtils, type SelectAwareExtResult, type SelectIncludeOmit, type SelectInput, type SelectSubset, type SimplifiedPlainResult, type SimplifiedResult, type SlicingOptions, type SortOrder, type StringFilter, type Subset, type ToKysely, type TransactionClientContract, TransactionIsolationLevel, type TypeDefResult, type TypedJsonFilter, type UpdateArgs, type UpdateInput, type UpdateManyAndReturnArgs, type UpdateManyArgs, type UpsertArgs, type WhereInput, type WhereUniqueInput, ZENSTACK_QUERY_KIND_SYMBOL, ZENSTACK_QUERY_SYMBOL, type ZModelFunction, type ZModelFunctionContext, ZenStackClient, type ZenStackPromise, type ZenStackQueryKind, createQuerySchemaFactory, definePlugin, getCrudDialect };
3409
+ export { type AfterEntityMutationCallback, type AggregateArgs, type AggregateResult, AllCrudOperations, type AllModelOperations, AllReadOperations, AnyNull, AnyNullClass, type AnyPlugin, type AuthType, BaseCrudDialect, type BatchResult, type BeforeEntityMutationCallback, type BooleanFilter, type BytesFilter, CRUD, CRUD_EXT, type ClientConstructor, type ClientContract, type ClientOptions, type ComputedFieldsOptions, CoreCreateOperations, CoreCrudOperations, CoreDeleteOperations, CoreReadOperations, CoreUpdateOperations, CoreWriteOperations, type CountArgs, type CountResult, type CreateArgs, type CreateInput, type CreateManyAndReturnArgs, type CreateManyArgs, type CreateManyInput, type DateTimeFilter, DbNull, DbNullClass, type DefaultModelResult, type DefaultWhereConfig, type DeleteArgs, type DeleteManyArgs, type EntityMutationHooksDef, type ExistsArgs, type ExtClientMembersBase, type ExtQueryArgsBase, type ExtResultBase, type ExtResultInferenceArgs, type ExtResultSelectOmitFields, type ExtractExtResult, type FilterKind, type FindArgs, type FindFirstArgs, type FindManyArgs, type FindUniqueArgs, type GetAllIncludedOperations, type GetIncludedOperations, type GetProcedure, type GetProcedureNames, type GetProcedureParams, type GetQueryOptions, type GetSlicedFilterKindsForField, type GetSlicedModels, type GetSlicedOperations, type GetSlicedProcedures, type GroupByArgs, type GroupByResult, type HasComputedFields, type HasProcedures, type IncludeInput, InputValidator, type JsonArray, type JsonFilter, JsonNull, JsonNullClass, type JsonNullValues, type JsonObject, type JsonValue, kyselyUtils as KyselyUtils, LOGICAL_COMBINATORS, type MapModelFieldType, type ModelAllowsCreate, type ModelHasRequiredUnsupportedField, type ModelOperations, type ModelResult, type ModelSlicingOptions, type NullsOrder, type NumberFilter, ORMError, ORMErrorReason, type OmitConfig, type OmitInput, type OnKyselyQueryArgs, type OnKyselyQueryCallback, type OnProcedureHookContext, type OperationsRequiringCreate, type OrderBy, type PluginAfterEntityMutationArgs, type PluginBeforeEntityMutationArgs, type ProcedureEnvelope, type ProcedureFunc, type ProcedureHandlerFunc, type ProcedureOperations, type ProceduresOptions, type ProceedKyselyQueryFunction, type QueryOptions, queryUtils as QueryUtils, RejectedByPolicyReason, type RuntimePlugin, schemaUtils as SchemaUtils, type SearchFieldMap, type SearchMode, type SearchPayload, type SearchStrategy, type SelectAwareExtResult, type SelectIncludeOmit, type SelectInput, type SelectSubset, type SimplifiedPlainResult, type SimplifiedResult, type SlicingOptions, type SortOrder, type StringFilter, type Subset, type ToKysely, type TransactionClientContract, TransactionIsolationLevel, type TypeDefResult, type TypedJsonFilter, type UpdateArgs, type UpdateInput, type UpdateManyAndReturnArgs, type UpdateManyArgs, type UpsertArgs, type WhereInput, type WhereUniqueInput, ZENSTACK_QUERY_KIND_SYMBOL, ZENSTACK_QUERY_SYMBOL, type ZModelFunction, type ZModelFunctionContext, ZenStackClient, type ZenStackPromise, type ZenStackQueryKind, createQuerySchemaFactory, definePlugin, getCrudDialect };
package/dist/index.d.ts CHANGED
@@ -234,6 +234,19 @@ declare const FILTER_PROPERTY_TO_KIND: {
234
234
  */
235
235
  type FilterPropertyToKind = typeof FILTER_PROPERTY_TO_KIND;
236
236
 
237
+ type SearchMode = 'contains' | 'startsWith' | 'equals';
238
+ type SearchStrategy = 'all' | 'any';
239
+ interface SearchFieldMap {
240
+ [key: string]: true | SearchFieldMap;
241
+ }
242
+ interface SearchPayload {
243
+ q: string;
244
+ fields?: SearchFieldMap;
245
+ profile?: string;
246
+ mode?: SearchMode;
247
+ strategy?: SearchStrategy;
248
+ }
249
+
237
250
  type ToKyselySchema<Schema extends SchemaDef> = {
238
251
  [Model in GetModels<Schema>]: ToKyselyTable<Schema, Model>;
239
252
  };
@@ -637,6 +650,13 @@ type FieldSlicingOptions = {
637
650
  */
638
651
  excludedFilterKinds?: readonly FilterKind[];
639
652
  };
653
+ /**
654
+ * Configuration for default where clauses applied to all queries.
655
+ * `$all` applies to every model. Model-specific keys override `$all`.
656
+ */
657
+ type DefaultWhereConfig = {
658
+ $all?: Record<string, unknown>;
659
+ } & Record<string, Record<string, unknown> | undefined>;
640
660
  /**
641
661
  * Partial ORM client options that defines customizable behaviors.
642
662
  */
@@ -659,6 +679,17 @@ type QueryOptions<Schema extends SchemaDef> = {
659
679
  * ZenStack client options.
660
680
  */
661
681
  type ClientOptions<Schema extends SchemaDef> = QueryOptions<Schema> & {
682
+ /**
683
+ * Default query options applied to all operations.
684
+ */
685
+ default?: {
686
+ /**
687
+ * Default where clauses merged into every query. `$all` applies to all models.
688
+ * Model-specific keys override `$all`. Accepts a static object or a function
689
+ * for request-scoped values.
690
+ */
691
+ where?: DefaultWhereConfig | (() => DefaultWhereConfig);
692
+ };
662
693
  /**
663
694
  * Kysely dialect.
664
695
  */
@@ -1154,6 +1185,7 @@ type WhereInput<Schema extends SchemaDef, Model extends GetModels<Schema>, Optio
1154
1185
  [Key in GetModelFields<Schema, Model> as ScalarOnly extends true ? Key extends RelationFields<Schema, Model> ? never : Key : Key]?: FieldFilter<Schema, Model, Key, Options, WithAggregations>;
1155
1186
  } & {
1156
1187
  $expr?: (eb: ExpressionBuilder<ToKyselySchema<Schema>, Model>) => OperandExpression<SqlBool>;
1188
+ search?: SearchPayload;
1157
1189
  } & {
1158
1190
  AND?: OrArray<WhereInput<Schema, Model, Options, ScalarOnly>>;
1159
1191
  OR?: WhereInput<Schema, Model, Options, ScalarOnly>[];
@@ -3374,4 +3406,4 @@ declare namespace schemaUtils {
3374
3406
  export { schemaUtils_ExpressionVisitor as ExpressionVisitor, schemaUtils_MatchingExpressionVisitor as MatchingExpressionVisitor, type schemaUtils_VisitResult as VisitResult };
3375
3407
  }
3376
3408
 
3377
- export { type AfterEntityMutationCallback, type AggregateArgs, type AggregateResult, AllCrudOperations, type AllModelOperations, AllReadOperations, AnyNull, AnyNullClass, type AnyPlugin, type AuthType, BaseCrudDialect, type BatchResult, type BeforeEntityMutationCallback, type BooleanFilter, type BytesFilter, CRUD, CRUD_EXT, type ClientConstructor, type ClientContract, type ClientOptions, type ComputedFieldsOptions, CoreCreateOperations, CoreCrudOperations, CoreDeleteOperations, CoreReadOperations, CoreUpdateOperations, CoreWriteOperations, type CountArgs, type CountResult, type CreateArgs, type CreateInput, type CreateManyAndReturnArgs, type CreateManyArgs, type CreateManyInput, type DateTimeFilter, DbNull, DbNullClass, type DefaultModelResult, type DeleteArgs, type DeleteManyArgs, type EntityMutationHooksDef, type ExistsArgs, type ExtClientMembersBase, type ExtQueryArgsBase, type ExtResultBase, type ExtResultInferenceArgs, type ExtResultSelectOmitFields, type ExtractExtResult, type FilterKind, type FindArgs, type FindFirstArgs, type FindManyArgs, type FindUniqueArgs, type GetAllIncludedOperations, type GetIncludedOperations, type GetProcedure, type GetProcedureNames, type GetProcedureParams, type GetQueryOptions, type GetSlicedFilterKindsForField, type GetSlicedModels, type GetSlicedOperations, type GetSlicedProcedures, type GroupByArgs, type GroupByResult, type HasComputedFields, type HasProcedures, type IncludeInput, InputValidator, type JsonArray, type JsonFilter, JsonNull, JsonNullClass, type JsonNullValues, type JsonObject, type JsonValue, kyselyUtils as KyselyUtils, LOGICAL_COMBINATORS, type MapModelFieldType, type ModelAllowsCreate, type ModelHasRequiredUnsupportedField, type ModelOperations, type ModelResult, type ModelSlicingOptions, type NullsOrder, type NumberFilter, ORMError, ORMErrorReason, type OmitConfig, type OmitInput, type OnKyselyQueryArgs, type OnKyselyQueryCallback, type OnProcedureHookContext, type OperationsRequiringCreate, type OrderBy, type PluginAfterEntityMutationArgs, type PluginBeforeEntityMutationArgs, type ProcedureEnvelope, type ProcedureFunc, type ProcedureHandlerFunc, type ProcedureOperations, type ProceduresOptions, type ProceedKyselyQueryFunction, type QueryOptions, queryUtils as QueryUtils, RejectedByPolicyReason, type RuntimePlugin, schemaUtils as SchemaUtils, type SelectAwareExtResult, type SelectIncludeOmit, type SelectInput, type SelectSubset, type SimplifiedPlainResult, type SimplifiedResult, type SlicingOptions, type SortOrder, type StringFilter, type Subset, type ToKysely, type TransactionClientContract, TransactionIsolationLevel, type TypeDefResult, type TypedJsonFilter, type UpdateArgs, type UpdateInput, type UpdateManyAndReturnArgs, type UpdateManyArgs, type UpsertArgs, type WhereInput, type WhereUniqueInput, ZENSTACK_QUERY_KIND_SYMBOL, ZENSTACK_QUERY_SYMBOL, type ZModelFunction, type ZModelFunctionContext, ZenStackClient, type ZenStackPromise, type ZenStackQueryKind, createQuerySchemaFactory, definePlugin, getCrudDialect };
3409
+ export { type AfterEntityMutationCallback, type AggregateArgs, type AggregateResult, AllCrudOperations, type AllModelOperations, AllReadOperations, AnyNull, AnyNullClass, type AnyPlugin, type AuthType, BaseCrudDialect, type BatchResult, type BeforeEntityMutationCallback, type BooleanFilter, type BytesFilter, CRUD, CRUD_EXT, type ClientConstructor, type ClientContract, type ClientOptions, type ComputedFieldsOptions, CoreCreateOperations, CoreCrudOperations, CoreDeleteOperations, CoreReadOperations, CoreUpdateOperations, CoreWriteOperations, type CountArgs, type CountResult, type CreateArgs, type CreateInput, type CreateManyAndReturnArgs, type CreateManyArgs, type CreateManyInput, type DateTimeFilter, DbNull, DbNullClass, type DefaultModelResult, type DefaultWhereConfig, type DeleteArgs, type DeleteManyArgs, type EntityMutationHooksDef, type ExistsArgs, type ExtClientMembersBase, type ExtQueryArgsBase, type ExtResultBase, type ExtResultInferenceArgs, type ExtResultSelectOmitFields, type ExtractExtResult, type FilterKind, type FindArgs, type FindFirstArgs, type FindManyArgs, type FindUniqueArgs, type GetAllIncludedOperations, type GetIncludedOperations, type GetProcedure, type GetProcedureNames, type GetProcedureParams, type GetQueryOptions, type GetSlicedFilterKindsForField, type GetSlicedModels, type GetSlicedOperations, type GetSlicedProcedures, type GroupByArgs, type GroupByResult, type HasComputedFields, type HasProcedures, type IncludeInput, InputValidator, type JsonArray, type JsonFilter, JsonNull, JsonNullClass, type JsonNullValues, type JsonObject, type JsonValue, kyselyUtils as KyselyUtils, LOGICAL_COMBINATORS, type MapModelFieldType, type ModelAllowsCreate, type ModelHasRequiredUnsupportedField, type ModelOperations, type ModelResult, type ModelSlicingOptions, type NullsOrder, type NumberFilter, ORMError, ORMErrorReason, type OmitConfig, type OmitInput, type OnKyselyQueryArgs, type OnKyselyQueryCallback, type OnProcedureHookContext, type OperationsRequiringCreate, type OrderBy, type PluginAfterEntityMutationArgs, type PluginBeforeEntityMutationArgs, type ProcedureEnvelope, type ProcedureFunc, type ProcedureHandlerFunc, type ProcedureOperations, type ProceduresOptions, type ProceedKyselyQueryFunction, type QueryOptions, queryUtils as QueryUtils, RejectedByPolicyReason, type RuntimePlugin, schemaUtils as SchemaUtils, type SearchFieldMap, type SearchMode, type SearchPayload, type SearchStrategy, type SelectAwareExtResult, type SelectIncludeOmit, type SelectInput, type SelectSubset, type SimplifiedPlainResult, type SimplifiedResult, type SlicingOptions, type SortOrder, type StringFilter, type Subset, type ToKysely, type TransactionClientContract, TransactionIsolationLevel, type TypeDefResult, type TypedJsonFilter, type UpdateArgs, type UpdateInput, type UpdateManyAndReturnArgs, type UpdateManyArgs, type UpsertArgs, type WhereInput, type WhereUniqueInput, ZENSTACK_QUERY_KIND_SYMBOL, ZENSTACK_QUERY_SYMBOL, type ZModelFunction, type ZModelFunctionContext, ZenStackClient, type ZenStackPromise, type ZenStackQueryKind, createQuerySchemaFactory, definePlugin, getCrudDialect };
package/dist/index.js CHANGED
@@ -617,7 +617,7 @@ __name(tmpAlias, "tmpAlias");
617
617
 
618
618
  // src/client/crud/operations/base.ts
619
619
  import { createId as cuid2 } from "@paralleldrive/cuid2";
620
- import { clone, enumerate as enumerate2, invariant as invariant7, isPlainObject as isPlainObject2 } from "@zenstackhq/common-helpers";
620
+ import { clone, enumerate as enumerate2, invariant as invariant7, isPlainObject as isPlainObject3 } from "@zenstackhq/common-helpers";
621
621
  import { default as cuid1 } from "cuid";
622
622
  import { createQueryId, expressionBuilder as expressionBuilder5, sql as sql5 } from "kysely";
623
623
  import { nanoid } from "nanoid";
@@ -2775,6 +2775,224 @@ function getCrudDialect(schema, options) {
2775
2775
  }
2776
2776
  __name(getCrudDialect, "getCrudDialect");
2777
2777
 
2778
+ // src/client/plugins/search.ts
2779
+ import { isPlainObject as isPlainObject2 } from "@zenstackhq/common-helpers";
2780
+ function isSearchPayload(value) {
2781
+ return isPlainObject2(value) && typeof value.q === "string" && (value.fields !== void 0 || value.profile !== void 0);
2782
+ }
2783
+ __name(isSearchPayload, "isSearchPayload");
2784
+ function buildStringFilter(mode, token) {
2785
+ if (mode === "equals") return {
2786
+ equals: token,
2787
+ mode: "insensitive"
2788
+ };
2789
+ if (mode === "startsWith") return {
2790
+ startsWith: token,
2791
+ mode: "insensitive"
2792
+ };
2793
+ return {
2794
+ contains: token,
2795
+ mode: "insensitive"
2796
+ };
2797
+ }
2798
+ __name(buildStringFilter, "buildStringFilter");
2799
+ function unique(arr) {
2800
+ return [
2801
+ ...new Set(arr)
2802
+ ];
2803
+ }
2804
+ __name(unique, "unique");
2805
+ function extractSearch(where) {
2806
+ if (Array.isArray(where)) {
2807
+ let found2;
2808
+ const cleaned2 = [];
2809
+ for (const item of where) {
2810
+ const result = extractSearch(item);
2811
+ if (result.search) found2 = result.search;
2812
+ cleaned2.push(result.where);
2813
+ }
2814
+ return {
2815
+ where: cleaned2,
2816
+ search: found2
2817
+ };
2818
+ }
2819
+ if (!isPlainObject2(where)) {
2820
+ return {
2821
+ where
2822
+ };
2823
+ }
2824
+ const obj = where;
2825
+ let found;
2826
+ const cleaned = {};
2827
+ for (const [key, value] of Object.entries(obj)) {
2828
+ if (key === "search" && isSearchPayload(value)) {
2829
+ found = value;
2830
+ continue;
2831
+ }
2832
+ if (key === "AND" || key === "OR") {
2833
+ const result = extractSearch(value);
2834
+ if (result.search) found = result.search;
2835
+ cleaned[key] = result.where;
2836
+ } else if (key === "NOT") {
2837
+ const result = extractSearch(value);
2838
+ if (result.search) found = result.search;
2839
+ cleaned[key] = result.where;
2840
+ } else {
2841
+ cleaned[key] = value;
2842
+ }
2843
+ }
2844
+ return {
2845
+ where: cleaned,
2846
+ search: found
2847
+ };
2848
+ }
2849
+ __name(extractSearch, "extractSearch");
2850
+ function buildTokenFilter(model, fields, token, mode, models, virtualRelations) {
2851
+ const clauses = [];
2852
+ const modelDef = models[model];
2853
+ if (!modelDef) return void 0;
2854
+ for (const [fieldName, fieldSpec] of Object.entries(fields)) {
2855
+ const schemaDef = modelDef.fields[fieldName];
2856
+ if (schemaDef) {
2857
+ if (schemaDef.relation) {
2858
+ const childFields = fieldSpec === true ? void 0 : fieldSpec;
2859
+ if (!childFields) continue;
2860
+ const childFilter = buildTokenFilter(schemaDef.type, childFields, token, mode, models, virtualRelations);
2861
+ if (childFilter) {
2862
+ if (schemaDef.array) {
2863
+ clauses.push({
2864
+ [fieldName]: {
2865
+ some: childFilter
2866
+ }
2867
+ });
2868
+ } else {
2869
+ clauses.push({
2870
+ [fieldName]: childFilter
2871
+ });
2872
+ }
2873
+ }
2874
+ } else if (schemaDef.type === "String") {
2875
+ clauses.push({
2876
+ [fieldName]: buildStringFilter(mode, token)
2877
+ });
2878
+ }
2879
+ } else if (virtualRelations) {
2880
+ const modelVRs = virtualRelations[model];
2881
+ const vr = modelVRs?.[fieldName];
2882
+ if (!vr) continue;
2883
+ const childFields = fieldSpec === true ? void 0 : fieldSpec;
2884
+ if (!childFields) continue;
2885
+ if (vr.kind === "filtered" && vr.relation) {
2886
+ const sourceFieldDef = modelDef.fields[vr.relation];
2887
+ if (!sourceFieldDef) continue;
2888
+ const childFilter = buildTokenFilter(sourceFieldDef.type, childFields, token, mode, models, virtualRelations);
2889
+ if (childFilter) {
2890
+ const mergedChild = vr.where ? {
2891
+ AND: [
2892
+ childFilter,
2893
+ vr.where
2894
+ ]
2895
+ } : childFilter;
2896
+ if (sourceFieldDef.array) {
2897
+ clauses.push({
2898
+ [vr.relation]: {
2899
+ some: mergedChild
2900
+ }
2901
+ });
2902
+ } else {
2903
+ clauses.push({
2904
+ [vr.relation]: mergedChild
2905
+ });
2906
+ }
2907
+ }
2908
+ } else if (vr.kind === "through" && vr.path) {
2909
+ const [sourceField, ...restPath] = vr.path;
2910
+ if (!sourceField) continue;
2911
+ const sourceFieldDef = modelDef.fields[sourceField];
2912
+ if (!sourceFieldDef) continue;
2913
+ let currentModel2 = sourceFieldDef.type;
2914
+ for (const segment of restPath) {
2915
+ const m = models[currentModel2];
2916
+ if (!m) break;
2917
+ const f = m.fields[segment];
2918
+ if (!f) break;
2919
+ currentModel2 = f.type;
2920
+ }
2921
+ const childFilter = buildTokenFilter(currentModel2, childFields, token, mode, models, virtualRelations);
2922
+ if (childFilter) {
2923
+ let wrapped = childFilter;
2924
+ for (let i = restPath.length - 1; i >= 0; i--) {
2925
+ const seg = restPath[i];
2926
+ wrapped = {
2927
+ [seg]: wrapped
2928
+ };
2929
+ }
2930
+ if (sourceFieldDef.array) {
2931
+ clauses.push({
2932
+ [sourceField]: {
2933
+ some: wrapped
2934
+ }
2935
+ });
2936
+ } else {
2937
+ clauses.push({
2938
+ [sourceField]: wrapped
2939
+ });
2940
+ }
2941
+ }
2942
+ }
2943
+ }
2944
+ }
2945
+ if (clauses.length === 0) return void 0;
2946
+ if (clauses.length === 1) return clauses[0];
2947
+ return {
2948
+ OR: clauses
2949
+ };
2950
+ }
2951
+ __name(buildTokenFilter, "buildTokenFilter");
2952
+ function expandSearch(model, where, searchDefaults, schemaModels, virtualRelations) {
2953
+ if (!where || !isPlainObject2(where)) return {
2954
+ where
2955
+ };
2956
+ const { where: remaining, search: search2 } = extractSearch(where);
2957
+ if (!search2) return {
2958
+ where
2959
+ };
2960
+ const profile = search2.profile ? searchDefaults?.[model]?.[search2.profile] : void 0;
2961
+ const fields = search2.fields ?? profile?.fields;
2962
+ if (!fields) return {
2963
+ where: remaining
2964
+ };
2965
+ const mode = search2.mode ?? profile?.mode ?? "contains";
2966
+ const strategy = search2.strategy ?? profile?.strategy ?? "all";
2967
+ const tokens = unique(search2.q.trim().split(/\s+/).map((t) => t.toLowerCase()).filter(Boolean));
2968
+ if (tokens.length === 0) return {
2969
+ where: remaining
2970
+ };
2971
+ const tokenClauses = tokens.map((t) => buildTokenFilter(model, fields, t, mode, schemaModels, virtualRelations)).filter((c) => c !== void 0);
2972
+ if (tokenClauses.length === 0) return {
2973
+ where: remaining
2974
+ };
2975
+ const searchWhere = tokenClauses.length === 1 ? tokenClauses[0] : strategy === "any" ? {
2976
+ OR: tokenClauses
2977
+ } : {
2978
+ AND: tokenClauses
2979
+ };
2980
+ const remainingObj = remaining;
2981
+ const hasRemaining = Object.keys(remainingObj).length > 0;
2982
+ if (!hasRemaining) return {
2983
+ where: searchWhere
2984
+ };
2985
+ return {
2986
+ where: {
2987
+ AND: [
2988
+ remainingObj,
2989
+ searchWhere
2990
+ ]
2991
+ }
2992
+ };
2993
+ }
2994
+ __name(expandSearch, "expandSearch");
2995
+
2778
2996
  // src/client/crud/operations/base.ts
2779
2997
  var CoreCrudOperations2 = [
2780
2998
  "findMany",
@@ -3133,9 +3351,49 @@ var BaseOperationHandler = class {
3133
3351
  return result;
3134
3352
  }
3135
3353
  // --- End schema plugin defaults ---
3354
+ // --- Search expansion ---
3355
+ applySearchExpansion(model, args) {
3356
+ const searchDefaults = this.schema.plugins?.searchDefaults;
3357
+ if (!searchDefaults) return args;
3358
+ if (!args?.where) return args;
3359
+ const schemaModels = this.schema.models;
3360
+ if (!schemaModels) return args;
3361
+ const virtualRelations = this.schema.plugins?.virtualRelations;
3362
+ const { where } = expandSearch(model, args.where, searchDefaults, schemaModels, virtualRelations);
3363
+ return {
3364
+ ...args,
3365
+ where
3366
+ };
3367
+ }
3368
+ // --- End search expansion ---
3369
+ applyDefaultWhere(model, args) {
3370
+ const defaultOpt = this.client?.$options?.default?.where;
3371
+ if (!defaultOpt) return args;
3372
+ const config = typeof defaultOpt === "function" ? defaultOpt() : defaultOpt;
3373
+ if (!config) return args;
3374
+ const modelWhere = config[model] ?? config.$all;
3375
+ if (!modelWhere || typeof modelWhere !== "object") return args;
3376
+ let result = args ? {
3377
+ ...args
3378
+ } : {};
3379
+ const userWhere = result.where ?? {};
3380
+ const mergedWhere = {
3381
+ ...userWhere
3382
+ };
3383
+ const modelFields = this.schema.models?.[model]?.fields;
3384
+ for (const [key, value] of Object.entries(modelWhere)) {
3385
+ if (key in userWhere) continue;
3386
+ if (modelFields && !(key in modelFields)) continue;
3387
+ mergedWhere[key] = value;
3388
+ }
3389
+ result.where = Object.keys(mergedWhere).length > 0 ? mergedWhere : void 0;
3390
+ return result;
3391
+ }
3136
3392
  async read(kysely, model, args) {
3137
- const defaultedArgs = this.applySchemaPluginDefaults(model, args);
3138
- const { args: rewrittenArgs, plan } = this.rewriteVirtualRelations(model, defaultedArgs);
3393
+ const defaultWhereArgs = this.applyDefaultWhere(model, args);
3394
+ const defaultedArgs = this.applySchemaPluginDefaults(model, defaultWhereArgs);
3395
+ const searchExpandedArgs = this.applySearchExpansion(model, defaultedArgs);
3396
+ const { args: rewrittenArgs, plan } = this.rewriteVirtualRelations(model, searchExpandedArgs);
3139
3397
  const query = this.buildReadQuery(model, rewrittenArgs);
3140
3398
  let result = [];
3141
3399
  const compiled = kysely.getExecutor().compileQuery(query.toOperationNode(), createQueryId());
@@ -4555,7 +4813,7 @@ var BaseOperationHandler = class {
4555
4813
  for (const [key, value] of Object.entries(args)) {
4556
4814
  if (value === void 0) {
4557
4815
  delete args[key];
4558
- } else if (value && isPlainObject2(value)) {
4816
+ } else if (value && isPlainObject3(value)) {
4559
4817
  this.doNormalizeArgs(value);
4560
4818
  }
4561
4819
  }
@@ -5357,10 +5615,10 @@ var ZodSchemaFactory = class {
5357
5615
  }
5358
5616
  makeFindSchema(model, operation, options) {
5359
5617
  const fields = {};
5360
- const unique = operation === "findUnique";
5618
+ const unique2 = operation === "findUnique";
5361
5619
  const findOne = operation === "findUnique" || operation === "findFirst";
5362
- const where = this.makeWhereSchema(model, unique, false, false, options);
5363
- if (unique) {
5620
+ const where = this.makeWhereSchema(model, unique2, false, false, options);
5621
+ if (unique2) {
5364
5622
  fields["where"] = where;
5365
5623
  } else {
5366
5624
  fields["where"] = where.optional();
@@ -5368,7 +5626,7 @@ var ZodSchemaFactory = class {
5368
5626
  fields["select"] = this.makeSelectSchema(model, options).optional().nullable();
5369
5627
  fields["include"] = this.makeIncludeSchema(model, options).optional().nullable();
5370
5628
  fields["omit"] = this.makeOmitSchema(model).optional().nullable();
5371
- if (!unique) {
5629
+ if (!unique2) {
5372
5630
  fields["skip"] = this.makeSkipSchema().optional();
5373
5631
  if (findOne) {
5374
5632
  fields["take"] = z.literal(1).optional();
@@ -5384,7 +5642,7 @@ var ZodSchemaFactory = class {
5384
5642
  result = this.refineForSelectIncludeMutuallyExclusive(result);
5385
5643
  result = this.refineForSelectOmitMutuallyExclusive(result);
5386
5644
  result = this.refineForSelectHasTruthyField(result);
5387
- if (!unique) {
5645
+ if (!unique2) {
5388
5646
  result = result.optional();
5389
5647
  }
5390
5648
  return result;
@@ -5445,8 +5703,8 @@ var ZodSchemaFactory = class {
5445
5703
  });
5446
5704
  return finalSchema;
5447
5705
  }
5448
- makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false, options) {
5449
- const uniqueFieldNames = unique ? getUniqueFields(this.schema, model).filter((uf) => (
5706
+ makeWhereSchema(model, unique2, withoutRelationFields = false, withAggregations = false, options) {
5707
+ const uniqueFieldNames = unique2 ? getUniqueFields(this.schema, model).filter((uf) => (
5450
5708
  // single-field unique
5451
5709
  "def" in uf
5452
5710
  )).map((uf) => uf.name) : void 0;
@@ -5502,7 +5760,7 @@ var ZodSchemaFactory = class {
5502
5760
  fields[field] = fieldSchema.optional();
5503
5761
  }
5504
5762
  }
5505
- if (unique) {
5763
+ if (unique2) {
5506
5764
  const uniqueFields = getUniqueFields(this.schema, model);
5507
5765
  for (const uniqueField of uniqueFields) {
5508
5766
  if ("defs" in uniqueField) {
@@ -5539,7 +5797,7 @@ var ZodSchemaFactory = class {
5539
5797
  fields["NOT"] = this.orArray(z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields, false, options)), true).optional();
5540
5798
  const baseWhere = z.strictObject(fields);
5541
5799
  let result = baseWhere;
5542
- if (unique) {
5800
+ if (unique2) {
5543
5801
  const uniqueFields = getUniqueFields(this.schema, model);
5544
5802
  if (uniqueFields.length === 0) {
5545
5803
  throw createInternalError(`Model "${model}" has no unique fields`);