@@ -377,53 +377,94 @@ type FieldFilter<
377377 AllowedKinds
378378 >
379379 : // primitive
380- AddFuzzyFilterIfSupported <
381- Schema ,
382- Model ,
383- Field ,
384- AllowedKinds ,
385- PrimitiveFilter <
386- GetModelFieldType < Schema , Model , Field > ,
387- ModelFieldIsOptional < Schema , Model , Field > ,
388- WithAggregations ,
389- AllowedKinds
390- >
391- > ;
380+ GetModelFieldType < Schema , Model , Field > extends 'String'
381+ ? // string — additionally consider fuzzy / full-text augmentations
382+ AddFullTextFilterIfSupported <
383+ Schema ,
384+ Model ,
385+ Field ,
386+ AllowedKinds ,
387+ AddFuzzyFilterIfSupported <
388+ Schema ,
389+ Model ,
390+ Field ,
391+ AllowedKinds ,
392+ PrimitiveFilter <
393+ GetModelFieldType < Schema , Model , Field > ,
394+ ModelFieldIsOptional < Schema , Model , Field > ,
395+ WithAggregations ,
396+ AllowedKinds
397+ >
398+ >
399+ >
400+ : PrimitiveFilter <
401+ GetModelFieldType < Schema , Model , Field > ,
402+ ModelFieldIsOptional < Schema , Model , Field > ,
403+ WithAggregations ,
404+ AllowedKinds
405+ > ;
392406
393407/**
394- * Conditionally augments a primitive filter with the `fuzzy` operator when:
395- * 1. The field's type is `String`, AND
396- * 2. The `Fuzzy` filter kind is allowed for this field, AND
397- * 3. The schema's provider supports fuzzy search (postgres only), AND
398- * 4. The field is annotated with `@fuzzy` in the ZModel schema.
408+ * Conditionally augments a string-field filter with the `fuzzy` operator when:
409+ * 1. The `Fuzzy` filter kind is allowed for this field, AND
410+ * 2. The schema's provider supports fuzzy search (postgres only), AND
411+ * 3. The field is annotated with `@fuzzy` in the ZModel schema.
399412 *
400- * Returns `Base` unchanged when any condition fails — never `Base & {}`,
401- * since intersecting with `{}` would strip `null`/`undefined` from `Base` .
413+ * Caller is responsible for only invoking this on String-typed fields
414+ * (the gate lives in `FieldFilter`) .
402415 */
403416type AddFuzzyFilterIfSupported <
404417 Schema extends SchemaDef ,
405418 Model extends GetModels < Schema > ,
406419 Field extends GetModelFields < Schema , Model > ,
407420 AllowedKinds extends FilterKind ,
408421 Base ,
409- > =
410- GetModelFieldType < Schema , Model , Field > extends 'String'
411- ? 'Fuzzy' extends AllowedKinds
412- ? ProviderSupportsFuzzy < Schema > extends true
413- ? GetModelField < Schema , Model , Field > [ 'fuzzy' ] extends true
414- ? Base & {
415- /**
416- * Performs a fuzzy search on the string field. Only available when
417- * the schema's provider is `postgresql` (requires `pg_trgm` extension)
418- * and the field is annotated with `@fuzzy` in the ZModel schema.
419- * See {@link FuzzyFilterPayload} for the full options reference.
420- */
421- fuzzy ?: FuzzyFilterPayload ;
422- }
423- : Base
424- : Base
422+ > = 'Fuzzy' extends AllowedKinds
423+ ? ProviderSupportsFuzzy < Schema > extends true
424+ ? GetModelField < Schema , Model , Field > [ 'fuzzy' ] extends true
425+ ? Base & {
426+ /**
427+ * Performs a fuzzy search on the string field. Only available when
428+ * the schema's provider is `postgresql` (requires `pg_trgm` extension)
429+ * and the field is annotated with `@fuzzy` in the ZModel schema.
430+ * See {@link FuzzyFilterPayload} for the full options reference.
431+ */
432+ fuzzy ?: FuzzyFilterPayload ;
433+ }
434+ : Base
435+ : Base
436+ : Base ;
437+
438+ /**
439+ * Conditionally augments a string-field filter with the `fts` operator when:
440+ * 1. The `FullText` filter kind is allowed for this field, AND
441+ * 2. The schema's provider supports full-text search (postgres only), AND
442+ * 3. The field is annotated with `@fullText` in the ZModel schema.
443+ *
444+ * Caller is responsible for only invoking this on String-typed fields
445+ * (the gate lives in `FieldFilter`).
446+ */
447+ type AddFullTextFilterIfSupported <
448+ Schema extends SchemaDef ,
449+ Model extends GetModels < Schema > ,
450+ Field extends GetModelFields < Schema , Model > ,
451+ AllowedKinds extends FilterKind ,
452+ Base ,
453+ > = 'FullText' extends AllowedKinds
454+ ? ProviderSupportsFullText < Schema > extends true
455+ ? GetModelField < Schema , Model , Field > [ 'fullText' ] extends true
456+ ? Base & {
457+ /**
458+ * Performs a full-text search on the string field. Only available when
459+ * the schema's provider is `postgresql` and the field is annotated with
460+ * `@fullText` in the ZModel schema.
461+ * See {@link FullTextFilterPayload} for the full options reference.
462+ */
463+ fts ?: FullTextFilterPayload ;
464+ }
425465 : Base
426- : Base ;
466+ : Base
467+ : Base ;
427468
428469type EnumFilter <
429470 Schema extends SchemaDef ,
@@ -994,9 +1035,6 @@ export type FuzzyRelevanceOrderBy<Schema extends SchemaDef, Model extends GetMod
9941035 * Sorts by fuzzy search relevance using PostgreSQL `pg_trgm` similarity functions.
9951036 * Not supported on MySQL or SQLite (throws `NotSupported` at runtime).
9961037 * Cannot be combined with cursor-based pagination.
997- *
998- * The `_fuzzyRelevance` name is intentionally distinct from `_searchRelevance`
999- * (reserved for future full-text-search relevance) so the two can coexist.
10001038 */
10011039 _fuzzyRelevance ?: {
10021040 /**
@@ -1025,6 +1063,66 @@ export type FuzzyRelevanceOrderBy<Schema extends SchemaDef, Model extends GetMod
10251063 } ;
10261064} ;
10271065
1066+ /**
1067+ * String fields that have been annotated with `@fullText` and are therefore eligible
1068+ * for `_ftsRelevance` ordering.
1069+ */
1070+ type FullTextFields < Schema extends SchemaDef , Model extends GetModels < Schema > > = {
1071+ [ Key in StringFields < Schema , Model > ] : GetModelField < Schema , Model , Key > [ 'fullText' ] extends true ? Key : never ;
1072+ } [ StringFields < Schema , Model > ] ;
1073+
1074+ /**
1075+ * Payload for the `fts` string filter operator. Performs full-text search using
1076+ * PostgreSQL `to_tsvector` / `to_tsquery` (postgresql provider only).
1077+ *
1078+ * Query syntax follows `to_tsquery`: callers write raw `&` (AND), `|` (OR),
1079+ * `!` (NOT), `<->` (FOLLOWED BY). Malformed queries throw at SQL execution time.
1080+ */
1081+ export type FullTextFilterPayload = {
1082+ /**
1083+ * Search query in `to_tsquery` syntax (must be a non-empty string).
1084+ */
1085+ search : string ;
1086+ /**
1087+ * Postgres text-search configuration (e.g. `'english'`, `'simple'`). When
1088+ * omitted, the database's `default_text_search_config` setting is used —
1089+ * the SQL is emitted as `to_tsvector(field) @@ to_tsquery(query)` without
1090+ * an explicit regconfig argument.
1091+ */
1092+ config ?: string ;
1093+ } ;
1094+
1095+ export type FtsRelevanceOrderBy < Schema extends SchemaDef , Model extends GetModels < Schema > > = {
1096+ /**
1097+ * Sorts by full-text-search relevance using PostgreSQL `ts_rank`.
1098+ */
1099+ _ftsRelevance ?: {
1100+ /**
1101+ * String fields annotated with `@fullText` to compute relevance against (must be non-empty).
1102+ *
1103+ * When multiple fields are provided, the fields are concatenated with a
1104+ * space separator and a single `ts_rank` is computed over the combined
1105+ * document — i.e. `ts_rank(to_tsvector(concat_ws(' ', f1, f2, ...)), q)`.
1106+ * This means an AND query (e.g. `'cat & dog'`) matches rows where the
1107+ * terms appear across different fields, not just within the same field.
1108+ */
1109+ fields : [ FullTextFields < Schema , Model > , ...FullTextFields < Schema , Model > [ ] ] ;
1110+ /**
1111+ * The search term to compute relevance for (in `to_tsquery` syntax).
1112+ */
1113+ search : string ;
1114+ /**
1115+ * Postgres text-search configuration. When omitted, the database's
1116+ * `default_text_search_config` setting is used.
1117+ */
1118+ config ?: string ;
1119+ /**
1120+ * Sort direction.
1121+ */
1122+ sort : SortOrder ;
1123+ } ;
1124+ } ;
1125+
10281126export type OrderBy <
10291127 Schema extends SchemaDef ,
10301128 Model extends GetModels < Schema > ,
@@ -1377,7 +1475,8 @@ type SortAndTakeArgs<
13771475 */
13781476 orderBy ?: OrArray <
13791477 OrderBy < Schema , Model , true , false > &
1380- ( ProviderSupportsFuzzy < Schema > extends true ? FuzzyRelevanceOrderBy < Schema , Model > : { } )
1478+ ( ProviderSupportsFuzzy < Schema > extends true ? FuzzyRelevanceOrderBy < Schema , Model > : { } ) &
1479+ ( ProviderSupportsFullText < Schema > extends true ? FtsRelevanceOrderBy < Schema , Model > : { } )
13811480 > ;
13821481
13831482 /**
@@ -2757,6 +2856,10 @@ type ProviderSupportsDistinct<Schema extends SchemaDef> = Schema['provider']['ty
27572856
27582857type ProviderSupportsFuzzy < Schema extends SchemaDef > = Schema [ 'provider' ] [ 'type' ] extends 'postgresql' ? true : false ;
27592858
2859+ type ProviderSupportsFullText < Schema extends SchemaDef > = Schema [ 'provider' ] [ 'type' ] extends 'postgresql'
2860+ ? true
2861+ : false ;
2862+
27602863/**
27612864 * Extracts extended query args for a specific operation.
27622865 */
0 commit comments