@umituz/react-native-firebase 2.6.3 → 2.6.5
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/package.json +1 -1
- package/src/application/auth/index.ts +2 -34
- package/src/application/auth/use-cases/index.ts +1 -21
- package/src/domains/account-deletion/domain/index.ts +1 -8
- package/src/domains/account-deletion/index.ts +0 -42
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts +79 -0
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionTypes.ts +0 -1
- package/src/domains/account-deletion/infrastructure/services/account-deletion.service.ts +2 -14
- package/src/domains/auth/index.ts +3 -12
- package/src/domains/auth/infrastructure/config/FirebaseAuthClient.ts +48 -60
- package/src/domains/auth/infrastructure/config/index.ts +2 -0
- package/src/domains/auth/infrastructure/config/initializers/index.ts +1 -0
- package/src/domains/auth/infrastructure/services/index.ts +16 -0
- package/src/domains/auth/infrastructure/services/utils/index.ts +1 -0
- package/src/domains/auth/infrastructure/stores/index.ts +1 -0
- package/src/domains/auth/infrastructure/utils/index.ts +1 -0
- package/src/domains/auth/infrastructure.ts +11 -0
- package/src/domains/auth/presentation/hooks/useGoogleOAuth.ts +18 -59
- package/src/domains/firestore/domain/entities/Collection.ts +0 -2
- package/src/domains/firestore/domain/index.ts +6 -2
- package/src/domains/firestore/domain/value-objects/WhereClause.ts +0 -14
- package/src/domains/firestore/index.ts +0 -1
- package/src/domains/firestore/infrastructure/config/FirestoreClient.ts +42 -60
- package/src/domains/firestore/presentation/hooks/useFirestoreMutation.ts +1 -1
- package/src/domains/firestore/presentation/hooks/useFirestoreQuery.ts +1 -1
- package/src/shared/infrastructure/base/ErrorHandler.ts +81 -0
- package/src/shared/infrastructure/base/ServiceBase.ts +62 -0
- package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts +39 -0
- package/src/application/auth/ports/AuthPort.ts.bak +0 -164
- package/src/application/auth/ports/AuthPort_part_aa +0 -150
- package/src/application/auth/ports/AuthPort_part_ab +0 -14
- package/src/application/auth/use-cases/SignInUseCase.ts.bak +0 -253
- package/src/application/auth/use-cases/SignInUseCaseHelpers.ts +0 -0
- package/src/application/auth/use-cases/SignInUseCaseMain.ts +0 -0
- package/src/application/auth/use-cases/SignInUseCase_part_aa +0 -150
- package/src/application/auth/use-cases/SignInUseCase_part_ab +0 -103
- package/src/application/auth/use-cases/SignOutUseCase.ts.bak +0 -288
- package/src/application/auth/use-cases/SignOutUseCaseCleanup.ts +0 -0
- package/src/application/auth/use-cases/SignOutUseCaseMain.ts +0 -0
- package/src/application/auth/use-cases/SignOutUseCase_part_aa +0 -150
- package/src/application/auth/use-cases/SignOutUseCase_part_ab +0 -138
- package/src/domains/account-deletion/domain/services/UserValidationHelpers.ts.bak +0 -181
- package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_aa +0 -150
- package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_ab +0 -31
- package/src/domains/account-deletion/domain/services/UserValidationService.ts.bak +0 -286
- package/src/domains/account-deletion/domain/services/UserValidationService_part_aa +0 -150
- package/src/domains/account-deletion/domain/services/UserValidationService_part_ab +0 -136
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts.bak +0 -230
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_ab +0 -80
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler.ts.bak +0 -174
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_ab +0 -24
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository.ts.bak +0 -266
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_ab +0 -116
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service.ts.bak +0 -160
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_ab +0 -10
- package/src/domains/auth/infrastructure.ts.bak +0 -156
- package/src/domains/auth/infrastructure_part_aa +0 -150
- package/src/domains/auth/infrastructure_part_ab +0 -6
- package/src/domains/auth/presentation/hooks/GoogleOAuthHelpers.ts +0 -0
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService.ts.bak +0 -247
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_aa +0 -150
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_ab +0 -97
- package/src/domains/auth/presentation/hooks/GoogleOAuthService.ts +0 -0
- package/src/domains/firestore/domain/entities/Collection.ts.bak +0 -288
- package/src/domains/firestore/domain/entities/Collection_part_aa +0 -150
- package/src/domains/firestore/domain/entities/Collection_part_ab +0 -138
- package/src/domains/firestore/domain/entities/Document.ts.bak +0 -233
- package/src/domains/firestore/domain/entities/DocumentHelpers.ts +0 -0
- package/src/domains/firestore/domain/entities/DocumentMain.ts +0 -0
- package/src/domains/firestore/domain/entities/Document_part_aa +0 -150
- package/src/domains/firestore/domain/entities/Document_part_ab +0 -83
- package/src/domains/firestore/domain/services/QueryService.ts.bak +0 -182
- package/src/domains/firestore/domain/services/QueryServiceAnalysis.ts.bak +0 -169
- package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_ab +0 -19
- package/src/domains/firestore/domain/services/QueryServiceHelpers.ts.bak +0 -151
- package/src/domains/firestore/domain/services/QueryServiceHelpers_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryServiceHelpers_part_ab +0 -1
- package/src/domains/firestore/domain/services/QueryService_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryService_part_ab +0 -32
- package/src/domains/firestore/domain/value-objects/QueryOptions.ts.bak +0 -191
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization.ts.bak +0 -207
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_ab +0 -57
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation.ts.bak +0 -182
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_ab +0 -32
- package/src/domains/firestore/domain/value-objects/QueryOptions_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptions_part_ab +0 -41
- package/src/domains/firestore/domain/value-objects/WhereClause.ts.bak +0 -299
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts.bak +0 -207
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_ab +0 -57
- package/src/domains/firestore/domain/value-objects/WhereClause_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/WhereClause_part_ab +0 -149
- package/src/shared/infrastructure/base/ErrorHandler.ts.bak +0 -189
- package/src/shared/infrastructure/base/ErrorHandler_part_aa +0 -150
- package/src/shared/infrastructure/base/ErrorHandler_part_ab +0 -39
- package/src/shared/infrastructure/base/ServiceBase.ts.bak +0 -220
- package/src/shared/infrastructure/base/ServiceBase_part_aa +0 -150
- package/src/shared/infrastructure/base/ServiceBase_part_ab +0 -70
- package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts.bak +0 -155
- package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_aa +0 -150
- package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_ab +0 -5
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Options Value Object (Main)
|
|
3
|
-
* Single Responsibility: Encapsulate query configuration options
|
|
4
|
-
*
|
|
5
|
-
* Value object that represents query options in a type-safe way.
|
|
6
|
-
* Provides validation and business logic for query configuration.
|
|
7
|
-
*
|
|
8
|
-
* Max lines: 150 (enforced for maintainability)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { WhereFilterOp, OrderByDirection } from 'firebase/firestore';
|
|
12
|
-
import { WhereClause } from './WhereClause';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Sort options
|
|
16
|
-
*/
|
|
17
|
-
export interface SortOptions {
|
|
18
|
-
readonly field: string;
|
|
19
|
-
readonly direction: OrderByDirection;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Date range options
|
|
24
|
-
*/
|
|
25
|
-
export interface DateRangeOptions {
|
|
26
|
-
readonly field: string;
|
|
27
|
-
readonly startDate?: Date;
|
|
28
|
-
readonly endDate?: Date;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Pagination options
|
|
33
|
-
*/
|
|
34
|
-
export interface PaginationOptions {
|
|
35
|
-
readonly cursor?: number;
|
|
36
|
-
readonly limit?: number;
|
|
37
|
-
readonly startAfter?: number;
|
|
38
|
-
readonly startAt?: number;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Query options value object
|
|
43
|
-
* Immutable configuration for Firestore queries
|
|
44
|
-
*/
|
|
45
|
-
export class QueryOptions {
|
|
46
|
-
readonly whereClauses: readonly WhereClause[];
|
|
47
|
-
readonly sortOptions: readonly SortOptions[];
|
|
48
|
-
readonly dateRange: DateRangeOptions | null;
|
|
49
|
-
readonly pagination: PaginationOptions | null;
|
|
50
|
-
|
|
51
|
-
private constructor(
|
|
52
|
-
whereClauses: WhereClause[],
|
|
53
|
-
sortOptions: SortOptions[],
|
|
54
|
-
dateRange: DateRangeOptions | null,
|
|
55
|
-
pagination: PaginationOptions | null
|
|
56
|
-
) {
|
|
57
|
-
this.whereClauses = Object.freeze(whereClauses);
|
|
58
|
-
this.sortOptions = Object.freeze(sortOptions);
|
|
59
|
-
this.dateRange = dateRange ? Object.freeze(dateRange) : null;
|
|
60
|
-
this.pagination = pagination ? Object.freeze(pagination) : null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create empty query options
|
|
65
|
-
*/
|
|
66
|
-
static empty(): QueryOptions {
|
|
67
|
-
return new QueryOptions([], [], null, null);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Create query options from partial configuration
|
|
72
|
-
*/
|
|
73
|
-
static create(options: {
|
|
74
|
-
where?: WhereClause[];
|
|
75
|
-
sort?: SortOptions[];
|
|
76
|
-
dateRange?: DateRangeOptions;
|
|
77
|
-
pagination?: PaginationOptions;
|
|
78
|
-
}): QueryOptions {
|
|
79
|
-
return new QueryOptions(
|
|
80
|
-
options.where || [],
|
|
81
|
-
options.sort || [],
|
|
82
|
-
options.dateRange || null,
|
|
83
|
-
options.pagination || null
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Add where clause
|
|
89
|
-
*/
|
|
90
|
-
withWhere(clause: WhereClause): QueryOptions {
|
|
91
|
-
return new QueryOptions(
|
|
92
|
-
[...this.whereClauses, clause] as WhereClause[],
|
|
93
|
-
this.sortOptions,
|
|
94
|
-
this.dateRange,
|
|
95
|
-
this.pagination
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Add sort option
|
|
101
|
-
*/
|
|
102
|
-
withSort(sort: SortOptions): QueryOptions {
|
|
103
|
-
return new QueryOptions(
|
|
104
|
-
this.whereClauses,
|
|
105
|
-
[...this.sortOptions, sort] as SortOptions[],
|
|
106
|
-
this.dateRange,
|
|
107
|
-
this.pagination
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Set date range
|
|
113
|
-
*/
|
|
114
|
-
withDateRange(dateRange: DateRangeOptions): QueryOptions {
|
|
115
|
-
return new QueryOptions(
|
|
116
|
-
this.whereClauses,
|
|
117
|
-
this.sortOptions,
|
|
118
|
-
dateRange,
|
|
119
|
-
this.pagination
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Set pagination
|
|
125
|
-
*/
|
|
126
|
-
withPagination(pagination: PaginationOptions): QueryOptions {
|
|
127
|
-
return new QueryOptions(
|
|
128
|
-
this.whereClauses,
|
|
129
|
-
this.sortOptions,
|
|
130
|
-
this.dateRange,
|
|
131
|
-
pagination
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Remove all where clauses
|
|
137
|
-
*/
|
|
138
|
-
clearWhere(): QueryOptions {
|
|
139
|
-
return new QueryOptions([], this.sortOptions, this.dateRange, this.pagination);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Remove all sort options
|
|
144
|
-
*/
|
|
145
|
-
clearSort(): QueryOptions {
|
|
146
|
-
return new QueryOptions(this.whereClauses, [], this.dateRange, this.pagination);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Remove date range
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
*/
|
|
2
|
-
clearDateRange(): QueryOptions {
|
|
3
|
-
return new QueryOptions(this.whereClauses, this.sortOptions, null, this.pagination);
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Remove pagination
|
|
8
|
-
*/
|
|
9
|
-
clearPagination(): QueryOptions {
|
|
10
|
-
return new QueryOptions(this.whereClauses, this.sortOptions, this.dateRange, null);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Clone with modifications
|
|
15
|
-
*/
|
|
16
|
-
clone(modifications: {
|
|
17
|
-
where?: WhereClause[];
|
|
18
|
-
sort?: SortOptions[];
|
|
19
|
-
dateRange?: DateRangeOptions | null;
|
|
20
|
-
pagination?: PaginationOptions | null;
|
|
21
|
-
}): QueryOptions {
|
|
22
|
-
return QueryOptions.create({
|
|
23
|
-
where: modifications.where ?? [...this.whereClauses] as WhereClause[],
|
|
24
|
-
sort: modifications.sort ?? [...this.sortOptions] as SortOptions[],
|
|
25
|
-
dateRange: modifications.dateRange ?? this.dateRange ?? null,
|
|
26
|
-
pagination: modifications.pagination ?? this.pagination ?? null,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Factory function to create query options
|
|
33
|
-
*/
|
|
34
|
-
export function createQueryOptions(options?: {
|
|
35
|
-
where?: WhereClause[];
|
|
36
|
-
sort?: SortOptions[];
|
|
37
|
-
dateRange?: DateRangeOptions;
|
|
38
|
-
pagination?: PaginationOptions;
|
|
39
|
-
}): QueryOptions {
|
|
40
|
-
return options ? QueryOptions.create(options) : QueryOptions.empty();
|
|
41
|
-
}
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Where Clause Value Object
|
|
3
|
-
* Single Responsibility: Encapsulate where clause conditions
|
|
4
|
-
*
|
|
5
|
-
* Value object that represents a single where clause condition.
|
|
6
|
-
* Provides validation and business logic for query filtering.
|
|
7
|
-
*
|
|
8
|
-
* Max lines: 150 (enforced for maintainability)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { WhereFilterOp } from 'firebase/firestore';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Valid where operators for Firestore queries
|
|
15
|
-
*/
|
|
16
|
-
export type WhereOperator =
|
|
17
|
-
| '=='
|
|
18
|
-
| '!='
|
|
19
|
-
| '<'
|
|
20
|
-
| '<='
|
|
21
|
-
| '>'
|
|
22
|
-
| '>='
|
|
23
|
-
| 'array-contains'
|
|
24
|
-
| 'array-contains-any'
|
|
25
|
-
| 'in'
|
|
26
|
-
| 'not-in';
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Where clause value object
|
|
30
|
-
* Immutable representation of a single query condition
|
|
31
|
-
*/
|
|
32
|
-
export class WhereClause {
|
|
33
|
-
readonly field: string;
|
|
34
|
-
readonly operator: WhereFilterOp;
|
|
35
|
-
readonly value: unknown;
|
|
36
|
-
|
|
37
|
-
private constructor(field: string, operator: WhereFilterOp, value: unknown) {
|
|
38
|
-
this.field = field;
|
|
39
|
-
this.operator = operator;
|
|
40
|
-
this.value = Object.freeze(value);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Create a where clause
|
|
45
|
-
*/
|
|
46
|
-
static create(field: string, operator: WhereFilterOp, value: unknown): WhereClause {
|
|
47
|
-
return new WhereClause(field, operator, value);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Create equality clause (==)
|
|
52
|
-
*/
|
|
53
|
-
static equals(field: string, value: unknown): WhereClause {
|
|
54
|
-
return new WhereClause(field, '==', value);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Create inequality clause (!=)
|
|
59
|
-
*/
|
|
60
|
-
static notEquals(field: string, value: unknown): WhereClause {
|
|
61
|
-
return new WhereClause(field, '!=', value);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Create less than clause (<)
|
|
66
|
-
*/
|
|
67
|
-
static lessThan(field: string, value: unknown): WhereClause {
|
|
68
|
-
return new WhereClause(field, '<', value);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Create less than or equal clause (<=)
|
|
73
|
-
*/
|
|
74
|
-
static lessThanOrEqual(field: string, value: unknown): WhereClause {
|
|
75
|
-
return new WhereClause(field, '<=', value);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Create greater than clause (>)
|
|
80
|
-
*/
|
|
81
|
-
static greaterThan(field: string, value: unknown): WhereClause {
|
|
82
|
-
return new WhereClause(field, '>', value);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Create greater than or equal clause (>=)
|
|
87
|
-
*/
|
|
88
|
-
static greaterThanOrEqual(field: string, value: unknown): WhereClause {
|
|
89
|
-
return new WhereClause(field, '>=', value);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Create array contains clause
|
|
94
|
-
*/
|
|
95
|
-
static arrayContains(field: string, value: unknown): WhereClause {
|
|
96
|
-
return new WhereClause(field, 'array-contains', value);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Create array contains any clause
|
|
101
|
-
*/
|
|
102
|
-
static arrayContainsAny(field: string, values: unknown[]): WhereClause {
|
|
103
|
-
return new WhereClause(field, 'array-contains-any', values);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Create in clause
|
|
108
|
-
*/
|
|
109
|
-
static in(field: string, values: unknown[]): WhereClause {
|
|
110
|
-
return new WhereClause(field, 'in', values);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Create not-in clause
|
|
115
|
-
*/
|
|
116
|
-
static notIn(field: string, values: unknown[]): WhereClause {
|
|
117
|
-
return new WhereClause(field, 'not-in', values);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Validate where clause
|
|
122
|
-
*/
|
|
123
|
-
validate(): { valid: boolean; errors: string[] } {
|
|
124
|
-
const errors: string[] = [];
|
|
125
|
-
|
|
126
|
-
// Validate field name
|
|
127
|
-
if (!this.field || typeof this.field !== 'string' || this.field.trim() === '') {
|
|
128
|
-
errors.push('Field name must be a non-empty string');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Validate operator
|
|
132
|
-
const validOperators: WhereFilterOp[] = [
|
|
133
|
-
'==', '!=', '<', '<=', '>', '>=',
|
|
134
|
-
'array-contains', 'array-contains-any', 'in', 'not-in'
|
|
135
|
-
];
|
|
136
|
-
if (!validOperators.includes(this.operator)) {
|
|
137
|
-
errors.push(`Invalid operator: ${this.operator}`);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Validate value based on operator
|
|
141
|
-
if (this.operator === 'array-contains-any' || this.operator === 'in' || this.operator === 'not-in') {
|
|
142
|
-
if (!Array.isArray(this.value)) {
|
|
143
|
-
errors.push(`Operator ${this.operator} requires an array value`);
|
|
144
|
-
} else if (this.value.length === 0) {
|
|
145
|
-
errors.push(`Operator ${this.operator} requires a non-empty array`);
|
|
146
|
-
} else if (this.value.length > 10) {
|
|
147
|
-
errors.push(`Operator ${this.operator} supports maximum 10 elements`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return {
|
|
152
|
-
valid: errors.length === 0,
|
|
153
|
-
errors,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Check if equals another where clause
|
|
159
|
-
*/
|
|
160
|
-
equals(other: WhereClause): boolean {
|
|
161
|
-
return (
|
|
162
|
-
this.field === other.field &&
|
|
163
|
-
this.operator === other.operator &&
|
|
164
|
-
JSON.stringify(this.value) === JSON.stringify(other.value)
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Check if compatible for compound queries
|
|
170
|
-
* Some operator combinations are not allowed in Firestore
|
|
171
|
-
*/
|
|
172
|
-
isCompatibleWith(other: WhereClause): boolean {
|
|
173
|
-
// Equality and inequality operators can be combined
|
|
174
|
-
// Array operators and membership operators have restrictions
|
|
175
|
-
if (
|
|
176
|
-
(this.isArrayOperator() || this.isMembership()) &&
|
|
177
|
-
(other.isArrayOperator() || other.isMembership())
|
|
178
|
-
) {
|
|
179
|
-
// Only one array/membership clause per query
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return true;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Get field path components
|
|
188
|
-
* Returns array of field path segments (for nested fields)
|
|
189
|
-
*/
|
|
190
|
-
getFieldPath(): string[] {
|
|
191
|
-
return this.field.split('.');
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Check if field is nested (contains dots)
|
|
196
|
-
*/
|
|
197
|
-
isNestedField(): boolean {
|
|
198
|
-
return this.field.includes('.');
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Get top-level field name
|
|
203
|
-
*/
|
|
204
|
-
getTopLevelField(): string {
|
|
205
|
-
return this.getFieldPath()[0];
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Get human-readable description
|
|
210
|
-
*/
|
|
211
|
-
getDescription(): string {
|
|
212
|
-
const valueStr = Array.isArray(this.value)
|
|
213
|
-
? `[${this.value.map(v => JSON.stringify(v)).join(', ')}]`
|
|
214
|
-
: JSON.stringify(this.value);
|
|
215
|
-
|
|
216
|
-
return `${this.field} ${this.operator} ${valueStr}`;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Convert to plain object (for serialization)
|
|
221
|
-
*/
|
|
222
|
-
toObject(): { field: string; operator: WhereFilterOp; value: unknown } {
|
|
223
|
-
return {
|
|
224
|
-
field: this.field,
|
|
225
|
-
operator: this.operator,
|
|
226
|
-
value: this.value,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Create from plain object
|
|
232
|
-
*/
|
|
233
|
-
static fromObject(obj: { field: string; operator: WhereFilterOp; value: unknown }): WhereClause {
|
|
234
|
-
return WhereClause.create(obj.field, obj.operator, obj.value);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Clone with new value
|
|
239
|
-
*/
|
|
240
|
-
withValue(newValue: unknown): WhereClause {
|
|
241
|
-
return new WhereClause(this.field, this.operator, newValue);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Clone with new field
|
|
246
|
-
*/
|
|
247
|
-
withField(newField: string): WhereClause {
|
|
248
|
-
return new WhereClause(newField, this.operator, this.value);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Clone with new operator
|
|
253
|
-
*/
|
|
254
|
-
withOperator(newOperator: WhereFilterOp): WhereClause {
|
|
255
|
-
return new WhereClause(this.field, newOperator, this.value);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Check if is equality operator
|
|
260
|
-
*/
|
|
261
|
-
isEquality(): boolean {
|
|
262
|
-
return this.operator === '==';
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Check if is inequality operator
|
|
267
|
-
*/
|
|
268
|
-
isInequality(): boolean {
|
|
269
|
-
return this.operator === '!=';
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Check if is comparison operator (<, <=, >, >=)
|
|
274
|
-
*/
|
|
275
|
-
isComparison(): boolean {
|
|
276
|
-
return ['<', '<=', '>', '>='].includes(this.operator);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Check if is array operator
|
|
281
|
-
*/
|
|
282
|
-
isArrayOperator(): boolean {
|
|
283
|
-
return ['array-contains', 'array-contains-any'].includes(this.operator);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Check if is membership operator (in, not-in)
|
|
288
|
-
*/
|
|
289
|
-
isMembership(): boolean {
|
|
290
|
-
return ['in', 'not-in'].includes(this.operator);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Check if operator requires array value
|
|
295
|
-
*/
|
|
296
|
-
requiresArrayValue(): boolean {
|
|
297
|
-
return ['array-contains-any', 'in', 'not-in'].includes(this.operator);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Where Clause Factory
|
|
3
|
-
* Single Responsibility: Provide factory methods for common where clauses
|
|
4
|
-
*
|
|
5
|
-
* Factory functions for creating commonly used where clauses.
|
|
6
|
-
* Separated from WhereClause for better maintainability.
|
|
7
|
-
*
|
|
8
|
-
* Max lines: 150 (enforced for maintainability)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { WhereFilterOp } from 'firebase/firestore';
|
|
12
|
-
import { WhereClause } from './WhereClause';
|
|
13
|
-
import type { WhereOperator } from './WhereClause';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Factory function to create where clause
|
|
17
|
-
*/
|
|
18
|
-
export function createWhereClause(
|
|
19
|
-
field: string,
|
|
20
|
-
operator: WhereFilterOp,
|
|
21
|
-
value: unknown
|
|
22
|
-
): WhereClause {
|
|
23
|
-
return WhereClause.create(field, operator, value);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Factory functions for common where clauses
|
|
28
|
-
*/
|
|
29
|
-
export const where = {
|
|
30
|
-
equals: WhereClause.equals,
|
|
31
|
-
notEquals: WhereClause.notEquals,
|
|
32
|
-
lessThan: WhereClause.lessThan,
|
|
33
|
-
lessThanOrEqual: WhereClause.lessThanOrEqual,
|
|
34
|
-
greaterThan: WhereClause.greaterThan,
|
|
35
|
-
greaterThanOrEqual: WhereClause.greaterThanOrEqual,
|
|
36
|
-
arrayContains: WhereClause.arrayContains,
|
|
37
|
-
arrayContainsAny: WhereClause.arrayContainsAny,
|
|
38
|
-
in: WhereClause.in,
|
|
39
|
-
notIn: WhereClause.notIn,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Create batch of where clauses
|
|
44
|
-
*/
|
|
45
|
-
export function createWhereBatch(
|
|
46
|
-
clauses: Array<{ field: string; operator: WhereFilterOp; value: unknown }>
|
|
47
|
-
): WhereClause[] {
|
|
48
|
-
return clauses.map(c => WhereClause.create(c.field, c.operator, c.value));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Create equality clauses from object
|
|
53
|
-
*/
|
|
54
|
-
export function createEqualityFilters(obj: Record<string, unknown>): WhereClause[] {
|
|
55
|
-
return Object.entries(obj).map(([field, value]) =>
|
|
56
|
-
WhereClause.equals(field, value)
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Create in clause from values
|
|
62
|
-
*/
|
|
63
|
-
export function createInClause(field: string, values: unknown[]): WhereClause {
|
|
64
|
-
return WhereClause.in(field, values);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Create not-in clause from values
|
|
69
|
-
*/
|
|
70
|
-
export function createNotInClause(field: string, values: unknown[]): WhereClause {
|
|
71
|
-
return WhereClause.notIn(field, values);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Create range clause (>= start and <= end)
|
|
76
|
-
*/
|
|
77
|
-
export function createRangeClause(
|
|
78
|
-
field: string,
|
|
79
|
-
startValue: unknown,
|
|
80
|
-
endValue: unknown
|
|
81
|
-
): WhereClause[] {
|
|
82
|
-
return [
|
|
83
|
-
WhereClause.greaterThanOrEqual(field, startValue),
|
|
84
|
-
WhereClause.lessThanOrEqual(field, endValue),
|
|
85
|
-
];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Create date range clause
|
|
90
|
-
*/
|
|
91
|
-
export function createDateRangeClause(
|
|
92
|
-
field: string,
|
|
93
|
-
startDate: Date,
|
|
94
|
-
endDate: Date
|
|
95
|
-
): WhereClause[] {
|
|
96
|
-
return createRangeClause(field, startDate, endDate);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Create text search clause (case-insensitive contains)
|
|
101
|
-
* Note: Firestore doesn't support native contains, this is for consistency
|
|
102
|
-
*/
|
|
103
|
-
export function createTextSearchClause(field: string, searchText: string): WhereClause {
|
|
104
|
-
return WhereClause.equals(field, searchText);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Create multiple equality clauses combined
|
|
109
|
-
*/
|
|
110
|
-
export function createMultiFieldFilter(filters: Record<string, unknown>): WhereClause[] {
|
|
111
|
-
return createEqualityFilters(filters);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Create not-null clause
|
|
116
|
-
*/
|
|
117
|
-
export function createNotNullClause(field: string): WhereClause {
|
|
118
|
-
return WhereClause.notEquals(field, null);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Create null clause
|
|
123
|
-
*/
|
|
124
|
-
export function createNullClause(field: string): WhereClause {
|
|
125
|
-
return WhereClause.equals(field, null);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Create boolean clause
|
|
130
|
-
*/
|
|
131
|
-
export function createBooleanClause(field: string, value: boolean): WhereClause {
|
|
132
|
-
return WhereClause.equals(field, value);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Create number range clause
|
|
137
|
-
*/
|
|
138
|
-
export function createNumberRangeClause(
|
|
139
|
-
field: string,
|
|
140
|
-
min: number,
|
|
141
|
-
max: number
|
|
142
|
-
): WhereClause[] {
|
|
143
|
-
return [
|
|
144
|
-
WhereClause.greaterThanOrEqual(field, min),
|
|
145
|
-
WhereClause.lessThanOrEqual(field, max),
|
|
146
|
-
];
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Validate where clauses compatibility
|
|
151
|
-
*/
|
|
152
|
-
export function validateWhereClauses(clauses: WhereClause[]): {
|
|
153
|
-
valid: boolean;
|
|
154
|
-
errors: string[];
|
|
155
|
-
} {
|
|
156
|
-
const errors: string[] = [];
|
|
157
|
-
|
|
158
|
-
// Validate each clause individually
|
|
159
|
-
for (let i = 0; i < clauses.length; i++) {
|
|
160
|
-
const validation = clauses[i].validate();
|
|
161
|
-
if (!validation.valid) {
|
|
162
|
-
errors.push(`Clause ${i}: ${validation.errors.join(', ')}`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Validate compatibility
|
|
167
|
-
for (let i = 0; i < clauses.length; i++) {
|
|
168
|
-
for (let j = i + 1; j < clauses.length; j++) {
|
|
169
|
-
if (!clauses[i].isCompatibleWith(clauses[j])) {
|
|
170
|
-
errors.push(`Clauses ${i} and ${j} are incompatible`);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return {
|
|
176
|
-
valid: errors.length === 0,
|
|
177
|
-
errors,
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Optimize where clauses
|
|
183
|
-
* Removes duplicates and incompatible clauses
|
|
184
|
-
*/
|
|
185
|
-
export function optimizeWhereClauses(clauses: WhereClause[]): WhereClause[] {
|
|
186
|
-
// Remove duplicates
|
|
187
|
-
const unique = clauses.filter((clause, index, self) =>
|
|
188
|
-
index === self.findIndex(c => clause.equals(c))
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
// Remove incompatible (keep first occurrences)
|
|
192
|
-
const compatible: WhereClause[] = [];
|
|
193
|
-
for (const clause of unique) {
|
|
194
|
-
let canAdd = true;
|
|
195
|
-
for (const existing of compatible) {
|
|
196
|
-
if (!clause.isCompatibleWith(existing)) {
|
|
197
|
-
canAdd = false;
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
if (canAdd) {
|
|
202
|
-
compatible.push(clause);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return compatible;
|
|
207
|
-
}
|