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.
- package/.medusa/server/src/admin/composite.png +0 -0
- package/.medusa/server/src/admin/index.js +10512 -0
- package/.medusa/server/src/admin/index.mjs +10510 -0
- package/.medusa/server/src/admin/params.png +0 -0
- package/.medusa/server/src/admin/view.png +0 -0
- package/.medusa/server/src/admin/visualizations.png +0 -0
- package/.medusa/server/src/api/admin/statistics/alert-logs/[id]/route.d.ts +6 -0
- package/.medusa/server/src/api/admin/statistics/alert-logs/[id]/route.js +18 -0
- package/.medusa/server/src/api/admin/statistics/alert-logs/route.d.ts +6 -0
- package/.medusa/server/src/api/admin/statistics/alert-logs/route.js +33 -0
- package/.medusa/server/src/api/admin/statistics/alerts/[id]/logs/route.d.ts +6 -0
- package/.medusa/server/src/api/admin/statistics/alerts/[id]/logs/route.js +23 -0
- package/.medusa/server/src/api/admin/statistics/alerts/[id]/route.d.ts +17 -0
- package/.medusa/server/src/api/admin/statistics/alerts/[id]/route.js +64 -0
- package/.medusa/server/src/api/admin/statistics/alerts/[id]/toggle/route.d.ts +6 -0
- package/.medusa/server/src/api/admin/statistics/alerts/[id]/toggle/route.js +18 -0
- package/.medusa/server/src/api/admin/statistics/alerts/route.d.ts +12 -0
- package/.medusa/server/src/api/admin/statistics/alerts/route.js +94 -0
- package/.medusa/server/src/api/admin/statistics/charts/[id]/route.d.ts +17 -0
- package/.medusa/server/src/api/admin/statistics/charts/[id]/route.js +50 -0
- package/.medusa/server/src/api/admin/statistics/charts/[id]/statistics/route.d.ts +15 -0
- package/.medusa/server/src/api/admin/statistics/charts/[id]/statistics/route.js +40 -0
- package/.medusa/server/src/api/admin/statistics/charts/route.d.ts +4 -0
- package/.medusa/server/src/api/admin/statistics/charts/route.js +55 -0
- package/.medusa/server/src/api/admin/statistics/options/[id]/calculate/route.d.ts +7 -0
- package/.medusa/server/src/api/admin/statistics/options/[id]/calculate/route.js +23 -0
- package/.medusa/server/src/api/admin/statistics/options/[id]/clone/route.d.ts +7 -0
- package/.medusa/server/src/api/admin/statistics/options/[id]/clone/route.js +15 -0
- package/.medusa/server/src/api/admin/statistics/options/[id]/route.d.ts +17 -0
- package/.medusa/server/src/api/admin/statistics/options/[id]/route.js +69 -0
- package/.medusa/server/src/api/admin/statistics/options/route.d.ts +12 -0
- package/.medusa/server/src/api/admin/statistics/options/route.js +87 -0
- package/.medusa/server/src/api/admin/statistics/providers/[id]/route.d.ts +6 -0
- package/.medusa/server/src/api/admin/statistics/providers/[id]/route.js +18 -0
- package/.medusa/server/src/api/admin/statistics/providers/[id]/statistics/route.d.ts +6 -0
- package/.medusa/server/src/api/admin/statistics/providers/[id]/statistics/route.js +18 -0
- package/.medusa/server/src/api/admin/statistics/providers/route.d.ts +7 -0
- package/.medusa/server/src/api/admin/statistics/providers/route.js +57 -0
- package/.medusa/server/src/api/admin/statistics/utils/option-graph.d.ts +3 -0
- package/.medusa/server/src/api/admin/statistics/utils/option-graph.js +34 -0
- package/.medusa/server/src/api/admin/statistics/views/[id]/calculate/route.d.ts +7 -0
- package/.medusa/server/src/api/admin/statistics/views/[id]/calculate/route.js +21 -0
- package/.medusa/server/src/api/admin/statistics/views/[id]/clone/route.d.ts +7 -0
- package/.medusa/server/src/api/admin/statistics/views/[id]/clone/route.js +21 -0
- package/.medusa/server/src/api/admin/statistics/views/[id]/route.d.ts +17 -0
- package/.medusa/server/src/api/admin/statistics/views/[id]/route.js +71 -0
- package/.medusa/server/src/api/admin/statistics/views/route.d.ts +12 -0
- package/.medusa/server/src/api/admin/statistics/views/route.js +74 -0
- package/.medusa/server/src/api/middlewares.d.ts +2 -0
- package/.medusa/server/src/api/middlewares.js +194 -0
- package/.medusa/server/src/api/validation/statistics/schemas.d.ts +1013 -0
- package/.medusa/server/src/api/validation/statistics/schemas.js +288 -0
- package/.medusa/server/src/index.d.ts +1 -0
- package/.medusa/server/src/index.js +18 -0
- package/.medusa/server/src/jobs/evaluate-statistics-alerts.d.ts +6 -0
- package/.medusa/server/src/jobs/evaluate-statistics-alerts.js +110 -0
- package/.medusa/server/src/links/statistics-alert-user.d.ts +2 -0
- package/.medusa/server/src/links/statistics-alert-user.js +16 -0
- package/.medusa/server/src/links/statistics-option-user.d.ts +2 -0
- package/.medusa/server/src/links/statistics-option-user.js +16 -0
- package/.medusa/server/src/loaders/statistics/index.d.ts +5 -0
- package/.medusa/server/src/loaders/statistics/index.js +47 -0
- package/.medusa/server/src/modules/statistics/index.d.ts +107 -0
- package/.medusa/server/src/modules/statistics/index.js +32 -0
- package/.medusa/server/src/modules/statistics/migrations/Migration20260223131741.d.ts +5 -0
- package/.medusa/server/src/modules/statistics/migrations/Migration20260223131741.js +57 -0
- package/.medusa/server/src/modules/statistics/models/alert-log.d.ts +74 -0
- package/.medusa/server/src/modules/statistics/models/alert-log.js +16 -0
- package/.medusa/server/src/modules/statistics/models/alert.d.ts +74 -0
- package/.medusa/server/src/modules/statistics/models/alert.js +24 -0
- package/.medusa/server/src/modules/statistics/models/chart.d.ts +81 -0
- package/.medusa/server/src/modules/statistics/models/chart.js +28 -0
- package/.medusa/server/src/modules/statistics/models/index.d.ts +7 -0
- package/.medusa/server/src/modules/statistics/models/index.js +24 -0
- package/.medusa/server/src/modules/statistics/models/option-input.d.ts +135 -0
- package/.medusa/server/src/modules/statistics/models/option-input.js +27 -0
- package/.medusa/server/src/modules/statistics/models/option.d.ts +78 -0
- package/.medusa/server/src/modules/statistics/models/option.js +41 -0
- package/.medusa/server/src/modules/statistics/models/provider.d.ts +75 -0
- package/.medusa/server/src/modules/statistics/models/provider.js +15 -0
- package/.medusa/server/src/modules/statistics/models/view.d.ts +79 -0
- package/.medusa/server/src/modules/statistics/models/view.js +30 -0
- package/.medusa/server/src/modules/statistics/providers/index.d.ts +1 -0
- package/.medusa/server/src/modules/statistics/providers/index.js +18 -0
- package/.medusa/server/src/modules/statistics/providers/provider.d.ts +254 -0
- package/.medusa/server/src/modules/statistics/providers/provider.js +307 -0
- package/.medusa/server/src/modules/statistics/service.d.ts +953 -0
- package/.medusa/server/src/modules/statistics/service.js +190 -0
- package/.medusa/server/src/modules/statistics/utils/dependency-option-map.d.ts +13 -0
- package/.medusa/server/src/modules/statistics/utils/dependency-option-map.js +67 -0
- package/.medusa/server/src/modules/statistics/utils/period-utils.d.ts +23 -0
- package/.medusa/server/src/modules/statistics/utils/period-utils.js +78 -0
- package/.medusa/server/src/modules/statistics/utils/time-series-utils.d.ts +6 -0
- package/.medusa/server/src/modules/statistics/utils/time-series-utils.js +8 -0
- package/.medusa/server/src/providers/common/index.d.ts +2 -0
- package/.medusa/server/src/providers/common/index.js +1232 -0
- package/.medusa/server/src/providers/composite/index.d.ts +2 -0
- package/.medusa/server/src/providers/composite/index.js +147 -0
- package/.medusa/server/src/workflows/statistics/calculate-single-statistic.d.ts +15 -0
- package/.medusa/server/src/workflows/statistics/calculate-single-statistic.js +28 -0
- package/.medusa/server/src/workflows/statistics/calculate-statistics.d.ts +20 -0
- package/.medusa/server/src/workflows/statistics/calculate-statistics.js +15 -0
- package/.medusa/server/src/workflows/statistics/calculate-view.d.ts +31 -0
- package/.medusa/server/src/workflows/statistics/calculate-view.js +30 -0
- package/.medusa/server/src/workflows/statistics/clone-view.d.ts +227 -0
- package/.medusa/server/src/workflows/statistics/clone-view.js +10 -0
- package/.medusa/server/src/workflows/statistics/create-alert.d.ts +139 -0
- package/.medusa/server/src/workflows/statistics/create-alert.js +12 -0
- package/.medusa/server/src/workflows/statistics/create-chart.d.ts +122 -0
- package/.medusa/server/src/workflows/statistics/create-chart.js +14 -0
- package/.medusa/server/src/workflows/statistics/create-view-with-options.d.ts +1342 -0
- package/.medusa/server/src/workflows/statistics/create-view-with-options.js +29 -0
- package/.medusa/server/src/workflows/statistics/delete-chart.d.ts +10 -0
- package/.medusa/server/src/workflows/statistics/delete-chart.js +14 -0
- package/.medusa/server/src/workflows/statistics/evaluate-alerts.d.ts +28 -0
- package/.medusa/server/src/workflows/statistics/evaluate-alerts.js +67 -0
- package/.medusa/server/src/workflows/statistics/get-available-statistics.d.ts +5 -0
- package/.medusa/server/src/workflows/statistics/get-available-statistics.js +10 -0
- package/.medusa/server/src/workflows/statistics/index.d.ts +14 -0
- package/.medusa/server/src/workflows/statistics/index.js +31 -0
- package/.medusa/server/src/workflows/statistics/manage-chart-statistics.d.ts +12 -0
- package/.medusa/server/src/workflows/statistics/manage-chart-statistics.js +14 -0
- package/.medusa/server/src/workflows/statistics/steps/calculate-statistics.d.ts +37 -0
- package/.medusa/server/src/workflows/statistics/steps/calculate-statistics.js +222 -0
- package/.medusa/server/src/workflows/statistics/steps/clone-view.d.ts +227 -0
- package/.medusa/server/src/workflows/statistics/steps/clone-view.js +39 -0
- package/.medusa/server/src/workflows/statistics/steps/create-alert-log-entries.d.ts +17 -0
- package/.medusa/server/src/workflows/statistics/steps/create-alert-log-entries.js +50 -0
- package/.medusa/server/src/workflows/statistics/steps/create-alert.d.ts +120 -0
- package/.medusa/server/src/workflows/statistics/steps/create-alert.js +21 -0
- package/.medusa/server/src/workflows/statistics/steps/create-chart.d.ts +118 -0
- package/.medusa/server/src/workflows/statistics/steps/create-chart.js +19 -0
- package/.medusa/server/src/workflows/statistics/steps/create-statistics-options.d.ts +117 -0
- package/.medusa/server/src/workflows/statistics/steps/create-statistics-options.js +16 -0
- package/.medusa/server/src/workflows/statistics/steps/create-statistics-view.d.ts +119 -0
- package/.medusa/server/src/workflows/statistics/steps/create-statistics-view.js +16 -0
- package/.medusa/server/src/workflows/statistics/steps/dedupe-alerts.d.ts +22 -0
- package/.medusa/server/src/workflows/statistics/steps/dedupe-alerts.js +64 -0
- package/.medusa/server/src/workflows/statistics/steps/delete-chart.d.ts +6 -0
- package/.medusa/server/src/workflows/statistics/steps/delete-chart.js +17 -0
- package/.medusa/server/src/workflows/statistics/steps/emit-alert-events.d.ts +17 -0
- package/.medusa/server/src/workflows/statistics/steps/emit-alert-events.js +41 -0
- package/.medusa/server/src/workflows/statistics/steps/evaluate-each-condition.d.ts +15 -0
- package/.medusa/server/src/workflows/statistics/steps/evaluate-each-condition.js +109 -0
- package/.medusa/server/src/workflows/statistics/steps/extract-alert-values.d.ts +12 -0
- package/.medusa/server/src/workflows/statistics/steps/extract-alert-values.js +86 -0
- package/.medusa/server/src/workflows/statistics/steps/fetch-active-alerts-for-option.d.ts +112 -0
- package/.medusa/server/src/workflows/statistics/steps/fetch-active-alerts-for-option.js +16 -0
- package/.medusa/server/src/workflows/statistics/steps/fetch-available-statistics.d.ts +4 -0
- package/.medusa/server/src/workflows/statistics/steps/fetch-available-statistics.js +39 -0
- package/.medusa/server/src/workflows/statistics/steps/fetch-option-with-relations.d.ts +112 -0
- package/.medusa/server/src/workflows/statistics/steps/fetch-option-with-relations.js +11 -0
- package/.medusa/server/src/workflows/statistics/steps/fetch-view-with-options.d.ts +112 -0
- package/.medusa/server/src/workflows/statistics/steps/fetch-view-with-options.js +20 -0
- package/.medusa/server/src/workflows/statistics/steps/manage-chart-statistics.d.ts +8 -0
- package/.medusa/server/src/workflows/statistics/steps/manage-chart-statistics.js +26 -0
- package/.medusa/server/src/workflows/statistics/steps/update-chart.d.ts +117 -0
- package/.medusa/server/src/workflows/statistics/steps/update-chart.js +32 -0
- package/.medusa/server/src/workflows/statistics/steps/update-view.d.ts +120 -0
- package/.medusa/server/src/workflows/statistics/steps/update-view.js +18 -0
- package/.medusa/server/src/workflows/statistics/steps/validate-alert-input.d.ts +1 -0
- package/.medusa/server/src/workflows/statistics/steps/validate-alert-input.js +34 -0
- package/.medusa/server/src/workflows/statistics/steps/validate-option-parameters.d.ts +21 -0
- package/.medusa/server/src/workflows/statistics/steps/validate-option-parameters.js +43 -0
- package/.medusa/server/src/workflows/statistics/steps/validate-view-input.d.ts +10 -0
- package/.medusa/server/src/workflows/statistics/steps/validate-view-input.js +15 -0
- package/.medusa/server/src/workflows/statistics/update-chart.d.ts +120 -0
- package/.medusa/server/src/workflows/statistics/update-chart.js +13 -0
- package/.medusa/server/src/workflows/statistics/update-view-configuration.d.ts +128 -0
- package/.medusa/server/src/workflows/statistics/update-view-configuration.js +18 -0
- package/.medusa/server/src/workflows/statistics/utils/cache-utils.d.ts +60 -0
- package/.medusa/server/src/workflows/statistics/utils/cache-utils.js +66 -0
- package/.medusa/server/src/workflows/statistics/utils/dependency-graph.d.ts +51 -0
- package/.medusa/server/src/workflows/statistics/utils/dependency-graph.js +131 -0
- package/.medusa/server/src/workflows/statistics/utils/parameter-utils.d.ts +54 -0
- package/.medusa/server/src/workflows/statistics/utils/parameter-utils.js +147 -0
- package/.medusa/server/src/workflows/statistics/validate-option-configuration.d.ts +9 -0
- package/.medusa/server/src/workflows/statistics/validate-option-configuration.js +35 -0
- package/README.md +310 -0
- 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1ldGVyLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zdGF0aXN0aWNzL3V0aWxzL3BhcmFtZXRlci11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWdCQSxzQ0FNQztBQUtELHNDQUdDO0FBS0QsMENBdUJDO0FBS0QsMENBMkJDO0FBS0QsZ0RBT0M7QUFLRCxvREFjQztBQUtELHNEQXFDQztBQUtELGdFQTJCQztBQUtELDBDQU9DO0FBL01ELDZCQUF3QjtBQWF4Qjs7R0FFRztBQUNILFNBQWdCLGFBQWEsQ0FBQyxHQUFXO0lBQ3JDLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0IsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3JCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUNELE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsYUFBYSxDQUFDLEtBQWEsRUFBRSxPQUFlO0lBQ3hELE1BQU0sS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztJQUNuRSxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsZUFBZSxDQUMzQixRQUFnQixFQUNoQixlQUF1QixFQUN2QixrQkFBMEIsRUFDMUIsVUFBa0I7SUFFbEIsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFFM0IsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxPQUFPLGFBQWEsQ0FBQyxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkQsQ0FBQztTQUFNLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFFMUQsTUFBTSxDQUFDLGVBQWUsRUFBRSxhQUFhLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdELElBQUksYUFBYSxFQUFFLENBQUM7WUFFaEIsT0FBTyxhQUFhLENBQUMsVUFBVSxFQUFFLGVBQWUsQ0FBQztnQkFDN0MsYUFBYSxDQUFDLGtCQUFrQixFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQ3pELENBQUM7YUFBTSxDQUFDO1lBRUosT0FBTyxhQUFhLENBQUMsVUFBVSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBQ3RELENBQUM7SUFDTCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsZUFBZSxDQUMzQixVQUErQixFQUMvQixRQUE2QixFQUM3QixXQUFnQyxFQUNoQyxlQUF1QixFQUN2QixrQkFBMEIsRUFDMUIsVUFBa0I7SUFFbEIsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLFVBQVUsRUFBRSxDQUFDO0lBR2pDLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDbEQsTUFBTSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFakQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBRWIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUN4QixDQUFDO2FBQU0sSUFBSSxRQUFRLElBQUksZUFBZSxDQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsa0JBQWtCLEVBQUUsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUVoRyxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzlCLENBQUM7SUFDTCxDQUFDO0lBR0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFFbkMsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0Isa0JBQWtCLENBQzlCLFVBQStCLEVBQy9CLE1BQWtDO0lBRWxDLE1BQU0sTUFBTSxHQUFHLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRTVDLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixvQkFBb0IsQ0FDaEMsTUFBa0MsRUFDbEMsT0FBTyxHQUFHLEtBQUs7SUFFZixNQUFNLE1BQU0sR0FBRyxPQUFDLENBQUMsTUFBTSxDQUNuQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFO1FBQ3pCLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2YsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQ25DLENBQUM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNmLENBQUMsRUFBRSxFQUFvQyxDQUFDLENBQzNDLENBQUM7SUFFRixPQUFPLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDL0MsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IscUJBQXFCLENBQ2pDLFVBQStCLEVBQy9CLE1BQWtDLEVBQ2xDLFVBQXdDLEVBQUU7SUFFMUMsTUFBTSxNQUFNLEdBQUcsb0JBQW9CLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLENBQUM7SUFFdEUsSUFBSSxDQUFDO1FBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN6QixPQUFPO1lBQ0gsT0FBTyxFQUFFLElBQUk7WUFDYixNQUFNLEVBQUUsRUFBRTtZQUNWLFVBQVUsRUFBRSxJQUFJO1NBQ25CLENBQUM7SUFDTixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxDQUFDLEtBQUssWUFBWSxPQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNqQyxPQUFPO2dCQUNILE9BQU8sRUFBRSxLQUFLO2dCQUNkLE1BQU0sRUFBRSxDQUFDLDBCQUEwQixDQUFDO2dCQUNwQyxVQUFVLEVBQUUsS0FBSzthQUNwQixDQUFDO1FBQ04sQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FDaEQsR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxlQUFlLENBQUMsT0FBTyxFQUFFLENBQ2xFLENBQUM7UUFFRixNQUFNLHFCQUFxQixHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUMzQyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsZUFBZSxDQUFDLElBQUksS0FBSyxjQUFjLENBQy9ELENBQUM7UUFFRixPQUFPO1lBQ0gsT0FBTyxFQUFFLEtBQUs7WUFDZCxNQUFNO1lBQ04sVUFBVSxFQUFFLENBQUMscUJBQXFCO1NBQ3JDLENBQUM7SUFDTixDQUFDO0FBQ0wsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsMEJBQTBCLENBQ3RDLG1CQUEwQyxFQUMxQyxVQUFrQixFQUNsQixrQkFBMEI7SUFFMUIsTUFBTSxhQUFhLEdBQUcsbUJBQW1CLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFdEQsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2pCLE9BQU87WUFDSCxjQUFjLEVBQUUsSUFBSTtZQUNwQixLQUFLLEVBQUUsWUFBWSxVQUFVLDJDQUEyQztTQUMzRSxDQUFDO0lBQ04sQ0FBQztJQUVELE1BQU0sY0FBYyxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFjLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssa0JBQWtCLENBQUMsQ0FBQztJQUVuRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDbEIsT0FBTztZQUNILGNBQWMsRUFBRSxJQUFJO1lBQ3BCLEtBQUssRUFBRSxhQUFhLGtCQUFrQiwwQkFBMEIsVUFBVSxFQUFFO1NBQy9FLENBQUM7SUFDTixDQUFDO0lBRUQsT0FBTztRQUNILGNBQWM7UUFDZCxLQUFLLEVBQUUsSUFBSTtLQUNkLENBQUM7QUFDTixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixlQUFlLENBQUMsSUFBNEM7SUFDeEUsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUd4QixPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQ3JDLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVMsQ0FDeEMsQ0FBQztBQUNOLENBQUMifQ==
|