@wix/sdk-types 1.14.0 → 1.16.0

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.
@@ -374,44 +374,6 @@ type OperatorsWithBooleanValues = '$isEmpty' | '$exists';
374
374
  type OperatorsWithArrayValues = '$in' | '$nin' | '$hasAll' | '$hasSome';
375
375
  type OperatorForArrayFiltering = '$matchItems';
376
376
 
377
- /**
378
- * Cursor-based paging configuration
379
- */
380
- interface CursorPaging {
381
- /** Maximum number of items to return in the results. */
382
- limit?: number | null;
383
- /**
384
- * Pointer to the next or previous page in the list of results.
385
- *
386
- * Pass the relevant cursor token from the `pagingMetadata` object in the previous call's response.
387
- * Not relevant for the first request.
388
- */
389
- cursor?: string | null;
390
- }
391
- /**
392
- * Offset-based paging configuration
393
- */
394
- interface OffsetPaging {
395
- /** Number of items to load */
396
- limit?: number | null;
397
- /** Number of items to skip in the current sort order */
398
- offset?: number | null;
399
- }
400
- /**
401
- * Supported paging types for search APIs
402
- */
403
- type PagingType = 'cursor' | 'offset';
404
- /**
405
- * Paging type based on the SearchSpec's paging type
406
- */
407
- type Paging<Spec extends {
408
- paging?: PagingType;
409
- }> = Spec['paging'] extends 'cursor' ? {
410
- cursorPaging: CursorPaging;
411
- } : Spec['paging'] extends 'offset' ? {
412
- paging: OffsetPaging;
413
- } : {};
414
-
415
377
  /**
416
378
  * Sort direction type for requests
417
379
  */
@@ -444,10 +406,10 @@ type WQLFields<WQLGroup> = WQLGroup extends {
444
406
  fields: readonly string[];
445
407
  } ? WQLGroup['fields'][number] : never;
446
408
  /**
447
- * Sorting configuration for search results
448
- * @template Spec The search specification type
409
+ * Sorting configuration for search/query results
410
+ * @template Spec The WQL specification type
449
411
  */
450
- type Sorting<Spec extends SearchSpec> = Spec['wql'] extends {
412
+ type Sorting<Spec extends WQLSpec> = Spec['wql'] extends {
451
413
  length: 0;
452
414
  } | [] ? {
453
415
  fieldName?: string;
@@ -505,42 +467,14 @@ interface WQL {
505
467
  }
506
468
 
507
469
  /**
508
- * Specification for a search API
509
- * Defines what fields can be filtered, sorted, searched, and aggregated
510
- * @example
511
- * interface MySearchSpec extends SearchSpec {
512
- * wql: [{
513
- * operators: ['$eq', '$ne'], // or 'typeof ALL_APPLICABLE_OPERATORS' for all operators that can be used based on the field type
514
- * fields: ['id', 'title'],
515
- * sort: 'BOTH' // or 'ASC' / 'DESC' for specific sorting
516
- * }],
517
- * paging: 'offset', // or 'cursor' for cursor-based pagination
518
- * searchable: ['title', 'description'],
519
- * aggregatable: ['category', 'price']
520
- * };
470
+ * Base specification interface for APIs that support WQL (Wix Query Language)
521
471
  */
522
- interface SearchSpec {
472
+ interface WQLSpec {
523
473
  /**
524
474
  * Groups of fields with shared operator and sorting capabilities
525
475
  * Each group defines what operations can be performed on its fields
526
476
  */
527
477
  wql: readonly WQL[];
528
- /**
529
- * Supported paging type for this search API
530
- * - 'cursor': Uses cursor-based pagination
531
- * - 'offset': Uses offset-based pagination
532
- */
533
- paging: PagingType;
534
- /**
535
- * Fields that can be used for full-text search
536
- * If not specified, all fields are searchable
537
- */
538
- searchable?: readonly string[];
539
- /**
540
- * Fields that can be used for aggregations
541
- * These fields must be searchable and not contain PII
542
- */
543
- aggregatable?: readonly string[];
544
478
  }
545
479
 
546
480
  /**
@@ -548,19 +482,11 @@ interface SearchSpec {
548
482
  */
549
483
  type GetNestedType<Entity, Path extends string> = Path extends keyof Entity ? Entity[Path] extends (infer ArrayElement)[] | null | undefined ? ArrayElement : Exclude<Entity[Path], null | undefined> : Path extends `${infer FirstPathPart}.${infer RemainingPath}` ? FirstPathPart extends keyof Entity ? Entity[FirstPathPart] extends (infer ArrayElement)[] | null | undefined ? GetNestedType<NonNullable<ArrayElement>, RemainingPath> : Entity[FirstPathPart] extends object | null | undefined ? GetNestedType<NonNullable<Entity[FirstPathPart]>, RemainingPath> : never : never : never;
550
484
  /**
551
- * Extracts all filterable field paths from a search spec
552
- * @template Spec The search specification type
485
+ * Extracts all filterable field paths from a spec
486
+ * @template Spec The WQL specification type
553
487
  * // Results in a union type of all field paths that can be filtered
554
488
  */
555
- type FilterableFields<Spec extends SearchSpec> = Spec['wql'][number]['fields'][number];
556
- /**
557
- * Extracts all searchable field paths from a search spec
558
- * @template Spec The search specification type
559
- * // Results in a union type of all field paths that can be searched
560
- */
561
- type SearchableFields<Spec extends SearchSpec> = Spec extends {
562
- searchable: readonly string[];
563
- } ? Spec['searchable'][number] : string;
489
+ type FilterableFields<Spec extends WQLSpec> = Spec['wql'][number]['fields'][number];
564
490
 
565
491
  /**
566
492
  * Helper type to detect if a type is an enum-like union of string literals
@@ -575,25 +501,25 @@ type IsEnumLike<T> = T extends string | null | undefined ? string extends NonNul
575
501
  */
576
502
  type ApplicableOperators<Entity, Path extends string> = Path extends keyof Entity ? Entity[Path] extends string | null | undefined ? IsEnumLike<Entity[Path]> extends true ? EnumOperators : StringOperators : Entity[Path] extends number | null | undefined ? NumberOperators : Entity[Path] extends boolean | null | undefined ? BooleanOperators : Entity[Path] extends Date | null | undefined ? DateOperators : Entity[Path] extends (infer E)[] | null | undefined ? E extends object ? ArrayOfObjectsOperators : ArrayOfPrimitivesOperators : Entity[Path] extends object | null | undefined ? ObjectOperators : never : Path extends `${infer K}.${infer R}` ? K extends keyof Entity ? Entity[K] extends (infer U)[] | null | undefined ? ApplicableOperators<NonNullable<U>, R> : Entity[K] extends object | null | undefined ? ApplicableOperators<NonNullable<Entity[K]>, R> : never : never : never;
577
503
  /**
578
- * Determines allowed operators for a field based on the search spec
504
+ * Determines allowed operators for a field based on the spec
579
505
  * @template Entity The entity type
580
- * @template Spec The search specification type
506
+ * @template Spec The WQL specification type
581
507
  * @template Field The field to check
582
508
  */
583
- type AllowedOperators<Entity, Spec extends SearchSpec, Field extends FilterableFields<Spec>> = Spec['wql'][number] extends infer WQLGroup ? WQLGroup extends WQL ? Field extends WQLGroup['fields'][number] ? WQLGroup['operators'] extends typeof ALL_APPLICABLE_OPERATORS ? ApplicableOperators<Entity, Field & string> : WQLGroup['operators'] extends readonly string[] ? WQLGroup['operators'][number] : never : never : never : never;
509
+ type AllowedOperators<Entity, Spec extends WQLSpec, Field extends FilterableFields<Spec>> = Spec['wql'][number] extends infer WQLGroup ? WQLGroup extends WQL ? Field extends WQLGroup['fields'][number] ? WQLGroup['operators'] extends typeof ALL_APPLICABLE_OPERATORS ? ApplicableOperators<Entity, Field & string> : WQLGroup['operators'] extends readonly string[] ? WQLGroup['operators'][number] : never : never : never : never;
584
510
  /**
585
511
  * Filter operations type for individual field conditions
586
512
  * @template Entity The entity type
587
- * @template Spec The search specification type
513
+ * @template Spec The WQL specification type
588
514
  * @template Field The field to filter on
589
515
  */
590
- type FilterOps<Entity, Spec extends SearchSpec, Field extends FilterableFields<Spec>> = Simplify<{
516
+ type FilterOps<Entity, Spec extends WQLSpec, Field extends FilterableFields<Spec>> = Simplify<{
591
517
  [Op in AllowedOperators<Entity, Spec, Field>]?: Op extends OperatorsWithBooleanValues ? boolean : Op extends OperatorForArrayFiltering ? JsonObject[] : Op extends OperatorsWithArrayValues ? GetNestedType<Entity, Field & string>[] : GetNestedType<Entity, Field & string>;
592
518
  }>;
593
519
  /**
594
520
  * Filter type for building type-safe query filters
595
521
  * @template Entity The entity type
596
- * @template Spec The search specification type
522
+ * @template Spec The WQL specification type
597
523
  * @example
598
524
  * // Simple filter
599
525
  * const filter: Filter<Product, ProductSpec> = {
@@ -612,7 +538,7 @@ type FilterOps<Entity, Spec extends SearchSpec, Field extends FilterableFields<S
612
538
  * ]
613
539
  * };
614
540
  */
615
- type Filter<Entity, Spec extends SearchSpec> = Simplify<{
541
+ type Filter<Entity, Spec extends WQLSpec> = Simplify<{
616
542
  [Field in FilterableFields<Spec>]?: AllowedOperators<Entity, Spec, Field> extends infer AllowedOps ? AllowedOps extends '$eq' ? GetNestedType<Entity, Field & string> | FilterOps<Entity, Spec, Field> : FilterOps<Entity, Spec, Field> : never;
617
543
  } | {
618
544
  $and?: Filter<Entity, Spec>[];
@@ -620,6 +546,78 @@ type Filter<Entity, Spec extends SearchSpec> = Simplify<{
620
546
  $not?: Filter<Entity, Spec>;
621
547
  }>;
622
548
 
549
+ /**
550
+ * Cursor-based paging configuration
551
+ */
552
+ interface CursorPaging {
553
+ /** Maximum number of items to return in the results. */
554
+ limit?: number | null;
555
+ /**
556
+ * Pointer to the next or previous page in the list of results.
557
+ *
558
+ * Pass the relevant cursor token from the `pagingMetadata` object in the previous call's response.
559
+ * Not relevant for the first request.
560
+ */
561
+ cursor?: string | null;
562
+ }
563
+ /**
564
+ * Offset-based paging configuration
565
+ */
566
+ interface OffsetPaging {
567
+ /** Number of items to load */
568
+ limit?: number | null;
569
+ /** Number of items to skip in the current sort order */
570
+ offset?: number | null;
571
+ }
572
+ /**
573
+ * Supported paging types for search APIs
574
+ */
575
+ type PagingType = 'cursor' | 'offset';
576
+ /**
577
+ * Paging type based on the SearchSpec's paging type
578
+ */
579
+ type Paging<Spec extends {
580
+ paging?: PagingType;
581
+ }> = Spec['paging'] extends 'cursor' ? {
582
+ cursorPaging: CursorPaging;
583
+ } : Spec['paging'] extends 'offset' ? {
584
+ paging: OffsetPaging;
585
+ } : {};
586
+
587
+ /**
588
+ * Specification for a search API
589
+ * Defines what fields can be filtered, sorted, searched, and aggregated
590
+ * @example
591
+ * interface MySearchSpec extends SearchSpec {
592
+ * wql: [{
593
+ * operators: ['$eq', '$ne'], // or 'typeof ALL_APPLICABLE_OPERATORS' for all operators that can be used based on the field type
594
+ * fields: ['id', 'title'],
595
+ * sort: 'BOTH' // or 'ASC' / 'DESC' for specific sorting
596
+ * }],
597
+ * paging: 'offset', // or 'cursor' for cursor-based pagination
598
+ * searchable: ['title', 'description'],
599
+ * aggregatable: ['category', 'price']
600
+ * };
601
+ */
602
+ interface SearchSpec extends WQLSpec {
603
+ /**
604
+ * Supported paging type for this search API
605
+ * - 'cursor': Uses cursor-based pagination
606
+ * - 'offset': Uses offset-based pagination
607
+ */
608
+ paging: PagingType;
609
+ /**
610
+ * Fields that can be used for full-text search
611
+ * If not specified, all fields are searchable
612
+ */
613
+ searchable?: readonly string[];
614
+ /**
615
+ * Fields that can be used for aggregations
616
+ * These fields must be searchable and not contain PII
617
+ */
618
+ aggregatable?: readonly string[];
619
+ }
620
+
623
621
  /**
624
622
  * Type of scalar aggregation to perform
625
623
  */
@@ -727,6 +725,15 @@ type Aggregation<Spec extends SearchSpec> = BaseAggregationWithoutType<Spec> & {
727
725
  nested?: NestedAggregation<Spec>;
728
726
  };
729
727
 
728
+ /**
729
+ * Extracts all searchable field paths from a search spec
730
+ * @template Spec The search specification type
731
+ * // Results in a union type of all field paths that can be searched
732
+ */
733
+ type SearchableFields<Spec extends SearchSpec> = Spec extends {
734
+ searchable: readonly string[];
735
+ } ? Spec['searchable'][number] : string;
736
+
730
737
  /**
731
738
  * Configuration for full-text search functionality
732
739
  * @template Spec The search specification type
@@ -817,4 +824,61 @@ type BaseSearch<Entity, Spec extends SearchSpec> = {
817
824
  */
818
825
  type Search<Entity, Spec extends SearchSpec> = BaseSearch<Entity, Spec> & Partial<Paging<Spec>>;
819
826
 
820
- export { type APIMetadata, type AmbassadorFactory, type AmbassadorFunctionDescriptor, type AmbassadorRequestOptions, type AuthenticationStrategy, type BaseEventMetadata, type BoundAuthenticationStrategy, type BuildAmbassadorFunction, type BuildDescriptors, type BuildEventDefinition, type BuildRESTFunction, type BuildServicePluginDefinition, type Descriptors, EventDefinition, type EventHandler, type EventIdentity, type ExposeFieldsBasedOnToggle, type HTTPMethod, type Host, type HostModule, type HostModuleAPI, type HttpClient, type HttpResponse, type MaybeContext, type Method, type MigrationOptions, type NonNullablePaths, type PublicMetadata, type RESTFunctionDescriptor, type RequestContext, type RequestOptions, type RequestOptionsFactory, type RestModuleMeta, SERVICE_PLUGIN_ERROR_TYPE, type Search, type SearchSpec, type ServicePluginContract, ServicePluginDefinition, type ServicePluginMethodInput, type ServicePluginMethodMetadata };
827
+ /**
828
+ * Specification for a query API
829
+ * Defines what fields can be filtered and sorted
830
+ * @example
831
+ * interface MyQuerySpec extends QuerySpec {
832
+ * wql: [{
833
+ * operators: ['$eq', '$ne'],
834
+ * fields: ['id', 'title'],
835
+ * sort: 'BOTH'
836
+ * }],
837
+ * paging: 'offset', // or 'cursor' for cursor-based pagination
838
+ * };
839
+ */
840
+ interface QuerySpec extends WQLSpec {
841
+ /**
842
+ * Supported paging type for this query API
843
+ * - 'cursor': Uses cursor-based pagination
844
+ * - 'offset': Uses offset-based pagination
845
+ */
846
+ paging: PagingType;
847
+ }
848
+
849
+ /**
850
+ * Complete query request for an entity type
851
+ * @template Entity The entity type being queried
852
+ * @template Spec The query specification type
853
+ * @example
854
+ * // Define a query type for products
855
+ * type QueryProducts = Query<Product, ProductQuerySpec>;
856
+ *
857
+ * // Create a query request with offset paging
858
+ * const query: QueryProducts = {
859
+ * filter: { price: { $gte: 10 } },
860
+ * sort: [{ fieldName: 'price', order: 'ASC' }],
861
+ * paging: { limit: 20, offset: 0 }
862
+ * };
863
+ *
864
+ * // Or with cursor paging (if spec.paging = 'cursor')
865
+ * const query: QueryProducts = {
866
+ * filter: { price: { $gte: 10 } },
867
+ * sort: [{ fieldName: 'price', order: 'ASC' }],
868
+ * cursorPaging: { limit: 20, cursor: "..." }
869
+ * };
870
+ */
871
+ type Query<Entity, Spec extends QuerySpec> = {
872
+ /**
873
+ * Filter object.
874
+ * Learn more about the [filter section](https://dev.wix.com/docs/rest/articles/getting-started/api-query-language#the-filter-section).
875
+ */
876
+ filter?: Filter<Entity, Spec>;
877
+ /**
878
+ * List of sort objects.
879
+ * Learn more about the [sort section](https://dev.wix.com/docs/rest/articles/getting-started/api-query-language#the-sort-section).
880
+ */
881
+ sort?: Sorting<Spec>[];
882
+ } & Partial<Paging<Spec>>;
883
+
884
+ export { type APIMetadata, type AmbassadorFactory, type AmbassadorFunctionDescriptor, type AmbassadorRequestOptions, type AuthenticationStrategy, type BaseEventMetadata, type BoundAuthenticationStrategy, type BuildAmbassadorFunction, type BuildDescriptors, type BuildEventDefinition, type BuildRESTFunction, type BuildServicePluginDefinition, type Descriptors, EventDefinition, type EventHandler, type EventIdentity, type ExposeFieldsBasedOnToggle, type Filter, type FilterableFields, type GetNestedType, type HTTPMethod, type Host, type HostModule, type HostModuleAPI, type HttpClient, type HttpResponse, type MaybeContext, type Method, type MigrationOptions, type NonNullablePaths, type PublicMetadata, type Query, type QuerySpec, type RESTFunctionDescriptor, type RequestContext, type RequestOptions, type RequestOptionsFactory, type RestModuleMeta, SERVICE_PLUGIN_ERROR_TYPE, SORT_CAPABILITIES, SORT_DIRECTIONS, type Search, type SearchSpec, type ServicePluginContract, ServicePluginDefinition, type ServicePluginMethodInput, type ServicePluginMethodMetadata, type SortCapability, type SortOrder, type Sorting, type WQL, type WQLSpec };
@@ -17,8 +17,21 @@ function ServicePluginDefinition(componentType, methods) {
17
17
  };
18
18
  }
19
19
  var SERVICE_PLUGIN_ERROR_TYPE = "wix_spi_error";
20
+
21
+ // src/common/sort.ts
22
+ var SORT_DIRECTIONS = {
23
+ ASC: "ASC",
24
+ DESC: "DESC"
25
+ };
26
+ var SORT_CAPABILITIES = {
27
+ ...SORT_DIRECTIONS,
28
+ BOTH: "BOTH",
29
+ NONE: "NONE"
30
+ };
20
31
  export {
21
32
  EventDefinition,
22
33
  SERVICE_PLUGIN_ERROR_TYPE,
34
+ SORT_CAPABILITIES,
35
+ SORT_DIRECTIONS,
23
36
  ServicePluginDefinition
24
37
  };
package/build/index.d.mts CHANGED
@@ -374,44 +374,6 @@ type OperatorsWithBooleanValues = '$isEmpty' | '$exists';
374
374
  type OperatorsWithArrayValues = '$in' | '$nin' | '$hasAll' | '$hasSome';
375
375
  type OperatorForArrayFiltering = '$matchItems';
376
376
 
377
- /**
378
- * Cursor-based paging configuration
379
- */
380
- interface CursorPaging {
381
- /** Maximum number of items to return in the results. */
382
- limit?: number | null;
383
- /**
384
- * Pointer to the next or previous page in the list of results.
385
- *
386
- * Pass the relevant cursor token from the `pagingMetadata` object in the previous call's response.
387
- * Not relevant for the first request.
388
- */
389
- cursor?: string | null;
390
- }
391
- /**
392
- * Offset-based paging configuration
393
- */
394
- interface OffsetPaging {
395
- /** Number of items to load */
396
- limit?: number | null;
397
- /** Number of items to skip in the current sort order */
398
- offset?: number | null;
399
- }
400
- /**
401
- * Supported paging types for search APIs
402
- */
403
- type PagingType = 'cursor' | 'offset';
404
- /**
405
- * Paging type based on the SearchSpec's paging type
406
- */
407
- type Paging<Spec extends {
408
- paging?: PagingType;
409
- }> = Spec['paging'] extends 'cursor' ? {
410
- cursorPaging: CursorPaging;
411
- } : Spec['paging'] extends 'offset' ? {
412
- paging: OffsetPaging;
413
- } : {};
414
-
415
377
  /**
416
378
  * Sort direction type for requests
417
379
  */
@@ -444,10 +406,10 @@ type WQLFields<WQLGroup> = WQLGroup extends {
444
406
  fields: readonly string[];
445
407
  } ? WQLGroup['fields'][number] : never;
446
408
  /**
447
- * Sorting configuration for search results
448
- * @template Spec The search specification type
409
+ * Sorting configuration for search/query results
410
+ * @template Spec The WQL specification type
449
411
  */
450
- type Sorting<Spec extends SearchSpec> = Spec['wql'] extends {
412
+ type Sorting<Spec extends WQLSpec> = Spec['wql'] extends {
451
413
  length: 0;
452
414
  } | [] ? {
453
415
  fieldName?: string;
@@ -505,42 +467,14 @@ interface WQL {
505
467
  }
506
468
 
507
469
  /**
508
- * Specification for a search API
509
- * Defines what fields can be filtered, sorted, searched, and aggregated
510
- * @example
511
- * interface MySearchSpec extends SearchSpec {
512
- * wql: [{
513
- * operators: ['$eq', '$ne'], // or 'typeof ALL_APPLICABLE_OPERATORS' for all operators that can be used based on the field type
514
- * fields: ['id', 'title'],
515
- * sort: 'BOTH' // or 'ASC' / 'DESC' for specific sorting
516
- * }],
517
- * paging: 'offset', // or 'cursor' for cursor-based pagination
518
- * searchable: ['title', 'description'],
519
- * aggregatable: ['category', 'price']
520
- * };
470
+ * Base specification interface for APIs that support WQL (Wix Query Language)
521
471
  */
522
- interface SearchSpec {
472
+ interface WQLSpec {
523
473
  /**
524
474
  * Groups of fields with shared operator and sorting capabilities
525
475
  * Each group defines what operations can be performed on its fields
526
476
  */
527
477
  wql: readonly WQL[];
528
- /**
529
- * Supported paging type for this search API
530
- * - 'cursor': Uses cursor-based pagination
531
- * - 'offset': Uses offset-based pagination
532
- */
533
- paging: PagingType;
534
- /**
535
- * Fields that can be used for full-text search
536
- * If not specified, all fields are searchable
537
- */
538
- searchable?: readonly string[];
539
- /**
540
- * Fields that can be used for aggregations
541
- * These fields must be searchable and not contain PII
542
- */
543
- aggregatable?: readonly string[];
544
478
  }
545
479
 
546
480
  /**
@@ -548,19 +482,11 @@ interface SearchSpec {
548
482
  */
549
483
  type GetNestedType<Entity, Path extends string> = Path extends keyof Entity ? Entity[Path] extends (infer ArrayElement)[] | null | undefined ? ArrayElement : Exclude<Entity[Path], null | undefined> : Path extends `${infer FirstPathPart}.${infer RemainingPath}` ? FirstPathPart extends keyof Entity ? Entity[FirstPathPart] extends (infer ArrayElement)[] | null | undefined ? GetNestedType<NonNullable<ArrayElement>, RemainingPath> : Entity[FirstPathPart] extends object | null | undefined ? GetNestedType<NonNullable<Entity[FirstPathPart]>, RemainingPath> : never : never : never;
550
484
  /**
551
- * Extracts all filterable field paths from a search spec
552
- * @template Spec The search specification type
485
+ * Extracts all filterable field paths from a spec
486
+ * @template Spec The WQL specification type
553
487
  * // Results in a union type of all field paths that can be filtered
554
488
  */
555
- type FilterableFields<Spec extends SearchSpec> = Spec['wql'][number]['fields'][number];
556
- /**
557
- * Extracts all searchable field paths from a search spec
558
- * @template Spec The search specification type
559
- * // Results in a union type of all field paths that can be searched
560
- */
561
- type SearchableFields<Spec extends SearchSpec> = Spec extends {
562
- searchable: readonly string[];
563
- } ? Spec['searchable'][number] : string;
489
+ type FilterableFields<Spec extends WQLSpec> = Spec['wql'][number]['fields'][number];
564
490
 
565
491
  /**
566
492
  * Helper type to detect if a type is an enum-like union of string literals
@@ -575,25 +501,25 @@ type IsEnumLike<T> = T extends string | null | undefined ? string extends NonNul
575
501
  */
576
502
  type ApplicableOperators<Entity, Path extends string> = Path extends keyof Entity ? Entity[Path] extends string | null | undefined ? IsEnumLike<Entity[Path]> extends true ? EnumOperators : StringOperators : Entity[Path] extends number | null | undefined ? NumberOperators : Entity[Path] extends boolean | null | undefined ? BooleanOperators : Entity[Path] extends Date | null | undefined ? DateOperators : Entity[Path] extends (infer E)[] | null | undefined ? E extends object ? ArrayOfObjectsOperators : ArrayOfPrimitivesOperators : Entity[Path] extends object | null | undefined ? ObjectOperators : never : Path extends `${infer K}.${infer R}` ? K extends keyof Entity ? Entity[K] extends (infer U)[] | null | undefined ? ApplicableOperators<NonNullable<U>, R> : Entity[K] extends object | null | undefined ? ApplicableOperators<NonNullable<Entity[K]>, R> : never : never : never;
577
503
  /**
578
- * Determines allowed operators for a field based on the search spec
504
+ * Determines allowed operators for a field based on the spec
579
505
  * @template Entity The entity type
580
- * @template Spec The search specification type
506
+ * @template Spec The WQL specification type
581
507
  * @template Field The field to check
582
508
  */
583
- type AllowedOperators<Entity, Spec extends SearchSpec, Field extends FilterableFields<Spec>> = Spec['wql'][number] extends infer WQLGroup ? WQLGroup extends WQL ? Field extends WQLGroup['fields'][number] ? WQLGroup['operators'] extends typeof ALL_APPLICABLE_OPERATORS ? ApplicableOperators<Entity, Field & string> : WQLGroup['operators'] extends readonly string[] ? WQLGroup['operators'][number] : never : never : never : never;
509
+ type AllowedOperators<Entity, Spec extends WQLSpec, Field extends FilterableFields<Spec>> = Spec['wql'][number] extends infer WQLGroup ? WQLGroup extends WQL ? Field extends WQLGroup['fields'][number] ? WQLGroup['operators'] extends typeof ALL_APPLICABLE_OPERATORS ? ApplicableOperators<Entity, Field & string> : WQLGroup['operators'] extends readonly string[] ? WQLGroup['operators'][number] : never : never : never : never;
584
510
  /**
585
511
  * Filter operations type for individual field conditions
586
512
  * @template Entity The entity type
587
- * @template Spec The search specification type
513
+ * @template Spec The WQL specification type
588
514
  * @template Field The field to filter on
589
515
  */
590
- type FilterOps<Entity, Spec extends SearchSpec, Field extends FilterableFields<Spec>> = Simplify<{
516
+ type FilterOps<Entity, Spec extends WQLSpec, Field extends FilterableFields<Spec>> = Simplify<{
591
517
  [Op in AllowedOperators<Entity, Spec, Field>]?: Op extends OperatorsWithBooleanValues ? boolean : Op extends OperatorForArrayFiltering ? JsonObject[] : Op extends OperatorsWithArrayValues ? GetNestedType<Entity, Field & string>[] : GetNestedType<Entity, Field & string>;
592
518
  }>;
593
519
  /**
594
520
  * Filter type for building type-safe query filters
595
521
  * @template Entity The entity type
596
- * @template Spec The search specification type
522
+ * @template Spec The WQL specification type
597
523
  * @example
598
524
  * // Simple filter
599
525
  * const filter: Filter<Product, ProductSpec> = {
@@ -612,7 +538,7 @@ type FilterOps<Entity, Spec extends SearchSpec, Field extends FilterableFields<S
612
538
  * ]
613
539
  * };
614
540
  */
615
- type Filter<Entity, Spec extends SearchSpec> = Simplify<{
541
+ type Filter<Entity, Spec extends WQLSpec> = Simplify<{
616
542
  [Field in FilterableFields<Spec>]?: AllowedOperators<Entity, Spec, Field> extends infer AllowedOps ? AllowedOps extends '$eq' ? GetNestedType<Entity, Field & string> | FilterOps<Entity, Spec, Field> : FilterOps<Entity, Spec, Field> : never;
617
543
  } | {
618
544
  $and?: Filter<Entity, Spec>[];
@@ -620,6 +546,78 @@ type Filter<Entity, Spec extends SearchSpec> = Simplify<{
620
546
  $not?: Filter<Entity, Spec>;
621
547
  }>;
622
548
 
549
+ /**
550
+ * Cursor-based paging configuration
551
+ */
552
+ interface CursorPaging {
553
+ /** Maximum number of items to return in the results. */
554
+ limit?: number | null;
555
+ /**
556
+ * Pointer to the next or previous page in the list of results.
557
+ *
558
+ * Pass the relevant cursor token from the `pagingMetadata` object in the previous call's response.
559
+ * Not relevant for the first request.
560
+ */
561
+ cursor?: string | null;
562
+ }
563
+ /**
564
+ * Offset-based paging configuration
565
+ */
566
+ interface OffsetPaging {
567
+ /** Number of items to load */
568
+ limit?: number | null;
569
+ /** Number of items to skip in the current sort order */
570
+ offset?: number | null;
571
+ }
572
+ /**
573
+ * Supported paging types for search APIs
574
+ */
575
+ type PagingType = 'cursor' | 'offset';
576
+ /**
577
+ * Paging type based on the SearchSpec's paging type
578
+ */
579
+ type Paging<Spec extends {
580
+ paging?: PagingType;
581
+ }> = Spec['paging'] extends 'cursor' ? {
582
+ cursorPaging: CursorPaging;
583
+ } : Spec['paging'] extends 'offset' ? {
584
+ paging: OffsetPaging;
585
+ } : {};
586
+
587
+ /**
588
+ * Specification for a search API
589
+ * Defines what fields can be filtered, sorted, searched, and aggregated
590
+ * @example
591
+ * interface MySearchSpec extends SearchSpec {
592
+ * wql: [{
593
+ * operators: ['$eq', '$ne'], // or 'typeof ALL_APPLICABLE_OPERATORS' for all operators that can be used based on the field type
594
+ * fields: ['id', 'title'],
595
+ * sort: 'BOTH' // or 'ASC' / 'DESC' for specific sorting
596
+ * }],
597
+ * paging: 'offset', // or 'cursor' for cursor-based pagination
598
+ * searchable: ['title', 'description'],
599
+ * aggregatable: ['category', 'price']
600
+ * };
601
+ */
602
+ interface SearchSpec extends WQLSpec {
603
+ /**
604
+ * Supported paging type for this search API
605
+ * - 'cursor': Uses cursor-based pagination
606
+ * - 'offset': Uses offset-based pagination
607
+ */
608
+ paging: PagingType;
609
+ /**
610
+ * Fields that can be used for full-text search
611
+ * If not specified, all fields are searchable
612
+ */
613
+ searchable?: readonly string[];
614
+ /**
615
+ * Fields that can be used for aggregations
616
+ * These fields must be searchable and not contain PII
617
+ */
618
+ aggregatable?: readonly string[];
619
+ }
620
+
623
621
  /**
624
622
  * Type of scalar aggregation to perform
625
623
  */
@@ -727,6 +725,15 @@ type Aggregation<Spec extends SearchSpec> = BaseAggregationWithoutType<Spec> & {
727
725
  nested?: NestedAggregation<Spec>;
728
726
  };
729
727
 
728
+ /**
729
+ * Extracts all searchable field paths from a search spec
730
+ * @template Spec The search specification type
731
+ * // Results in a union type of all field paths that can be searched
732
+ */
733
+ type SearchableFields<Spec extends SearchSpec> = Spec extends {
734
+ searchable: readonly string[];
735
+ } ? Spec['searchable'][number] : string;
736
+
730
737
  /**
731
738
  * Configuration for full-text search functionality
732
739
  * @template Spec The search specification type
@@ -817,4 +824,61 @@ type BaseSearch<Entity, Spec extends SearchSpec> = {
817
824
  */
818
825
  type Search<Entity, Spec extends SearchSpec> = BaseSearch<Entity, Spec> & Partial<Paging<Spec>>;
819
826
 
820
- export { type APIMetadata, type AmbassadorFactory, type AmbassadorFunctionDescriptor, type AmbassadorRequestOptions, type AuthenticationStrategy, type BaseEventMetadata, type BoundAuthenticationStrategy, type BuildAmbassadorFunction, type BuildDescriptors, type BuildEventDefinition, type BuildRESTFunction, type BuildServicePluginDefinition, type Descriptors, EventDefinition, type EventHandler, type EventIdentity, type ExposeFieldsBasedOnToggle, type HTTPMethod, type Host, type HostModule, type HostModuleAPI, type HttpClient, type HttpResponse, type MaybeContext, type Method, type MigrationOptions, type NonNullablePaths, type PublicMetadata, type RESTFunctionDescriptor, type RequestContext, type RequestOptions, type RequestOptionsFactory, type RestModuleMeta, SERVICE_PLUGIN_ERROR_TYPE, type Search, type SearchSpec, type ServicePluginContract, ServicePluginDefinition, type ServicePluginMethodInput, type ServicePluginMethodMetadata };
827
+ /**
828
+ * Specification for a query API
829
+ * Defines what fields can be filtered and sorted
830
+ * @example
831
+ * interface MyQuerySpec extends QuerySpec {
832
+ * wql: [{
833
+ * operators: ['$eq', '$ne'],
834
+ * fields: ['id', 'title'],
835
+ * sort: 'BOTH'
836
+ * }],
837
+ * paging: 'offset', // or 'cursor' for cursor-based pagination
838
+ * };
839
+ */
840
+ interface QuerySpec extends WQLSpec {
841
+ /**
842
+ * Supported paging type for this query API
843
+ * - 'cursor': Uses cursor-based pagination
844
+ * - 'offset': Uses offset-based pagination
845
+ */
846
+ paging: PagingType;
847
+ }
848
+
849
+ /**
850
+ * Complete query request for an entity type
851
+ * @template Entity The entity type being queried
852
+ * @template Spec The query specification type
853
+ * @example
854
+ * // Define a query type for products
855
+ * type QueryProducts = Query<Product, ProductQuerySpec>;
856
+ *
857
+ * // Create a query request with offset paging
858
+ * const query: QueryProducts = {
859
+ * filter: { price: { $gte: 10 } },
860
+ * sort: [{ fieldName: 'price', order: 'ASC' }],
861
+ * paging: { limit: 20, offset: 0 }
862
+ * };
863
+ *
864
+ * // Or with cursor paging (if spec.paging = 'cursor')
865
+ * const query: QueryProducts = {
866
+ * filter: { price: { $gte: 10 } },
867
+ * sort: [{ fieldName: 'price', order: 'ASC' }],
868
+ * cursorPaging: { limit: 20, cursor: "..." }
869
+ * };
870
+ */
871
+ type Query<Entity, Spec extends QuerySpec> = {
872
+ /**
873
+ * Filter object.
874
+ * Learn more about the [filter section](https://dev.wix.com/docs/rest/articles/getting-started/api-query-language#the-filter-section).
875
+ */
876
+ filter?: Filter<Entity, Spec>;
877
+ /**
878
+ * List of sort objects.
879
+ * Learn more about the [sort section](https://dev.wix.com/docs/rest/articles/getting-started/api-query-language#the-sort-section).
880
+ */
881
+ sort?: Sorting<Spec>[];
882
+ } & Partial<Paging<Spec>>;
883
+
884
+ export { type APIMetadata, type AmbassadorFactory, type AmbassadorFunctionDescriptor, type AmbassadorRequestOptions, type AuthenticationStrategy, type BaseEventMetadata, type BoundAuthenticationStrategy, type BuildAmbassadorFunction, type BuildDescriptors, type BuildEventDefinition, type BuildRESTFunction, type BuildServicePluginDefinition, type Descriptors, EventDefinition, type EventHandler, type EventIdentity, type ExposeFieldsBasedOnToggle, type Filter, type FilterableFields, type GetNestedType, type HTTPMethod, type Host, type HostModule, type HostModuleAPI, type HttpClient, type HttpResponse, type MaybeContext, type Method, type MigrationOptions, type NonNullablePaths, type PublicMetadata, type Query, type QuerySpec, type RESTFunctionDescriptor, type RequestContext, type RequestOptions, type RequestOptionsFactory, type RestModuleMeta, SERVICE_PLUGIN_ERROR_TYPE, SORT_CAPABILITIES, SORT_DIRECTIONS, type Search, type SearchSpec, type ServicePluginContract, ServicePluginDefinition, type ServicePluginMethodInput, type ServicePluginMethodMetadata, type SortCapability, type SortOrder, type Sorting, type WQL, type WQLSpec };