@powerhousedao/analytics-engine-graphql 6.0.0-dev.105 → 6.0.0-dev.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +265 -0
- package/dist/index.js.map +1 -0
- package/package.json +10 -7
- package/dist/src/AnalyticsModel.d.ts +0 -39
- package/dist/src/AnalyticsModel.d.ts.map +0 -1
- package/dist/src/AnalyticsResolvers.d.ts +0 -2
- package/dist/src/AnalyticsResolvers.d.ts.map +0 -1
- package/dist/src/index.d.ts +0 -5
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -9654
- package/dist/src/schema.d.ts +0 -2
- package/dist/src/schema.d.ts.map +0 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as _powerhousedao_analytics_engine_core0 from "@powerhousedao/analytics-engine-core";
|
|
2
|
+
import { AnalyticsQuery, AnalyticsQueryEngine } from "@powerhousedao/analytics-engine-core";
|
|
3
|
+
|
|
4
|
+
//#region src/AnalyticsResolvers.d.ts
|
|
5
|
+
declare const AnalyticsResolvers: any;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/AnalyticsModel.d.ts
|
|
8
|
+
type queryFilter = {
|
|
9
|
+
start?: string;
|
|
10
|
+
end?: string;
|
|
11
|
+
granularity?: string;
|
|
12
|
+
metrics: string[];
|
|
13
|
+
dimensions: [Record<string, string>];
|
|
14
|
+
currency?: string;
|
|
15
|
+
};
|
|
16
|
+
type CurrencyConversion = {
|
|
17
|
+
metric: string;
|
|
18
|
+
sourceCurrency: string;
|
|
19
|
+
};
|
|
20
|
+
type MultiCurrencyFilter = queryFilter & {
|
|
21
|
+
conversions: CurrencyConversion[];
|
|
22
|
+
};
|
|
23
|
+
declare class AnalyticsModel {
|
|
24
|
+
readonly engine: AnalyticsQueryEngine;
|
|
25
|
+
queryLogger: (query: AnalyticsQuery) => void;
|
|
26
|
+
constructor(engine: AnalyticsQueryEngine, queryLogger?: (query: AnalyticsQuery) => void);
|
|
27
|
+
query(filter: queryFilter): Promise<{
|
|
28
|
+
start: Date;
|
|
29
|
+
end: Date;
|
|
30
|
+
period: string;
|
|
31
|
+
rows: Array<{
|
|
32
|
+
dimensions: Record<string, _powerhousedao_analytics_engine_core0.AnalyticsDimension>;
|
|
33
|
+
metric: string;
|
|
34
|
+
unit: string | null;
|
|
35
|
+
value: number;
|
|
36
|
+
sum: number;
|
|
37
|
+
}>;
|
|
38
|
+
}[]>;
|
|
39
|
+
multiCurrencyQuery(filter: MultiCurrencyFilter): Promise<_powerhousedao_analytics_engine_core0.GroupedPeriodResults>;
|
|
40
|
+
getDimensions(): Promise<any>;
|
|
41
|
+
getCurrencies(): Promise<string[]>;
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/schema.d.ts
|
|
45
|
+
declare const typedefs = "\ntype AnalyticsQuery {\n series(filter: AnalyticsFilter): [AnalyticsPeriod]\n multiCurrencySeries(filter: MultiCurrencyConversions): [AnalyticsPeriod]\n metrics: [String]\n dimensions: [Dimension]\n currencies: [String]\n}\n\ntype AnalyticsPeriod {\n period: String\n start: DateTime\n end: DateTime\n rows: [AnalyticsSeries]\n}\n\ntype AnalyticsSeries {\n dimensions: [AnalyticsSeriesDimension]\n metric: String\n unit: String\n value: Float\n sum: Float\n}\n\ntype AnalyticsSeriesDimension {\n name: String\n path: String\n label: String\n description: String\n icon: String\n}\n\ntype Dimension {\n name: String\n values: [Value]\n}\n\ntype Value {\n path: String\n label: String\n description: String\n icon: String\n}\n\nenum AnalyticsGranularity {\n hourly\n daily\n weekly\n monthly\n quarterly\n semiAnnual\n annual\n total\n}\n\ninput AnalyticsFilterDimension {\n name: String!\n select: String!\n lod: Int!\n}\n\ninput MultiCurrencyConversions {\n start: String\n end: String\n \"Period to group by\"\n granularity: AnalyticsGranularity\n \"List of metrics to filter by, such as 'budget' or 'actuals'\"\n metrics: [String]\n \"List of dimensions to filter by, such as 'budget' or 'project'\"\n dimensions: [AnalyticsFilterDimension]\n currency: String\n conversions: [CurrencyConversion]!\n}\n\ninput CurrencyConversion {\n metric: String!\n sourceCurrency: String!\n}\n\ninput AnalyticsFilter {\n start: String\n end: String\n \"Period to group by\"\n granularity: AnalyticsGranularity\n \"List of metrics to filter by, such as 'budget' or 'actuals'\"\n metrics: [String]\n \"List of dimensions to filter by, such as 'budget' or 'project'\"\n dimensions: [AnalyticsFilterDimension]\n currency: String\n}\n\nextend type Query {\n analytics: AnalyticsQuery\n}\n";
|
|
46
|
+
//#endregion
|
|
47
|
+
export { AnalyticsModel, AnalyticsResolvers, type queryFilter, typedefs };
|
|
48
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/AnalyticsResolvers.ts","../src/AnalyticsModel.ts","../src/schema.ts"],"mappings":";;;;cAEa,kBAAA;;;KCMD,WAAA;EACV,KAAA;EACA,GAAA;EACA,WAAA;EACA,OAAA;EACA,UAAA,GAAa,MAAA;EACb,QAAA;AAAA;AAAA,KAGG,kBAAA;EACH,MAAA;EACA,cAAA;AAAA;AAAA,KAGG,mBAAA,GAAsB,WAAA;EACzB,WAAA,EAAa,kBAAA;AAAA;AAAA,cAGF,cAAA;EAAA,SAIO,MAAA,EAAQ,oBAAA;EAH1B,WAAA,GAAc,KAAA,EAAO,cAAA;cAGH,MAAA,EAAQ,oBAAA,EACxB,WAAA,IAAe,KAAA,EAAO,cAAA;EAKX,KAAA,CAAM,MAAA,EAAQ,WAAA,GAAW,OAAA;;;;;;;;;;;;EAmDzB,kBAAA,CAAmB,MAAA,EAAQ,mBAAA,GAAmB,OAAA,CAAA,qCAAA,CAAA,oBAAA;EA+C9C,aAAA,CAAA,GAAa,OAAA;EAIb,aAAA,CAAA,GAAa,OAAA;AAAA;;;cC1If,QAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { AnalyticsGranularity, AnalyticsPath } from "@powerhousedao/analytics-engine-core";
|
|
2
|
+
import { DateTime } from "luxon";
|
|
3
|
+
//#region src/AnalyticsResolvers.ts
|
|
4
|
+
const AnalyticsResolvers = {
|
|
5
|
+
Query: { analytics: (_, __, { dataSources }) => {
|
|
6
|
+
return {};
|
|
7
|
+
} },
|
|
8
|
+
AnalyticsQuery: {
|
|
9
|
+
series: async (parent, { filter }, { dataSources }) => {
|
|
10
|
+
return (await dataSources.db.Analytics.query(filter)).map((s) => ({
|
|
11
|
+
...s,
|
|
12
|
+
rows: s.rows.map((r) => ({
|
|
13
|
+
...r,
|
|
14
|
+
dimensions: Object.keys(r.dimensions).map((d) => ({
|
|
15
|
+
name: d,
|
|
16
|
+
path: r.dimensions[d]["path"],
|
|
17
|
+
icon: r.dimensions[d]["icon"],
|
|
18
|
+
label: r.dimensions[d]["label"],
|
|
19
|
+
description: r.dimensions[d]["description"]
|
|
20
|
+
}))
|
|
21
|
+
}))
|
|
22
|
+
}));
|
|
23
|
+
},
|
|
24
|
+
metrics: async (parent, { filter }, { dataSources }) => {
|
|
25
|
+
return [
|
|
26
|
+
"Actuals",
|
|
27
|
+
"AuditorNetOutflow",
|
|
28
|
+
"Budget",
|
|
29
|
+
"Contributors",
|
|
30
|
+
"Count",
|
|
31
|
+
"DailyDaiPriceChange",
|
|
32
|
+
"DailyEthPriceChange",
|
|
33
|
+
"DailyMkrPriceChange",
|
|
34
|
+
"DailyUsdcPriceChange",
|
|
35
|
+
"DailyUsdpPriceChange",
|
|
36
|
+
"Forecast",
|
|
37
|
+
"PaymentsOffChainIncluded",
|
|
38
|
+
"PaymentsOnChain",
|
|
39
|
+
"ProtocolNetOutflow"
|
|
40
|
+
];
|
|
41
|
+
},
|
|
42
|
+
dimensions: async (_, { filter }, { dataSources }) => {
|
|
43
|
+
return await dataSources.db.Analytics.getDimensions();
|
|
44
|
+
},
|
|
45
|
+
currencies: async (_, { filter }, { dataSources }) => {
|
|
46
|
+
return [
|
|
47
|
+
"DAI",
|
|
48
|
+
"FTE",
|
|
49
|
+
"GUSD",
|
|
50
|
+
"MKR",
|
|
51
|
+
"USDC",
|
|
52
|
+
"USDP",
|
|
53
|
+
"USDT"
|
|
54
|
+
];
|
|
55
|
+
},
|
|
56
|
+
multiCurrencySeries: async (_, { filter }, { dataSources }) => {
|
|
57
|
+
return (await dataSources.db.Analytics.multiCurrencyQuery(filter)).map((s) => ({
|
|
58
|
+
...s,
|
|
59
|
+
rows: s.rows.map((r) => ({
|
|
60
|
+
...r,
|
|
61
|
+
dimensions: Object.keys(r.dimensions).map((d) => ({
|
|
62
|
+
name: d,
|
|
63
|
+
path: r.dimensions[d]["path"],
|
|
64
|
+
icon: r.dimensions[d]["icon"],
|
|
65
|
+
label: r.dimensions[d]["label"],
|
|
66
|
+
description: r.dimensions[d]["description"]
|
|
67
|
+
}))
|
|
68
|
+
}))
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/AnalyticsModel.ts
|
|
75
|
+
var AnalyticsModel = class {
|
|
76
|
+
queryLogger;
|
|
77
|
+
constructor(engine, queryLogger) {
|
|
78
|
+
this.engine = engine;
|
|
79
|
+
this.queryLogger = queryLogger || (() => {});
|
|
80
|
+
}
|
|
81
|
+
async query(filter) {
|
|
82
|
+
if (!filter) return [];
|
|
83
|
+
const query = {
|
|
84
|
+
start: filter.start ? DateTime.fromISO(filter.start) : null,
|
|
85
|
+
end: filter.end ? DateTime.fromISO(filter.end) : null,
|
|
86
|
+
granularity: getGranularity(filter.granularity),
|
|
87
|
+
metrics: filter.metrics,
|
|
88
|
+
currency: getCurrency(filter.currency),
|
|
89
|
+
select: {},
|
|
90
|
+
lod: {}
|
|
91
|
+
};
|
|
92
|
+
if (query.start && !query.start.isValid) query.start = null;
|
|
93
|
+
if (query.end && !query.end.isValid) query.end = null;
|
|
94
|
+
if (filter.dimensions.length < 1) throw new Error("No dimensions provided");
|
|
95
|
+
else filter.dimensions.forEach((dimension) => {
|
|
96
|
+
query.select[dimension.name] = [AnalyticsPath.fromString(dimension.select)];
|
|
97
|
+
query.lod[dimension.name] = Number(dimension.lod);
|
|
98
|
+
});
|
|
99
|
+
this.queryLogger(query);
|
|
100
|
+
return (await this.engine.execute(query)).map((r) => ({
|
|
101
|
+
...r,
|
|
102
|
+
start: r.start.toJSDate(),
|
|
103
|
+
end: r.end.toJSDate()
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
async multiCurrencyQuery(filter) {
|
|
107
|
+
if (!filter) return [];
|
|
108
|
+
const query = {
|
|
109
|
+
start: filter.start ? DateTime.fromISO(filter.start) : null,
|
|
110
|
+
end: filter.end ? DateTime.fromISO(filter.end) : null,
|
|
111
|
+
granularity: getGranularity(filter.granularity),
|
|
112
|
+
metrics: filter.metrics,
|
|
113
|
+
currency: getCurrency(filter.currency),
|
|
114
|
+
select: {},
|
|
115
|
+
lod: {}
|
|
116
|
+
};
|
|
117
|
+
if (query.start && !query.start.isValid) query.start = null;
|
|
118
|
+
if (query.end && !query.end.isValid) query.end = null;
|
|
119
|
+
if (filter.dimensions.length < 1) throw new Error("No dimensions provided");
|
|
120
|
+
else filter.dimensions.forEach((dimension) => {
|
|
121
|
+
query.select[dimension.name] = [AnalyticsPath.fromString(dimension.select)];
|
|
122
|
+
query.lod[dimension.name] = Number(dimension.lod);
|
|
123
|
+
});
|
|
124
|
+
this.queryLogger(query);
|
|
125
|
+
return this.engine.executeMultiCurrency(query, {
|
|
126
|
+
targetCurrency: query.currency,
|
|
127
|
+
conversions: filter.conversions.map((c) => {
|
|
128
|
+
return {
|
|
129
|
+
metric: c.metric,
|
|
130
|
+
currency: getCurrency(c.sourceCurrency)
|
|
131
|
+
};
|
|
132
|
+
})
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async getDimensions() {
|
|
136
|
+
return await this.engine.getDimensions();
|
|
137
|
+
}
|
|
138
|
+
async getCurrencies() {
|
|
139
|
+
return [
|
|
140
|
+
"DAI",
|
|
141
|
+
"FTE",
|
|
142
|
+
"MKR",
|
|
143
|
+
"USDC",
|
|
144
|
+
"USDP",
|
|
145
|
+
"USDT"
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const getGranularity = (granularity) => {
|
|
150
|
+
switch (granularity) {
|
|
151
|
+
case "hourly": return AnalyticsGranularity.Hourly;
|
|
152
|
+
case "daily": return AnalyticsGranularity.Daily;
|
|
153
|
+
case "weekly": return AnalyticsGranularity.Weekly;
|
|
154
|
+
case "monthly": return AnalyticsGranularity.Monthly;
|
|
155
|
+
case "quarterly": return AnalyticsGranularity.Quarterly;
|
|
156
|
+
case "semiAnnual": return AnalyticsGranularity.SemiAnnual;
|
|
157
|
+
case "annual": return AnalyticsGranularity.Annual;
|
|
158
|
+
case "total": return AnalyticsGranularity.Total;
|
|
159
|
+
default: return AnalyticsGranularity.Total;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const getCurrency = (currency) => {
|
|
163
|
+
return currency ? AnalyticsPath.fromString(currency) : void 0;
|
|
164
|
+
};
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/schema.ts
|
|
167
|
+
const typedefs = `
|
|
168
|
+
type AnalyticsQuery {
|
|
169
|
+
series(filter: AnalyticsFilter): [AnalyticsPeriod]
|
|
170
|
+
multiCurrencySeries(filter: MultiCurrencyConversions): [AnalyticsPeriod]
|
|
171
|
+
metrics: [String]
|
|
172
|
+
dimensions: [Dimension]
|
|
173
|
+
currencies: [String]
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
type AnalyticsPeriod {
|
|
177
|
+
period: String
|
|
178
|
+
start: DateTime
|
|
179
|
+
end: DateTime
|
|
180
|
+
rows: [AnalyticsSeries]
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
type AnalyticsSeries {
|
|
184
|
+
dimensions: [AnalyticsSeriesDimension]
|
|
185
|
+
metric: String
|
|
186
|
+
unit: String
|
|
187
|
+
value: Float
|
|
188
|
+
sum: Float
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
type AnalyticsSeriesDimension {
|
|
192
|
+
name: String
|
|
193
|
+
path: String
|
|
194
|
+
label: String
|
|
195
|
+
description: String
|
|
196
|
+
icon: String
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
type Dimension {
|
|
200
|
+
name: String
|
|
201
|
+
values: [Value]
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
type Value {
|
|
205
|
+
path: String
|
|
206
|
+
label: String
|
|
207
|
+
description: String
|
|
208
|
+
icon: String
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
enum AnalyticsGranularity {
|
|
212
|
+
hourly
|
|
213
|
+
daily
|
|
214
|
+
weekly
|
|
215
|
+
monthly
|
|
216
|
+
quarterly
|
|
217
|
+
semiAnnual
|
|
218
|
+
annual
|
|
219
|
+
total
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
input AnalyticsFilterDimension {
|
|
223
|
+
name: String!
|
|
224
|
+
select: String!
|
|
225
|
+
lod: Int!
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
input MultiCurrencyConversions {
|
|
229
|
+
start: String
|
|
230
|
+
end: String
|
|
231
|
+
"Period to group by"
|
|
232
|
+
granularity: AnalyticsGranularity
|
|
233
|
+
"List of metrics to filter by, such as 'budget' or 'actuals'"
|
|
234
|
+
metrics: [String]
|
|
235
|
+
"List of dimensions to filter by, such as 'budget' or 'project'"
|
|
236
|
+
dimensions: [AnalyticsFilterDimension]
|
|
237
|
+
currency: String
|
|
238
|
+
conversions: [CurrencyConversion]!
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
input CurrencyConversion {
|
|
242
|
+
metric: String!
|
|
243
|
+
sourceCurrency: String!
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
input AnalyticsFilter {
|
|
247
|
+
start: String
|
|
248
|
+
end: String
|
|
249
|
+
"Period to group by"
|
|
250
|
+
granularity: AnalyticsGranularity
|
|
251
|
+
"List of metrics to filter by, such as 'budget' or 'actuals'"
|
|
252
|
+
metrics: [String]
|
|
253
|
+
"List of dimensions to filter by, such as 'budget' or 'project'"
|
|
254
|
+
dimensions: [AnalyticsFilterDimension]
|
|
255
|
+
currency: String
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
extend type Query {
|
|
259
|
+
analytics: AnalyticsQuery
|
|
260
|
+
}
|
|
261
|
+
`;
|
|
262
|
+
//#endregion
|
|
263
|
+
export { AnalyticsModel, AnalyticsResolvers, typedefs };
|
|
264
|
+
|
|
265
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/AnalyticsResolvers.ts","../src/AnalyticsModel.ts","../src/schema.ts"],"sourcesContent":["import type { AnalyticsModel } from \"./AnalyticsModel.js\";\n\nexport const AnalyticsResolvers: any = {\n Query: {\n analytics: (_: any, __: any, { dataSources }: any) => {\n return {};\n },\n },\n AnalyticsQuery: {\n series: async (parent: any, { filter }: any, { dataSources }: any) => {\n const queryEngine: AnalyticsModel = dataSources.db.Analytics;\n const results = await queryEngine.query(filter);\n return results.map((s) => ({\n ...s,\n rows: s.rows.map((r: any) => ({\n ...r,\n dimensions: Object.keys(r.dimensions).map((d) => ({\n name: d,\n path: r.dimensions[d][\"path\"],\n icon: r.dimensions[d][\"icon\"],\n label: r.dimensions[d][\"label\"],\n description: r.dimensions[d][\"description\"],\n })),\n })),\n }));\n },\n metrics: async (parent: any, { filter }: any, { dataSources }: any) => {\n return [\n \"Actuals\",\n \"AuditorNetOutflow\",\n \"Budget\",\n \"Contributors\",\n \"Count\",\n \"DailyDaiPriceChange\",\n \"DailyEthPriceChange\",\n \"DailyMkrPriceChange\",\n \"DailyUsdcPriceChange\",\n \"DailyUsdpPriceChange\",\n \"Forecast\",\n \"PaymentsOffChainIncluded\",\n \"PaymentsOnChain\",\n \"ProtocolNetOutflow\",\n ];\n },\n dimensions: async (_: any, { filter }: any, { dataSources }: any) => {\n const queryEngine: AnalyticsModel = dataSources.db.Analytics;\n return await queryEngine.getDimensions();\n },\n currencies: async (_: any, { filter }: any, { dataSources }: any) => {\n return [\"DAI\", \"FTE\", \"GUSD\", \"MKR\", \"USDC\", \"USDP\", \"USDT\"];\n },\n multiCurrencySeries: async (\n _: any,\n { filter }: any,\n { dataSources }: any,\n ) => {\n const queryEngine: AnalyticsModel = dataSources.db.Analytics;\n const results = await queryEngine.multiCurrencyQuery(filter);\n\n return results.map((s) => ({\n ...s,\n rows: s.rows.map((r: any) => ({\n ...r,\n dimensions: Object.keys(r.dimensions).map((d) => ({\n name: d,\n path: r.dimensions[d][\"path\"],\n icon: r.dimensions[d][\"icon\"],\n label: r.dimensions[d][\"label\"],\n description: r.dimensions[d][\"description\"],\n })),\n })),\n }));\n },\n },\n};\n","import type { AnalyticsQueryEngine } from \"@powerhousedao/analytics-engine-core\";\nimport {\n AnalyticsGranularity,\n AnalyticsPath,\n type AnalyticsQuery,\n} from \"@powerhousedao/analytics-engine-core\";\nimport { DateTime } from \"luxon\";\n\nexport type queryFilter = {\n start?: string;\n end?: string;\n granularity?: string;\n metrics: string[];\n dimensions: [Record<string, string>];\n currency?: string;\n};\n\ntype CurrencyConversion = {\n metric: string;\n sourceCurrency: string;\n};\n\ntype MultiCurrencyFilter = queryFilter & {\n conversions: CurrencyConversion[];\n};\n\nexport class AnalyticsModel {\n queryLogger: (query: AnalyticsQuery) => void;\n\n constructor(\n public readonly engine: AnalyticsQueryEngine,\n queryLogger?: (query: AnalyticsQuery) => void,\n ) {\n this.queryLogger = queryLogger || (() => {});\n }\n\n public async query(filter: queryFilter) {\n if (!filter) {\n return [];\n }\n\n const query: AnalyticsQuery = {\n start: filter.start ? DateTime.fromISO(filter.start) : null,\n end: filter.end ? DateTime.fromISO(filter.end) : null,\n granularity: getGranularity(filter.granularity),\n metrics: filter.metrics,\n currency: getCurrency(filter.currency),\n select: {},\n lod: {},\n };\n\n if (query.start && !query.start.isValid) {\n query.start = null;\n }\n\n if (query.end && !query.end.isValid) {\n query.end = null;\n }\n\n if (filter.dimensions.length < 1) {\n throw new Error(\"No dimensions provided\");\n } else {\n filter.dimensions.forEach((dimension) => {\n query.select[dimension.name] = [\n AnalyticsPath.fromString(dimension.select),\n ];\n query.lod[dimension.name] = Number(dimension.lod);\n });\n }\n\n this.queryLogger(query);\n\n const results = await this.engine.execute(query);\n\n // convert dates again\n const convertedResults = results.map((r) => ({\n ...r,\n start: r.start.toJSDate(),\n end: r.end.toJSDate(),\n }));\n\n return convertedResults;\n\n // TODO: pull caching interface out into analytics module\n //return measureAnalyticsQueryPerformance('analyticsQuery', 'analyticsQuery', query, false, \"high\");\n }\n\n public async multiCurrencyQuery(filter: MultiCurrencyFilter) {\n if (!filter) {\n return [];\n }\n\n const query: AnalyticsQuery = {\n start: filter.start ? DateTime.fromISO(filter.start) : null,\n end: filter.end ? DateTime.fromISO(filter.end) : null,\n granularity: getGranularity(filter.granularity),\n metrics: filter.metrics,\n currency: getCurrency(filter.currency),\n select: {},\n lod: {},\n };\n\n if (query.start && !query.start.isValid) {\n query.start = null;\n }\n\n if (query.end && !query.end.isValid) {\n query.end = null;\n }\n\n if (filter.dimensions.length < 1) {\n throw new Error(\"No dimensions provided\");\n } else {\n filter.dimensions.forEach((dimension) => {\n query.select[dimension.name] = [\n AnalyticsPath.fromString(dimension.select),\n ];\n query.lod[dimension.name] = Number(dimension.lod);\n });\n }\n\n this.queryLogger(query);\n\n return this.engine.executeMultiCurrency(query, {\n targetCurrency: query.currency,\n conversions: filter.conversions.map((c) => {\n return {\n metric: c.metric,\n currency: getCurrency(c.sourceCurrency),\n };\n }),\n });\n }\n\n public async getDimensions() {\n return await this.engine.getDimensions();\n }\n\n public async getCurrencies() {\n // todo: use knex inside of the analytics engine to select distinct currencies\n return [\"DAI\", \"FTE\", \"MKR\", \"USDC\", \"USDP\", \"USDT\"];\n }\n}\n\nconst getGranularity = (\n granularity: string | undefined,\n): AnalyticsGranularity => {\n switch (granularity) {\n case \"hourly\": {\n return AnalyticsGranularity.Hourly;\n }\n case \"daily\": {\n return AnalyticsGranularity.Daily;\n }\n case \"weekly\": {\n return AnalyticsGranularity.Weekly;\n }\n case \"monthly\": {\n return AnalyticsGranularity.Monthly;\n }\n case \"quarterly\": {\n return AnalyticsGranularity.Quarterly;\n }\n case \"semiAnnual\": {\n return AnalyticsGranularity.SemiAnnual;\n }\n case \"annual\": {\n return AnalyticsGranularity.Annual;\n }\n case \"total\": {\n return AnalyticsGranularity.Total;\n }\n default: {\n return AnalyticsGranularity.Total;\n }\n }\n};\n\nconst getCurrency = (currency: string | undefined) => {\n return currency ? AnalyticsPath.fromString(currency) : undefined;\n};\n","export const typedefs = `\ntype AnalyticsQuery {\n series(filter: AnalyticsFilter): [AnalyticsPeriod]\n multiCurrencySeries(filter: MultiCurrencyConversions): [AnalyticsPeriod]\n metrics: [String]\n dimensions: [Dimension]\n currencies: [String]\n}\n\ntype AnalyticsPeriod {\n period: String\n start: DateTime\n end: DateTime\n rows: [AnalyticsSeries]\n}\n\ntype AnalyticsSeries {\n dimensions: [AnalyticsSeriesDimension]\n metric: String\n unit: String\n value: Float\n sum: Float\n}\n\ntype AnalyticsSeriesDimension {\n name: String\n path: String\n label: String\n description: String\n icon: String\n}\n\ntype Dimension {\n name: String\n values: [Value]\n}\n\ntype Value {\n path: String\n label: String\n description: String\n icon: String\n}\n\nenum AnalyticsGranularity {\n hourly\n daily\n weekly\n monthly\n quarterly\n semiAnnual\n annual\n total\n}\n\ninput AnalyticsFilterDimension {\n name: String!\n select: String!\n lod: Int!\n}\n\ninput MultiCurrencyConversions {\n start: String\n end: String\n \"Period to group by\"\n granularity: AnalyticsGranularity\n \"List of metrics to filter by, such as 'budget' or 'actuals'\"\n metrics: [String]\n \"List of dimensions to filter by, such as 'budget' or 'project'\"\n dimensions: [AnalyticsFilterDimension]\n currency: String\n conversions: [CurrencyConversion]!\n}\n\ninput CurrencyConversion {\n metric: String!\n sourceCurrency: String!\n}\n\ninput AnalyticsFilter {\n start: String\n end: String\n \"Period to group by\"\n granularity: AnalyticsGranularity\n \"List of metrics to filter by, such as 'budget' or 'actuals'\"\n metrics: [String]\n \"List of dimensions to filter by, such as 'budget' or 'project'\"\n dimensions: [AnalyticsFilterDimension]\n currency: String\n}\n\nextend type Query {\n analytics: AnalyticsQuery\n}\n`;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/analytics-engine-graphql",
|
|
3
|
-
"version": "6.0.0-dev.
|
|
3
|
+
"version": "6.0.0-dev.106",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,21 +12,24 @@
|
|
|
12
12
|
"type": "module",
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
|
-
"types": "./dist/
|
|
16
|
-
"import": "./dist/
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
|
-
"dist
|
|
20
|
+
"dist"
|
|
21
21
|
],
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"luxon": "3.7.2",
|
|
24
|
+
"@powerhousedao/analytics-engine-core": "6.0.0-dev.106"
|
|
25
|
+
},
|
|
22
26
|
"devDependencies": {
|
|
23
27
|
"vitest": "3.2.4",
|
|
24
28
|
"@types/luxon": "3.7.1",
|
|
25
|
-
"
|
|
26
|
-
"@powerhousedao/analytics-engine-core": "6.0.0-dev.105"
|
|
29
|
+
"tsdown": "0.21.0"
|
|
27
30
|
},
|
|
28
31
|
"scripts": {
|
|
29
32
|
"test": "vitest --run ./**/*.test.ts",
|
|
30
|
-
"build:bundle": "
|
|
33
|
+
"build:bundle": "tsdown"
|
|
31
34
|
}
|
|
32
35
|
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { AnalyticsQueryEngine } from "@powerhousedao/analytics-engine-core";
|
|
2
|
-
import { type AnalyticsQuery } from "@powerhousedao/analytics-engine-core";
|
|
3
|
-
export type queryFilter = {
|
|
4
|
-
start?: string;
|
|
5
|
-
end?: string;
|
|
6
|
-
granularity?: string;
|
|
7
|
-
metrics: string[];
|
|
8
|
-
dimensions: [Record<string, string>];
|
|
9
|
-
currency?: string;
|
|
10
|
-
};
|
|
11
|
-
type CurrencyConversion = {
|
|
12
|
-
metric: string;
|
|
13
|
-
sourceCurrency: string;
|
|
14
|
-
};
|
|
15
|
-
type MultiCurrencyFilter = queryFilter & {
|
|
16
|
-
conversions: CurrencyConversion[];
|
|
17
|
-
};
|
|
18
|
-
export declare class AnalyticsModel {
|
|
19
|
-
readonly engine: AnalyticsQueryEngine;
|
|
20
|
-
queryLogger: (query: AnalyticsQuery) => void;
|
|
21
|
-
constructor(engine: AnalyticsQueryEngine, queryLogger?: (query: AnalyticsQuery) => void);
|
|
22
|
-
query(filter: queryFilter): Promise<{
|
|
23
|
-
start: Date;
|
|
24
|
-
end: Date;
|
|
25
|
-
period: string;
|
|
26
|
-
rows: Array<{
|
|
27
|
-
dimensions: Record<string, import("@powerhousedao/analytics-engine-core").AnalyticsDimension>;
|
|
28
|
-
metric: string;
|
|
29
|
-
unit: string | null;
|
|
30
|
-
value: number;
|
|
31
|
-
sum: number;
|
|
32
|
-
}>;
|
|
33
|
-
}[]>;
|
|
34
|
-
multiCurrencyQuery(filter: MultiCurrencyFilter): Promise<import("@powerhousedao/analytics-engine-core").GroupedPeriodResults>;
|
|
35
|
-
getDimensions(): Promise<any>;
|
|
36
|
-
getCurrencies(): Promise<string[]>;
|
|
37
|
-
}
|
|
38
|
-
export {};
|
|
39
|
-
//# sourceMappingURL=AnalyticsModel.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsModel.d.ts","sourceRoot":"","sources":["../../src/AnalyticsModel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,sCAAsC,CAAC;AAG9C,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,mBAAmB,GAAG,WAAW,GAAG;IACvC,WAAW,EAAE,kBAAkB,EAAE,CAAC;CACnC,CAAC;AAEF,qBAAa,cAAc;aAIP,MAAM,EAAE,oBAAoB;IAH9C,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;gBAG3B,MAAM,EAAE,oBAAoB,EAC5C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI;IAKlC,KAAK,CAAC,MAAM,EAAE,WAAW;;;;;;;;;;;;IAmDzB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB;IA+C9C,aAAa;IAIb,aAAa;CAI3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsResolvers.d.ts","sourceRoot":"","sources":["../../src/AnalyticsResolvers.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,EAAE,GAwEhC,CAAC"}
|
package/dist/src/index.d.ts
DELETED
package/dist/src/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
|