@umituz/react-native-firebase 2.6.0 → 2.6.2

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.
Files changed (102) hide show
  1. package/package.json +1 -1
  2. package/src/application/auth/index.ts +42 -0
  3. package/src/application/auth/ports/AuthPort.ts.bak +164 -0
  4. package/src/application/auth/ports/AuthPort_part_aa +150 -0
  5. package/src/application/auth/ports/AuthPort_part_ab +14 -0
  6. package/src/application/auth/use-cases/SignInUseCase.ts.bak +253 -0
  7. package/src/application/auth/use-cases/SignInUseCaseHelpers.ts +0 -0
  8. package/src/application/auth/use-cases/SignInUseCaseMain.ts +0 -0
  9. package/src/application/auth/use-cases/SignInUseCase_part_aa +150 -0
  10. package/src/application/auth/use-cases/SignInUseCase_part_ab +103 -0
  11. package/src/application/auth/use-cases/SignOutUseCase.ts.bak +288 -0
  12. package/src/application/auth/use-cases/SignOutUseCaseCleanup.ts +0 -0
  13. package/src/application/auth/use-cases/SignOutUseCaseMain.ts +0 -0
  14. package/src/application/auth/use-cases/SignOutUseCase_part_aa +150 -0
  15. package/src/application/auth/use-cases/SignOutUseCase_part_ab +138 -0
  16. package/src/application/auth/use-cases/index.ts +26 -0
  17. package/src/domains/account-deletion/domain/index.ts +15 -0
  18. package/src/domains/account-deletion/domain/services/UserValidationHelpers.ts.bak +181 -0
  19. package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_aa +150 -0
  20. package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_ab +31 -0
  21. package/src/domains/account-deletion/domain/services/UserValidationService.ts.bak +286 -0
  22. package/src/domains/account-deletion/domain/services/UserValidationService_part_aa +150 -0
  23. package/src/domains/account-deletion/domain/services/UserValidationService_part_ab +136 -0
  24. package/src/domains/account-deletion/index.ts +43 -6
  25. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts.bak +230 -0
  26. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_aa +150 -0
  27. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_ab +80 -0
  28. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler.ts.bak +174 -0
  29. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_aa +150 -0
  30. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_ab +24 -0
  31. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository.ts.bak +266 -0
  32. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_aa +150 -0
  33. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_ab +116 -0
  34. package/src/domains/account-deletion/infrastructure/services/AccountDeletionTypes.ts +33 -0
  35. package/src/domains/account-deletion/infrastructure/services/account-deletion.service.ts +39 -227
  36. package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_aa +150 -0
  37. package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_ab +10 -0
  38. package/src/domains/auth/domain.ts +16 -0
  39. package/src/domains/auth/index.ts +7 -148
  40. package/src/domains/auth/infrastructure.ts.bak +156 -0
  41. package/src/domains/auth/infrastructure_part_aa +150 -0
  42. package/src/domains/auth/infrastructure_part_ab +6 -0
  43. package/src/domains/auth/presentation/hooks/GoogleOAuthHelpers.ts +0 -0
  44. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService.ts.bak +247 -0
  45. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_aa +150 -0
  46. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_ab +97 -0
  47. package/src/domains/auth/presentation/hooks/GoogleOAuthService.ts +0 -0
  48. package/src/domains/auth/presentation/hooks/useGoogleOAuth.ts +49 -103
  49. package/src/domains/auth/presentation.ts +25 -0
  50. package/src/domains/firestore/domain/entities/Collection.ts +128 -0
  51. package/src/domains/firestore/domain/entities/Collection.ts.bak +288 -0
  52. package/src/domains/firestore/domain/entities/CollectionFactory.ts +55 -0
  53. package/src/domains/firestore/domain/entities/CollectionHelpers.ts +143 -0
  54. package/src/domains/firestore/domain/entities/CollectionUtils.ts +72 -0
  55. package/src/domains/firestore/domain/entities/CollectionValidation.ts +138 -0
  56. package/src/domains/firestore/domain/entities/Collection_part_aa +150 -0
  57. package/src/domains/firestore/domain/entities/Collection_part_ab +138 -0
  58. package/src/domains/firestore/domain/entities/Document.ts.bak +233 -0
  59. package/src/domains/firestore/domain/entities/DocumentHelpers.ts +0 -0
  60. package/src/domains/firestore/domain/entities/DocumentMain.ts +0 -0
  61. package/src/domains/firestore/domain/entities/Document_part_aa +150 -0
  62. package/src/domains/firestore/domain/entities/Document_part_ab +83 -0
  63. package/src/domains/firestore/domain/index.ts +65 -0
  64. package/src/domains/firestore/domain/services/QueryService.ts.bak +182 -0
  65. package/src/domains/firestore/domain/services/QueryServiceAnalysis.ts.bak +169 -0
  66. package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_aa +150 -0
  67. package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_ab +19 -0
  68. package/src/domains/firestore/domain/services/QueryServiceHelpers.ts.bak +151 -0
  69. package/src/domains/firestore/domain/services/QueryServiceHelpers_part_aa +150 -0
  70. package/src/domains/firestore/domain/services/QueryServiceHelpers_part_ab +1 -0
  71. package/src/domains/firestore/domain/services/QueryService_part_aa +150 -0
  72. package/src/domains/firestore/domain/services/QueryService_part_ab +32 -0
  73. package/src/domains/firestore/domain/value-objects/QueryOptions.ts.bak +191 -0
  74. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization.ts.bak +207 -0
  75. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_aa +150 -0
  76. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_ab +57 -0
  77. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation.ts.bak +182 -0
  78. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_aa +150 -0
  79. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_ab +32 -0
  80. package/src/domains/firestore/domain/value-objects/QueryOptions_part_aa +150 -0
  81. package/src/domains/firestore/domain/value-objects/QueryOptions_part_ab +41 -0
  82. package/src/domains/firestore/domain/value-objects/WhereClause.ts.bak +299 -0
  83. package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts.bak +207 -0
  84. package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_aa +150 -0
  85. package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_ab +57 -0
  86. package/src/domains/firestore/domain/value-objects/WhereClause_part_aa +150 -0
  87. package/src/domains/firestore/domain/value-objects/WhereClause_part_ab +149 -0
  88. package/src/domains/firestore/index.ts +9 -6
  89. package/src/index.ts +25 -0
  90. package/src/shared/domain/utils/error-handlers/error-messages.ts +11 -0
  91. package/src/shared/infrastructure/base/ErrorHandler.ts.bak +189 -0
  92. package/src/shared/infrastructure/base/ErrorHandler_part_aa +150 -0
  93. package/src/shared/infrastructure/base/ErrorHandler_part_ab +39 -0
  94. package/src/shared/infrastructure/base/ServiceBase.ts.bak +220 -0
  95. package/src/shared/infrastructure/base/ServiceBase_part_aa +150 -0
  96. package/src/shared/infrastructure/base/ServiceBase_part_ab +70 -0
  97. package/src/shared/infrastructure/base/TypedGuard.ts +131 -0
  98. package/src/shared/infrastructure/base/index.ts +34 -0
  99. package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_aa +150 -0
  100. package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_ab +5 -0
  101. /package/src/domains/account-deletion/infrastructure/services/{reauthentication.service.ts → reauthentication.service.ts.bak} +0 -0
  102. /package/src/shared/infrastructure/config/base/{ServiceClientSingleton.ts → ServiceClientSingleton.ts.bak} +0 -0
@@ -0,0 +1,97 @@
1
+ if (!this.isAvailable()) {
2
+ return {
3
+ valid: false,
4
+ error: 'expo-auth-session is not available. Please install expo-auth-session and expo-web-browser.',
5
+ };
6
+ }
7
+
8
+ if (!this.isConfigured()) {
9
+ return {
10
+ valid: false,
11
+ error: 'Google Sign-In is not configured. Please provide valid client IDs.',
12
+ };
13
+ }
14
+
15
+ return { valid: true };
16
+ }
17
+
18
+ /**
19
+ * Get error message from error
20
+ */
21
+ getErrorMessage(error: unknown): string {
22
+ if (error instanceof Error) {
23
+ return error.message;
24
+ }
25
+ return 'Google sign-in failed';
26
+ }
27
+
28
+ /**
29
+ * Check if response is successful
30
+ */
31
+ isSuccessfulResponse(response: AuthSessionResponse | null): boolean {
32
+ return response?.type === 'success' && !!response.authentication?.idToken;
33
+ }
34
+
35
+ /**
36
+ * Check if response is error
37
+ */
38
+ isErrorResponse(response: AuthSessionResponse | null): boolean {
39
+ return response?.type === 'error';
40
+ }
41
+
42
+ /**
43
+ * Extract ID token from response
44
+ */
45
+ extractIdToken(response: AuthSessionResponse | null): string | null {
46
+ return response?.authentication?.idToken || null;
47
+ }
48
+
49
+ /**
50
+ * Create error result
51
+ */
52
+ createErrorResult(error: string): { success: false; error: string } {
53
+ return { success: false, error };
54
+ }
55
+
56
+ /**
57
+ * Check if auth request is ready
58
+ */
59
+ isReady(): boolean {
60
+ const [request, , promptAsync] = this.authRequest;
61
+ return request !== null && promptAsync !== null;
62
+ }
63
+
64
+ /**
65
+ * Get configuration
66
+ */
67
+ getConfig(): GoogleOAuthConfig | undefined {
68
+ return this.config;
69
+ }
70
+
71
+ /**
72
+ * Reset service state
73
+ */
74
+ reset(): void {
75
+ this.config = undefined;
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Factory function to create Google OAuth hook service
81
+ */
82
+ export function createGoogleOAuthHookService(config?: GoogleOAuthConfig): GoogleOAuthHookService {
83
+ return new GoogleOAuthHookService(config);
84
+ }
85
+
86
+ /**
87
+ * Check if expo-auth-session is available
88
+ * Useful for conditional rendering
89
+ */
90
+ export function isExpoAuthSessionAvailable(): boolean {
91
+ return isExpoAuthAvailable;
92
+ }
93
+
94
+ /**
95
+ * Re-export types for convenience
96
+ */
97
+ export type { AuthSessionResponse, ExpoAuthSessionModule };
@@ -1,37 +1,21 @@
1
1
  /**
2
2
  * useGoogleOAuth Hook
3
3
  * Handles Google OAuth flow using expo-auth-session and Firebase auth
4
- * This hook is optional and requires expo-auth-session to be installed
4
+ *
5
+ * This hook delegates business logic to GoogleOAuthHookService.
6
+ * Focuses only on React state management and side effects.
7
+ *
8
+ * Max lines: 150 (enforced for maintainability)
5
9
  */
6
10
 
7
- import { useState, useCallback, useEffect, useRef, useMemo } from "react";
8
- import { googleOAuthService } from "../../infrastructure/services/google-oauth.service";
9
- import { getFirebaseAuth } from "../../infrastructure/config/FirebaseAuthClient";
10
- import type { GoogleOAuthConfig } from "../../infrastructure/services/google-oauth.service";
11
- // Conditional import for expo-auth-session
12
- interface AuthSessionResponse {
13
- type: string;
14
- authentication?: { idToken?: string } | null;
15
- }
16
-
17
- interface ExpoAuthSessionModule {
18
- useAuthRequest: (config: {
19
- iosClientId: string;
20
- webClientId: string;
21
- androidClientId: string;
22
- }) => [unknown, AuthSessionResponse | null, (() => Promise<AuthSessionResponse>) | null];
23
- }
24
-
25
- let ExpoAuthSession: ExpoAuthSessionModule | null = null;
26
- let isExpoAuthAvailable = false;
27
-
28
- try {
29
- // eslint-disable-next-line @typescript-eslint/no-require-imports
30
- ExpoAuthSession = require("expo-auth-session/providers/google") as ExpoAuthSessionModule;
31
- isExpoAuthAvailable = true;
32
- } catch {
33
- // expo-auth-session not available - hook will return unavailable state
34
- }
11
+ import { useState, useCallback, useEffect, useMemo } from 'react';
12
+ import { getFirebaseAuth } from '../../infrastructure/config/FirebaseAuthClient';
13
+ import type { GoogleOAuthConfig } from '../../infrastructure/services/google-oauth.service';
14
+ import {
15
+ GoogleOAuthHookService,
16
+ createGoogleOAuthHookService,
17
+ isExpoAuthSessionAvailable,
18
+ } from './GoogleOAuthHookService';
35
19
 
36
20
  export interface UseGoogleOAuthResult {
37
21
  signInWithGoogle: () => Promise<SocialAuthResult>;
@@ -55,107 +39,62 @@ export function useGoogleOAuth(config?: GoogleOAuthConfig): UseGoogleOAuthResult
55
39
  const [isLoading, setIsLoading] = useState(false);
56
40
  const [googleError, setGoogleError] = useState<string | null>(null);
57
41
 
58
- // Memoize service checks to avoid repeated calls on every render
59
- const googleAvailable = useMemo(() => googleOAuthService.isAvailable(), []);
60
- const googleConfigured = useMemo(() => googleOAuthService.isConfigured(config), [config]);
61
-
62
- // Keep config in a ref so the response useEffect doesn't re-run when config object reference changes
63
- const configRef = useRef(config);
64
- configRef.current = config;
65
-
66
- // Call the Hook directly (only valid in React component)
67
- // If expo-auth-session is not available, these will be null
68
- // Empty strings are passed when config is missing to preserve hook call order (Rules of Hooks)
69
- const [request, response, promptAsync] = isExpoAuthAvailable && ExpoAuthSession
70
- ? ExpoAuthSession.useAuthRequest({
71
- iosClientId: config?.iosClientId ?? "",
72
- webClientId: config?.webClientId ?? "",
73
- androidClientId: config?.androidClientId ?? "",
74
- })
75
- : [null, null, null];
42
+ // Initialize service with config
43
+ const service = useMemo(() => createGoogleOAuthHookService(config), [config]);
44
+
45
+ // Update service when config changes
46
+ useEffect(() => {
47
+ service.updateConfig(config);
48
+ }, [service, config]);
49
+
50
+ // Memoize service checks
51
+ const googleAvailable = useMemo(() => service.isAvailable(), [service]);
52
+ const googleConfigured = useMemo(() => service.isConfigured(), [service]);
53
+
54
+ // Get auth request tuple from service
55
+ const [, response] = service.getAuthRequest();
76
56
 
77
57
  // Handle OAuth response
78
58
  useEffect(() => {
79
59
  if (!googleAvailable || !response) return;
80
60
 
81
61
  const handleResponse = async () => {
82
- if (response.type === "success" && response.authentication?.idToken) {
83
- setIsLoading(true);
84
- setGoogleError(null);
85
-
86
- try {
87
- const auth = getFirebaseAuth();
88
- if (!auth) {
89
- setGoogleError("Firebase Auth not initialized");
90
- setIsLoading(false);
91
- return;
92
- }
93
-
94
- await googleOAuthService.signInWithOAuth(
95
- auth,
96
- configRef.current,
97
- async () => response
98
- );
99
- } catch (error) {
100
- setGoogleError(
101
- error instanceof Error ? error.message : "Firebase sign-in failed"
102
- );
103
- } finally {
104
- setIsLoading(false);
105
- }
106
- } else if (response.type === "error") {
107
- setGoogleError("Google authentication failed");
62
+ setIsLoading(true);
63
+ setGoogleError(null);
64
+
65
+ try {
66
+ const auth = getFirebaseAuth();
67
+ await service.handleResponse(response, auth);
68
+ } catch (error) {
69
+ setGoogleError(service.getErrorMessage(error));
70
+ } finally {
71
+ setIsLoading(false);
108
72
  }
109
73
  };
110
74
 
111
- // Call async function and catch errors separately
112
75
  handleResponse().catch((err) => {
113
- // Errors are already handled in handleResponse
114
76
  if (__DEV__) {
115
77
  console.error('[useGoogleOAuth] Unexpected error in handleResponse:', err);
116
78
  }
117
79
  });
118
- }, [response, googleAvailable]); // config read via ref to prevent re-running on reference changes
80
+ }, [response, googleAvailable, service]);
119
81
 
82
+ // Sign in with Google
120
83
  const signInWithGoogle = useCallback(async (): Promise<SocialAuthResult> => {
121
- if (!googleAvailable) {
122
- const error = "expo-auth-session is not available. Please install expo-auth-session and expo-web-browser.";
123
- setGoogleError(error);
124
- return { success: false, error };
125
- }
126
-
127
- if (!googleConfigured) {
128
- const error = "Google Sign-In is not configured. Please provide valid client IDs.";
129
- setGoogleError(error);
130
- return { success: false, error };
131
- }
132
-
133
- if (!request || !promptAsync) {
134
- const error = "Google Sign-In not ready";
135
- setGoogleError(error);
136
- return { success: false, error };
137
- }
138
-
139
84
  setIsLoading(true);
140
85
  setGoogleError(null);
141
86
 
142
87
  try {
143
88
  const auth = getFirebaseAuth();
144
- if (!auth) {
145
- const error = "Firebase Auth not initialized";
146
- setGoogleError(error);
147
- return { success: false, error };
148
- }
149
-
150
- return await googleOAuthService.signInWithOAuth(auth, config, promptAsync);
89
+ return await service.signIn(auth);
151
90
  } catch (error) {
152
- const errorMessage = error instanceof Error ? error.message : "Google sign-in failed";
91
+ const errorMessage = service.getErrorMessage(error);
153
92
  setGoogleError(errorMessage);
154
93
  return { success: false, error: errorMessage };
155
94
  } finally {
156
95
  setIsLoading(false);
157
96
  }
158
- }, [googleAvailable, googleConfigured, request, promptAsync]); // config read via ref to prevent re-creation on reference changes
97
+ }, [service]);
159
98
 
160
99
  return {
161
100
  signInWithGoogle,
@@ -165,3 +104,10 @@ export function useGoogleOAuth(config?: GoogleOAuthConfig): UseGoogleOAuthResult
165
104
  googleError,
166
105
  };
167
106
  }
107
+
108
+ /**
109
+ * Check if expo-auth-session is available
110
+ * Useful for conditional rendering
111
+ */
112
+ export { isExpoAuthSessionAvailable };
113
+
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Firebase Auth Presentation Layer
3
+ * Domain-Driven Design (DDD) - Presentation Exports
4
+ *
5
+ * React hooks for Firebase authentication.
6
+ * Provides clean interface for UI components.
7
+ */
8
+
9
+ export { useFirebaseAuth } from './presentation/hooks/useFirebaseAuth';
10
+ export type { UseFirebaseAuthResult } from './presentation/hooks/useFirebaseAuth';
11
+
12
+ export { useAnonymousAuth } from './presentation/hooks/useAnonymousAuth';
13
+ export type { UseAnonymousAuthResult } from './presentation/hooks/useAnonymousAuth';
14
+
15
+ export { useSocialAuth } from './presentation/hooks/useSocialAuth';
16
+ export type {
17
+ SocialAuthConfig,
18
+ SocialAuthResult,
19
+ UseSocialAuthResult,
20
+ } from './presentation/hooks/useSocialAuth';
21
+
22
+ export { useGoogleOAuth } from './presentation/hooks/useGoogleOAuth';
23
+ export type {
24
+ UseGoogleOAuthResult,
25
+ } from './presentation/hooks/useGoogleOAuth';
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Collection Entity (Main)
3
+ * Single Responsibility: Represent a Firestore collection with metadata
4
+ *
5
+ * Domain entity that encapsulates collection information and metadata.
6
+ * Provides business logic for collection operations.
7
+ *
8
+ * Max lines: 150 (enforced for maintainability)
9
+ */
10
+
11
+ import type { CollectionReference, Query } from 'firebase/firestore';
12
+ import {
13
+ isValidCollectionName,
14
+ isValidCollectionPath,
15
+ extractCollectionNameFromPath,
16
+ extractParentCollectionPath,
17
+ isUserCollectionPath,
18
+ extractUserIdFromPath,
19
+ createSubCollectionPath as createSubCollectionPathUtil,
20
+ } from './CollectionValidation';
21
+ import {
22
+ getCollectionDepth,
23
+ collectionToObject,
24
+ isQueryReference,
25
+ isCollectionReference as isCollectionReferenceUtil,
26
+ } from './CollectionUtils';
27
+ import { fromReference, fromQuery } from './CollectionFactory';
28
+
29
+ /**
30
+ * Collection metadata
31
+ */
32
+ export interface CollectionMetadata {
33
+ readonly name: string;
34
+ readonly path: string;
35
+ readonly parentPath?: string;
36
+ }
37
+
38
+ /**
39
+ * Collection entity
40
+ * Represents a Firestore collection with metadata
41
+ */
42
+ export class Collection<TDocument = unknown> {
43
+ readonly name: string;
44
+ readonly path: string;
45
+ readonly parentPath: string | undefined;
46
+ private readonly reference: CollectionReference<TDocument> | Query<TDocument>;
47
+
48
+ constructor(
49
+ reference: CollectionReference<TDocument> | Query<TDocument>,
50
+ metadata: CollectionMetadata
51
+ ) {
52
+ this.reference = reference;
53
+ this.name = metadata.name;
54
+ this.path = metadata.path;
55
+ this.parentPath = metadata.parentPath || undefined;
56
+ }
57
+
58
+ /**
59
+ * Create collection from collection reference
60
+ */
61
+ static fromReference<TDocument = unknown>(
62
+ reference: CollectionReference<TDocument>
63
+ ): Collection<TDocument> {
64
+ return fromReference(reference);
65
+ }
66
+
67
+ /**
68
+ * Create collection from query
69
+ */
70
+ static fromQuery<TDocument = unknown>(query: Query<TDocument>, name: string, path: string): Collection<TDocument> {
71
+ return fromQuery(query, name, path);
72
+ }
73
+
74
+ getName(): string {
75
+ return this.name;
76
+ }
77
+
78
+ getPath(): string {
79
+ return this.path;
80
+ }
81
+
82
+ getParentPath(): string | undefined {
83
+ return this.parentPath;
84
+ }
85
+
86
+ isNested(): boolean {
87
+ return this.parentPath !== undefined;
88
+ }
89
+
90
+ isRootLevel(): boolean {
91
+ return this.parentPath === undefined;
92
+ }
93
+
94
+ getDepth(): number {
95
+ return getCollectionDepth(this);
96
+ }
97
+
98
+ getReference(): CollectionReference<TDocument> | Query<TDocument> {
99
+ return this.reference;
100
+ }
101
+
102
+ isQuery(): boolean {
103
+ return isQueryReference(this.reference);
104
+ }
105
+
106
+ isCollectionReference(): boolean {
107
+ return isCollectionReferenceUtil(this.reference);
108
+ }
109
+
110
+ toObject(): CollectionMetadata {
111
+ return collectionToObject(this);
112
+ }
113
+
114
+ createSubCollectionPath(subCollectionName: string): string | null {
115
+ return createSubCollectionPathUtil(this.path, subCollectionName);
116
+ }
117
+
118
+ isUserCollection(): boolean {
119
+ return isUserCollectionPath(this.path);
120
+ }
121
+
122
+ extractUserId(): string | null {
123
+ return extractUserIdFromPath(this.path);
124
+ }
125
+ }
126
+
127
+ // Re-export factory function for backward compatibility
128
+ export { createCollection, fromReference, fromQuery } from './CollectionFactory';