medusa-stats 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/.medusa/server/src/admin/composite.png +0 -0
  2. package/.medusa/server/src/admin/index.js +10512 -0
  3. package/.medusa/server/src/admin/index.mjs +10510 -0
  4. package/.medusa/server/src/admin/params.png +0 -0
  5. package/.medusa/server/src/admin/view.png +0 -0
  6. package/.medusa/server/src/admin/visualizations.png +0 -0
  7. package/.medusa/server/src/api/admin/statistics/alert-logs/[id]/route.d.ts +6 -0
  8. package/.medusa/server/src/api/admin/statistics/alert-logs/[id]/route.js +18 -0
  9. package/.medusa/server/src/api/admin/statistics/alert-logs/route.d.ts +6 -0
  10. package/.medusa/server/src/api/admin/statistics/alert-logs/route.js +33 -0
  11. package/.medusa/server/src/api/admin/statistics/alerts/[id]/logs/route.d.ts +6 -0
  12. package/.medusa/server/src/api/admin/statistics/alerts/[id]/logs/route.js +23 -0
  13. package/.medusa/server/src/api/admin/statistics/alerts/[id]/route.d.ts +17 -0
  14. package/.medusa/server/src/api/admin/statistics/alerts/[id]/route.js +64 -0
  15. package/.medusa/server/src/api/admin/statistics/alerts/[id]/toggle/route.d.ts +6 -0
  16. package/.medusa/server/src/api/admin/statistics/alerts/[id]/toggle/route.js +18 -0
  17. package/.medusa/server/src/api/admin/statistics/alerts/route.d.ts +12 -0
  18. package/.medusa/server/src/api/admin/statistics/alerts/route.js +94 -0
  19. package/.medusa/server/src/api/admin/statistics/charts/[id]/route.d.ts +17 -0
  20. package/.medusa/server/src/api/admin/statistics/charts/[id]/route.js +50 -0
  21. package/.medusa/server/src/api/admin/statistics/charts/[id]/statistics/route.d.ts +15 -0
  22. package/.medusa/server/src/api/admin/statistics/charts/[id]/statistics/route.js +40 -0
  23. package/.medusa/server/src/api/admin/statistics/charts/route.d.ts +4 -0
  24. package/.medusa/server/src/api/admin/statistics/charts/route.js +55 -0
  25. package/.medusa/server/src/api/admin/statistics/options/[id]/calculate/route.d.ts +7 -0
  26. package/.medusa/server/src/api/admin/statistics/options/[id]/calculate/route.js +23 -0
  27. package/.medusa/server/src/api/admin/statistics/options/[id]/clone/route.d.ts +7 -0
  28. package/.medusa/server/src/api/admin/statistics/options/[id]/clone/route.js +15 -0
  29. package/.medusa/server/src/api/admin/statistics/options/[id]/route.d.ts +17 -0
  30. package/.medusa/server/src/api/admin/statistics/options/[id]/route.js +69 -0
  31. package/.medusa/server/src/api/admin/statistics/options/route.d.ts +12 -0
  32. package/.medusa/server/src/api/admin/statistics/options/route.js +87 -0
  33. package/.medusa/server/src/api/admin/statistics/providers/[id]/route.d.ts +6 -0
  34. package/.medusa/server/src/api/admin/statistics/providers/[id]/route.js +18 -0
  35. package/.medusa/server/src/api/admin/statistics/providers/[id]/statistics/route.d.ts +6 -0
  36. package/.medusa/server/src/api/admin/statistics/providers/[id]/statistics/route.js +18 -0
  37. package/.medusa/server/src/api/admin/statistics/providers/route.d.ts +7 -0
  38. package/.medusa/server/src/api/admin/statistics/providers/route.js +57 -0
  39. package/.medusa/server/src/api/admin/statistics/utils/option-graph.d.ts +3 -0
  40. package/.medusa/server/src/api/admin/statistics/utils/option-graph.js +34 -0
  41. package/.medusa/server/src/api/admin/statistics/views/[id]/calculate/route.d.ts +7 -0
  42. package/.medusa/server/src/api/admin/statistics/views/[id]/calculate/route.js +21 -0
  43. package/.medusa/server/src/api/admin/statistics/views/[id]/clone/route.d.ts +7 -0
  44. package/.medusa/server/src/api/admin/statistics/views/[id]/clone/route.js +21 -0
  45. package/.medusa/server/src/api/admin/statistics/views/[id]/route.d.ts +17 -0
  46. package/.medusa/server/src/api/admin/statistics/views/[id]/route.js +71 -0
  47. package/.medusa/server/src/api/admin/statistics/views/route.d.ts +12 -0
  48. package/.medusa/server/src/api/admin/statistics/views/route.js +74 -0
  49. package/.medusa/server/src/api/middlewares.d.ts +2 -0
  50. package/.medusa/server/src/api/middlewares.js +194 -0
  51. package/.medusa/server/src/api/validation/statistics/schemas.d.ts +1013 -0
  52. package/.medusa/server/src/api/validation/statistics/schemas.js +288 -0
  53. package/.medusa/server/src/index.d.ts +1 -0
  54. package/.medusa/server/src/index.js +18 -0
  55. package/.medusa/server/src/jobs/evaluate-statistics-alerts.d.ts +6 -0
  56. package/.medusa/server/src/jobs/evaluate-statistics-alerts.js +110 -0
  57. package/.medusa/server/src/links/statistics-alert-user.d.ts +2 -0
  58. package/.medusa/server/src/links/statistics-alert-user.js +16 -0
  59. package/.medusa/server/src/links/statistics-option-user.d.ts +2 -0
  60. package/.medusa/server/src/links/statistics-option-user.js +16 -0
  61. package/.medusa/server/src/loaders/statistics/index.d.ts +5 -0
  62. package/.medusa/server/src/loaders/statistics/index.js +47 -0
  63. package/.medusa/server/src/modules/statistics/index.d.ts +107 -0
  64. package/.medusa/server/src/modules/statistics/index.js +32 -0
  65. package/.medusa/server/src/modules/statistics/migrations/Migration20260223131741.d.ts +5 -0
  66. package/.medusa/server/src/modules/statistics/migrations/Migration20260223131741.js +57 -0
  67. package/.medusa/server/src/modules/statistics/models/alert-log.d.ts +74 -0
  68. package/.medusa/server/src/modules/statistics/models/alert-log.js +16 -0
  69. package/.medusa/server/src/modules/statistics/models/alert.d.ts +74 -0
  70. package/.medusa/server/src/modules/statistics/models/alert.js +24 -0
  71. package/.medusa/server/src/modules/statistics/models/chart.d.ts +81 -0
  72. package/.medusa/server/src/modules/statistics/models/chart.js +28 -0
  73. package/.medusa/server/src/modules/statistics/models/index.d.ts +7 -0
  74. package/.medusa/server/src/modules/statistics/models/index.js +24 -0
  75. package/.medusa/server/src/modules/statistics/models/option-input.d.ts +135 -0
  76. package/.medusa/server/src/modules/statistics/models/option-input.js +27 -0
  77. package/.medusa/server/src/modules/statistics/models/option.d.ts +78 -0
  78. package/.medusa/server/src/modules/statistics/models/option.js +41 -0
  79. package/.medusa/server/src/modules/statistics/models/provider.d.ts +75 -0
  80. package/.medusa/server/src/modules/statistics/models/provider.js +15 -0
  81. package/.medusa/server/src/modules/statistics/models/view.d.ts +79 -0
  82. package/.medusa/server/src/modules/statistics/models/view.js +30 -0
  83. package/.medusa/server/src/modules/statistics/providers/index.d.ts +1 -0
  84. package/.medusa/server/src/modules/statistics/providers/index.js +18 -0
  85. package/.medusa/server/src/modules/statistics/providers/provider.d.ts +254 -0
  86. package/.medusa/server/src/modules/statistics/providers/provider.js +307 -0
  87. package/.medusa/server/src/modules/statistics/service.d.ts +953 -0
  88. package/.medusa/server/src/modules/statistics/service.js +190 -0
  89. package/.medusa/server/src/modules/statistics/utils/dependency-option-map.d.ts +13 -0
  90. package/.medusa/server/src/modules/statistics/utils/dependency-option-map.js +67 -0
  91. package/.medusa/server/src/modules/statistics/utils/period-utils.d.ts +23 -0
  92. package/.medusa/server/src/modules/statistics/utils/period-utils.js +78 -0
  93. package/.medusa/server/src/modules/statistics/utils/time-series-utils.d.ts +6 -0
  94. package/.medusa/server/src/modules/statistics/utils/time-series-utils.js +8 -0
  95. package/.medusa/server/src/providers/common/index.d.ts +2 -0
  96. package/.medusa/server/src/providers/common/index.js +1232 -0
  97. package/.medusa/server/src/providers/composite/index.d.ts +2 -0
  98. package/.medusa/server/src/providers/composite/index.js +147 -0
  99. package/.medusa/server/src/workflows/statistics/calculate-single-statistic.d.ts +15 -0
  100. package/.medusa/server/src/workflows/statistics/calculate-single-statistic.js +28 -0
  101. package/.medusa/server/src/workflows/statistics/calculate-statistics.d.ts +20 -0
  102. package/.medusa/server/src/workflows/statistics/calculate-statistics.js +15 -0
  103. package/.medusa/server/src/workflows/statistics/calculate-view.d.ts +31 -0
  104. package/.medusa/server/src/workflows/statistics/calculate-view.js +30 -0
  105. package/.medusa/server/src/workflows/statistics/clone-view.d.ts +227 -0
  106. package/.medusa/server/src/workflows/statistics/clone-view.js +10 -0
  107. package/.medusa/server/src/workflows/statistics/create-alert.d.ts +139 -0
  108. package/.medusa/server/src/workflows/statistics/create-alert.js +12 -0
  109. package/.medusa/server/src/workflows/statistics/create-chart.d.ts +122 -0
  110. package/.medusa/server/src/workflows/statistics/create-chart.js +14 -0
  111. package/.medusa/server/src/workflows/statistics/create-view-with-options.d.ts +1342 -0
  112. package/.medusa/server/src/workflows/statistics/create-view-with-options.js +29 -0
  113. package/.medusa/server/src/workflows/statistics/delete-chart.d.ts +10 -0
  114. package/.medusa/server/src/workflows/statistics/delete-chart.js +14 -0
  115. package/.medusa/server/src/workflows/statistics/evaluate-alerts.d.ts +28 -0
  116. package/.medusa/server/src/workflows/statistics/evaluate-alerts.js +67 -0
  117. package/.medusa/server/src/workflows/statistics/get-available-statistics.d.ts +5 -0
  118. package/.medusa/server/src/workflows/statistics/get-available-statistics.js +10 -0
  119. package/.medusa/server/src/workflows/statistics/index.d.ts +14 -0
  120. package/.medusa/server/src/workflows/statistics/index.js +31 -0
  121. package/.medusa/server/src/workflows/statistics/manage-chart-statistics.d.ts +12 -0
  122. package/.medusa/server/src/workflows/statistics/manage-chart-statistics.js +14 -0
  123. package/.medusa/server/src/workflows/statistics/steps/calculate-statistics.d.ts +37 -0
  124. package/.medusa/server/src/workflows/statistics/steps/calculate-statistics.js +222 -0
  125. package/.medusa/server/src/workflows/statistics/steps/clone-view.d.ts +227 -0
  126. package/.medusa/server/src/workflows/statistics/steps/clone-view.js +39 -0
  127. package/.medusa/server/src/workflows/statistics/steps/create-alert-log-entries.d.ts +17 -0
  128. package/.medusa/server/src/workflows/statistics/steps/create-alert-log-entries.js +50 -0
  129. package/.medusa/server/src/workflows/statistics/steps/create-alert.d.ts +120 -0
  130. package/.medusa/server/src/workflows/statistics/steps/create-alert.js +21 -0
  131. package/.medusa/server/src/workflows/statistics/steps/create-chart.d.ts +118 -0
  132. package/.medusa/server/src/workflows/statistics/steps/create-chart.js +19 -0
  133. package/.medusa/server/src/workflows/statistics/steps/create-statistics-options.d.ts +117 -0
  134. package/.medusa/server/src/workflows/statistics/steps/create-statistics-options.js +16 -0
  135. package/.medusa/server/src/workflows/statistics/steps/create-statistics-view.d.ts +119 -0
  136. package/.medusa/server/src/workflows/statistics/steps/create-statistics-view.js +16 -0
  137. package/.medusa/server/src/workflows/statistics/steps/dedupe-alerts.d.ts +22 -0
  138. package/.medusa/server/src/workflows/statistics/steps/dedupe-alerts.js +64 -0
  139. package/.medusa/server/src/workflows/statistics/steps/delete-chart.d.ts +6 -0
  140. package/.medusa/server/src/workflows/statistics/steps/delete-chart.js +17 -0
  141. package/.medusa/server/src/workflows/statistics/steps/emit-alert-events.d.ts +17 -0
  142. package/.medusa/server/src/workflows/statistics/steps/emit-alert-events.js +41 -0
  143. package/.medusa/server/src/workflows/statistics/steps/evaluate-each-condition.d.ts +15 -0
  144. package/.medusa/server/src/workflows/statistics/steps/evaluate-each-condition.js +109 -0
  145. package/.medusa/server/src/workflows/statistics/steps/extract-alert-values.d.ts +12 -0
  146. package/.medusa/server/src/workflows/statistics/steps/extract-alert-values.js +86 -0
  147. package/.medusa/server/src/workflows/statistics/steps/fetch-active-alerts-for-option.d.ts +112 -0
  148. package/.medusa/server/src/workflows/statistics/steps/fetch-active-alerts-for-option.js +16 -0
  149. package/.medusa/server/src/workflows/statistics/steps/fetch-available-statistics.d.ts +4 -0
  150. package/.medusa/server/src/workflows/statistics/steps/fetch-available-statistics.js +39 -0
  151. package/.medusa/server/src/workflows/statistics/steps/fetch-option-with-relations.d.ts +112 -0
  152. package/.medusa/server/src/workflows/statistics/steps/fetch-option-with-relations.js +11 -0
  153. package/.medusa/server/src/workflows/statistics/steps/fetch-view-with-options.d.ts +112 -0
  154. package/.medusa/server/src/workflows/statistics/steps/fetch-view-with-options.js +20 -0
  155. package/.medusa/server/src/workflows/statistics/steps/manage-chart-statistics.d.ts +8 -0
  156. package/.medusa/server/src/workflows/statistics/steps/manage-chart-statistics.js +26 -0
  157. package/.medusa/server/src/workflows/statistics/steps/update-chart.d.ts +117 -0
  158. package/.medusa/server/src/workflows/statistics/steps/update-chart.js +32 -0
  159. package/.medusa/server/src/workflows/statistics/steps/update-view.d.ts +120 -0
  160. package/.medusa/server/src/workflows/statistics/steps/update-view.js +18 -0
  161. package/.medusa/server/src/workflows/statistics/steps/validate-alert-input.d.ts +1 -0
  162. package/.medusa/server/src/workflows/statistics/steps/validate-alert-input.js +34 -0
  163. package/.medusa/server/src/workflows/statistics/steps/validate-option-parameters.d.ts +21 -0
  164. package/.medusa/server/src/workflows/statistics/steps/validate-option-parameters.js +43 -0
  165. package/.medusa/server/src/workflows/statistics/steps/validate-view-input.d.ts +10 -0
  166. package/.medusa/server/src/workflows/statistics/steps/validate-view-input.js +15 -0
  167. package/.medusa/server/src/workflows/statistics/update-chart.d.ts +120 -0
  168. package/.medusa/server/src/workflows/statistics/update-chart.js +13 -0
  169. package/.medusa/server/src/workflows/statistics/update-view-configuration.d.ts +128 -0
  170. package/.medusa/server/src/workflows/statistics/update-view-configuration.js +18 -0
  171. package/.medusa/server/src/workflows/statistics/utils/cache-utils.d.ts +60 -0
  172. package/.medusa/server/src/workflows/statistics/utils/cache-utils.js +66 -0
  173. package/.medusa/server/src/workflows/statistics/utils/dependency-graph.d.ts +51 -0
  174. package/.medusa/server/src/workflows/statistics/utils/dependency-graph.js +131 -0
  175. package/.medusa/server/src/workflows/statistics/utils/parameter-utils.d.ts +54 -0
  176. package/.medusa/server/src/workflows/statistics/utils/parameter-utils.js +147 -0
  177. package/.medusa/server/src/workflows/statistics/validate-option-configuration.d.ts +9 -0
  178. package/.medusa/server/src/workflows/statistics/validate-option-configuration.js +35 -0
  179. package/README.md +310 -0
  180. package/package.json +87 -0
@@ -0,0 +1,128 @@
1
+ export interface UpdateViewConfigurationInput {
2
+ id: string;
3
+ name?: string;
4
+ description?: string;
5
+ stats_data?: Record<string, any>;
6
+ layout_config?: Record<string, any>;
7
+ metadata?: Record<string, any>;
8
+ period_type?: "rolling" | "calendar" | "custom";
9
+ period_config?: Record<string, any>;
10
+ interval?: number;
11
+ }
12
+ /**
13
+ * Updates a statistics view configuration.
14
+ *
15
+ * Note: Cached statistics are not automatically invalidated when view configuration changes.
16
+ * Cache invalidation requires specific state parameters (periodStart, periodEnd, interval).
17
+ * Cached data will expire naturally via TTL (600s), or can be manually invalidated via
18
+ * the cache invalidation endpoint with specific state parameters if immediate refresh is needed.
19
+ */
20
+ export declare const updateViewConfigurationWorkflow: import("@medusajs/framework/workflows-sdk").ReturnWorkflow<UpdateViewConfigurationInput, {
21
+ id: string;
22
+ name: string;
23
+ description: string | null;
24
+ charts: {
25
+ id: string;
26
+ name: string;
27
+ description: string | null;
28
+ visualization_config: Record<string, unknown> | null;
29
+ layout: Record<string, unknown> | null;
30
+ view: /*elided*/ any;
31
+ statistics: {
32
+ id: string;
33
+ provider_option_name: string;
34
+ local_option_name: string;
35
+ data: Record<string, unknown>;
36
+ visualization_config: Record<string, unknown> | null;
37
+ cache_options: Record<string, unknown> | null;
38
+ parameter_config: Record<string, unknown> | null;
39
+ preset: boolean;
40
+ provider: {
41
+ id: string;
42
+ display_name: string;
43
+ is_enabled: boolean;
44
+ options: /*elided*/ any[];
45
+ created_at: Date;
46
+ updated_at: Date;
47
+ deleted_at: Date | null;
48
+ };
49
+ alerts: {
50
+ id: string;
51
+ name: string;
52
+ description: string | null;
53
+ option: /*elided*/ any;
54
+ condition: Record<string, unknown>;
55
+ period: Record<string, unknown> | null;
56
+ interval: number;
57
+ severity: "info" | "warning" | "critical";
58
+ is_enabled: boolean;
59
+ metadata: Record<string, unknown> | null;
60
+ logs: {
61
+ id: string;
62
+ alert: /*elided*/ any;
63
+ triggered_at: Date;
64
+ evaluation_data: Record<string, unknown>;
65
+ evaluation_hash: string;
66
+ metadata: Record<string, unknown> | null;
67
+ created_at: Date;
68
+ updated_at: Date;
69
+ deleted_at: Date | null;
70
+ alert_id: string;
71
+ }[];
72
+ created_at: Date;
73
+ updated_at: Date;
74
+ deleted_at: Date | null;
75
+ option_id: string;
76
+ }[];
77
+ charts: /*elided*/ any[];
78
+ input_dependencies: {
79
+ id: string;
80
+ composite_option: /*elided*/ any;
81
+ input_option: /*elided*/ any;
82
+ parameter_name: string | null;
83
+ order: number | null;
84
+ metadata: Record<string, unknown> | null;
85
+ raw_order: Record<string, unknown> | null;
86
+ created_at: Date;
87
+ updated_at: Date;
88
+ deleted_at: Date | null;
89
+ composite_option_id: string;
90
+ input_option_id: string;
91
+ }[];
92
+ dependent_composites: {
93
+ id: string;
94
+ composite_option: /*elided*/ any;
95
+ input_option: /*elided*/ any;
96
+ parameter_name: string | null;
97
+ order: number | null;
98
+ metadata: Record<string, unknown> | null;
99
+ raw_order: Record<string, unknown> | null;
100
+ created_at: Date;
101
+ updated_at: Date;
102
+ deleted_at: Date | null;
103
+ composite_option_id: string;
104
+ input_option_id: string;
105
+ }[];
106
+ created_at: Date;
107
+ updated_at: Date;
108
+ deleted_at: Date | null;
109
+ provider_id: string;
110
+ }[];
111
+ metadata: Record<string, unknown>;
112
+ created_at: Date;
113
+ updated_at: Date;
114
+ deleted_at: Date | null;
115
+ view_id: string;
116
+ }[];
117
+ stats_data: Record<string, unknown> | null;
118
+ period_type: "rolling" | "calendar" | "custom" | null;
119
+ period_config: Record<string, unknown> | null;
120
+ interval: number | null;
121
+ cache_options: Record<string, unknown> | null;
122
+ layout_config: Record<string, unknown>;
123
+ metadata: Record<string, unknown>;
124
+ raw_interval: Record<string, unknown> | null;
125
+ created_at: Date;
126
+ updated_at: Date;
127
+ deleted_at: Date | null;
128
+ } | null, []>;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateViewConfigurationWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const update_view_1 = require("./steps/update-view");
6
+ /**
7
+ * Updates a statistics view configuration.
8
+ *
9
+ * Note: Cached statistics are not automatically invalidated when view configuration changes.
10
+ * Cache invalidation requires specific state parameters (periodStart, periodEnd, interval).
11
+ * Cached data will expire naturally via TTL (600s), or can be manually invalidated via
12
+ * the cache invalidation endpoint with specific state parameters if immediate refresh is needed.
13
+ */
14
+ exports.updateViewConfigurationWorkflow = (0, workflows_sdk_1.createWorkflow)("update-stat-view-configuration", (input) => {
15
+ const updatedViewResult = (0, update_view_1.updateViewStep)(input);
16
+ return new workflows_sdk_1.WorkflowResponse(updatedViewResult.length ? updatedViewResult[0] : null);
17
+ });
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlLXZpZXctY29uZmlndXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3Mvc3RhdGlzdGljcy91cGRhdGUtdmlldy1jb25maWd1cmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUFxRjtBQUVyRixxREFBcUQ7QUFjckQ7Ozs7Ozs7R0FPRztBQUNVLFFBQUEsK0JBQStCLEdBQUcsSUFBQSw4QkFBYyxFQUN6RCxnQ0FBZ0MsRUFDaEMsQ0FBQyxLQUFtQyxFQUFFLEVBQUU7SUFFcEMsTUFBTSxpQkFBaUIsR0FBRyxJQUFBLDRCQUFjLEVBQUMsS0FBSyxDQUFDLENBQUM7SUFFaEQsT0FBTyxJQUFJLGdDQUFnQixDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3hGLENBQUMsQ0FDSixDQUFDIn0=
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Configuration for statistics cache
3
+ */
4
+ export declare const STATISTICS_CACHE_CONFIG: {
5
+ readonly DEFAULT_TTL: 300;
6
+ readonly KEY_PREFIX: "stats:";
7
+ };
8
+ /**
9
+ * Generates cache key data for a single statistic calculation
10
+ * To be used with cacheService.computeKey()
11
+ */
12
+ export declare function getStatisticCacheKeyData(params: {
13
+ option_id: string;
14
+ periodStart: Date;
15
+ periodEnd: Date;
16
+ interval: number;
17
+ parameters: Record<string, any>;
18
+ }): {
19
+ prefix: "stats:";
20
+ type: string;
21
+ option_id: string;
22
+ periodStart: string;
23
+ periodEnd: string;
24
+ interval: number;
25
+ parameters: Record<string, any>;
26
+ };
27
+ /**
28
+ * Helper to build cache key for a statistic option
29
+ * Uses cacheService.computeKey internally
30
+ */
31
+ export declare function generateStatisticCacheKey(cacheService: any, params: {
32
+ option_id: string;
33
+ periodStart: Date;
34
+ periodEnd: Date;
35
+ interval: number;
36
+ parameters: Record<string, any>;
37
+ }): Promise<string>;
38
+ /**
39
+ * Check if caching is enabled for an option
40
+ * Checks both option-level and view-level cache_options
41
+ * If cache_options is not set or enabled is not specified, caching is enabled by default
42
+ */
43
+ export declare function isCachingEnabled(optionCacheOptions?: {
44
+ enabled?: boolean;
45
+ ttl?: number;
46
+ } | null, viewCacheOptions?: {
47
+ enabled?: boolean;
48
+ ttl?: number;
49
+ } | null): boolean;
50
+ /**
51
+ * Determine effective TTL for a statistic calculation
52
+ * Priority: option.cache_options.ttl > view.cache_options.ttl > default TTL
53
+ */
54
+ export declare function getEffectiveCacheTTL(optionCacheOptions?: {
55
+ enabled?: boolean;
56
+ ttl?: number;
57
+ } | null, viewCacheOptions?: {
58
+ enabled?: boolean;
59
+ ttl?: number;
60
+ } | null): number;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.STATISTICS_CACHE_CONFIG = void 0;
4
+ exports.getStatisticCacheKeyData = getStatisticCacheKeyData;
5
+ exports.generateStatisticCacheKey = generateStatisticCacheKey;
6
+ exports.isCachingEnabled = isCachingEnabled;
7
+ exports.getEffectiveCacheTTL = getEffectiveCacheTTL;
8
+ /**
9
+ * Configuration for statistics cache
10
+ */
11
+ exports.STATISTICS_CACHE_CONFIG = {
12
+ DEFAULT_TTL: 300,
13
+ KEY_PREFIX: "stats:",
14
+ };
15
+ /**
16
+ * Generates cache key data for a single statistic calculation
17
+ * To be used with cacheService.computeKey()
18
+ */
19
+ function getStatisticCacheKeyData(params) {
20
+ const { option_id, periodStart, periodEnd, interval, parameters } = params;
21
+ return {
22
+ prefix: exports.STATISTICS_CACHE_CONFIG.KEY_PREFIX,
23
+ type: "single",
24
+ option_id,
25
+ periodStart: new Date(periodStart).toISOString(),
26
+ periodEnd: new Date(periodEnd).toISOString(),
27
+ interval,
28
+ parameters
29
+ };
30
+ }
31
+ /**
32
+ * Helper to build cache key for a statistic option
33
+ * Uses cacheService.computeKey internally
34
+ */
35
+ async function generateStatisticCacheKey(cacheService, params) {
36
+ const keyData = getStatisticCacheKeyData(params);
37
+ return cacheService.computeKey(keyData);
38
+ }
39
+ /**
40
+ * Check if caching is enabled for an option
41
+ * Checks both option-level and view-level cache_options
42
+ * If cache_options is not set or enabled is not specified, caching is enabled by default
43
+ */
44
+ function isCachingEnabled(optionCacheOptions, viewCacheOptions) {
45
+ if (optionCacheOptions?.enabled !== undefined) {
46
+ return optionCacheOptions.enabled;
47
+ }
48
+ if (viewCacheOptions?.enabled !== undefined) {
49
+ return viewCacheOptions.enabled;
50
+ }
51
+ return true;
52
+ }
53
+ /**
54
+ * Determine effective TTL for a statistic calculation
55
+ * Priority: option.cache_options.ttl > view.cache_options.ttl > default TTL
56
+ */
57
+ function getEffectiveCacheTTL(optionCacheOptions, viewCacheOptions) {
58
+ if (optionCacheOptions?.ttl !== undefined && optionCacheOptions.ttl > 0) {
59
+ return optionCacheOptions.ttl;
60
+ }
61
+ if (viewCacheOptions?.ttl !== undefined && viewCacheOptions.ttl > 0) {
62
+ return viewCacheOptions.ttl;
63
+ }
64
+ return exports.STATISTICS_CACHE_CONFIG.DEFAULT_TTL;
65
+ }
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N0YXRpc3RpY3MvdXRpbHMvY2FjaGUtdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBYUEsNERBa0JDO0FBTUQsOERBWUM7QUFPRCw0Q0FnQkM7QUFNRCxvREFnQkM7QUE5RkQ7O0dBRUc7QUFDVSxRQUFBLHVCQUF1QixHQUFHO0lBRW5DLFdBQVcsRUFBRSxHQUFHO0lBQ2hCLFVBQVUsRUFBRSxRQUFRO0NBQ2QsQ0FBQztBQUVYOzs7R0FHRztBQUNILFNBQWdCLHdCQUF3QixDQUFDLE1BTXhDO0lBQ0csTUFBTSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFFM0UsT0FBTztRQUNILE1BQU0sRUFBRSwrQkFBdUIsQ0FBQyxVQUFVO1FBQzFDLElBQUksRUFBRSxRQUFRO1FBQ2QsU0FBUztRQUNULFdBQVcsRUFBRSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxXQUFXLEVBQUU7UUFDaEQsU0FBUyxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFdBQVcsRUFBRTtRQUM1QyxRQUFRO1FBQ1IsVUFBVTtLQUNiLENBQUM7QUFDTixDQUFDO0FBRUQ7OztHQUdHO0FBQ0ksS0FBSyxVQUFVLHlCQUF5QixDQUMzQyxZQUFpQixFQUNqQixNQU1DO0lBRUQsTUFBTSxPQUFPLEdBQUcsd0JBQXdCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsT0FBTyxZQUFZLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzVDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsZ0JBQWdCLENBQzVCLGtCQUErRCxFQUMvRCxnQkFBNkQ7SUFHN0QsSUFBSSxrQkFBa0IsRUFBRSxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDNUMsT0FBTyxrQkFBa0IsQ0FBQyxPQUFPLENBQUM7SUFDdEMsQ0FBQztJQUdELElBQUksZ0JBQWdCLEVBQUUsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzFDLE9BQU8sZ0JBQWdCLENBQUMsT0FBTyxDQUFDO0lBQ3BDLENBQUM7SUFHRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0Isb0JBQW9CLENBQ2hDLGtCQUErRCxFQUMvRCxnQkFBNkQ7SUFHN0QsSUFBSSxrQkFBa0IsRUFBRSxHQUFHLEtBQUssU0FBUyxJQUFJLGtCQUFrQixDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0RSxPQUFPLGtCQUFrQixDQUFDLEdBQUcsQ0FBQztJQUNsQyxDQUFDO0lBR0QsSUFBSSxnQkFBZ0IsRUFBRSxHQUFHLEtBQUssU0FBUyxJQUFJLGdCQUFnQixDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNsRSxPQUFPLGdCQUFnQixDQUFDLEdBQUcsQ0FBQztJQUNoQyxDQUFDO0lBR0QsT0FBTywrQkFBdUIsQ0FBQyxXQUFXLENBQUM7QUFDL0MsQ0FBQyJ9
@@ -0,0 +1,51 @@
1
+ import StatisticsService from "../../../modules/statistics/service";
2
+ /**
3
+ * Represents a node in the dependency graph
4
+ */
5
+ export interface DependencyNode {
6
+ id: string;
7
+ name: string;
8
+ provider_option_name: string;
9
+ parameter_name?: string;
10
+ dependencies: DependencyNode[];
11
+ depth: number;
12
+ }
13
+ /**
14
+ * Result of dependency resolution
15
+ */
16
+ export interface DependencyResolution {
17
+ calculationOrder: string[];
18
+ dependencyTree: DependencyNode;
19
+ hasCycles: boolean;
20
+ cycleNodes?: string[];
21
+ }
22
+ /**
23
+ * Utility class for dependency graph operations
24
+ */
25
+ export declare class DependencyGraphUtils {
26
+ /**
27
+ * Build complete dependency tree for an option
28
+ */
29
+ static buildDependencyTree(optionId: string, statisticsService: StatisticsService, visited?: Set<string>, depth?: number): Promise<DependencyNode>;
30
+ /**
31
+ * Get calculation order using topological sort
32
+ * Dependencies must be calculated before their dependents
33
+ */
34
+ static getCalculationOrder(tree: DependencyNode): string[];
35
+ /**
36
+ * Detect circular dependencies in the graph
37
+ */
38
+ static detectCycles(optionId: string, allDependencies: Map<string, string[]>, visited?: Set<string>, recursionStack?: Set<string>): string[] | null;
39
+ /**
40
+ * Validate dependency integrity
41
+ * Checks for cycles and validates all dependencies exist
42
+ */
43
+ static validateDependencies(optionId: string, statisticsService: StatisticsService): Promise<{
44
+ isValid: boolean;
45
+ errors: string[];
46
+ }>;
47
+ /**
48
+ * Flatten dependency tree to list of all option IDs
49
+ */
50
+ static flattenTree(tree: DependencyNode): string[];
51
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DependencyGraphUtils = void 0;
4
+ const dependency_option_map_1 = require("../../../modules/statistics/utils/dependency-option-map");
5
+ const utils_1 = require("@medusajs/framework/utils");
6
+ /**
7
+ * Utility class for dependency graph operations
8
+ */
9
+ class DependencyGraphUtils {
10
+ /**
11
+ * Build complete dependency tree for an option
12
+ */
13
+ static async buildDependencyTree(optionId, statisticsService, visited = new Set(), depth = 0) {
14
+ const optionMap = await (0, dependency_option_map_1.buildDependencyOptionMap)([optionId], [], async (idsToFetch) => {
15
+ const options = await Promise.all(idsToFetch.map((id) => statisticsService.retrieveStatisticsOption(id, {
16
+ relations: ["input_dependencies", "input_dependencies.input_option"],
17
+ })));
18
+ return options;
19
+ });
20
+ const buildNode = (currentId, currentDepth, path) => {
21
+ if (path.has(currentId)) {
22
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Circular dependency detected at option: ${currentId}`);
23
+ }
24
+ const option = optionMap.get(currentId);
25
+ if (!option) {
26
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Option not found in dependency graph: ${currentId}`);
27
+ }
28
+ const nextPath = new Set(path);
29
+ nextPath.add(currentId);
30
+ const node = {
31
+ id: option.id,
32
+ name: option.local_option_name,
33
+ provider_option_name: option.provider_option_name,
34
+ depth: currentDepth,
35
+ dependencies: [],
36
+ };
37
+ if (option.input_dependencies?.length) {
38
+ for (const dep of option.input_dependencies) {
39
+ const inputId = dep.input_option?.id || dep.input_option_id;
40
+ if (!inputId) {
41
+ continue;
42
+ }
43
+ const childNode = buildNode(inputId, currentDepth + 1, nextPath);
44
+ childNode.parameter_name = dep.parameter_name;
45
+ node.dependencies.push(childNode);
46
+ }
47
+ }
48
+ return node;
49
+ };
50
+ return buildNode(optionId, depth, new Set(visited));
51
+ }
52
+ /**
53
+ * Get calculation order using topological sort
54
+ * Dependencies must be calculated before their dependents
55
+ */
56
+ static getCalculationOrder(tree) {
57
+ const order = [];
58
+ const visited = new Set();
59
+ const visit = (node) => {
60
+ if (visited.has(node.id)) {
61
+ return;
62
+ }
63
+ for (const dep of node.dependencies) {
64
+ visit(dep);
65
+ }
66
+ visited.add(node.id);
67
+ order.push(node.id);
68
+ };
69
+ visit(tree);
70
+ return order;
71
+ }
72
+ /**
73
+ * Detect circular dependencies in the graph
74
+ */
75
+ static detectCycles(optionId, allDependencies, visited = new Set(), recursionStack = new Set()) {
76
+ visited.add(optionId);
77
+ recursionStack.add(optionId);
78
+ const dependencies = allDependencies.get(optionId) || [];
79
+ for (const depId of dependencies) {
80
+ if (!visited.has(depId)) {
81
+ const cycle = this.detectCycles(depId, allDependencies, visited, recursionStack);
82
+ if (cycle) {
83
+ return [optionId, ...cycle];
84
+ }
85
+ }
86
+ else if (recursionStack.has(depId)) {
87
+ return [optionId, depId];
88
+ }
89
+ }
90
+ recursionStack.delete(optionId);
91
+ return null;
92
+ }
93
+ /**
94
+ * Validate dependency integrity
95
+ * Checks for cycles and validates all dependencies exist
96
+ */
97
+ static async validateDependencies(optionId, statisticsService) {
98
+ const errors = [];
99
+ try {
100
+ await this.buildDependencyTree(optionId, statisticsService);
101
+ }
102
+ catch (error) {
103
+ if (error.message.includes("Circular dependency")) {
104
+ errors.push(error.message);
105
+ }
106
+ else {
107
+ errors.push(`Failed to build dependency tree: ${error.message}`);
108
+ }
109
+ }
110
+ return {
111
+ isValid: errors.length === 0,
112
+ errors,
113
+ };
114
+ }
115
+ /**
116
+ * Flatten dependency tree to list of all option IDs
117
+ */
118
+ static flattenTree(tree) {
119
+ const ids = new Set();
120
+ const collect = (node) => {
121
+ ids.add(node.id);
122
+ for (const dep of node.dependencies) {
123
+ collect(dep);
124
+ }
125
+ };
126
+ collect(tree);
127
+ return Array.from(ids);
128
+ }
129
+ }
130
+ exports.DependencyGraphUtils = DependencyGraphUtils;
131
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwZW5kZW5jeS1ncmFwaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3Mvc3RhdGlzdGljcy91dGlscy9kZXBlbmRlbmN5LWdyYXBoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLG1HQUFtRztBQUNuRyxxREFBd0Q7QUF3QnhEOztHQUVHO0FBQ0gsTUFBYSxvQkFBb0I7SUFDN0I7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUM1QixRQUFnQixFQUNoQixpQkFBb0MsRUFDcEMsVUFBdUIsSUFBSSxHQUFHLEVBQUUsRUFDaEMsUUFBZ0IsQ0FBQztRQUVqQixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUEsZ0RBQXdCLEVBQzVDLENBQUMsUUFBUSxDQUFDLEVBQ1YsRUFBRSxFQUNGLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtZQUNqQixNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQzdCLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUNsQixpQkFBaUIsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLEVBQUU7Z0JBQzNDLFNBQVMsRUFBRSxDQUFDLG9CQUFvQixFQUFFLGlDQUFpQyxDQUFDO2FBQ3ZFLENBQUMsQ0FDTCxDQUNKLENBQUM7WUFFRixPQUFPLE9BQU8sQ0FBQztRQUNuQixDQUFDLENBQ0osQ0FBQztRQUVGLE1BQU0sU0FBUyxHQUFHLENBQ2QsU0FBaUIsRUFDakIsWUFBb0IsRUFDcEIsSUFBaUIsRUFDSCxFQUFFO1lBQ2hCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUN0QixNQUFNLElBQUksbUJBQVcsQ0FDakIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QiwyQ0FBMkMsU0FBUyxFQUFFLENBQ3pELENBQUM7WUFDTixDQUFDO1lBRUQsTUFBTSxN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
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ import { ParameterFieldDefinition } from "../../../modules/statistics/providers/provider";
3
+ interface ValidateParameterDataOptions {
4
+ partial?: boolean;
5
+ }
6
+ interface ValidateParameterDataResult {
7
+ isValid: boolean;
8
+ errors: string[];
9
+ isComplete: boolean;
10
+ }
11
+ /**
12
+ * Parse selector syntax: "selector:paramName" or just "paramName"
13
+ */
14
+ export declare function parseSelector(key: string): [string | null, string];
15
+ /**
16
+ * Simple wildcard matching (* supported)
17
+ */
18
+ export declare function wildcardMatch(value: string, pattern: string): boolean;
19
+ /**
20
+ * Check if selector matches the option
21
+ */
22
+ export declare function selectorMatches(selector: string, localOptionName: string, providerOptionName: string, providerId: string): boolean;
23
+ /**
24
+ * Merge parameters from option, view (with selectors), and runtime
25
+ */
26
+ export declare function mergeParameters(optionData: Record<string, any>, viewData: Record<string, any>, runtimeData: Record<string, any>, localOptionName: string, providerOptionName: string, providerId: string): Record<string, any>;
27
+ /**
28
+ * Validate parameters against field definitions
29
+ */
30
+ export declare function validateParameters(parameters: Record<string, any>, fields: ParameterFieldDefinition[]): Record<string, any>;
31
+ /**
32
+ * Build Zod schema from parameter field definitions
33
+ */
34
+ export declare function buildParameterSchema(fields: ParameterFieldDefinition[], partial?: boolean): z.ZodObject<Record<string, z.ZodType<any, z.ZodTypeDef, any>>, "strip", z.ZodTypeAny, {
35
+ [x: string]: any;
36
+ }, {
37
+ [x: string]: any;
38
+ }>;
39
+ /**
40
+ * Validate parameter data and return formatted validation state
41
+ */
42
+ export declare function validateParameterData(parameters: Record<string, any>, fields: ParameterFieldDefinition[], options?: ValidateParameterDataOptions): ValidateParameterDataResult;
43
+ /**
44
+ * Resolve provider statistic definition by provider/option identifiers
45
+ */
46
+ export declare function resolveStatisticDefinition(availableStatistics: Record<string, any[]>, providerId: string, providerOptionName: string): {
47
+ statDefinition: any | null;
48
+ error: string | null;
49
+ };
50
+ /**
51
+ * Check if option data is complete (has all required values)
52
+ */
53
+ export declare function hasCompleteData(data: Record<string, any> | null | undefined): boolean;
54
+ export {};
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSelector = parseSelector;
4
+ exports.wildcardMatch = wildcardMatch;
5
+ exports.selectorMatches = selectorMatches;
6
+ exports.mergeParameters = mergeParameters;
7
+ exports.validateParameters = validateParameters;
8
+ exports.buildParameterSchema = buildParameterSchema;
9
+ exports.validateParameterData = validateParameterData;
10
+ exports.resolveStatisticDefinition = resolveStatisticDefinition;
11
+ exports.hasCompleteData = hasCompleteData;
12
+ const zod_1 = require("zod");
13
+ /**
14
+ * Parse selector syntax: "selector:paramName" or just "paramName"
15
+ */
16
+ function parseSelector(key) {
17
+ const parts = key.split(':');
18
+ if (parts.length === 1) {
19
+ return [null, key];
20
+ }
21
+ return [parts[0], parts[1]];
22
+ }
23
+ /**
24
+ * Simple wildcard matching (* supported)
25
+ */
26
+ function wildcardMatch(value, pattern) {
27
+ const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
28
+ return regex.test(value);
29
+ }
30
+ /**
31
+ * Check if selector matches the option
32
+ */
33
+ function selectorMatches(selector, localOptionName, providerOptionName, providerId) {
34
+ if (selector.startsWith('@')) {
35
+ const pattern = selector.slice(1);
36
+ return wildcardMatch(localOptionName, pattern);
37
+ }
38
+ else if (selector.includes('.') || selector.includes('*')) {
39
+ const [providerPattern, optionPattern] = selector.split(':');
40
+ if (optionPattern) {
41
+ return wildcardMatch(providerId, providerPattern) &&
42
+ wildcardMatch(providerOptionName, optionPattern);
43
+ }
44
+ else {
45
+ return wildcardMatch(providerId, providerPattern);
46
+ }
47
+ }
48
+ return false;
49
+ }
50
+ /**
51
+ * Merge parameters from option, view (with selectors), and runtime
52
+ */
53
+ function mergeParameters(optionData, viewData, runtimeData, localOptionName, providerOptionName, providerId) {
54
+ const merged = { ...optionData };
55
+ for (const [key, value] of Object.entries(viewData)) {
56
+ const [selector, paramName] = parseSelector(key);
57
+ if (!paramName) {
58
+ merged[key] = value;
59
+ }
60
+ else if (selector && selectorMatches(selector, localOptionName, providerOptionName, providerId)) {
61
+ merged[paramName] = value;
62
+ }
63
+ }
64
+ Object.assign(merged, runtimeData);
65
+ return merged;
66
+ }
67
+ /**
68
+ * Validate parameters against field definitions
69
+ */
70
+ function validateParameters(parameters, fields) {
71
+ const schema = buildParameterSchema(fields);
72
+ return schema.parse(parameters);
73
+ }
74
+ /**
75
+ * Build Zod schema from parameter field definitions
76
+ */
77
+ function buildParameterSchema(fields, partial = false) {
78
+ const schema = zod_1.z.object(fields.reduce((acc, field) => {
79
+ if (field.schema) {
80
+ acc[field.name] = field.schema;
81
+ }
82
+ return acc;
83
+ }, {}));
84
+ return partial ? schema.partial() : schema;
85
+ }
86
+ /**
87
+ * Validate parameter data and return formatted validation state
88
+ */
89
+ function validateParameterData(parameters, fields, options = {}) {
90
+ const schema = buildParameterSchema(fields, options.partial ?? false);
91
+ try {
92
+ schema.parse(parameters);
93
+ return {
94
+ isValid: true,
95
+ errors: [],
96
+ isComplete: true,
97
+ };
98
+ }
99
+ catch (error) {
100
+ if (!(error instanceof zod_1.z.ZodError)) {
101
+ return {
102
+ isValid: false,
103
+ errors: ["Unknown validation error"],
104
+ isComplete: false,
105
+ };
106
+ }
107
+ const errors = error.errors.map((validationError) => `${validationError.path.join(".")}: ${validationError.message}`);
108
+ const missingRequiredValues = error.errors.some((validationError) => validationError.code === "invalid_type");
109
+ return {
110
+ isValid: false,
111
+ errors,
112
+ isComplete: !missingRequiredValues,
113
+ };
114
+ }
115
+ }
116
+ /**
117
+ * Resolve provider statistic definition by provider/option identifiers
118
+ */
119
+ function resolveStatisticDefinition(availableStatistics, providerId, providerOptionName) {
120
+ const providerStats = availableStatistics[providerId];
121
+ if (!providerStats) {
122
+ return {
123
+ statDefinition: null,
124
+ error: `Provider ${providerId} not found or has no available statistics`,
125
+ };
126
+ }
127
+ const statDefinition = providerStats.find((statistic) => statistic.id === providerOptionName);
128
+ if (!statDefinition) {
129
+ return {
130
+ statDefinition: null,
131
+ error: `Statistic ${providerOptionName} not found in provider ${providerId}`,
132
+ };
133
+ }
134
+ return {
135
+ statDefinition,
136
+ error: null,
137
+ };
138
+ }
139
+ /**
140
+ * Check if option data is complete (has all required values)
141
+ */
142
+ function hasCompleteData(data) {
143
+ if (!data)
144
+ return false;
145
+ return Object.values(data).every(value => value !== null && value !== undefined);
146
+ }
147
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1ldGVyLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zdGF0aXN0aWNzL3V0aWxzL3BhcmFtZXRlci11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWdCQSxzQ0FNQztBQUtELHNDQUdDO0FBS0QsMENBdUJDO0FBS0QsMENBMkJDO0FBS0QsZ0RBT0M7QUFLRCxvREFjQztBQUtELHNEQXFDQztBQUtELGdFQTJCQztBQUtELDBDQU9DO0FBL01ELDZCQUF3QjtBQWF4Qjs7R0FFRztBQUNILFNBQWdCLGFBQWEsQ0FBQyxHQUFXO0lBQ3JDLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0IsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3JCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUNELE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsYUFBYSxDQUFDLEtBQWEsRUFBRSxPQUFlO0lBQ3hELE1BQU0sS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztJQUNuRSxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsZUFBZSxDQUMzQixRQUFnQixFQUNoQixlQUF1QixFQUN2QixrQkFBMEIsRUFDMUIsVUFBa0I7SUFFbEIsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFFM0IsTUFB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