@squidcloud/client 1.0.84 → 1.0.86

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.
@@ -26,7 +26,6 @@ export * from './named-query.context';
26
26
  export * from './named-query.schemas';
27
27
  export * from './named-query.types';
28
28
  export * from './query';
29
- export * from './query.schemas';
30
29
  export * from './query.types';
31
30
  export * from './regions';
32
31
  export * from './schema/schema.types';
@@ -18,6 +18,12 @@ export interface SnapshotEmitter<ReturnType> {
18
18
  * @returns An observable for the query results.
19
19
  */
20
20
  snapshots(subscribe?: boolean): Observable<Array<ReturnType>>;
21
+ limit(limit: number): SnapshotEmitter<ReturnType>;
22
+ /**
23
+ * Returns a pagination wrapper for this query.
24
+ * @param options The pagination options. Defaults to `{ subscribe: true, pageSize: 100 }`.
25
+ */
26
+ paginate(options?: Partial<PaginationOptions>): Pagination<ReturnType>;
21
27
  }
22
28
  /** Query builder base class. */
23
29
  export declare abstract class BaseQueryBuilder<MyDocType extends DocumentData> {
@@ -120,3 +126,61 @@ export declare abstract class BaseQueryBuilder<MyDocType extends DocumentData> {
120
126
  */
121
127
  abstract sortBy(fieldName: keyof MyDocType & FieldName, asc?: boolean): this;
122
128
  }
129
+ export interface HasDereference {
130
+ /**
131
+ * Dereferences the document references in the result of this query. For example, collection.query().snapshot()
132
+ * returns an array of DocumentReference objects, but collection.query().dereference().snapshot() returns an array of
133
+ * the actual document data.
134
+ */
135
+ dereference(): any;
136
+ }
137
+ /** The state of a pagination. */
138
+ export interface PaginationState<ReturnType> {
139
+ data: Array<ReturnType>;
140
+ hasNext: boolean;
141
+ hasPrev: boolean;
142
+ isLoading: boolean;
143
+ }
144
+ /** Pagination options */
145
+ export interface PaginationOptions {
146
+ /** Whether to show real-time updates. Defaults to true. */
147
+ subscribe: boolean;
148
+ /** The number of items in a page. Defaults to 100. */
149
+ pageSize: number;
150
+ }
151
+ /** A query wrapper that provides pagination functionality. */
152
+ export declare class Pagination<ReturnType> {
153
+ private readonly templateSnapshotEmitter;
154
+ /**
155
+ * The first page data - only available when subscribe is true.
156
+ * It is used for:
157
+ * 1 - Telling whether there is a previous page
158
+ * 2 - Used as the data when the current page has less than page size and hasNext = true
159
+ */
160
+ private readonly firstPageSnapshotEmitterWrapper;
161
+ private readonly firstPageDataAvailable;
162
+ /**
163
+ * The last page data - only available when subscribe is true. Lazily initialized when calling prev.
164
+ * It is used for telling whether there is a next result after calling prev.
165
+ */
166
+ private lastPageSnapshotEmitterWrapper;
167
+ private lastPageDataAvailable;
168
+ private readonly isDestroyed;
169
+ private readonly destroyedObs;
170
+ private readonly _observeState;
171
+ /** The current snapshot emitter wrapper. */
172
+ private readonly currentPageSnapshotEmitterWrapperSubject;
173
+ private readonly options;
174
+ /** Requests the next page. */
175
+ next(): Promise<PaginationState<ReturnType>>;
176
+ /** Requests the previous page. */
177
+ prev(): Promise<PaginationState<ReturnType>>;
178
+ /** Unsubscribe from the pagination object and from the query. */
179
+ unsubscribe(): void;
180
+ /** The current pagination state and data. */
181
+ observeState(): Observable<PaginationState<ReturnType>>;
182
+ /** Wait for the data to be available (the isLoading flag to be false). */
183
+ waitForData(): Promise<PaginationState<ReturnType>>;
184
+ private createLastPageSnapshotEmitterWrapper;
185
+ private resetToFirstPageData;
186
+ }
@@ -1,8 +1,8 @@
1
1
  import { IntegrationId } from '../communication.types';
2
- import { CollectionName, DocumentData, FieldName } from '../document.types';
3
- import { AllOperators, ContextConditions, FieldSort, GeneralCondition, GeneralConditions, GenericValue, Query } from '../query.types';
4
- import { PartialBy, Paths } from '../types';
5
- export declare class QueryContext<T = any> {
2
+ import { CollectionName, DocumentData } from '../document.types';
3
+ import { FieldSort, Operator, Query, SimpleCondition } from '../query.types';
4
+ import { DeepRecord, FieldOf, PartialBy, Paths } from '../types';
5
+ export declare class QueryContext<T extends DocumentData = any> {
6
6
  readonly query: Query<T>;
7
7
  private readonly parsedConditions;
8
8
  /**
@@ -45,7 +45,7 @@ export declare class QueryContext<T = any> {
45
45
  * @param value The value of the condition.
46
46
  * @returns Whether the query is a subquery of the parent condition.
47
47
  */
48
- isSubqueryOf<F extends FieldName<T>, O extends AllOperators>(fieldName: F, operator: O, value: GenericValue<T, F, O> | null): boolean;
48
+ isSubqueryOf<F extends Paths<T>, O extends AllOperators>(fieldName: F, operator: O, value: GenericValue<T, F, O> | null): boolean;
49
49
  /**
50
50
  * Verifies that the query is a subquery of the specified condition. A subquery is defined as a query that evaluates
51
51
  * to a subset of the results that would be obtained by applying the parent condition. The subquery may also include
@@ -79,7 +79,7 @@ export declare class QueryContext<T = any> {
79
79
  * @param fieldNames The field names for which to retrieve conditions.
80
80
  * @returns An array of conditions that involve any of the specified field names.
81
81
  */
82
- getConditionsFor<K extends FieldName<T>>(...fieldNames: K[]): ContextConditions<T, K>;
82
+ getConditionsFor<K extends Paths<T>>(...fieldNames: Array<K>): ContextConditions<T, K>;
83
83
  /**
84
84
  * Returns all conditions that apply to the specified field name. This method provides
85
85
  * a convenient way to retrieve all conditions that involve a specific field.
@@ -107,3 +107,31 @@ export declare class QueryContext<T = any> {
107
107
  private evaluateIncludes;
108
108
  private parseConditions;
109
109
  }
110
+ /** A list of context conditions */
111
+ type ContextConditions<Doc extends DocumentData = any, F extends Paths<Doc> = Paths<Doc>> = Array<ContextCondition<Doc, F>>;
112
+ /** A Context condition - a condition that replaces multiple '==' or '!=' conditions with 'in' and 'not in'. */
113
+ type ContextCondition<Doc extends DocumentData = any, F extends Paths<Doc> = Paths<Doc>> = InContextCondition<Doc, F> | NotInContextCondition<Doc, F> | OtherContextCondition<Doc, F>;
114
+ interface InContextCondition<Doc extends DocumentData = any, F extends Paths<Doc> = Paths<Doc>> extends SimpleCondition<Doc, F, 'in'> {
115
+ operator: 'in';
116
+ value: Array<FieldOf<DeepRecord<Doc>, Paths<Doc>> | any>;
117
+ }
118
+ interface NotInContextCondition<Doc extends DocumentData = any, F extends Paths<Doc> = Paths<Doc>> extends SimpleCondition<Doc, F, 'not in'> {
119
+ operator: 'not in';
120
+ value: Array<FieldOf<DeepRecord<Doc>, Paths<Doc>> | any>;
121
+ }
122
+ interface OtherContextCondition<Doc extends DocumentData = any, F extends Paths<Doc> = Paths<Doc>> extends SimpleCondition<Doc, F, Exclude<ContextOperator, 'in' | 'not in'>> {
123
+ operator: Exclude<ContextOperator, 'in' | 'not in'>;
124
+ value: FieldOf<DeepRecord<Doc>, Paths<Doc>> | any;
125
+ }
126
+ /** A condition that includes the 'in' and 'not in' operators. */
127
+ interface GeneralCondition<Doc extends DocumentData = any, F extends Paths<Doc> = Paths<Doc>> extends SimpleCondition<Doc, F, AllOperators> {
128
+ operator: AllOperators;
129
+ value: any;
130
+ }
131
+ /** A list of general conditions. */
132
+ type GeneralConditions<Doc extends DocumentData = any, F extends Paths<Doc> = Paths<Doc>> = Array<GeneralCondition<Doc, F>>;
133
+ type ContextOperator = Exclude<Operator, '==' | '!='> | 'in' | 'not in';
134
+ type AllOperators = Operator | 'in' | 'not in';
135
+ /** A generic value that can exist in a query. */
136
+ type GenericValue<Doc = any, F extends Paths<Doc> = Paths<Doc>, O extends AllOperators = any> = O extends 'in' ? Array<DeepRecord<Doc>[F]> | null : O extends 'not in' ? Array<DeepRecord<Doc>[F]> | null : DeepRecord<Doc>[F] | null;
137
+ export {};
@@ -1,48 +1,36 @@
1
1
  import { ClientRequestId } from './communication.types';
2
- import { CollectionName, FieldName } from './document.types';
2
+ import { CollectionName, DocumentData, FieldName } from './document.types';
3
+ import { Paths } from './types';
3
4
  /** A list of query conditions. */
4
- export type Conditions<Doc = any, F extends FieldName<Doc> = any> = Array<Condition<Doc, F>>;
5
- /** A single query condition. */
6
- export interface Condition<Doc = any, F extends FieldName<Doc> = any> {
5
+ export type Condition<Doc extends DocumentData = any> = SimpleCondition<Doc> | CompositeCondition<Doc>;
6
+ export type Conditions<Doc extends DocumentData = any> = Array<Condition<Doc>>;
7
+ /** A single field query condition. */
8
+ export interface SimpleCondition<Doc extends DocumentData = any, F extends Paths<Doc> = Paths<Doc>, MyOperator = Operator> {
7
9
  fieldName: F;
8
- operator: Operator;
9
- value: Doc[F] | null;
10
- }
11
- /** An operator in a query condition. */
12
- export type Operator = '==' | '>=' | '<=' | '>' | '<' | '!=' | 'like' | 'not like' | 'like_cs' | 'not like_cs';
13
- /** A list of context conditions */
14
- export type ContextConditions<Doc = any, F extends FieldName<Doc> = any> = Array<ContextCondition<Doc, F>>;
15
- /** A generic value that can exist in a query. */
16
- export type GenericValue<Doc = any, F extends FieldName<Doc> = any, O extends AllOperators = any> = O extends 'in' ? Array<Doc[F]> | null : O extends 'not in' ? Array<Doc[F]> | null : Doc[F] | null;
17
- /** A Context condition - a condition that replaces multiple '==' or '!=' conditions with 'in' and 'not in'. */
18
- export type ContextCondition<Doc = any, F extends FieldName<Doc> = any> = InContextCondition<Doc, F> | NotInContextCondition<Doc, F> | OtherContextCondition<Doc, F>;
19
- interface InContextCondition<Doc = any, F extends FieldName<Doc> = any> extends Omit<Condition<Doc, F>, 'operator' | 'value'> {
20
- operator: 'in';
21
- value: Array<Doc[F]>;
22
- }
23
- interface NotInContextCondition<Doc = any, F extends FieldName<Doc> = any> extends Omit<Condition<Doc, F>, 'operator' | 'value'> {
24
- operator: 'not in';
25
- value: Array<Doc[F]>;
26
- }
27
- export interface OtherContextCondition<Doc = any, F extends FieldName<Doc> = any> extends Omit<Condition<Doc, F>, 'operator'> {
28
- operator: Exclude<ContextOperator, 'in' | 'not in'>;
29
- }
30
- /** A condition that includes the 'in' and 'not in' operators. */
31
- export interface GeneralCondition<Doc = any, F extends FieldName<Doc> = any> extends Omit<Condition<Doc, F>, 'operator' | 'value'> {
32
- operator: AllOperators;
10
+ operator: MyOperator;
33
11
  value: any;
34
12
  }
35
- /** A list of general conditions. */
36
- export type GeneralConditions<Doc = any, F extends FieldName<Doc> = any> = Array<GeneralCondition<Doc, F>>;
37
- export type ContextOperator = Exclude<Operator, '==' | '!='> | 'in' | 'not in';
38
- export type AllOperators = Operator | 'in' | 'not in';
13
+ /**
14
+ * A composite fields query condition.
15
+ * Just a list of simple conditions with specific set of operators. It should be
16
+ * evaluated this way:
17
+ * If A, B, C are the conditions and A` = A with '==' operator:
18
+ * A || (A' && B) || (A' && B' && C)
19
+ */
20
+ export interface CompositeCondition<Doc extends DocumentData = any> {
21
+ fields: Array<SimpleCondition<Doc, Paths<Doc>, CompositeConditionOperator>>;
22
+ }
23
+ export declare function isSimpleCondition(condition: Condition): condition is SimpleCondition;
24
+ type CompositeConditionOperator = '>=' | '<=' | '>' | '<';
25
+ /** An operator in a query condition. */
26
+ export type Operator = '==' | '!=' | CompositeConditionOperator | 'like' | 'not like' | 'like_cs' | 'not like_cs';
39
27
  /** A definition of a sort by a filed. */
40
28
  export interface FieldSort<Doc> {
41
29
  fieldName: FieldName<Doc>;
42
30
  asc: boolean;
43
31
  }
44
32
  /** A query object. */
45
- export interface Query<Doc = any> {
33
+ export interface Query<Doc extends DocumentData = any> {
46
34
  collectionName: CollectionName;
47
35
  integrationId: string;
48
36
  conditions: Conditions<Doc>;
@@ -1,8 +1,14 @@
1
1
  export interface Type<T> extends Function {
2
2
  new (...args: any[]): T;
3
3
  }
4
+ type PropertiesWithPrefix<Prefix extends string> = {
5
+ [key in `${Prefix}${string}`]: any;
6
+ };
4
7
  type Pred = [0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
5
- export type Paths<T, RemainingDepth extends number & keyof Pred = 5, Prefix extends string = ''> = RemainingDepth extends 0 ? `${Prefix}${string}` : {
6
- [k in keyof T]-?: k extends string | number ? `${Prefix}${k}` | (Required<T>[k] extends any[] ? never : Required<T>[k] extends object ? Paths<Required<T>[k], Pred[RemainingDepth], `${Prefix}${k}.`> : never) : never;
8
+ export type DeepRecord<T, RemainingDepth extends number & keyof Pred = 5, Prefix extends string = ''> = RemainingDepth extends 0 ? PropertiesWithPrefix<Prefix> : {
9
+ [k in keyof T]-?: k extends string | number ? Record<`${Prefix}${k}`, T[k]> | (Required<T>[k] extends any[] ? never : Required<T>[k] extends object ? DeepRecord<Required<T>[k], Pred[RemainingDepth], `${Prefix}${k}.`> : never) : never;
7
10
  }[keyof T];
11
+ export type UnionKeys<T> = T extends any ? keyof T : never;
12
+ export type FieldOf<T, K extends UnionKeys<T>> = Extract<T, Record<K, any>>[K];
13
+ export type Paths<T> = UnionKeys<DeepRecord<T>>;
8
14
  export {};