@umituz/react-native-firebase 3.0.3 → 3.0.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 +7 -1
- package/src/domains/account-deletion/index.ts +15 -10
- package/src/domains/account-deletion/infrastructure/services/account-deletion.service.ts +226 -26
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service.ts +160 -0
- package/src/domains/auth/domain/value-objects/FirebaseAuthConfig.ts +1 -1
- package/src/domains/auth/index.ts +156 -6
- package/src/domains/auth/infrastructure/config/FirebaseAuthClient.ts +60 -48
- package/src/domains/auth/infrastructure/config/initializers/FirebaseAuthInitializer.ts +41 -5
- package/src/domains/auth/presentation/hooks/useGoogleOAuth.ts +115 -20
- package/src/domains/firestore/domain/constants/QuotaLimits.ts +101 -0
- package/src/domains/firestore/domain/entities/QuotaMetrics.ts +26 -0
- package/src/domains/firestore/domain/entities/RequestLog.ts +28 -0
- package/src/domains/firestore/domain/services/QuotaCalculator.ts +71 -0
- package/src/domains/firestore/index.ts +86 -31
- package/src/domains/firestore/infrastructure/config/FirestoreClient.ts +82 -45
- package/src/domains/firestore/infrastructure/config/initializers/FirebaseFirestoreInitializer.ts +249 -4
- package/src/domains/firestore/infrastructure/middleware/QueryDeduplicationMiddleware.ts +312 -0
- package/src/domains/firestore/infrastructure/middleware/QuotaTrackingMiddleware.ts +95 -0
- package/src/domains/firestore/infrastructure/repositories/BasePaginatedRepository.ts +7 -1
- package/src/domains/firestore/infrastructure/repositories/BaseQueryRepository.ts +34 -8
- package/src/domains/firestore/infrastructure/repositories/BaseRepository.ts +48 -9
- package/src/domains/firestore/infrastructure/services/RequestLoggerService.ts +165 -0
- package/src/domains/firestore/presentation/hooks/index.ts +10 -0
- package/src/domains/firestore/presentation/hooks/useFirestoreMutation.ts +1 -1
- package/src/domains/firestore/presentation/hooks/useFirestoreQuery.ts +1 -1
- package/src/domains/firestore/presentation/hooks/useSmartFirestoreSnapshot.ts +361 -0
- package/src/domains/firestore/presentation/query-keys/createFirestoreKeys.ts +32 -0
- package/src/domains/firestore/presentation/query-keys/index.ts +1 -0
- package/src/domains/firestore/utils/deduplication/pending-query-manager.util.ts +119 -0
- package/src/domains/firestore/utils/deduplication/query-key-generator.util.ts +34 -0
- package/src/domains/firestore/utils/deduplication/timer-manager.util.ts +83 -0
- package/src/index.ts +2 -30
- package/src/shared/domain/utils/calculation.util.ts +305 -17
- package/src/shared/domain/utils/error-handlers/error-messages.ts +0 -11
- package/src/shared/domain/utils/index.ts +5 -0
- package/src/shared/infrastructure/config/base/ClientStateManager.ts +82 -0
- package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts +136 -20
- package/src/shared/infrastructure/config/clients/FirebaseClientSingleton.ts +1 -1
- package/src/shared/infrastructure/config/initializers/FirebaseAppInitializer.ts +9 -0
- package/src/shared/infrastructure/config/services/FirebaseInitializationService.ts +1 -1
- package/src/shared/infrastructure/config/state/FirebaseClientState.ts +14 -36
- package/src/application/auth/index.ts +0 -10
- package/src/application/auth/use-cases/index.ts +0 -6
- package/src/domains/account-deletion/domain/index.ts +0 -8
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts +0 -79
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionTypes.ts +0 -32
- package/src/domains/auth/domain.ts +0 -16
- package/src/domains/auth/infrastructure/config/index.ts +0 -2
- package/src/domains/auth/infrastructure/config/initializers/index.ts +0 -1
- package/src/domains/auth/infrastructure/services/index.ts +0 -16
- package/src/domains/auth/infrastructure/services/utils/index.ts +0 -1
- package/src/domains/auth/infrastructure/stores/index.ts +0 -1
- package/src/domains/auth/infrastructure/utils/index.ts +0 -1
- package/src/domains/auth/infrastructure.ts +0 -11
- package/src/domains/auth/presentation/hooks/useAppleAuth.ts +0 -82
- package/src/domains/auth/presentation.ts +0 -31
- package/src/domains/firestore/domain/entities/Collection.ts +0 -122
- package/src/domains/firestore/domain/entities/CollectionFactory.ts +0 -55
- package/src/domains/firestore/domain/entities/CollectionHelpers.ts +0 -143
- package/src/domains/firestore/domain/entities/CollectionUtils.ts +0 -72
- package/src/domains/firestore/domain/entities/CollectionValidation.ts +0 -138
- package/src/domains/firestore/domain/index.ts +0 -61
- package/src/domains/firestore/domain/value-objects/QueryOptions.ts +0 -143
- package/src/domains/firestore/domain/value-objects/QueryOptionsFactory.ts +0 -95
- package/src/domains/firestore/domain/value-objects/QueryOptionsHelpers.ts +0 -110
- package/src/domains/firestore/domain/value-objects/WhereClause.ts +0 -114
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts +0 -101
- package/src/domains/firestore/domain/value-objects/WhereClauseHelpers.ts +0 -123
- package/src/domains/firestore/domain/value-objects/WhereClauseValidation.ts +0 -83
- package/src/shared/infrastructure/base/ErrorHandler.ts +0 -81
- package/src/shared/infrastructure/base/ServiceBase.ts +0 -62
- package/src/shared/infrastructure/base/TypedGuard.ts +0 -131
- package/src/shared/infrastructure/base/index.ts +0 -34
- package/src/shared/types/firebase.types.ts +0 -274
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Options Value Object (Main)
|
|
3
|
-
* Single Responsibility: Encapsulate query configuration options
|
|
4
|
-
*
|
|
5
|
-
* Max lines: 150 (enforced for maintainability)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { OrderByDirection } from 'firebase/firestore';
|
|
9
|
-
import { WhereClause } from './WhereClause';
|
|
10
|
-
import * as Factory from './QueryOptionsFactory';
|
|
11
|
-
|
|
12
|
-
export interface SortOptions {
|
|
13
|
-
readonly field: string;
|
|
14
|
-
readonly direction: OrderByDirection;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface DateRangeOptions {
|
|
18
|
-
readonly field: string;
|
|
19
|
-
readonly startDate?: Date;
|
|
20
|
-
readonly endDate?: Date;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface PaginationOptions {
|
|
24
|
-
readonly cursor?: number;
|
|
25
|
-
readonly limit?: number;
|
|
26
|
-
readonly startAfter?: number;
|
|
27
|
-
readonly startAt?: number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export class QueryOptions {
|
|
31
|
-
readonly whereClauses: readonly WhereClause[];
|
|
32
|
-
readonly sortOptions: readonly SortOptions[];
|
|
33
|
-
readonly dateRange: DateRangeOptions | null;
|
|
34
|
-
readonly pagination: PaginationOptions | null;
|
|
35
|
-
|
|
36
|
-
private constructor(
|
|
37
|
-
whereClauses: WhereClause[],
|
|
38
|
-
sortOptions: SortOptions[],
|
|
39
|
-
dateRange: DateRangeOptions | null,
|
|
40
|
-
pagination: PaginationOptions | null
|
|
41
|
-
) {
|
|
42
|
-
this.whereClauses = Object.freeze(whereClauses);
|
|
43
|
-
this.sortOptions = Object.freeze(sortOptions);
|
|
44
|
-
this.dateRange = dateRange ? Object.freeze(dateRange) : null;
|
|
45
|
-
this.pagination = pagination ? Object.freeze(pagination) : null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
static empty(): QueryOptions {
|
|
49
|
-
return new QueryOptions([], [], null, null);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
static create(options: {
|
|
53
|
-
where?: WhereClause[];
|
|
54
|
-
sort?: SortOptions[];
|
|
55
|
-
dateRange?: DateRangeOptions;
|
|
56
|
-
pagination?: PaginationOptions;
|
|
57
|
-
}): QueryOptions {
|
|
58
|
-
return new QueryOptions(
|
|
59
|
-
options.where || [],
|
|
60
|
-
options.sort || [],
|
|
61
|
-
options.dateRange || null,
|
|
62
|
-
options.pagination || null
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
withWhere(clause: WhereClause): QueryOptions {
|
|
67
|
-
return new QueryOptions(
|
|
68
|
-
[...this.whereClauses, clause] as WhereClause[],
|
|
69
|
-
[...this.sortOptions] as SortOptions[],
|
|
70
|
-
this.dateRange,
|
|
71
|
-
this.pagination
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
withSort(sort: SortOptions): QueryOptions {
|
|
76
|
-
return new QueryOptions(
|
|
77
|
-
[...this.whereClauses] as WhereClause[],
|
|
78
|
-
[...this.sortOptions, sort] as SortOptions[],
|
|
79
|
-
this.dateRange,
|
|
80
|
-
this.pagination
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
withDateRange(dateRange: DateRangeOptions): QueryOptions {
|
|
85
|
-
return new QueryOptions(
|
|
86
|
-
[...this.whereClauses] as WhereClause[],
|
|
87
|
-
[...this.sortOptions] as SortOptions[],
|
|
88
|
-
dateRange,
|
|
89
|
-
this.pagination
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
withPagination(pagination: PaginationOptions): QueryOptions {
|
|
94
|
-
return new QueryOptions(
|
|
95
|
-
[...this.whereClauses] as WhereClause[],
|
|
96
|
-
[...this.sortOptions] as SortOptions[],
|
|
97
|
-
this.dateRange,
|
|
98
|
-
pagination
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
withLimit(limit: number): QueryOptions {
|
|
103
|
-
return this.withPagination({
|
|
104
|
-
...this.pagination,
|
|
105
|
-
limit,
|
|
106
|
-
} as PaginationOptions);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
clearWhere(): QueryOptions {
|
|
110
|
-
return new QueryOptions([], [...this.sortOptions] as SortOptions[], this.dateRange, this.pagination);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
clearSort(): QueryOptions {
|
|
114
|
-
return new QueryOptions([...this.whereClauses] as WhereClause[], [], this.dateRange, this.pagination);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
clearDateRange(): QueryOptions {
|
|
118
|
-
return new QueryOptions([...this.whereClauses] as WhereClause[], [...this.sortOptions] as SortOptions[], null, this.pagination);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
clearPagination(): QueryOptions {
|
|
122
|
-
return new QueryOptions([...this.whereClauses] as WhereClause[], [...this.sortOptions] as SortOptions[], this.dateRange, null);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
clone(modifications: {
|
|
126
|
-
where?: WhereClause[];
|
|
127
|
-
sort?: SortOptions[];
|
|
128
|
-
dateRange?: DateRangeOptions | null;
|
|
129
|
-
pagination?: PaginationOptions | null;
|
|
130
|
-
}): QueryOptions {
|
|
131
|
-
return Factory.clone(this, modifications);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Factory function
|
|
136
|
-
export function createQueryOptions(options?: {
|
|
137
|
-
where?: WhereClause[];
|
|
138
|
-
sort?: SortOptions[];
|
|
139
|
-
dateRange?: DateRangeOptions;
|
|
140
|
-
pagination?: PaginationOptions;
|
|
141
|
-
}): QueryOptions {
|
|
142
|
-
return options ? QueryOptions.create(options) : QueryOptions.empty();
|
|
143
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Options Factory
|
|
3
|
-
* Single Responsibility: Create query options
|
|
4
|
-
*
|
|
5
|
-
* Max lines: 150 (enforced for maintainability)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { WhereFilterOp, OrderByDirection } from 'firebase/firestore';
|
|
9
|
-
import type { SortOptions, DateRangeOptions, PaginationOptions } from './QueryOptions';
|
|
10
|
-
import { WhereClause } from './WhereClause';
|
|
11
|
-
import { QueryOptions } from './QueryOptions';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Create empty query options
|
|
15
|
-
*/
|
|
16
|
-
export function empty(): QueryOptions {
|
|
17
|
-
return QueryOptions.empty();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Create query options from partial configuration
|
|
22
|
-
*/
|
|
23
|
-
export function create(options: {
|
|
24
|
-
where?: WhereClause[];
|
|
25
|
-
sort?: SortOptions[];
|
|
26
|
-
dateRange?: DateRangeOptions;
|
|
27
|
-
pagination?: PaginationOptions;
|
|
28
|
-
}): QueryOptions {
|
|
29
|
-
return QueryOptions.create(options);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Create query options with where clause
|
|
34
|
-
*/
|
|
35
|
-
export function withWhere(
|
|
36
|
-
baseOptions: QueryOptions,
|
|
37
|
-
field: string,
|
|
38
|
-
operator: WhereFilterOp,
|
|
39
|
-
value: unknown
|
|
40
|
-
): QueryOptions {
|
|
41
|
-
const clause = new WhereClause(field, operator, value);
|
|
42
|
-
return baseOptions.withWhere(clause);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Create query options with sort
|
|
47
|
-
*/
|
|
48
|
-
export function withSort(
|
|
49
|
-
baseOptions: QueryOptions,
|
|
50
|
-
field: string,
|
|
51
|
-
direction: OrderByDirection
|
|
52
|
-
): QueryOptions {
|
|
53
|
-
return baseOptions.withSort({ field, direction });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Create query options with date range
|
|
58
|
-
*/
|
|
59
|
-
export function withDateRange(
|
|
60
|
-
baseOptions: QueryOptions,
|
|
61
|
-
field: string,
|
|
62
|
-
startDate?: Date,
|
|
63
|
-
endDate?: Date
|
|
64
|
-
): QueryOptions {
|
|
65
|
-
return baseOptions.withDateRange({ field, startDate, endDate });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Create query options with pagination
|
|
70
|
-
*/
|
|
71
|
-
export function withPagination(
|
|
72
|
-
baseOptions: QueryOptions,
|
|
73
|
-
pagination: PaginationOptions
|
|
74
|
-
): QueryOptions {
|
|
75
|
-
return baseOptions.withPagination(pagination);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Create query options with limit
|
|
80
|
-
*/
|
|
81
|
-
export function withLimit(baseOptions: QueryOptions, limit: number): QueryOptions {
|
|
82
|
-
return baseOptions.withLimit(limit);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Clone query options with modifications
|
|
87
|
-
*/
|
|
88
|
-
export function clone(baseOptions: QueryOptions, modifications: {
|
|
89
|
-
where?: WhereClause[];
|
|
90
|
-
sort?: SortOptions[];
|
|
91
|
-
dateRange?: DateRangeOptions | null;
|
|
92
|
-
pagination?: PaginationOptions | null;
|
|
93
|
-
}): QueryOptions {
|
|
94
|
-
return baseOptions.clone(modifications);
|
|
95
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Options Helpers
|
|
3
|
-
* Single Responsibility: Provide helper functions for query options
|
|
4
|
-
*
|
|
5
|
-
* Max lines: 150 (enforced for maintainability)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { QueryOptions } from './QueryOptions';
|
|
9
|
-
import type { SortOptions } from './QueryOptions';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Check if query options has where clauses
|
|
13
|
-
*/
|
|
14
|
-
export function hasWhereClauses(options: QueryOptions): boolean {
|
|
15
|
-
return options.whereClauses.length > 0;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Check if query options has sort options
|
|
20
|
-
*/
|
|
21
|
-
export function hasSortOptions(options: QueryOptions): boolean {
|
|
22
|
-
return options.sortOptions.length > 0;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Check if query options has date range
|
|
27
|
-
*/
|
|
28
|
-
export function hasDateRange(options: QueryOptions): boolean {
|
|
29
|
-
return options.dateRange !== null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Check if query options has pagination
|
|
34
|
-
*/
|
|
35
|
-
export function hasPagination(options: QueryOptions): boolean {
|
|
36
|
-
return options.pagination !== null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Check if query options is empty
|
|
41
|
-
*/
|
|
42
|
-
export function isEmpty(options: QueryOptions): boolean {
|
|
43
|
-
return (
|
|
44
|
-
options.whereClauses.length === 0 &&
|
|
45
|
-
options.sortOptions.length === 0 &&
|
|
46
|
-
options.dateRange === null &&
|
|
47
|
-
options.pagination === null
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Get where clause count
|
|
53
|
-
*/
|
|
54
|
-
export function getWhereClauseCount(options: QueryOptions): number {
|
|
55
|
-
return options.whereClauses.length;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Get sort option count
|
|
60
|
-
*/
|
|
61
|
-
export function getSortOptionCount(options: QueryOptions): number {
|
|
62
|
-
return options.sortOptions.length;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Get first sort option
|
|
67
|
-
*/
|
|
68
|
-
export function getFirstSortOption(options: QueryOptions): SortOptions | null {
|
|
69
|
-
return options.sortOptions.length > 0 ? options.sortOptions[0] || null : null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Check if query has limit
|
|
74
|
-
*/
|
|
75
|
-
export function hasLimit(options: QueryOptions): boolean {
|
|
76
|
-
return options.pagination !== null && options.pagination.limit !== undefined;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Get limit value
|
|
81
|
-
*/
|
|
82
|
-
export function getLimit(options: QueryOptions): number | null {
|
|
83
|
-
return options.pagination?.limit || null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Get cursor value
|
|
88
|
-
*/
|
|
89
|
-
export function getCursor(options: QueryOptions): number | null {
|
|
90
|
-
return options.pagination?.cursor || null;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Convert query options to summary object
|
|
95
|
-
*/
|
|
96
|
-
export function toSummary(options: QueryOptions): {
|
|
97
|
-
whereCount: number;
|
|
98
|
-
sortCount: number;
|
|
99
|
-
hasDateRange: boolean;
|
|
100
|
-
hasPagination: boolean;
|
|
101
|
-
limit: number | null;
|
|
102
|
-
} {
|
|
103
|
-
return {
|
|
104
|
-
whereCount: options.whereClauses.length,
|
|
105
|
-
sortCount: options.sortOptions.length,
|
|
106
|
-
hasDateRange: options.dateRange !== null,
|
|
107
|
-
hasPagination: options.pagination !== null,
|
|
108
|
-
limit: options.pagination?.limit || null,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Where Clause Value Object (Main)
|
|
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
|
-
import * as Validation from './WhereClauseValidation';
|
|
13
|
-
import * as Helpers from './WhereClauseHelpers';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Valid where operators for Firestore queries
|
|
17
|
-
*/
|
|
18
|
-
export type WhereOperator =
|
|
19
|
-
| '=='
|
|
20
|
-
| '!='
|
|
21
|
-
| '<'
|
|
22
|
-
| '<='
|
|
23
|
-
| '>'
|
|
24
|
-
| '>='
|
|
25
|
-
| 'array-contains'
|
|
26
|
-
| 'array-contains-any'
|
|
27
|
-
| 'in'
|
|
28
|
-
| 'not-in';
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Where clause value object
|
|
32
|
-
* Immutable representation of a single query condition
|
|
33
|
-
*/
|
|
34
|
-
export class WhereClause {
|
|
35
|
-
readonly field: string;
|
|
36
|
-
readonly operator: WhereFilterOp;
|
|
37
|
-
readonly value: unknown;
|
|
38
|
-
|
|
39
|
-
constructor(field: string, operator: WhereFilterOp, value: unknown) {
|
|
40
|
-
this.field = field;
|
|
41
|
-
this.operator = operator;
|
|
42
|
-
this.value = Object.freeze(value);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Instance methods using helpers
|
|
46
|
-
validate(): { valid: boolean; errors: string[] } {
|
|
47
|
-
return Validation.validateWhereClause(this);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
equals(other: WhereClause): boolean {
|
|
51
|
-
return Helpers.whereClausesEqual(this, other);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
isCompatibleWith(other: WhereClause): boolean {
|
|
55
|
-
return Helpers.areClausesCompatible(this, other);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
getFieldPath(): string[] {
|
|
59
|
-
return Helpers.getFieldPath(this);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
isNestedField(): boolean {
|
|
63
|
-
return Helpers.isNestedField(this);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
getTopLevelField(): string {
|
|
67
|
-
return Helpers.getTopLevelField(this);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
getDescription(): string {
|
|
71
|
-
return Helpers.getDescription(this);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
toObject(): { field: string; operator: WhereFilterOp; value: unknown } {
|
|
75
|
-
return Helpers.toObject(this);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
withValue(newValue: unknown): WhereClause {
|
|
79
|
-
return new WhereClause(this.field, this.operator, newValue);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
withField(newField: string): WhereClause {
|
|
83
|
-
return new WhereClause(newField, this.operator, this.value);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
withOperator(newOperator: WhereFilterOp): WhereClause {
|
|
87
|
-
return new WhereClause(this.field, newOperator, this.value);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
isEquality(): boolean {
|
|
91
|
-
return Helpers.isEqualityClause(this);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
isInequality(): boolean {
|
|
95
|
-
return Helpers.isInequalityClause(this);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
isComparison(): boolean {
|
|
99
|
-
return Helpers.isComparisonClause(this);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
isArrayOperator(): boolean {
|
|
103
|
-
return Helpers.isArrayClause(this);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
isMembership(): boolean {
|
|
107
|
-
return Helpers.isMembershipClause(this);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
requiresArrayValue(): boolean {
|
|
111
|
-
return Validation.requiresArrayValue(this.operator);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Where Clause Factory
|
|
3
|
-
* Single Responsibility: Create where clauses
|
|
4
|
-
*
|
|
5
|
-
* Max lines: 150 (enforced for maintainability)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { WhereFilterOp } from 'firebase/firestore';
|
|
9
|
-
import { WhereClause } from './WhereClause';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Create equals where clause
|
|
13
|
-
*/
|
|
14
|
-
export function equals(field: string, value: unknown): WhereClause {
|
|
15
|
-
return new WhereClause(field, '==', value);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Create not-equals where clause
|
|
20
|
-
*/
|
|
21
|
-
export function notEquals(field: string, value: unknown): WhereClause {
|
|
22
|
-
return new WhereClause(field, '!=', value);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Create less-than where clause
|
|
27
|
-
*/
|
|
28
|
-
export function lessThan(field: string, value: unknown): WhereClause {
|
|
29
|
-
return new WhereClause(field, '<', value);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Create less-than-or-equal where clause
|
|
34
|
-
*/
|
|
35
|
-
export function lessThanOrEqual(field: string, value: unknown): WhereClause {
|
|
36
|
-
return new WhereClause(field, '<=', value);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Create greater-than where clause
|
|
41
|
-
*/
|
|
42
|
-
export function greaterThan(field: string, value: unknown): WhereClause {
|
|
43
|
-
return new WhereClause(field, '>', value);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Create greater-than-or-equal where clause
|
|
48
|
-
*/
|
|
49
|
-
export function greaterThanOrEqual(field: string, value: unknown): WhereClause {
|
|
50
|
-
return new WhereClause(field, '>=', value);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Create array-contains where clause
|
|
55
|
-
*/
|
|
56
|
-
export function arrayContains(field: string, value: unknown): WhereClause {
|
|
57
|
-
return new WhereClause(field, 'array-contains', value);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Create in where clause
|
|
62
|
-
*/
|
|
63
|
-
export function inOp(field: string, values: unknown[]): WhereClause {
|
|
64
|
-
return new WhereClause(field, 'in', values);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Create not-in where clause
|
|
69
|
-
*/
|
|
70
|
-
export function notIn(field: string, values: unknown[]): WhereClause {
|
|
71
|
-
return new WhereClause(field, 'not-in', values);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Create array-contains-any where clause
|
|
76
|
-
*/
|
|
77
|
-
export function arrayContainsAny(field: string, values: unknown[]): WhereClause {
|
|
78
|
-
return new WhereClause(field, 'array-contains-any', values);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Create where clause with custom operator
|
|
83
|
-
*/
|
|
84
|
-
export function where(
|
|
85
|
-
field: string,
|
|
86
|
-
operator: WhereFilterOp,
|
|
87
|
-
value: unknown
|
|
88
|
-
): WhereClause {
|
|
89
|
-
return new WhereClause(field, operator, value);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Create where clause from object
|
|
94
|
-
*/
|
|
95
|
-
export function fromObject(obj: {
|
|
96
|
-
field: string;
|
|
97
|
-
operator: WhereFilterOp;
|
|
98
|
-
value: unknown;
|
|
99
|
-
}): WhereClause {
|
|
100
|
-
return new WhereClause(obj.field, obj.operator, obj.value);
|
|
101
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Where Clause Helper Utilities
|
|
3
|
-
* Single Responsibility: Provide helper functions for where clauses
|
|
4
|
-
*
|
|
5
|
-
* Max lines: 150 (enforced for maintainability)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { WhereFilterOp } from 'firebase/firestore';
|
|
9
|
-
import type { WhereClause } from './WhereClause';
|
|
10
|
-
import {
|
|
11
|
-
isEqualityOperator,
|
|
12
|
-
isInequalityOperator,
|
|
13
|
-
isComparisonOperator,
|
|
14
|
-
isArrayOperator,
|
|
15
|
-
isMembershipOperator,
|
|
16
|
-
} from './WhereClauseValidation';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Get field path as array
|
|
20
|
-
*/
|
|
21
|
-
export function getFieldPath(clause: WhereClause): string[] {
|
|
22
|
-
return clause.field.split('.');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Check if field is nested
|
|
27
|
-
*/
|
|
28
|
-
export function isNestedField(clause: WhereClause): boolean {
|
|
29
|
-
return clause.field.includes('.');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Get top-level field name
|
|
34
|
-
*/
|
|
35
|
-
export function getTopLevelField(clause: WhereClause): string {
|
|
36
|
-
const parts = clause.field.split('.');
|
|
37
|
-
return parts[0] || '';
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Get description of where clause
|
|
42
|
-
*/
|
|
43
|
-
export function getDescription(clause: WhereClause): string {
|
|
44
|
-
return `${clause.field} ${clause.operator} ${JSON.stringify(clause.value)}`;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Convert where clause to object
|
|
49
|
-
*/
|
|
50
|
-
export function toObject(clause: WhereClause): {
|
|
51
|
-
field: string;
|
|
52
|
-
operator: WhereFilterOp;
|
|
53
|
-
value: unknown;
|
|
54
|
-
} {
|
|
55
|
-
return {
|
|
56
|
-
field: clause.field,
|
|
57
|
-
operator: clause.operator,
|
|
58
|
-
value: clause.value,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Check if two where clauses are equal
|
|
64
|
-
*/
|
|
65
|
-
export function whereClausesEqual(a: WhereClause, b: WhereClause): boolean {
|
|
66
|
-
return (
|
|
67
|
-
a.field === b.field &&
|
|
68
|
-
a.operator === b.operator &&
|
|
69
|
-
JSON.stringify(a.value) === JSON.stringify(b.value)
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Check if where clauses are compatible (can be used together)
|
|
75
|
-
*/
|
|
76
|
-
export function areClausesCompatible(a: WhereClause, b: WhereClause): boolean {
|
|
77
|
-
// Same field with different operators is not allowed
|
|
78
|
-
if (a.field === b.field && a.operator !== b.operator) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Inequality operators cannot be combined with other inequality operators on same field
|
|
83
|
-
if (a.field === b.field && isInequalityOperator(a.operator) && isInequalityOperator(b.operator)) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Check if clause is equality type
|
|
92
|
-
*/
|
|
93
|
-
export function isEqualityClause(clause: WhereClause): boolean {
|
|
94
|
-
return isEqualityOperator(clause.operator);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Check if clause is inequality type
|
|
99
|
-
*/
|
|
100
|
-
export function isInequalityClause(clause: WhereClause): boolean {
|
|
101
|
-
return isInequalityOperator(clause.operator);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Check if clause is comparison type
|
|
106
|
-
*/
|
|
107
|
-
export function isComparisonClause(clause: WhereClause): boolean {
|
|
108
|
-
return isComparisonOperator(clause.operator);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Check if clause is array type
|
|
113
|
-
*/
|
|
114
|
-
export function isArrayClause(clause: WhereClause): boolean {
|
|
115
|
-
return isArrayOperator(clause.operator);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Check if clause is membership type
|
|
120
|
-
*/
|
|
121
|
-
export function isMembershipClause(clause: WhereClause): boolean {
|
|
122
|
-
return isMembershipOperator(clause.operator);
|
|
123
|
-
}
|