@equinor/fusion-framework-module-analytics 3.0.1 → 3.0.3

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 (78) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/esm/AnalyticsConfigurator.js +11 -2
  3. package/dist/esm/AnalyticsConfigurator.js.map +1 -1
  4. package/dist/esm/AnalyticsProvider.js +12 -2
  5. package/dist/esm/AnalyticsProvider.js.map +1 -1
  6. package/dist/esm/adapters/ConsoleAnalyticsAdapter.js +7 -1
  7. package/dist/esm/adapters/ConsoleAnalyticsAdapter.js.map +1 -1
  8. package/dist/esm/adapters/FusionAnalyticsAdapter.js +6 -1
  9. package/dist/esm/adapters/FusionAnalyticsAdapter.js.map +1 -1
  10. package/dist/esm/collectors/AppLoadedCollector.js +11 -3
  11. package/dist/esm/collectors/AppLoadedCollector.js.map +1 -1
  12. package/dist/esm/collectors/AppSelectedCollector.js +11 -2
  13. package/dist/esm/collectors/AppSelectedCollector.js.map +1 -1
  14. package/dist/esm/collectors/ContextSelectedCollector.js +11 -2
  15. package/dist/esm/collectors/ContextSelectedCollector.js.map +1 -1
  16. package/dist/esm/collectors/{BaseCollector.js → create-schema.js} +4 -1
  17. package/dist/esm/collectors/create-schema.js.map +1 -0
  18. package/dist/esm/collectors/utils/app-key-schema.js +14 -0
  19. package/dist/esm/collectors/utils/app-key-schema.js.map +1 -0
  20. package/dist/esm/collectors/utils/app-schema.js +19 -0
  21. package/dist/esm/collectors/utils/app-schema.js.map +1 -0
  22. package/dist/esm/collectors/utils/context-schema.js +19 -0
  23. package/dist/esm/collectors/utils/context-schema.js.map +1 -0
  24. package/dist/esm/collectors/utils/extract-app-key-metadata.js +12 -0
  25. package/dist/esm/collectors/utils/extract-app-key-metadata.js.map +1 -0
  26. package/dist/esm/collectors/utils/extract-app-metadata.js +17 -0
  27. package/dist/esm/collectors/utils/extract-app-metadata.js.map +1 -0
  28. package/dist/esm/collectors/utils/extract-context-metadata.js +16 -0
  29. package/dist/esm/collectors/utils/extract-context-metadata.js.map +1 -0
  30. package/dist/esm/enable-analytics.js +1 -0
  31. package/dist/esm/enable-analytics.js.map +1 -1
  32. package/dist/esm/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.js +9 -3
  33. package/dist/esm/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.js.map +1 -1
  34. package/dist/esm/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.js +5 -0
  35. package/dist/esm/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.js.map +1 -1
  36. package/dist/esm/version.js +1 -1
  37. package/dist/tsconfig.tsbuildinfo +1 -1
  38. package/dist/types/AnalyticsConfigurator.d.ts +3 -0
  39. package/dist/types/AnalyticsProvider.d.ts +3 -0
  40. package/dist/types/adapters/ConsoleAnalyticsAdapter.d.ts +7 -1
  41. package/dist/types/adapters/FusionAnalyticsAdapter.d.ts +6 -1
  42. package/dist/types/collectors/AppLoadedCollector.d.ts +9 -3
  43. package/dist/types/collectors/AppSelectedCollector.d.ts +8 -2
  44. package/dist/types/collectors/ContextSelectedCollector.d.ts +8 -2
  45. package/dist/types/collectors/{BaseCollector.d.ts → create-schema.d.ts} +2 -0
  46. package/dist/types/collectors/utils/app-key-schema.d.ts +12 -0
  47. package/dist/types/collectors/utils/app-schema.d.ts +18 -0
  48. package/dist/types/collectors/utils/{extractContextMetadata.d.ts → context-schema.d.ts} +0 -8
  49. package/dist/types/collectors/utils/extract-app-key-metadata.d.ts +10 -0
  50. package/dist/types/collectors/utils/extract-app-metadata.d.ts +10 -0
  51. package/dist/types/collectors/utils/extract-context-metadata.d.ts +10 -0
  52. package/dist/types/version.d.ts +1 -1
  53. package/package.json +14 -14
  54. package/src/AnalyticsConfigurator.ts +7 -0
  55. package/src/AnalyticsProvider.ts +12 -2
  56. package/src/adapters/ConsoleAnalyticsAdapter.ts +7 -1
  57. package/src/adapters/FusionAnalyticsAdapter.ts +6 -1
  58. package/src/collectors/AppLoadedCollector.ts +11 -7
  59. package/src/collectors/AppSelectedCollector.ts +11 -6
  60. package/src/collectors/ContextSelectedCollector.ts +11 -6
  61. package/src/collectors/{BaseCollector.ts → create-schema.ts} +3 -0
  62. package/src/collectors/utils/app-key-schema.ts +17 -0
  63. package/src/collectors/utils/app-schema.ts +22 -0
  64. package/src/collectors/utils/{extractContextMetadata.ts → context-schema.ts} +0 -17
  65. package/src/collectors/utils/extract-app-key-metadata.ts +15 -0
  66. package/src/collectors/utils/extract-app-metadata.ts +20 -0
  67. package/src/collectors/utils/extract-context-metadata.ts +19 -0
  68. package/src/enable-analytics.ts +1 -0
  69. package/src/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.ts +9 -1
  70. package/src/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.ts +5 -0
  71. package/src/version.ts +1 -1
  72. package/dist/esm/collectors/BaseCollector.js.map +0 -1
  73. package/dist/esm/collectors/utils/extractAppMetadata.js +0 -58
  74. package/dist/esm/collectors/utils/extractAppMetadata.js.map +0 -1
  75. package/dist/esm/collectors/utils/extractContextMetadata.js +0 -34
  76. package/dist/esm/collectors/utils/extractContextMetadata.js.map +0 -1
  77. package/dist/types/collectors/utils/extractAppMetadata.d.ts +0 -44
  78. package/src/collectors/utils/extractAppMetadata.ts +0 -68
@@ -0,0 +1,19 @@
1
+ import type { ContextItem } from '@equinor/fusion-framework-module-context';
2
+ import type { z } from 'zod';
3
+ import type { contextSchema } from './context-schema.js';
4
+
5
+ /**
6
+ * Extracts context metadata from a `ContextItem` for analytics events.
7
+ *
8
+ * @param context - The Fusion context item.
9
+ * @returns An object with id, type, and optional title, externalId, and source.
10
+ */
11
+ export const extractContextMetadata = (context: ContextItem): z.input<typeof contextSchema> => {
12
+ return {
13
+ id: context.id,
14
+ externalId: context.externalId ?? undefined,
15
+ title: context.title ?? undefined,
16
+ type: context.type.id,
17
+ source: context.source ?? undefined,
18
+ };
19
+ };
@@ -35,6 +35,7 @@ export const enableAnalytics = (
35
35
  configurator.addConfig({
36
36
  module,
37
37
  configure: async (builder) => {
38
+ // Only invoke the callback when one was supplied by the caller
38
39
  if (callback) {
39
40
  await Promise.resolve(callback(builder));
40
41
  }
@@ -1,9 +1,10 @@
1
1
  import type { LogRecordExporter, ReadableLogRecord } from '@opentelemetry/sdk-logs';
2
2
 
3
- import { JsonLogsSerializer } from '@opentelemetry/otlp-transformer';
3
+ import { JsonLogsSerializer, LogsExporterMetricsHelper } from '@opentelemetry/otlp-transformer';
4
4
 
5
5
  import {
6
6
  createOtlpNetworkExportDelegate,
7
+ ExporterMetrics,
7
8
  OTLPExporterBase,
8
9
  type OtlpSharedConfiguration,
9
10
  } from '@opentelemetry/otlp-exporter-base';
@@ -56,6 +57,13 @@ export class FusionOTLPLogExporter
56
57
  createOtlpNetworkExportDelegate(
57
58
  getSharedConfigurationDefaults(),
58
59
  JsonLogsSerializer,
60
+ new ExporterMetrics({
61
+ componentType: 'fusion_otlp_http_log_exporter',
62
+ metricsHelper: LogsExporterMetricsHelper,
63
+ url: undefined,
64
+ meterProvider: undefined,
65
+ responseAttributesFromError: () => ({}),
66
+ }),
59
67
  new HttpClientExporterTransport(httpClient),
60
68
  ),
61
69
  );
@@ -25,17 +25,20 @@ function isExportRetryable(statusCode: number): boolean {
25
25
  * @returns Delay in milliseconds, `-1` for non-positive integers, or `undefined` if absent.
26
26
  */
27
27
  function parseRetryAfterToMills(retryAfter?: string | undefined | null): number | undefined {
28
+ // No header present — nothing to compute
28
29
  if (retryAfter == null) {
29
30
  return undefined;
30
31
  }
31
32
 
32
33
  const seconds = Number.parseInt(retryAfter, 10);
34
+ // Retry-After given as a plain integer number of seconds
33
35
  if (Number.isInteger(seconds)) {
34
36
  return seconds > 0 ? seconds * 1000 : -1;
35
37
  }
36
38
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After#directives
37
39
  const delay = new Date(retryAfter).getTime() - Date.now();
38
40
 
41
+ // Only report a positive delay; a past date means retry is already due
39
42
  if (delay >= 0) {
40
43
  return delay;
41
44
  }
@@ -84,6 +87,7 @@ export class HttpClientExporterTransport implements IExporterTransport {
84
87
  signal: abortController.signal,
85
88
  });
86
89
 
90
+ // A 2xx response means the export succeeded outright
87
91
  if (response.ok) {
88
92
  return { status: 'success' };
89
93
  } else if (isExportRetryable(response.status)) {
@@ -97,6 +101,7 @@ export class HttpClientExporterTransport implements IExporterTransport {
97
101
  };
98
102
  } catch (error) {
99
103
  const err = error as Error;
104
+ // Distinguish a timeout (AbortController fired) from other fetch failures
100
105
  if (err?.name === 'AbortError') {
101
106
  return {
102
107
  status: 'failure',
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '3.0.1';
2
+ export const version = '3.0.3';
@@ -1 +0,0 @@
1
- {"version":3,"file":"BaseCollector.js","sourceRoot":"","sources":["../../../src/collectors/BaseCollector.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAwB,OAAO,EAAsC,MAAM,MAAM,CAAC;AACpG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAA0B,EAC1B,UAA8B,EAC9B,EAAE;IACF,OAAO,CAAC,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE;KAClC,CAAC,CAAC;AACL,CAAC,CAAC;AAOF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAgB,aAAa;IAKjC,OAAO,CAAiC;IACxC,KAAK,CAAS;IACd,QAAQ,GAAqD,IAAI,OAAO,EAErE,CAAC;IAEJ;;;;;OAKG;IACH,YAAY,IAAY,EAAE,MAAsC;QAC9D,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAaD;;;;OAIG;IACH,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;aACrB,IAAI,CACH,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE;YAC5B,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,KAAK;gBAChB,KAAK,EAAE,KAAK;gBACZ,UAAU,EAAE,UAAU;aACvB,CAAC;QACJ,CAAC,CAAC,EACF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAClC;aACA,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,QAAoE;QAC5E,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;CACF"}
@@ -1,58 +0,0 @@
1
- import { z } from 'zod';
2
- /**
3
- * Zod schema for an object containing an optional `appKey` string.
4
- *
5
- * @remarks
6
- * Used by {@link AppSelectedCollector} to validate the event body.
7
- */
8
- export const appKeySchema = z
9
- .object({
10
- appKey: z.string().optional(),
11
- })
12
- .optional()
13
- .nullable();
14
- /**
15
- * Zod schema for a Fusion application metadata object.
16
- *
17
- * @remarks
18
- * Validates core app fields (appKey, displayName, type) and optional build
19
- * and category information. Used by {@link AppLoadedCollector}.
20
- */
21
- export const appSchema = z
22
- .object({
23
- appKey: z.string(),
24
- displayName: z.string(),
25
- type: z.string(),
26
- categoryName: z.string().optional(),
27
- buildVersion: z.string().optional(),
28
- buildTag: z.string().optional().nullable(),
29
- })
30
- .optional();
31
- /**
32
- * Extracts app-key metadata from a `CurrentApp` instance.
33
- *
34
- * @param app - The current app object.
35
- * @returns An object containing the optional `appKey`.
36
- */
37
- export const extractAppKeyMetadata = (app) => {
38
- return {
39
- appKey: app?.appKey,
40
- };
41
- };
42
- /**
43
- * Extracts detailed app metadata from an `AppManifest` for analytics events.
44
- *
45
- * @param app - The application manifest.
46
- * @returns An object with appKey, displayName, type, and optional build/category info.
47
- */
48
- export const extractAppMetadata = (app) => {
49
- return {
50
- appKey: app.appKey,
51
- displayName: app.displayName,
52
- type: app.type,
53
- categoryName: app.category?.name,
54
- buildVersion: app.build?.version,
55
- buildTag: app.build?.tag,
56
- };
57
- };
58
- //# sourceMappingURL=extractAppMetadata.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extractAppMetadata.js","sourceRoot":"","sources":["../../../../src/collectors/utils/extractAppMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC;KACD,QAAQ,EAAE;KACV,QAAQ,EAAE,CAAC;AAEd;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC;KACD,QAAQ,EAAE,CAAC;AAQd;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAe,EAAgC,EAAE;IACrF,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,MAAM;KACpB,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAgB,EAA6B,EAAE;IAChF,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,YAAY,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI;QAChC,YAAY,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO;QAChC,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG;KACzB,CAAC;AACJ,CAAC,CAAC"}
@@ -1,34 +0,0 @@
1
- import { z } from 'zod';
2
- /**
3
- * Zod schema for a Fusion context metadata object.
4
- *
5
- * @remarks
6
- * Validates core context fields (id, type) and optional title, externalId,
7
- * and source. Used by {@link ContextSelectedCollector} and {@link AppLoadedCollector}.
8
- */
9
- export const contextSchema = z
10
- .object({
11
- id: z.string(),
12
- type: z.string(),
13
- title: z.string().optional(),
14
- externalId: z.string().optional(),
15
- source: z.string().optional(),
16
- })
17
- .optional()
18
- .nullable();
19
- /**
20
- * Extracts context metadata from a `ContextItem` for analytics events.
21
- *
22
- * @param context - The Fusion context item.
23
- * @returns An object with id, type, and optional title, externalId, and source.
24
- */
25
- export const extractContextMetadata = (context) => {
26
- return {
27
- id: context.id,
28
- externalId: context.externalId ?? undefined,
29
- title: context.title ?? undefined,
30
- type: context.type.id,
31
- source: context.source ?? undefined,
32
- };
33
- };
34
- //# sourceMappingURL=extractContextMetadata.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extractContextMetadata.js","sourceRoot":"","sources":["../../../../src/collectors/utils/extractContextMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC;KACD,QAAQ,EAAE;KACV,QAAQ,EAAE,CAAC;AAKd;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAoB,EAAiC,EAAE;IAC5F,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,SAAS;QAC3C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS;QACjC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;QACrB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,SAAS;KACpC,CAAC;AACJ,CAAC,CAAC"}
@@ -1,44 +0,0 @@
1
- import { z } from 'zod';
2
- import type { AppManifest, CurrentApp } from '@equinor/fusion-framework-module-app';
3
- /**
4
- * Zod schema for an object containing an optional `appKey` string.
5
- *
6
- * @remarks
7
- * Used by {@link AppSelectedCollector} to validate the event body.
8
- */
9
- export declare const appKeySchema: z.ZodNullable<z.ZodOptional<z.ZodObject<{
10
- appKey: z.ZodOptional<z.ZodString>;
11
- }, z.core.$strip>>>;
12
- /**
13
- * Zod schema for a Fusion application metadata object.
14
- *
15
- * @remarks
16
- * Validates core app fields (appKey, displayName, type) and optional build
17
- * and category information. Used by {@link AppLoadedCollector}.
18
- */
19
- export declare const appSchema: z.ZodOptional<z.ZodObject<{
20
- appKey: z.ZodString;
21
- displayName: z.ZodString;
22
- type: z.ZodString;
23
- categoryName: z.ZodOptional<z.ZodString>;
24
- buildVersion: z.ZodOptional<z.ZodString>;
25
- buildTag: z.ZodNullable<z.ZodOptional<z.ZodString>>;
26
- }, z.core.$strip>>;
27
- /** Inferred type from {@link appKeySchema}. */
28
- export type AppKeyType = z.infer<typeof appKeySchema>;
29
- /** Inferred type from {@link appSchema}. */
30
- export type AppItemType = z.infer<typeof appSchema>;
31
- /**
32
- * Extracts app-key metadata from a `CurrentApp` instance.
33
- *
34
- * @param app - The current app object.
35
- * @returns An object containing the optional `appKey`.
36
- */
37
- export declare const extractAppKeyMetadata: (app: CurrentApp) => z.input<typeof appKeySchema>;
38
- /**
39
- * Extracts detailed app metadata from an `AppManifest` for analytics events.
40
- *
41
- * @param app - The application manifest.
42
- * @returns An object with appKey, displayName, type, and optional build/category info.
43
- */
44
- export declare const extractAppMetadata: (app: AppManifest) => z.input<typeof appSchema>;
@@ -1,68 +0,0 @@
1
- import { z } from 'zod';
2
- import type { AppManifest, CurrentApp } from '@equinor/fusion-framework-module-app';
3
-
4
- /**
5
- * Zod schema for an object containing an optional `appKey` string.
6
- *
7
- * @remarks
8
- * Used by {@link AppSelectedCollector} to validate the event body.
9
- */
10
- export const appKeySchema = z
11
- .object({
12
- appKey: z.string().optional(),
13
- })
14
- .optional()
15
- .nullable();
16
-
17
- /**
18
- * Zod schema for a Fusion application metadata object.
19
- *
20
- * @remarks
21
- * Validates core app fields (appKey, displayName, type) and optional build
22
- * and category information. Used by {@link AppLoadedCollector}.
23
- */
24
- export const appSchema = z
25
- .object({
26
- appKey: z.string(),
27
- displayName: z.string(),
28
- type: z.string(),
29
- categoryName: z.string().optional(),
30
- buildVersion: z.string().optional(),
31
- buildTag: z.string().optional().nullable(),
32
- })
33
- .optional();
34
-
35
- /** Inferred type from {@link appKeySchema}. */
36
- export type AppKeyType = z.infer<typeof appKeySchema>;
37
-
38
- /** Inferred type from {@link appSchema}. */
39
- export type AppItemType = z.infer<typeof appSchema>;
40
-
41
- /**
42
- * Extracts app-key metadata from a `CurrentApp` instance.
43
- *
44
- * @param app - The current app object.
45
- * @returns An object containing the optional `appKey`.
46
- */
47
- export const extractAppKeyMetadata = (app: CurrentApp): z.input<typeof appKeySchema> => {
48
- return {
49
- appKey: app?.appKey,
50
- };
51
- };
52
-
53
- /**
54
- * Extracts detailed app metadata from an `AppManifest` for analytics events.
55
- *
56
- * @param app - The application manifest.
57
- * @returns An object with appKey, displayName, type, and optional build/category info.
58
- */
59
- export const extractAppMetadata = (app: AppManifest): z.input<typeof appSchema> => {
60
- return {
61
- appKey: app.appKey,
62
- displayName: app.displayName,
63
- type: app.type,
64
- categoryName: app.category?.name,
65
- buildVersion: app.build?.version,
66
- buildTag: app.build?.tag,
67
- };
68
- };