@sneat/logging 0.26.6 → 0.27.0

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.
@@ -1,12 +1,20 @@
1
1
  import { inject, Injectable } from '@angular/core';
2
- import { Analytics, logEvent, setUserId, setUserProperties, } from '@angular/fire/analytics';
3
- import { ErrorLogger } from '@sneat/core';
2
+ import { logEvent, setUserId, setUserProperties } from 'firebase/analytics';
3
+ import { ErrorLogger, SNEAT_FIREBASE_ANALYTICS, } from '@sneat/core';
4
4
  import * as i0 from "@angular/core";
5
5
  const logErrOptions = { show: false, feedback: false };
6
6
  export class FireAnalyticsService {
7
7
  constructor() {
8
8
  this.errorLogger = inject(ErrorLogger);
9
- this.analytics = inject(Analytics);
9
+ /**
10
+ * Nullable by contract: `SNEAT_FIREBASE_ANALYTICS` resolves to `null` — it
11
+ * never throws — when the app has no real `measurementId` or when
12
+ * `getAnalytics()` is unsupported in the host environment. Every method
13
+ * below therefore no-ops on `null` instead of reporting a failed SDK call
14
+ * on each event. Before 0.27.0 this injected `@angular/fire`'s `Analytics`
15
+ * token, which threw NullInjectorError in exactly those cases.
16
+ */
17
+ this.analytics = inject(SNEAT_FIREBASE_ANALYTICS);
10
18
  this.logError = (e, m) => this.errorLogger.logError(e, m, logErrOptions);
11
19
  if (!this.errorLogger) {
12
20
  console.error(`FireAnalyticsService() - !errorLogger`);
@@ -16,25 +24,34 @@ export class FireAnalyticsService {
16
24
  }
17
25
  }
18
26
  logEvent(eventName, eventParams, options) {
27
+ const analytics = this.analytics;
28
+ if (!analytics)
29
+ return;
19
30
  try {
20
- logEvent(this.analytics, eventName, eventParams, options);
31
+ logEvent(analytics, eventName, eventParams, options);
21
32
  }
22
33
  catch (e) {
23
34
  this.logError(e, 'Failed to log event to Firebase analytics');
24
35
  }
25
36
  }
26
37
  setCurrentScreen(screenName, options) {
38
+ const analytics = this.analytics;
39
+ if (!analytics)
40
+ return;
27
41
  try {
28
42
  const args = { screenName: screenName };
29
- logEvent(this.analytics, '$screen_view', args, options);
43
+ logEvent(analytics, '$screen_view', args, options);
30
44
  }
31
45
  catch (e) {
32
46
  this.logError(e, 'Failed to log screen view to Firebase analytics');
33
47
  }
34
48
  }
35
49
  identify(userID, userPropertiesToSet, userPropertiesToSetOnce) {
50
+ const analytics = this.analytics;
51
+ if (!analytics)
52
+ return;
36
53
  try {
37
- setUserId(this.analytics, userID);
54
+ setUserId(analytics, userID);
38
55
  }
39
56
  catch (e) {
40
57
  this.logError(e, 'Failed to set user id in Firebase analytics');
@@ -45,15 +62,18 @@ export class FireAnalyticsService {
45
62
  if (userPropertiesToSetOnce)
46
63
  Object.keys(userPropertiesToSetOnce).forEach((k) => (customProperties[k] = userPropertiesToSetOnce[k]));
47
64
  try {
48
- setUserProperties(this.analytics, customProperties);
65
+ setUserProperties(analytics, customProperties);
49
66
  }
50
67
  catch (e) {
51
68
  this.logError(e, 'Failed to set user props in Firebase analytics');
52
69
  }
53
70
  }
54
71
  loggedOut() {
72
+ const analytics = this.analytics;
73
+ if (!analytics)
74
+ return;
55
75
  try {
56
- setUserId(this.analytics, null);
76
+ setUserId(analytics, null);
57
77
  }
58
78
  catch (e) {
59
79
  this.logError(e, 'Failed to logout user from Firebase analytics');
@@ -1 +1 @@
1
- {"version":3,"file":"fire-analytics.service.js","sourceRoot":"","sources":["../../../../../../libs/logging/src/lib/analytics/fire-analytics.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport {\n Analytics,\n logEvent,\n setUserId,\n setUserProperties,\n} from '@angular/fire/analytics';\nimport { ErrorLogger, IErrorLogger, ILogErrorOptions } from '@sneat/core';\nimport {\n IAnalyticsCallOptions,\n IAnalyticsService,\n UserProperties,\n} from '@sneat/core';\n\nconst logErrOptions: ILogErrorOptions = { show: false, feedback: false };\n\n@Injectable()\nexport class FireAnalyticsService implements IAnalyticsService {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly analytics = inject(Analytics);\n\n constructor() {\n if (!this.errorLogger) {\n console.error(`FireAnalyticsService() - !errorLogger`);\n }\n if (!this.analytics) {\n console.error(`FireAnalyticsService() - !analytics`);\n }\n }\n\n private readonly logError = (e: unknown, m: string) =>\n this.errorLogger.logError(e, m, logErrOptions);\n\n public logEvent(\n eventName: string,\n eventParams?: Record<string, unknown>,\n options?: IAnalyticsCallOptions,\n ): void {\n try {\n logEvent(this.analytics, eventName, eventParams, options);\n } catch (e) {\n this.logError(e, 'Failed to log event to Firebase analytics');\n }\n }\n\n public setCurrentScreen(\n screenName: string,\n options?: IAnalyticsCallOptions,\n ): void {\n try {\n const args = { screenName: screenName };\n logEvent(this.analytics, '$screen_view', args, options);\n } catch (e) {\n this.logError(e, 'Failed to log screen view to Firebase analytics');\n }\n }\n\n public identify(\n userID: string,\n userPropertiesToSet?: UserProperties,\n userPropertiesToSetOnce?: UserProperties,\n ): void {\n try {\n setUserId(this.analytics, userID);\n } catch (e) {\n this.logError(e, 'Failed to set user id in Firebase analytics');\n }\n const customProperties: { [id: string]: unknown } = {};\n\n if (userPropertiesToSet)\n Object.keys(userPropertiesToSet).forEach(\n (k) => (customProperties[k] = userPropertiesToSet[k]),\n );\n if (userPropertiesToSetOnce)\n Object.keys(userPropertiesToSetOnce).forEach(\n (k) => (customProperties[k] = userPropertiesToSetOnce[k]),\n );\n try {\n setUserProperties(this.analytics, customProperties);\n } catch (e) {\n this.logError(e, 'Failed to set user props in Firebase analytics');\n }\n }\n\n public loggedOut(): void {\n try {\n setUserId(this.analytics, null);\n } catch (e) {\n this.logError(e, 'Failed to logout user from Firebase analytics');\n }\n }\n}\n"]}
1
+ {"version":3,"file":"fire-analytics.service.js","sourceRoot":"","sources":["../../../../../../libs/logging/src/lib/analytics/fire-analytics.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { logEvent, setUserId, setUserProperties } from 'firebase/analytics';\nimport {\n ErrorLogger,\n IErrorLogger,\n ILogErrorOptions,\n SNEAT_FIREBASE_ANALYTICS,\n} from '@sneat/core';\nimport {\n IAnalyticsCallOptions,\n IAnalyticsService,\n UserProperties,\n} from '@sneat/core';\n\nconst logErrOptions: ILogErrorOptions = { show: false, feedback: false };\n\n@Injectable()\nexport class FireAnalyticsService implements IAnalyticsService {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n\n /**\n * Nullable by contract: `SNEAT_FIREBASE_ANALYTICS` resolves to `null` — it\n * never throws — when the app has no real `measurementId` or when\n * `getAnalytics()` is unsupported in the host environment. Every method\n * below therefore no-ops on `null` instead of reporting a failed SDK call\n * on each event. Before 0.27.0 this injected `@angular/fire`'s `Analytics`\n * token, which threw NullInjectorError in exactly those cases.\n */\n private readonly analytics = inject(SNEAT_FIREBASE_ANALYTICS);\n\n constructor() {\n if (!this.errorLogger) {\n console.error(`FireAnalyticsService() - !errorLogger`);\n }\n if (!this.analytics) {\n console.error(`FireAnalyticsService() - !analytics`);\n }\n }\n\n private readonly logError = (e: unknown, m: string) =>\n this.errorLogger.logError(e, m, logErrOptions);\n\n public logEvent(\n eventName: string,\n eventParams?: Record<string, unknown>,\n options?: IAnalyticsCallOptions,\n ): void {\n const analytics = this.analytics;\n if (!analytics) return;\n try {\n logEvent(analytics, eventName, eventParams, options);\n } catch (e) {\n this.logError(e, 'Failed to log event to Firebase analytics');\n }\n }\n\n public setCurrentScreen(\n screenName: string,\n options?: IAnalyticsCallOptions,\n ): void {\n const analytics = this.analytics;\n if (!analytics) return;\n try {\n const args = { screenName: screenName };\n logEvent(analytics, '$screen_view', args, options);\n } catch (e) {\n this.logError(e, 'Failed to log screen view to Firebase analytics');\n }\n }\n\n public identify(\n userID: string,\n userPropertiesToSet?: UserProperties,\n userPropertiesToSetOnce?: UserProperties,\n ): void {\n const analytics = this.analytics;\n if (!analytics) return;\n try {\n setUserId(analytics, userID);\n } catch (e) {\n this.logError(e, 'Failed to set user id in Firebase analytics');\n }\n const customProperties: { [id: string]: unknown } = {};\n\n if (userPropertiesToSet)\n Object.keys(userPropertiesToSet).forEach(\n (k) => (customProperties[k] = userPropertiesToSet[k]),\n );\n if (userPropertiesToSetOnce)\n Object.keys(userPropertiesToSetOnce).forEach(\n (k) => (customProperties[k] = userPropertiesToSetOnce[k]),\n );\n try {\n setUserProperties(analytics, customProperties);\n } catch (e) {\n this.logError(e, 'Failed to set user props in Firebase analytics');\n }\n }\n\n public loggedOut(): void {\n const analytics = this.analytics;\n if (!analytics) return;\n try {\n setUserId(analytics, null);\n } catch (e) {\n this.logError(e, 'Failed to logout user from Firebase analytics');\n }\n }\n}\n"]}
@@ -1,11 +1,10 @@
1
- import { getAnalytics } from '@angular/fire/analytics';
2
- import { FirebaseApp } from '@angular/fire/app';
3
- import { AnalyticsService, } from '@sneat/core';
1
+ import { AnalyticsService, SNEAT_FIREBASE_ANALYTICS, } from '@sneat/core';
4
2
  import { ErrorLogger } from '@sneat/core';
5
3
  import { FireAnalyticsService } from './fire-analytics.service';
6
4
  import { GtagAnalyticsService } from './gtag-analytics.service';
7
5
  import { MultiAnalyticsService } from './multi-analytics.service';
8
6
  import { PosthogAnalyticsService } from './posthog-analytics.service';
7
+ import { Injector } from '@angular/core';
9
8
  function getAnalyticsConfig(environmentConfig) {
10
9
  const useAnalytics = location.host === 'sneat.app' || location.protocol === 'https:';
11
10
  const firebaseMeasurementId = environmentConfig.firebaseConfig?.measurementId;
@@ -21,12 +20,14 @@ function getAnalyticsConfig(environmentConfig) {
21
20
  export function provideSneatAnalytics(environmentConfig) {
22
21
  return {
23
22
  provide: AnalyticsService,
24
- deps: [
25
- ErrorLogger,
26
- FirebaseApp,
27
- // [new Optional(), Analytics], // TODO: The received Analytics instance does not have app property :(
28
- ],
29
- useFactory: (errorLogger, fbApp) => {
23
+ // `Injector` rather than `SNEAT_FIREBASE_ANALYTICS` directly: listing the
24
+ // token in `deps` would resolve it — and so initialize Firebase Analytics —
25
+ // on every app that injects `AnalyticsService`, including the ones where
26
+ // `addFirebaseAnalytics` is false (plain http, non-sneat.app host). Reading
27
+ // it through the injector inside the branch below keeps initialization as
28
+ // lazy as the pre-0.27.0 `getAnalytics(fbApp)` call it replaces.
29
+ deps: [ErrorLogger, Injector],
30
+ useFactory: (errorLogger, injector) => {
30
31
  const config = getAnalyticsConfig(environmentConfig);
31
32
  const as = [];
32
33
  if (config?.addPosthog) {
@@ -36,10 +37,12 @@ export function provideSneatAnalytics(environmentConfig) {
36
37
  as.push(new GtagAnalyticsService(config.googleAnalyticsMeasurementId));
37
38
  }
38
39
  if (config?.addFirebaseAnalytics) {
39
- const analytics = fbApp && getAnalytics(fbApp); // Ideally we would want to get it from the DI
40
+ const analytics = injector.get(SNEAT_FIREBASE_ANALYTICS, null);
40
41
  if (analytics) {
42
+ // Constructed inside this factory's injection context, so
43
+ // FireAnalyticsService's own inject(SNEAT_FIREBASE_ANALYTICS)
44
+ // resolves — to this same, already-instantiated instance.
41
45
  as.push(new FireAnalyticsService());
42
- // as.push(new FireAnalyticsService(errorLogger, analytics));
43
46
  }
44
47
  else {
45
48
  errorLogger.logError('addFirebaseAnalytics==true, but Firebase Analytics is not provided', undefined, { show: false, feedback: false });
@@ -1 +1 @@
1
- {"version":3,"file":"provide-sneat-analytics.js","sourceRoot":"","sources":["../../../../../../libs/logging/src/lib/analytics/provide-sneat-analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,gBAAgB,GAGjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAWtE,SAAS,kBAAkB,CACzB,iBAAqC;IAErC,MAAM,YAAY,GAChB,QAAQ,CAAC,IAAI,KAAK,WAAW,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAElE,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,cAAc,EAAE,aAAa,CAAC;IAC9E,MAAM,eAAe,GAAG,iBAAiB,CAAC,eAAe,EAAE,aAAa,CAAC;IAEzE,OAAO;QACL,UAAU,EAAE,YAAY,IAAI,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK;QAC9D,oBAAoB,EAClB,YAAY;YACZ,CAAC,CAAC,qBAAqB;YACvB,qBAAqB,KAAK,qBAAqB;QACjD,4BAA4B,EAAE,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;KACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,iBAAqC;IAErC,OAAO;QACL,OAAO,EAAE,gBAAgB;QACzB,IAAI,EAAE;YACJ,WAAW;YACX,WAAW;YACX,sGAAsG;SACvG;QACD,UAAU,EAAE,CAAC,WAAyB,EAAE,KAAkB,EAAE,EAAE;YAC5D,MAAM,MAAM,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;YACrD,MAAM,EAAE,GAAwB,EAAE,CAAC;YACnC,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC;gBACvB,EAAE,CAAC,IAAI,CAAC,IAAI,uBAAuB,EAAE,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,MAAM,EAAE,4BAA4B,EAAE,CAAC;gBACzC,EAAE,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,IAAI,MAAM,EAAE,oBAAoB,EAAE,CAAC;gBACjC,MAAM,SAAS,GAAc,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,8CAA8C;gBACzG,IAAI,SAAS,EAAE,CAAC;oBACd,EAAE,CAAC,IAAI,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;oBACpC,6DAA6D;gBAC/D,CAAC;qBAAM,CAAC;oBACN,WAAW,CAAC,QAAQ,CAClB,oEAAoE,EACpE,SAAS,EACT,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CACjC,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,IAAI,qBAAqB,CAAC,EAAE,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { Analytics, getAnalytics } from '@angular/fire/analytics';\nimport { FirebaseApp } from '@angular/fire/app';\nimport {\n AnalyticsService,\n IAnalyticsService,\n IEnvironmentConfig,\n} from '@sneat/core';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport { FireAnalyticsService } from './fire-analytics.service';\nimport { GtagAnalyticsService } from './gtag-analytics.service';\nimport { MultiAnalyticsService } from './multi-analytics.service';\nimport { PosthogAnalyticsService } from './posthog-analytics.service';\nimport { Provider } from '@angular/core';\n\nexport interface IAnalyticsConfig {\n addPosthog?: boolean;\n addFirebaseAnalytics?: boolean;\n // GA4 measurement ID for the app's own per-domain property (the same stream\n // its marketing landing uses). When set, a gtag-based GA4 backend is added.\n googleAnalyticsMeasurementId?: string;\n}\n\nfunction getAnalyticsConfig(\n environmentConfig: IEnvironmentConfig,\n): IAnalyticsConfig {\n const useAnalytics =\n location.host === 'sneat.app' || location.protocol === 'https:';\n\n const firebaseMeasurementId = environmentConfig.firebaseConfig?.measurementId;\n const gaMeasurementId = environmentConfig.googleAnalytics?.measurementId;\n\n return {\n addPosthog: useAnalytics && !!environmentConfig.posthog?.token,\n addFirebaseAnalytics:\n useAnalytics &&\n !!firebaseMeasurementId &&\n firebaseMeasurementId !== 'G-PROVIDE_IF_NEEDED',\n googleAnalyticsMeasurementId: useAnalytics ? gaMeasurementId : undefined,\n };\n}\n\nexport function provideSneatAnalytics(\n environmentConfig: IEnvironmentConfig,\n): Provider {\n return {\n provide: AnalyticsService,\n deps: [\n ErrorLogger,\n FirebaseApp,\n // [new Optional(), Analytics], // TODO: The received Analytics instance does not have app property :(\n ],\n useFactory: (errorLogger: IErrorLogger, fbApp: FirebaseApp) => {\n const config = getAnalyticsConfig(environmentConfig);\n const as: IAnalyticsService[] = [];\n if (config?.addPosthog) {\n as.push(new PosthogAnalyticsService());\n }\n if (config?.googleAnalyticsMeasurementId) {\n as.push(new GtagAnalyticsService(config.googleAnalyticsMeasurementId));\n }\n if (config?.addFirebaseAnalytics) {\n const analytics: Analytics = fbApp && getAnalytics(fbApp); // Ideally we would want to get it from the DI\n if (analytics) {\n as.push(new FireAnalyticsService());\n // as.push(new FireAnalyticsService(errorLogger, analytics));\n } else {\n errorLogger.logError(\n 'addFirebaseAnalytics==true, but Firebase Analytics is not provided',\n undefined,\n { show: false, feedback: false },\n );\n }\n }\n return new MultiAnalyticsService(as);\n },\n };\n}\n"]}
1
+ {"version":3,"file":"provide-sneat-analytics.js","sourceRoot":"","sources":["../../../../../../libs/logging/src/lib/analytics/provide-sneat-analytics.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAGhB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAY,MAAM,eAAe,CAAC;AAUnD,SAAS,kBAAkB,CACzB,iBAAqC;IAErC,MAAM,YAAY,GAChB,QAAQ,CAAC,IAAI,KAAK,WAAW,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAElE,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,cAAc,EAAE,aAAa,CAAC;IAC9E,MAAM,eAAe,GAAG,iBAAiB,CAAC,eAAe,EAAE,aAAa,CAAC;IAEzE,OAAO;QACL,UAAU,EAAE,YAAY,IAAI,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK;QAC9D,oBAAoB,EAClB,YAAY;YACZ,CAAC,CAAC,qBAAqB;YACvB,qBAAqB,KAAK,qBAAqB;QACjD,4BAA4B,EAAE,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;KACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,iBAAqC;IAErC,OAAO;QACL,OAAO,EAAE,gBAAgB;QACzB,0EAA0E;QAC1E,4EAA4E;QAC5E,yEAAyE;QACzE,4EAA4E;QAC5E,0EAA0E;QAC1E,iEAAiE;QACjE,IAAI,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC;QAC7B,UAAU,EAAE,CAAC,WAAyB,EAAE,QAAkB,EAAE,EAAE;YAC5D,MAAM,MAAM,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;YACrD,MAAM,EAAE,GAAwB,EAAE,CAAC;YACnC,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC;gBACvB,EAAE,CAAC,IAAI,CAAC,IAAI,uBAAuB,EAAE,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,MAAM,EAAE,4BAA4B,EAAE,CAAC;gBACzC,EAAE,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,IAAI,MAAM,EAAE,oBAAoB,EAAE,CAAC;gBACjC,MAAM,SAAS,GAAqB,QAAQ,CAAC,GAAG,CAC9C,wBAAwB,EACxB,IAAI,CACL,CAAC;gBACF,IAAI,SAAS,EAAE,CAAC;oBACd,0DAA0D;oBAC1D,8DAA8D;oBAC9D,0DAA0D;oBAC1D,EAAE,CAAC,IAAI,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;gBACtC,CAAC;qBAAM,CAAC;oBACN,WAAW,CAAC,QAAQ,CAClB,oEAAoE,EACpE,SAAS,EACT,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CACjC,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,IAAI,qBAAqB,CAAC,EAAE,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Analytics } from 'firebase/analytics';\nimport {\n AnalyticsService,\n IAnalyticsService,\n IEnvironmentConfig,\n SNEAT_FIREBASE_ANALYTICS,\n} from '@sneat/core';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport { FireAnalyticsService } from './fire-analytics.service';\nimport { GtagAnalyticsService } from './gtag-analytics.service';\nimport { MultiAnalyticsService } from './multi-analytics.service';\nimport { PosthogAnalyticsService } from './posthog-analytics.service';\nimport { Injector, Provider } from '@angular/core';\n\nexport interface IAnalyticsConfig {\n addPosthog?: boolean;\n addFirebaseAnalytics?: boolean;\n // GA4 measurement ID for the app's own per-domain property (the same stream\n // its marketing landing uses). When set, a gtag-based GA4 backend is added.\n googleAnalyticsMeasurementId?: string;\n}\n\nfunction getAnalyticsConfig(\n environmentConfig: IEnvironmentConfig,\n): IAnalyticsConfig {\n const useAnalytics =\n location.host === 'sneat.app' || location.protocol === 'https:';\n\n const firebaseMeasurementId = environmentConfig.firebaseConfig?.measurementId;\n const gaMeasurementId = environmentConfig.googleAnalytics?.measurementId;\n\n return {\n addPosthog: useAnalytics && !!environmentConfig.posthog?.token,\n addFirebaseAnalytics:\n useAnalytics &&\n !!firebaseMeasurementId &&\n firebaseMeasurementId !== 'G-PROVIDE_IF_NEEDED',\n googleAnalyticsMeasurementId: useAnalytics ? gaMeasurementId : undefined,\n };\n}\n\nexport function provideSneatAnalytics(\n environmentConfig: IEnvironmentConfig,\n): Provider {\n return {\n provide: AnalyticsService,\n // `Injector` rather than `SNEAT_FIREBASE_ANALYTICS` directly: listing the\n // token in `deps` would resolve it — and so initialize Firebase Analytics —\n // on every app that injects `AnalyticsService`, including the ones where\n // `addFirebaseAnalytics` is false (plain http, non-sneat.app host). Reading\n // it through the injector inside the branch below keeps initialization as\n // lazy as the pre-0.27.0 `getAnalytics(fbApp)` call it replaces.\n deps: [ErrorLogger, Injector],\n useFactory: (errorLogger: IErrorLogger, injector: Injector) => {\n const config = getAnalyticsConfig(environmentConfig);\n const as: IAnalyticsService[] = [];\n if (config?.addPosthog) {\n as.push(new PosthogAnalyticsService());\n }\n if (config?.googleAnalyticsMeasurementId) {\n as.push(new GtagAnalyticsService(config.googleAnalyticsMeasurementId));\n }\n if (config?.addFirebaseAnalytics) {\n const analytics: Analytics | null = injector.get(\n SNEAT_FIREBASE_ANALYTICS,\n null,\n );\n if (analytics) {\n // Constructed inside this factory's injection context, so\n // FireAnalyticsService's own inject(SNEAT_FIREBASE_ANALYTICS)\n // resolves — to this same, already-instantiated instance.\n as.push(new FireAnalyticsService());\n } else {\n errorLogger.logError(\n 'addFirebaseAnalytics==true, but Firebase Analytics is not provided',\n undefined,\n { show: false, feedback: false },\n );\n }\n }\n return new MultiAnalyticsService(as);\n },\n };\n}\n"]}
@@ -2,6 +2,14 @@ import { IAnalyticsCallOptions, IAnalyticsService, UserProperties } from '@sneat
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class FireAnalyticsService implements IAnalyticsService {
4
4
  private readonly errorLogger;
5
+ /**
6
+ * Nullable by contract: `SNEAT_FIREBASE_ANALYTICS` resolves to `null` — it
7
+ * never throws — when the app has no real `measurementId` or when
8
+ * `getAnalytics()` is unsupported in the host environment. Every method
9
+ * below therefore no-ops on `null` instead of reporting a failed SDK call
10
+ * on each event. Before 0.27.0 this injected `@angular/fire`'s `Analytics`
11
+ * token, which threw NullInjectorError in exactly those cases.
12
+ */
5
13
  private readonly analytics;
6
14
  constructor();
7
15
  private readonly logError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sneat/logging",
3
- "version": "0.26.6",
3
+ "version": "0.27.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -8,10 +8,9 @@
8
8
  "@angular/common": ">=22.0.0 <23.0.0",
9
9
  "@angular/core": ">=22.0.0 <23.0.0",
10
10
  "@angular/router": ">=22.0.0 <23.0.0",
11
- "@angular/fire": ">=20",
12
11
  "@ionic/angular": ">=9.0.0 <10.0.0",
13
12
  "@sentry/angular": "*",
14
- "@sneat/core": "^0.26.0",
13
+ "@sneat/core": "^0.27.0",
15
14
  "firebase": "*",
16
15
  "posthog-js": "*",
17
16
  "rxjs": ">=7.8.0"