@blackcode_sa/metaestetics-api 1.13.5 → 1.13.8
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/dist/admin/index.d.mts +20 -1
- package/dist/admin/index.d.ts +20 -1
- package/dist/admin/index.js +217 -1
- package/dist/admin/index.mjs +217 -1
- package/dist/index.d.mts +26 -3
- package/dist/index.d.ts +26 -3
- package/dist/index.js +168 -6
- package/dist/index.mjs +168 -6
- package/package.json +121 -121
- package/src/__mocks__/firstore.ts +10 -10
- package/src/admin/aggregation/README.md +79 -79
- package/src/admin/aggregation/appointment/README.md +128 -128
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +1984 -1984
- package/src/admin/aggregation/appointment/index.ts +1 -1
- package/src/admin/aggregation/clinic/README.md +52 -52
- package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +966 -703
- package/src/admin/aggregation/clinic/index.ts +1 -1
- package/src/admin/aggregation/forms/README.md +13 -13
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +322 -322
- package/src/admin/aggregation/forms/index.ts +1 -1
- package/src/admin/aggregation/index.ts +8 -8
- package/src/admin/aggregation/patient/README.md +27 -27
- package/src/admin/aggregation/patient/index.ts +1 -1
- package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -141
- package/src/admin/aggregation/practitioner/README.md +42 -42
- package/src/admin/aggregation/practitioner/index.ts +1 -1
- package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -433
- package/src/admin/aggregation/practitioner-invite/index.ts +1 -1
- package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +961 -961
- package/src/admin/aggregation/procedure/README.md +43 -43
- package/src/admin/aggregation/procedure/index.ts +1 -1
- package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +702 -702
- package/src/admin/aggregation/reviews/index.ts +1 -1
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +689 -689
- package/src/admin/analytics/analytics.admin.service.ts +278 -278
- package/src/admin/analytics/index.ts +2 -2
- package/src/admin/booking/README.md +125 -125
- package/src/admin/booking/booking.admin.ts +1037 -1037
- package/src/admin/booking/booking.calculator.ts +712 -712
- package/src/admin/booking/booking.types.ts +59 -59
- package/src/admin/booking/index.ts +3 -3
- package/src/admin/booking/timezones-problem.md +185 -185
- package/src/admin/calendar/README.md +7 -7
- package/src/admin/calendar/calendar.admin.service.ts +345 -345
- package/src/admin/calendar/index.ts +1 -1
- package/src/admin/documentation-templates/document-manager.admin.ts +260 -260
- package/src/admin/documentation-templates/index.ts +1 -1
- package/src/admin/free-consultation/free-consultation-utils.admin.ts +148 -148
- package/src/admin/free-consultation/index.ts +1 -1
- package/src/admin/index.ts +81 -81
- package/src/admin/logger/index.ts +78 -78
- package/src/admin/mailing/README.md +95 -95
- package/src/admin/mailing/appointment/appointment.mailing.service.ts +732 -732
- package/src/admin/mailing/appointment/index.ts +1 -1
- package/src/admin/mailing/appointment/templates/patient/appointment-confirmed.html +40 -40
- package/src/admin/mailing/base.mailing.service.ts +208 -208
- package/src/admin/mailing/index.ts +3 -3
- package/src/admin/mailing/practitionerInvite/existing-practitioner-invite.mailing.ts +611 -611
- package/src/admin/mailing/practitionerInvite/index.ts +2 -2
- package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +395 -395
- package/src/admin/mailing/practitionerInvite/templates/existing-practitioner-invitation.template.ts +155 -155
- package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -101
- package/src/admin/mailing/practitionerInvite/templates/invite-accepted-notification.template.ts +228 -228
- package/src/admin/mailing/practitionerInvite/templates/invite-rejected-notification.template.ts +242 -242
- package/src/admin/notifications/index.ts +1 -1
- package/src/admin/notifications/notifications.admin.ts +710 -710
- package/src/admin/requirements/README.md +128 -128
- package/src/admin/requirements/index.ts +1 -1
- package/src/admin/requirements/patient-requirements.admin.service.ts +475 -475
- package/src/admin/users/index.ts +1 -1
- package/src/admin/users/user-profile.admin.ts +405 -405
- package/src/backoffice/constants/certification.constants.ts +13 -13
- package/src/backoffice/constants/index.ts +1 -1
- package/src/backoffice/errors/backoffice.errors.ts +181 -181
- package/src/backoffice/errors/index.ts +1 -1
- package/src/backoffice/expo-safe/README.md +26 -26
- package/src/backoffice/expo-safe/index.ts +41 -41
- package/src/backoffice/index.ts +5 -5
- package/src/backoffice/services/FIXES_README.md +102 -102
- package/src/backoffice/services/README.md +57 -57
- package/src/backoffice/services/analytics.service.proposal.md +863 -863
- package/src/backoffice/services/analytics.service.summary.md +143 -143
- package/src/backoffice/services/brand.service.ts +256 -256
- package/src/backoffice/services/category.service.ts +384 -384
- package/src/backoffice/services/constants.service.ts +385 -385
- package/src/backoffice/services/documentation-template.service.ts +202 -202
- package/src/backoffice/services/index.ts +10 -10
- package/src/backoffice/services/migrate-products.ts +116 -116
- package/src/backoffice/services/product.service.ts +553 -553
- package/src/backoffice/services/requirement.service.ts +235 -235
- package/src/backoffice/services/subcategory.service.ts +461 -461
- package/src/backoffice/services/technology.service.ts +1151 -1151
- package/src/backoffice/types/README.md +12 -12
- package/src/backoffice/types/admin-constants.types.ts +69 -69
- package/src/backoffice/types/brand.types.ts +29 -29
- package/src/backoffice/types/category.types.ts +67 -67
- package/src/backoffice/types/documentation-templates.types.ts +28 -28
- package/src/backoffice/types/index.ts +10 -10
- package/src/backoffice/types/procedure-product.types.ts +38 -38
- package/src/backoffice/types/product.types.ts +240 -240
- package/src/backoffice/types/requirement.types.ts +63 -63
- package/src/backoffice/types/static/README.md +18 -18
- package/src/backoffice/types/static/blocking-condition.types.ts +21 -21
- package/src/backoffice/types/static/certification.types.ts +37 -37
- package/src/backoffice/types/static/contraindication.types.ts +19 -19
- package/src/backoffice/types/static/index.ts +6 -6
- package/src/backoffice/types/static/pricing.types.ts +16 -16
- package/src/backoffice/types/static/procedure-family.types.ts +14 -14
- package/src/backoffice/types/static/treatment-benefit.types.ts +22 -22
- package/src/backoffice/types/subcategory.types.ts +34 -34
- package/src/backoffice/types/technology.types.ts +168 -168
- package/src/backoffice/validations/index.ts +1 -1
- package/src/backoffice/validations/schemas.ts +164 -164
- package/src/config/__mocks__/firebase.ts +99 -99
- package/src/config/firebase.ts +78 -78
- package/src/config/index.ts +9 -9
- package/src/errors/auth.error.ts +6 -6
- package/src/errors/auth.errors.ts +211 -200
- package/src/errors/clinic.errors.ts +32 -32
- package/src/errors/firebase.errors.ts +47 -47
- package/src/errors/user.errors.ts +99 -99
- package/src/index.backup.ts +407 -407
- package/src/index.ts +6 -6
- package/src/locales/en.ts +31 -31
- package/src/recommender/admin/index.ts +1 -1
- package/src/recommender/admin/services/recommender.service.admin.ts +5 -5
- package/src/recommender/front/index.ts +1 -1
- package/src/recommender/front/services/onboarding.service.ts +5 -5
- package/src/recommender/front/services/recommender.service.ts +3 -3
- package/src/recommender/index.ts +1 -1
- package/src/services/PATIENTAUTH.MD +197 -197
- package/src/services/README.md +106 -106
- package/src/services/__tests__/auth/auth.mock.test.ts +17 -17
- package/src/services/__tests__/auth/auth.setup.ts +293 -293
- package/src/services/__tests__/auth.service.test.ts +346 -346
- package/src/services/__tests__/base.service.test.ts +77 -77
- package/src/services/__tests__/user.service.test.ts +528 -528
- package/src/services/analytics/ARCHITECTURE.md +199 -199
- package/src/services/analytics/CLOUD_FUNCTIONS.md +225 -225
- package/src/services/analytics/GROUPED_ANALYTICS.md +501 -501
- package/src/services/analytics/QUICK_START.md +393 -393
- package/src/services/analytics/README.md +304 -304
- package/src/services/analytics/SUMMARY.md +141 -141
- package/src/services/analytics/TRENDS.md +380 -380
- package/src/services/analytics/USAGE_GUIDE.md +518 -518
- package/src/services/analytics/analytics-cloud.service.ts +222 -222
- package/src/services/analytics/analytics.service.ts +2142 -2142
- package/src/services/analytics/index.ts +4 -4
- package/src/services/analytics/review-analytics.service.ts +941 -941
- package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -138
- package/src/services/analytics/utils/cost-calculation.utils.ts +182 -182
- package/src/services/analytics/utils/grouping.utils.ts +434 -434
- package/src/services/analytics/utils/stored-analytics.utils.ts +347 -347
- package/src/services/analytics/utils/time-calculation.utils.ts +186 -186
- package/src/services/analytics/utils/trend-calculation.utils.ts +200 -200
- package/src/services/appointment/README.md +17 -17
- package/src/services/appointment/appointment.service.ts +2558 -2558
- package/src/services/appointment/index.ts +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +552 -552
- package/src/services/appointment/utils/extended-procedure.utils.ts +314 -314
- package/src/services/appointment/utils/form-initialization.utils.ts +225 -225
- package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
- package/src/services/appointment/utils/zone-management.utils.ts +353 -353
- package/src/services/appointment/utils/zone-photo.utils.ts +152 -152
- package/src/services/auth/auth.service.ts +1043 -989
- package/src/services/auth/auth.v2.service.ts +961 -961
- package/src/services/auth/index.ts +7 -7
- package/src/services/auth/utils/error.utils.ts +90 -90
- package/src/services/auth/utils/firebase.utils.ts +49 -49
- package/src/services/auth/utils/index.ts +21 -21
- package/src/services/auth/utils/practitioner.utils.ts +125 -125
- package/src/services/base.service.ts +41 -41
- package/src/services/calendar/calendar.service.ts +1077 -1077
- package/src/services/calendar/calendar.v2.service.ts +1683 -1683
- package/src/services/calendar/calendar.v3.service.ts +313 -313
- package/src/services/calendar/externalCalendar.service.ts +178 -178
- package/src/services/calendar/index.ts +5 -5
- package/src/services/calendar/synced-calendars.service.ts +743 -743
- package/src/services/calendar/utils/appointment.utils.ts +265 -265
- package/src/services/calendar/utils/calendar-event.utils.ts +646 -646
- package/src/services/calendar/utils/clinic.utils.ts +237 -237
- package/src/services/calendar/utils/docs.utils.ts +157 -157
- package/src/services/calendar/utils/google-calendar.utils.ts +697 -697
- package/src/services/calendar/utils/index.ts +8 -8
- package/src/services/calendar/utils/patient.utils.ts +198 -198
- package/src/services/calendar/utils/practitioner.utils.ts +221 -221
- package/src/services/calendar/utils/synced-calendar.utils.ts +472 -472
- package/src/services/clinic/README.md +204 -204
- package/src/services/clinic/__tests__/clinic-admin.service.test.ts +287 -287
- package/src/services/clinic/__tests__/clinic-group.service.test.ts +352 -352
- package/src/services/clinic/__tests__/clinic.service.test.ts +354 -354
- package/src/services/clinic/billing-transactions.service.ts +217 -217
- package/src/services/clinic/clinic-admin.service.ts +202 -202
- package/src/services/clinic/clinic-group.service.ts +310 -310
- package/src/services/clinic/clinic.service.ts +708 -708
- package/src/services/clinic/index.ts +5 -5
- package/src/services/clinic/practitioner-invite.service.ts +519 -519
- package/src/services/clinic/utils/admin.utils.ts +551 -551
- package/src/services/clinic/utils/clinic-group.utils.ts +646 -646
- package/src/services/clinic/utils/clinic.utils.ts +949 -949
- package/src/services/clinic/utils/filter.utils.d.ts +23 -23
- package/src/services/clinic/utils/filter.utils.ts +446 -446
- package/src/services/clinic/utils/index.ts +11 -11
- package/src/services/clinic/utils/photos.utils.ts +188 -188
- package/src/services/clinic/utils/search.utils.ts +84 -84
- package/src/services/clinic/utils/tag.utils.ts +124 -124
- package/src/services/documentation-templates/documentation-template.service.ts +537 -537
- package/src/services/documentation-templates/filled-document.service.ts +587 -587
- package/src/services/documentation-templates/index.ts +2 -2
- package/src/services/index.ts +14 -14
- package/src/services/media/index.ts +1 -1
- package/src/services/media/media.service.ts +418 -418
- package/src/services/notifications/__tests__/notification.service.test.ts +242 -242
- package/src/services/notifications/index.ts +1 -1
- package/src/services/notifications/notification.service.ts +215 -215
- package/src/services/patient/README.md +48 -48
- package/src/services/patient/To-Do.md +43 -43
- package/src/services/patient/__tests__/patient.service.test.ts +294 -294
- package/src/services/patient/index.ts +2 -2
- package/src/services/patient/patient.service.ts +883 -883
- package/src/services/patient/patientRequirements.service.ts +285 -285
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
- package/src/services/patient/utils/clinic.utils.ts +80 -80
- package/src/services/patient/utils/docs.utils.ts +142 -142
- package/src/services/patient/utils/index.ts +9 -9
- package/src/services/patient/utils/location.utils.ts +126 -126
- package/src/services/patient/utils/medical-stuff.utils.ts +143 -143
- package/src/services/patient/utils/medical.utils.ts +458 -458
- package/src/services/patient/utils/practitioner.utils.ts +260 -260
- package/src/services/patient/utils/profile.utils.ts +510 -510
- package/src/services/patient/utils/sensitive.utils.ts +260 -260
- package/src/services/patient/utils/token.utils.ts +211 -211
- package/src/services/practitioner/README.md +145 -145
- package/src/services/practitioner/index.ts +1 -1
- package/src/services/practitioner/practitioner.service.ts +1799 -1742
- package/src/services/procedure/README.md +163 -163
- package/src/services/procedure/index.ts +1 -1
- package/src/services/procedure/procedure.service.ts +2307 -2200
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +734 -734
- package/src/services/user/index.ts +1 -1
- package/src/services/user/user.service.ts +489 -489
- package/src/services/user/user.v2.service.ts +466 -466
- package/src/types/analytics/analytics.types.ts +597 -597
- package/src/types/analytics/grouped-analytics.types.ts +173 -173
- package/src/types/analytics/index.ts +4 -4
- package/src/types/analytics/stored-analytics.types.ts +137 -137
- package/src/types/appointment/index.ts +480 -480
- package/src/types/calendar/index.ts +258 -258
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +498 -498
- package/src/types/clinic/practitioner-invite.types.ts +91 -91
- package/src/types/clinic/preferences.types.ts +159 -159
- package/src/types/clinic/to-do +3 -3
- package/src/types/documentation-templates/index.ts +308 -308
- package/src/types/index.ts +47 -47
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +286 -286
- package/src/types/patient/aesthetic-analysis.types.ts +66 -66
- package/src/types/patient/allergies.ts +58 -58
- package/src/types/patient/index.ts +275 -275
- package/src/types/patient/medical-info.types.ts +152 -152
- package/src/types/patient/patient-requirements.ts +92 -92
- package/src/types/patient/token.types.ts +61 -61
- package/src/types/practitioner/index.ts +206 -206
- package/src/types/procedure/index.ts +181 -181
- package/src/types/profile/index.ts +39 -39
- package/src/types/reviews/index.ts +132 -132
- package/src/types/tz-lookup.d.ts +4 -4
- package/src/types/user/index.ts +38 -38
- package/src/utils/TIMESTAMPS.md +176 -176
- package/src/utils/TimestampUtils.ts +241 -241
- package/src/utils/index.ts +1 -1
- package/src/validations/appointment.schema.ts +574 -574
- package/src/validations/calendar.schema.ts +225 -225
- package/src/validations/clinic.schema.ts +494 -494
- package/src/validations/common.schema.ts +25 -25
- package/src/validations/documentation-templates/index.ts +1 -1
- package/src/validations/documentation-templates/template.schema.ts +220 -220
- package/src/validations/documentation-templates.schema.ts +10 -10
- package/src/validations/index.ts +20 -20
- package/src/validations/media.schema.ts +10 -10
- package/src/validations/notification.schema.ts +90 -90
- package/src/validations/patient/aesthetic-analysis.schema.ts +55 -55
- package/src/validations/patient/medical-info.schema.ts +125 -125
- package/src/validations/patient/patient-requirements.schema.ts +84 -84
- package/src/validations/patient/token.schema.ts +29 -29
- package/src/validations/patient.schema.ts +217 -217
- package/src/validations/practitioner.schema.ts +222 -222
- package/src/validations/procedure-product.schema.ts +41 -41
- package/src/validations/procedure.schema.ts +124 -124
- package/src/validations/profile-info.schema.ts +41 -41
- package/src/validations/reviews.schema.ts +195 -195
- package/src/validations/schemas.ts +104 -104
- package/src/validations/shared.schema.ts +78 -78
|
@@ -1,241 +1,241 @@
|
|
|
1
|
-
import * as admin from "firebase-admin";
|
|
2
|
-
import { Timestamp as ClientTimestamp } from "firebase/firestore";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Detect if we're running in a server environment (like Cloud Functions)
|
|
6
|
-
* or compiled for server usage
|
|
7
|
-
*/
|
|
8
|
-
const IS_SERVER_ENV =
|
|
9
|
-
process.env.NODE_ENV === "production" ||
|
|
10
|
-
process.env.FUNCTIONS_EMULATOR === "true" ||
|
|
11
|
-
process.env.FIREBASE_CONFIG !== undefined;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Utilities for managing timestamps across client and server-side Firebase code.
|
|
15
|
-
* This module provides conversion functions to ensure timestamp compatibility
|
|
16
|
-
* between admin and client Firebase SDKs.
|
|
17
|
-
*/
|
|
18
|
-
export class TimestampUtils {
|
|
19
|
-
/**
|
|
20
|
-
* Flag to force server mode where admin timestamps are preserved
|
|
21
|
-
* This should be true in Cloud Functions environments
|
|
22
|
-
*/
|
|
23
|
-
private static serverMode = IS_SERVER_ENV;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Enables server mode where admin timestamps are preserved when saving
|
|
27
|
-
* to Firestore via the admin SDK
|
|
28
|
-
*/
|
|
29
|
-
static enableServerMode(): void {
|
|
30
|
-
this.serverMode = true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Disables server mode - use this only for client-side or mixed environments
|
|
35
|
-
*/
|
|
36
|
-
static disableServerMode(): void {
|
|
37
|
-
this.serverMode = false;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Converts an admin Firestore Timestamp to a client Firestore Timestamp
|
|
42
|
-
* In server mode, returns the original admin timestamp for storage consistency
|
|
43
|
-
*
|
|
44
|
-
* @param adminTimestamp - Admin SDK Timestamp (from firebase-admin)
|
|
45
|
-
* @returns A client SDK Timestamp (from firebase/firestore) with same seconds/nanoseconds,
|
|
46
|
-
* or the original admin timestamp in server mode,
|
|
47
|
-
* or null if input is null
|
|
48
|
-
*/
|
|
49
|
-
static adminToClient(
|
|
50
|
-
adminTimestamp: admin.firestore.Timestamp | null
|
|
51
|
-
): ClientTimestamp | admin.firestore.Timestamp | null {
|
|
52
|
-
if (!adminTimestamp) return null;
|
|
53
|
-
|
|
54
|
-
// In server mode (Cloud Functions), just return the admin timestamp
|
|
55
|
-
if (this.serverMode) {
|
|
56
|
-
return adminTimestamp;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// In client mode, convert to client timestamp
|
|
60
|
-
return new ClientTimestamp(
|
|
61
|
-
adminTimestamp.seconds,
|
|
62
|
-
adminTimestamp.nanoseconds
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Converts a client Firestore Timestamp to an admin Firestore Timestamp
|
|
68
|
-
* @param clientTimestamp - Client SDK Timestamp (from firebase/firestore)
|
|
69
|
-
* @returns An admin SDK Timestamp (from firebase-admin) with same seconds/nanoseconds or null if input is null
|
|
70
|
-
*/
|
|
71
|
-
static clientToAdmin(
|
|
72
|
-
clientTimestamp: ClientTimestamp | null
|
|
73
|
-
): admin.firestore.Timestamp | null {
|
|
74
|
-
if (!clientTimestamp) return null;
|
|
75
|
-
|
|
76
|
-
return new admin.firestore.Timestamp(
|
|
77
|
-
clientTimestamp.seconds,
|
|
78
|
-
clientTimestamp.nanoseconds
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Creates a timestamp for the current time in the appropriate format based on environment
|
|
84
|
-
* @returns A timestamp for the current time (admin timestamp in server mode, client in client mode)
|
|
85
|
-
*/
|
|
86
|
-
static nowAsTimestamp(): admin.firestore.Timestamp | ClientTimestamp {
|
|
87
|
-
const now = admin.firestore.Timestamp.now();
|
|
88
|
-
// In server mode, return the admin timestamp directly
|
|
89
|
-
if (this.serverMode) {
|
|
90
|
-
return now;
|
|
91
|
-
}
|
|
92
|
-
// In client mode, convert to client timestamp
|
|
93
|
-
return this.adminToClient(now) as ClientTimestamp;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @deprecated Use nowAsTimestamp() instead for better cross-environment compatibility
|
|
98
|
-
*/
|
|
99
|
-
static nowAsClient(): ClientTimestamp {
|
|
100
|
-
const now = admin.firestore.Timestamp.now();
|
|
101
|
-
return this.adminToClient(now) as ClientTimestamp;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Converts a Date object to a timestamp in the appropriate format based on environment
|
|
106
|
-
* @param date - JavaScript Date object
|
|
107
|
-
* @returns A timestamp (admin timestamp in server mode, client in client mode) or null if input is null
|
|
108
|
-
*/
|
|
109
|
-
static dateToTimestamp(
|
|
110
|
-
date: Date | null
|
|
111
|
-
): admin.firestore.Timestamp | ClientTimestamp | null {
|
|
112
|
-
if (!date) return null;
|
|
113
|
-
|
|
114
|
-
if (this.serverMode) {
|
|
115
|
-
return admin.firestore.Timestamp.fromDate(date);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return ClientTimestamp.fromDate(date);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
|
|
123
|
-
*/
|
|
124
|
-
static dateToClientTimestamp(date: Date | null): ClientTimestamp | null {
|
|
125
|
-
if (!date) return null;
|
|
126
|
-
return ClientTimestamp.fromDate(date);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
|
|
131
|
-
*/
|
|
132
|
-
static dateToAdminTimestamp(
|
|
133
|
-
date: Date | null
|
|
134
|
-
): admin.firestore.Timestamp | null {
|
|
135
|
-
if (!date) return null;
|
|
136
|
-
return admin.firestore.Timestamp.fromDate(date);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Gets a server timestamp field value for use in create/update operations
|
|
141
|
-
* Works in both admin and client environments
|
|
142
|
-
*/
|
|
143
|
-
static serverTimestamp(): admin.firestore.FieldValue | any {
|
|
144
|
-
if (this.serverMode) {
|
|
145
|
-
return admin.firestore.FieldValue.serverTimestamp();
|
|
146
|
-
}
|
|
147
|
-
// In client mode, we'd need to import from firebase/firestore
|
|
148
|
-
// This would be implemented for client environments
|
|
149
|
-
throw new Error("Server timestamp in client mode not implemented");
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* For objects with mixed timestamp types, ensures all timestamps are
|
|
154
|
-
* in the correct format for the current environment
|
|
155
|
-
*/
|
|
156
|
-
static normalizeTimestamps<T>(obj: T): T {
|
|
157
|
-
if (!obj || typeof obj !== "object") {
|
|
158
|
-
return obj;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (obj instanceof admin.firestore.Timestamp) {
|
|
162
|
-
return this.serverMode ? obj : (this.adminToClient(obj) as unknown as T);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (obj instanceof ClientTimestamp && this.serverMode) {
|
|
166
|
-
return this.clientToAdmin(obj) as unknown as T;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (Array.isArray(obj)) {
|
|
170
|
-
return obj.map((item) => this.normalizeTimestamps(item)) as unknown as T;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const result = { ...obj } as any;
|
|
174
|
-
|
|
175
|
-
for (const key in result) {
|
|
176
|
-
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
177
|
-
result[key] = this.normalizeTimestamps(result[key]);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return result as T;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* @deprecated Use normalizeTimestamps() instead for better cross-environment compatibility
|
|
186
|
-
*/
|
|
187
|
-
static convertObjectTimestampsAdminToClient<T>(obj: T): T {
|
|
188
|
-
if (!obj || typeof obj !== "object") {
|
|
189
|
-
return obj;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (obj instanceof admin.firestore.Timestamp) {
|
|
193
|
-
return this.adminToClient(obj) as unknown as T;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (Array.isArray(obj)) {
|
|
197
|
-
return obj.map((item) =>
|
|
198
|
-
this.convertObjectTimestampsAdminToClient(item)
|
|
199
|
-
) as unknown as T;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const result = { ...obj } as any;
|
|
203
|
-
|
|
204
|
-
for (const key in result) {
|
|
205
|
-
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
206
|
-
result[key] = this.convertObjectTimestampsAdminToClient(result[key]);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return result as T;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* @deprecated Use normalizeTimestamps() instead for better cross-environment compatibility
|
|
215
|
-
*/
|
|
216
|
-
static convertObjectTimestampsClientToAdmin<T>(obj: T): T {
|
|
217
|
-
if (!obj || typeof obj !== "object") {
|
|
218
|
-
return obj;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (obj instanceof ClientTimestamp) {
|
|
222
|
-
return this.clientToAdmin(obj) as unknown as T;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (Array.isArray(obj)) {
|
|
226
|
-
return obj.map((item) =>
|
|
227
|
-
this.convertObjectTimestampsClientToAdmin(item)
|
|
228
|
-
) as unknown as T;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const result = { ...obj } as any;
|
|
232
|
-
|
|
233
|
-
for (const key in result) {
|
|
234
|
-
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
235
|
-
result[key] = this.convertObjectTimestampsClientToAdmin(result[key]);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return result as T;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
1
|
+
import * as admin from "firebase-admin";
|
|
2
|
+
import { Timestamp as ClientTimestamp } from "firebase/firestore";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Detect if we're running in a server environment (like Cloud Functions)
|
|
6
|
+
* or compiled for server usage
|
|
7
|
+
*/
|
|
8
|
+
const IS_SERVER_ENV =
|
|
9
|
+
process.env.NODE_ENV === "production" ||
|
|
10
|
+
process.env.FUNCTIONS_EMULATOR === "true" ||
|
|
11
|
+
process.env.FIREBASE_CONFIG !== undefined;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Utilities for managing timestamps across client and server-side Firebase code.
|
|
15
|
+
* This module provides conversion functions to ensure timestamp compatibility
|
|
16
|
+
* between admin and client Firebase SDKs.
|
|
17
|
+
*/
|
|
18
|
+
export class TimestampUtils {
|
|
19
|
+
/**
|
|
20
|
+
* Flag to force server mode where admin timestamps are preserved
|
|
21
|
+
* This should be true in Cloud Functions environments
|
|
22
|
+
*/
|
|
23
|
+
private static serverMode = IS_SERVER_ENV;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Enables server mode where admin timestamps are preserved when saving
|
|
27
|
+
* to Firestore via the admin SDK
|
|
28
|
+
*/
|
|
29
|
+
static enableServerMode(): void {
|
|
30
|
+
this.serverMode = true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Disables server mode - use this only for client-side or mixed environments
|
|
35
|
+
*/
|
|
36
|
+
static disableServerMode(): void {
|
|
37
|
+
this.serverMode = false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Converts an admin Firestore Timestamp to a client Firestore Timestamp
|
|
42
|
+
* In server mode, returns the original admin timestamp for storage consistency
|
|
43
|
+
*
|
|
44
|
+
* @param adminTimestamp - Admin SDK Timestamp (from firebase-admin)
|
|
45
|
+
* @returns A client SDK Timestamp (from firebase/firestore) with same seconds/nanoseconds,
|
|
46
|
+
* or the original admin timestamp in server mode,
|
|
47
|
+
* or null if input is null
|
|
48
|
+
*/
|
|
49
|
+
static adminToClient(
|
|
50
|
+
adminTimestamp: admin.firestore.Timestamp | null
|
|
51
|
+
): ClientTimestamp | admin.firestore.Timestamp | null {
|
|
52
|
+
if (!adminTimestamp) return null;
|
|
53
|
+
|
|
54
|
+
// In server mode (Cloud Functions), just return the admin timestamp
|
|
55
|
+
if (this.serverMode) {
|
|
56
|
+
return adminTimestamp;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// In client mode, convert to client timestamp
|
|
60
|
+
return new ClientTimestamp(
|
|
61
|
+
adminTimestamp.seconds,
|
|
62
|
+
adminTimestamp.nanoseconds
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Converts a client Firestore Timestamp to an admin Firestore Timestamp
|
|
68
|
+
* @param clientTimestamp - Client SDK Timestamp (from firebase/firestore)
|
|
69
|
+
* @returns An admin SDK Timestamp (from firebase-admin) with same seconds/nanoseconds or null if input is null
|
|
70
|
+
*/
|
|
71
|
+
static clientToAdmin(
|
|
72
|
+
clientTimestamp: ClientTimestamp | null
|
|
73
|
+
): admin.firestore.Timestamp | null {
|
|
74
|
+
if (!clientTimestamp) return null;
|
|
75
|
+
|
|
76
|
+
return new admin.firestore.Timestamp(
|
|
77
|
+
clientTimestamp.seconds,
|
|
78
|
+
clientTimestamp.nanoseconds
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Creates a timestamp for the current time in the appropriate format based on environment
|
|
84
|
+
* @returns A timestamp for the current time (admin timestamp in server mode, client in client mode)
|
|
85
|
+
*/
|
|
86
|
+
static nowAsTimestamp(): admin.firestore.Timestamp | ClientTimestamp {
|
|
87
|
+
const now = admin.firestore.Timestamp.now();
|
|
88
|
+
// In server mode, return the admin timestamp directly
|
|
89
|
+
if (this.serverMode) {
|
|
90
|
+
return now;
|
|
91
|
+
}
|
|
92
|
+
// In client mode, convert to client timestamp
|
|
93
|
+
return this.adminToClient(now) as ClientTimestamp;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @deprecated Use nowAsTimestamp() instead for better cross-environment compatibility
|
|
98
|
+
*/
|
|
99
|
+
static nowAsClient(): ClientTimestamp {
|
|
100
|
+
const now = admin.firestore.Timestamp.now();
|
|
101
|
+
return this.adminToClient(now) as ClientTimestamp;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Converts a Date object to a timestamp in the appropriate format based on environment
|
|
106
|
+
* @param date - JavaScript Date object
|
|
107
|
+
* @returns A timestamp (admin timestamp in server mode, client in client mode) or null if input is null
|
|
108
|
+
*/
|
|
109
|
+
static dateToTimestamp(
|
|
110
|
+
date: Date | null
|
|
111
|
+
): admin.firestore.Timestamp | ClientTimestamp | null {
|
|
112
|
+
if (!date) return null;
|
|
113
|
+
|
|
114
|
+
if (this.serverMode) {
|
|
115
|
+
return admin.firestore.Timestamp.fromDate(date);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return ClientTimestamp.fromDate(date);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
|
|
123
|
+
*/
|
|
124
|
+
static dateToClientTimestamp(date: Date | null): ClientTimestamp | null {
|
|
125
|
+
if (!date) return null;
|
|
126
|
+
return ClientTimestamp.fromDate(date);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
|
|
131
|
+
*/
|
|
132
|
+
static dateToAdminTimestamp(
|
|
133
|
+
date: Date | null
|
|
134
|
+
): admin.firestore.Timestamp | null {
|
|
135
|
+
if (!date) return null;
|
|
136
|
+
return admin.firestore.Timestamp.fromDate(date);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Gets a server timestamp field value for use in create/update operations
|
|
141
|
+
* Works in both admin and client environments
|
|
142
|
+
*/
|
|
143
|
+
static serverTimestamp(): admin.firestore.FieldValue | any {
|
|
144
|
+
if (this.serverMode) {
|
|
145
|
+
return admin.firestore.FieldValue.serverTimestamp();
|
|
146
|
+
}
|
|
147
|
+
// In client mode, we'd need to import from firebase/firestore
|
|
148
|
+
// This would be implemented for client environments
|
|
149
|
+
throw new Error("Server timestamp in client mode not implemented");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* For objects with mixed timestamp types, ensures all timestamps are
|
|
154
|
+
* in the correct format for the current environment
|
|
155
|
+
*/
|
|
156
|
+
static normalizeTimestamps<T>(obj: T): T {
|
|
157
|
+
if (!obj || typeof obj !== "object") {
|
|
158
|
+
return obj;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (obj instanceof admin.firestore.Timestamp) {
|
|
162
|
+
return this.serverMode ? obj : (this.adminToClient(obj) as unknown as T);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (obj instanceof ClientTimestamp && this.serverMode) {
|
|
166
|
+
return this.clientToAdmin(obj) as unknown as T;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (Array.isArray(obj)) {
|
|
170
|
+
return obj.map((item) => this.normalizeTimestamps(item)) as unknown as T;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const result = { ...obj } as any;
|
|
174
|
+
|
|
175
|
+
for (const key in result) {
|
|
176
|
+
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
177
|
+
result[key] = this.normalizeTimestamps(result[key]);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return result as T;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @deprecated Use normalizeTimestamps() instead for better cross-environment compatibility
|
|
186
|
+
*/
|
|
187
|
+
static convertObjectTimestampsAdminToClient<T>(obj: T): T {
|
|
188
|
+
if (!obj || typeof obj !== "object") {
|
|
189
|
+
return obj;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (obj instanceof admin.firestore.Timestamp) {
|
|
193
|
+
return this.adminToClient(obj) as unknown as T;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (Array.isArray(obj)) {
|
|
197
|
+
return obj.map((item) =>
|
|
198
|
+
this.convertObjectTimestampsAdminToClient(item)
|
|
199
|
+
) as unknown as T;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const result = { ...obj } as any;
|
|
203
|
+
|
|
204
|
+
for (const key in result) {
|
|
205
|
+
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
206
|
+
result[key] = this.convertObjectTimestampsAdminToClient(result[key]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return result as T;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @deprecated Use normalizeTimestamps() instead for better cross-environment compatibility
|
|
215
|
+
*/
|
|
216
|
+
static convertObjectTimestampsClientToAdmin<T>(obj: T): T {
|
|
217
|
+
if (!obj || typeof obj !== "object") {
|
|
218
|
+
return obj;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (obj instanceof ClientTimestamp) {
|
|
222
|
+
return this.clientToAdmin(obj) as unknown as T;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (Array.isArray(obj)) {
|
|
226
|
+
return obj.map((item) =>
|
|
227
|
+
this.convertObjectTimestampsClientToAdmin(item)
|
|
228
|
+
) as unknown as T;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const result = { ...obj } as any;
|
|
232
|
+
|
|
233
|
+
for (const key in result) {
|
|
234
|
+
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
235
|
+
result[key] = this.convertObjectTimestampsClientToAdmin(result[key]);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return result as T;
|
|
240
|
+
}
|
|
241
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./TimestampUtils";
|
|
1
|
+
export * from "./TimestampUtils";
|