@topolo/sdk 0.7.0 → 0.8.1
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/README.md +11 -3
- package/dist/index.cjs +258 -53
- package/dist/index.d.cts +76 -8
- package/dist/index.d.ts +76 -8
- package/dist/index.js +255 -53
- package/dist/node/credential-store.cjs +16 -5
- package/dist/node/credential-store.d.cts +3 -1
- package/dist/node/credential-store.d.ts +3 -1
- package/dist/node/credential-store.js +16 -5
- package/package.json +5 -4
- package/src/application-requirements.ts +0 -517
- package/src/applications.generated.ts +0 -1509
- package/src/auth.ts +0 -48
- package/src/client.test.ts +0 -894
- package/src/client.ts +0 -1025
- package/src/errors.ts +0 -39
- package/src/index.test.ts +0 -69
- package/src/index.ts +0 -125
- package/src/modules/crm.test.ts +0 -208
- package/src/modules/crm.ts +0 -110
- package/src/modules/identity.test.ts +0 -165
- package/src/modules/identity.ts +0 -18
- package/src/modules/p2p.test.ts +0 -540
- package/src/modules/p2p.ts +0 -448
- package/src/node/credential-store.ts +0 -378
- package/src/oauth.test.ts +0 -216
- package/src/oauth.ts +0 -138
- package/src/services.generated.ts +0 -55
- package/src/services.test.ts +0 -243
- package/src/services.ts +0 -138
- package/src/widgets.test.ts +0 -416
- package/src/widgets.ts +0 -362
package/src/widgets.ts
DELETED
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
export const TOPOLO_WIDGET_ENDPOINT = "/api/widget";
|
|
2
|
-
export const TOPOLO_WIDGET_REFRESH_INTERVAL_MS = 60_000;
|
|
3
|
-
|
|
4
|
-
export type TopoloWidgetType =
|
|
5
|
-
| "stats"
|
|
6
|
-
| "recent-activity"
|
|
7
|
-
| "quick-actions"
|
|
8
|
-
| "notifications"
|
|
9
|
-
| "chart";
|
|
10
|
-
|
|
11
|
-
export interface TopoloWidgetBase {
|
|
12
|
-
appId: string;
|
|
13
|
-
serviceName: string;
|
|
14
|
-
serviceIcon?: string;
|
|
15
|
-
type: TopoloWidgetType;
|
|
16
|
-
lastUpdated: string;
|
|
17
|
-
snapshot: TopoloWidgetSnapshotMetadata;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface TopoloWidgetMetric {
|
|
21
|
-
key?: string;
|
|
22
|
-
label: string;
|
|
23
|
-
value: string | number;
|
|
24
|
-
change?: number;
|
|
25
|
-
changeLabel?: string;
|
|
26
|
-
icon?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface TopoloWidgetSnapshotMetric {
|
|
30
|
-
key: string;
|
|
31
|
-
label: string;
|
|
32
|
-
value: number;
|
|
33
|
-
unit?: string;
|
|
34
|
-
change?: number;
|
|
35
|
-
changeLabel?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface TopoloWidgetSnapshotMetadata {
|
|
39
|
-
presetKey?: string;
|
|
40
|
-
audience?: string;
|
|
41
|
-
scope?: string;
|
|
42
|
-
scopeLabel?: string;
|
|
43
|
-
generatedAt?: string;
|
|
44
|
-
summary: string;
|
|
45
|
-
defaultMetricKeys?: string[];
|
|
46
|
-
availableMetrics?: TopoloWidgetSnapshotMetric[];
|
|
47
|
-
highlights?: string[];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface TopoloStatsWidget extends TopoloWidgetBase {
|
|
51
|
-
type: "stats";
|
|
52
|
-
stats: TopoloWidgetMetric[];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface TopoloWidgetActivityItem {
|
|
56
|
-
id: string;
|
|
57
|
-
title: string;
|
|
58
|
-
description?: string;
|
|
59
|
-
timestamp: string;
|
|
60
|
-
icon?: string;
|
|
61
|
-
link?: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface TopoloRecentActivityWidget extends TopoloWidgetBase {
|
|
65
|
-
type: "recent-activity";
|
|
66
|
-
activities: TopoloWidgetActivityItem[];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface TopoloWidgetActionItem {
|
|
70
|
-
id: string;
|
|
71
|
-
label: string;
|
|
72
|
-
icon?: string;
|
|
73
|
-
link: string;
|
|
74
|
-
primary?: boolean;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface TopoloQuickActionsWidget extends TopoloWidgetBase {
|
|
78
|
-
type: "quick-actions";
|
|
79
|
-
actions: TopoloWidgetActionItem[];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface TopoloWidgetNotificationItem {
|
|
83
|
-
id: string;
|
|
84
|
-
title: string;
|
|
85
|
-
message: string;
|
|
86
|
-
type: "info" | "warning" | "error" | "success";
|
|
87
|
-
timestamp: string;
|
|
88
|
-
read: boolean;
|
|
89
|
-
link?: string;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export interface TopoloNotificationsWidget extends TopoloWidgetBase {
|
|
93
|
-
type: "notifications";
|
|
94
|
-
notifications: TopoloWidgetNotificationItem[];
|
|
95
|
-
unreadCount: number;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface TopoloChartWidget extends TopoloWidgetBase {
|
|
99
|
-
type: "chart";
|
|
100
|
-
chartType: "line" | "bar" | "pie" | "donut";
|
|
101
|
-
title: string;
|
|
102
|
-
data: {
|
|
103
|
-
labels: string[];
|
|
104
|
-
values: number[];
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export type TopoloWidget =
|
|
109
|
-
| TopoloStatsWidget
|
|
110
|
-
| TopoloRecentActivityWidget
|
|
111
|
-
| TopoloQuickActionsWidget
|
|
112
|
-
| TopoloNotificationsWidget
|
|
113
|
-
| TopoloChartWidget;
|
|
114
|
-
|
|
115
|
-
type TopoloWidgetWithOptionalMetadata<T extends TopoloWidget> = Omit<
|
|
116
|
-
T,
|
|
117
|
-
"appId" | "serviceName" | "lastUpdated"
|
|
118
|
-
> &
|
|
119
|
-
Partial<Pick<TopoloWidgetBase, "appId" | "serviceName" | "lastUpdated">>;
|
|
120
|
-
|
|
121
|
-
export type TopoloWidgetDraft = TopoloWidget extends infer Widget
|
|
122
|
-
? Widget extends TopoloWidget
|
|
123
|
-
? TopoloWidgetWithOptionalMetadata<Widget>
|
|
124
|
-
: never
|
|
125
|
-
: never;
|
|
126
|
-
|
|
127
|
-
export interface TopoloWidgetApiResponse {
|
|
128
|
-
success: boolean;
|
|
129
|
-
widgets: TopoloWidget[];
|
|
130
|
-
error?: string;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export interface TopoloWidgetResponseOptions {
|
|
134
|
-
appId: string;
|
|
135
|
-
serviceName: string;
|
|
136
|
-
widgets: TopoloWidgetDraft[];
|
|
137
|
-
now?: Date | string;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export interface TopoloWidgetValidationResult {
|
|
141
|
-
ok: boolean;
|
|
142
|
-
errors: string[];
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface TopoloWidgetConfig {
|
|
146
|
-
appId: string;
|
|
147
|
-
serviceName: string;
|
|
148
|
-
baseUrl: string;
|
|
149
|
-
widgetEndpoint: string;
|
|
150
|
-
enabled: boolean;
|
|
151
|
-
refreshInterval: number;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export function defineTopoloStatsWidget(
|
|
155
|
-
widget: Omit<TopoloStatsWidget, "type">,
|
|
156
|
-
): TopoloStatsWidget {
|
|
157
|
-
return { ...widget, type: "stats" };
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export function defineTopoloRecentActivityWidget(
|
|
161
|
-
widget: Omit<TopoloRecentActivityWidget, "type">,
|
|
162
|
-
): TopoloRecentActivityWidget {
|
|
163
|
-
return { ...widget, type: "recent-activity" };
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export function defineTopoloQuickActionsWidget(
|
|
167
|
-
widget: Omit<TopoloQuickActionsWidget, "type">,
|
|
168
|
-
): TopoloQuickActionsWidget {
|
|
169
|
-
return { ...widget, type: "quick-actions" };
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export function defineTopoloNotificationsWidget(
|
|
173
|
-
widget: Omit<TopoloNotificationsWidget, "type">,
|
|
174
|
-
): TopoloNotificationsWidget {
|
|
175
|
-
return { ...widget, type: "notifications" };
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function defineTopoloChartWidget(
|
|
179
|
-
widget: Omit<TopoloChartWidget, "type">,
|
|
180
|
-
): TopoloChartWidget {
|
|
181
|
-
return { ...widget, type: "chart" };
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export function createTopoloWidgetResponse({
|
|
185
|
-
appId,
|
|
186
|
-
serviceName,
|
|
187
|
-
widgets,
|
|
188
|
-
now,
|
|
189
|
-
}: TopoloWidgetResponseOptions): TopoloWidgetApiResponse {
|
|
190
|
-
const lastUpdated = toIsoTimestamp(now);
|
|
191
|
-
|
|
192
|
-
return {
|
|
193
|
-
success: true,
|
|
194
|
-
widgets: widgets.map((widget) => ({
|
|
195
|
-
...widget,
|
|
196
|
-
appId: widget.appId?.trim() || appId,
|
|
197
|
-
serviceName: widget.serviceName?.trim() || serviceName,
|
|
198
|
-
lastUpdated: widget.lastUpdated?.trim() || lastUpdated,
|
|
199
|
-
})) as TopoloWidget[],
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export function createTopoloWidgetError(
|
|
204
|
-
error: string,
|
|
205
|
-
): TopoloWidgetApiResponse {
|
|
206
|
-
return {
|
|
207
|
-
success: false,
|
|
208
|
-
widgets: [],
|
|
209
|
-
error,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export function validateTopoloWidgetResponse(
|
|
214
|
-
response: unknown,
|
|
215
|
-
): TopoloWidgetValidationResult {
|
|
216
|
-
const errors: string[] = [];
|
|
217
|
-
|
|
218
|
-
if (!isRecord(response)) {
|
|
219
|
-
return { ok: false, errors: ["response must be an object"] };
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (typeof response.success !== "boolean") {
|
|
223
|
-
errors.push("success must be a boolean");
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (!Array.isArray(response.widgets)) {
|
|
227
|
-
errors.push("widgets must be an array");
|
|
228
|
-
return { ok: errors.length === 0, errors };
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
response.widgets.forEach((widget, index) => {
|
|
232
|
-
validateWidget(widget, `widgets[${index}]`, errors);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
if (
|
|
236
|
-
response.success === false &&
|
|
237
|
-
response.error !== undefined &&
|
|
238
|
-
typeof response.error !== "string"
|
|
239
|
-
) {
|
|
240
|
-
errors.push("error must be a string when provided");
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return { ok: errors.length === 0, errors };
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function validateWidget(widget: unknown, path: string, errors: string[]) {
|
|
247
|
-
if (!isRecord(widget)) {
|
|
248
|
-
errors.push(`${path} must be an object`);
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
validateNonEmptyString(widget.appId, `${path}.appId`, errors);
|
|
253
|
-
validateNonEmptyString(widget.serviceName, `${path}.serviceName`, errors);
|
|
254
|
-
validateNonEmptyString(widget.lastUpdated, `${path}.lastUpdated`, errors);
|
|
255
|
-
validateSnapshotMetadata(widget.snapshot, `${path}.snapshot`, errors);
|
|
256
|
-
|
|
257
|
-
switch (widget.type) {
|
|
258
|
-
case "stats":
|
|
259
|
-
validateArray(widget.stats, `${path}.stats`, errors);
|
|
260
|
-
break;
|
|
261
|
-
case "recent-activity":
|
|
262
|
-
validateArray(widget.activities, `${path}.activities`, errors);
|
|
263
|
-
break;
|
|
264
|
-
case "quick-actions":
|
|
265
|
-
validateArray(widget.actions, `${path}.actions`, errors);
|
|
266
|
-
break;
|
|
267
|
-
case "notifications":
|
|
268
|
-
validateArray(widget.notifications, `${path}.notifications`, errors);
|
|
269
|
-
if (typeof widget.unreadCount !== "number") {
|
|
270
|
-
errors.push(`${path}.unreadCount must be a number`);
|
|
271
|
-
}
|
|
272
|
-
break;
|
|
273
|
-
case "chart":
|
|
274
|
-
validateNonEmptyString(widget.chartType, `${path}.chartType`, errors);
|
|
275
|
-
validateNonEmptyString(widget.title, `${path}.title`, errors);
|
|
276
|
-
if (!isRecord(widget.data)) {
|
|
277
|
-
errors.push(`${path}.data must be an object`);
|
|
278
|
-
} else {
|
|
279
|
-
validateArray(widget.data.labels, `${path}.data.labels`, errors);
|
|
280
|
-
validateArray(widget.data.values, `${path}.data.values`, errors);
|
|
281
|
-
}
|
|
282
|
-
break;
|
|
283
|
-
default:
|
|
284
|
-
errors.push(`${path}.type must be a supported Topolo widget type`);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
function validateSnapshotMetadata(
|
|
289
|
-
snapshot: unknown,
|
|
290
|
-
path: string,
|
|
291
|
-
errors: string[],
|
|
292
|
-
) {
|
|
293
|
-
if (snapshot === undefined) {
|
|
294
|
-
errors.push(`${path} must be an object`);
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
if (!isRecord(snapshot)) {
|
|
298
|
-
errors.push(`${path} must be an object`);
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
validateNonEmptyString(snapshot.summary, `${path}.summary`, errors);
|
|
302
|
-
if (
|
|
303
|
-
snapshot.defaultMetricKeys !== undefined &&
|
|
304
|
-
!Array.isArray(snapshot.defaultMetricKeys)
|
|
305
|
-
) {
|
|
306
|
-
errors.push(`${path}.defaultMetricKeys must be an array when provided`);
|
|
307
|
-
}
|
|
308
|
-
if (
|
|
309
|
-
snapshot.highlights !== undefined &&
|
|
310
|
-
!Array.isArray(snapshot.highlights)
|
|
311
|
-
) {
|
|
312
|
-
errors.push(`${path}.highlights must be an array when provided`);
|
|
313
|
-
}
|
|
314
|
-
if (snapshot.availableMetrics === undefined) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
if (!Array.isArray(snapshot.availableMetrics)) {
|
|
318
|
-
errors.push(`${path}.availableMetrics must be an array when provided`);
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
snapshot.availableMetrics.forEach((metric, index) => {
|
|
323
|
-
const metricPath = `${path}.availableMetrics[${index}]`;
|
|
324
|
-
if (!isRecord(metric)) {
|
|
325
|
-
errors.push(`${metricPath} must be an object`);
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
validateNonEmptyString(metric.key, `${metricPath}.key`, errors);
|
|
329
|
-
validateNonEmptyString(metric.label, `${metricPath}.label`, errors);
|
|
330
|
-
if (typeof metric.value !== "number" || Number.isNaN(metric.value)) {
|
|
331
|
-
errors.push(`${metricPath}.value must be a number`);
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function validateNonEmptyString(
|
|
337
|
-
value: unknown,
|
|
338
|
-
path: string,
|
|
339
|
-
errors: string[],
|
|
340
|
-
) {
|
|
341
|
-
if (typeof value !== "string" || value.trim().length === 0) {
|
|
342
|
-
errors.push(`${path} must be a non-empty string`);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function validateArray(value: unknown, path: string, errors: string[]) {
|
|
347
|
-
if (!Array.isArray(value)) {
|
|
348
|
-
errors.push(`${path} must be an array`);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
353
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
function toIsoTimestamp(input: Date | string | undefined): string {
|
|
357
|
-
if (input instanceof Date) {
|
|
358
|
-
return input.toISOString();
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
return input ?? new Date().toISOString();
|
|
362
|
-
}
|