@topolo/sdk 0.13.0 → 0.14.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/dist/index.cjs +690 -8
- package/dist/index.d.cts +71 -2
- package/dist/index.d.ts +71 -2
- package/dist/index.js +688 -8
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3237,7 +3237,7 @@ var TopoloOAuth = class {
|
|
|
3237
3237
|
};
|
|
3238
3238
|
|
|
3239
3239
|
// src/widget-validation.ts
|
|
3240
|
-
var CONTRACT_VERSION = "
|
|
3240
|
+
var CONTRACT_VERSION = "3.0.0";
|
|
3241
3241
|
var WIDGET_TYPES = ["stats", "chart", "activity", "notifications", "actions"];
|
|
3242
3242
|
var CONTEXTS = ["personal", "organization", "workspace", "resource"];
|
|
3243
3243
|
var SIZES = ["compact", "medium", "wide", "full"];
|
|
@@ -3248,6 +3248,9 @@ var AGGREGATIONS = ["last", "sum", "average", "minimum", "maximum", "count", "di
|
|
|
3248
3248
|
var CHART_TYPES = ["line", "bar", "area", "pie", "donut"];
|
|
3249
3249
|
var SEVERITIES = ["info", "warning", "error", "success"];
|
|
3250
3250
|
var RECOVERY_MODES = ["not_applicable", "retry", "compensating_action"];
|
|
3251
|
+
var VISUALIZATION_FAMILIES = ["number", "line", "area", "bar", "donut", "table", "funnel", "timeline", "actions"];
|
|
3252
|
+
var WORKSPACE_SELECTOR_MODES = ["none", "optional", "required"];
|
|
3253
|
+
var DIMENSION_VALUE_TYPES = ["string", "number", "boolean", "date", "datetime"];
|
|
3251
3254
|
var SEMVER = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
3252
3255
|
function validateTopoloWidgetResponse(response) {
|
|
3253
3256
|
const errors = [];
|
|
@@ -3298,6 +3301,7 @@ function validateWidget(value, path, errors) {
|
|
|
3298
3301
|
validateActions(value.controls, `${path}.controls`, errors);
|
|
3299
3302
|
validateLocalization(value.localization, `${path}.localization`, errors);
|
|
3300
3303
|
validateAccessibility(value.accessibility, `${path}.accessibility`, errors);
|
|
3304
|
+
validateContribution(value.contribution, `${path}.contribution`, value, errors);
|
|
3301
3305
|
switch (value.type) {
|
|
3302
3306
|
case "stats":
|
|
3303
3307
|
validateMetrics(value.metrics, `${path}.metrics`, errors, requiresContent(value));
|
|
@@ -3435,6 +3439,208 @@ function validateAccessibility(value, path, errors) {
|
|
|
3435
3439
|
nonEmptyString(value.label, `${path}.label`, errors);
|
|
3436
3440
|
optionalNonEmptyString(value.description, `${path}.description`, errors);
|
|
3437
3441
|
}
|
|
3442
|
+
function validateContribution(value, path, widget, errors) {
|
|
3443
|
+
if (!recordValue(value, path, errors)) return;
|
|
3444
|
+
nonEmptyString(value.summary, `${path}.summary`, errors);
|
|
3445
|
+
if (recordValue(value.identity, `${path}.identity`, errors)) {
|
|
3446
|
+
exactValue(value.identity.iconSource, "catalog", `${path}.identity.iconSource`, errors);
|
|
3447
|
+
}
|
|
3448
|
+
if (recordValue(value.workspaceSelector, `${path}.workspaceSelector`, errors)) {
|
|
3449
|
+
enumValue(value.workspaceSelector.mode, WORKSPACE_SELECTOR_MODES, `${path}.workspaceSelector.mode`, errors);
|
|
3450
|
+
nonEmptyString(value.workspaceSelector.resourceType, `${path}.workspaceSelector.resourceType`, errors);
|
|
3451
|
+
nonEmptyString(value.workspaceSelector.label, `${path}.workspaceSelector.label`, errors);
|
|
3452
|
+
booleanValue(value.workspaceSelector.supportsMultiple, `${path}.workspaceSelector.supportsMultiple`, errors);
|
|
3453
|
+
if (value.workspaceSelector.mode === "required" && requiresContent(widget) && isRecord5(widget.resource) && typeof widget.resource.resourceId !== "string") {
|
|
3454
|
+
errors.push(`${path}.workspaceSelector requires a bound resourceId for ready or stale data`);
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
3457
|
+
const metricKeys = validateMetricDefinitions(value.metricDefinitions, `${path}.metricDefinitions`, errors);
|
|
3458
|
+
const seriesKeys = validateSeriesDefinitions(value.seriesDefinitions, `${path}.seriesDefinitions`, metricKeys, errors);
|
|
3459
|
+
const dimensionKeys = validateDimensionDefinitions(value.dimensions, `${path}.dimensions`, errors);
|
|
3460
|
+
const lifecycleKeys = validateLifecycleStages(value.lifecycleStages, `${path}.lifecycleStages`, errors);
|
|
3461
|
+
const eventKeys = validateEventDefinitions(value.events, `${path}.events`, errors);
|
|
3462
|
+
const actionKeys = widgetActionKeys(widget);
|
|
3463
|
+
validateDatasets(value.datasets, `${path}.datasets`, {
|
|
3464
|
+
metricKeys,
|
|
3465
|
+
seriesKeys,
|
|
3466
|
+
dimensionKeys,
|
|
3467
|
+
eventKeys,
|
|
3468
|
+
actionKeys
|
|
3469
|
+
}, errors);
|
|
3470
|
+
enumArray(
|
|
3471
|
+
value.compatibleVisualizations,
|
|
3472
|
+
VISUALIZATION_FAMILIES,
|
|
3473
|
+
`${path}.compatibleVisualizations`,
|
|
3474
|
+
errors,
|
|
3475
|
+
true
|
|
3476
|
+
);
|
|
3477
|
+
enumValue(value.defaultVisualization, VISUALIZATION_FAMILIES, `${path}.defaultVisualization`, errors);
|
|
3478
|
+
if (typeof value.defaultVisualization === "string" && Array.isArray(value.compatibleVisualizations) && !value.compatibleVisualizations.includes(value.defaultVisualization)) {
|
|
3479
|
+
errors.push(`${path}.defaultVisualization must be included in compatibleVisualizations`);
|
|
3480
|
+
}
|
|
3481
|
+
if (Array.isArray(value.compatibleVisualizations)) {
|
|
3482
|
+
for (const family of value.compatibleVisualizations) {
|
|
3483
|
+
if (family === "number" && metricKeys.size === 0) errors.push(`${path}.compatibleVisualizations number requires a metric definition`);
|
|
3484
|
+
if ((family === "line" || family === "area") && seriesKeys.size === 0) errors.push(`${path}.compatibleVisualizations ${family} requires a series definition`);
|
|
3485
|
+
if (family === "donut" && (metricKeys.size === 0 || dimensionKeys.size === 0)) errors.push(`${path}.compatibleVisualizations donut requires metric and dimension definitions`);
|
|
3486
|
+
if (family === "funnel" && lifecycleKeys.size < 2) errors.push(`${path}.compatibleVisualizations funnel requires at least two lifecycle stages`);
|
|
3487
|
+
if (family === "timeline" && eventKeys.size === 0) errors.push(`${path}.compatibleVisualizations timeline requires an event definition`);
|
|
3488
|
+
if (family === "actions" && actionKeys.size === 0) errors.push(`${path}.compatibleVisualizations actions requires a published action`);
|
|
3489
|
+
if (family === "bar" && metricKeys.size === 0 && seriesKeys.size === 0) errors.push(`${path}.compatibleVisualizations bar requires a metric or series definition`);
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
validateRuntimeSemantics(widget, path, { metricKeys, seriesKeys, dimensionKeys }, errors);
|
|
3493
|
+
}
|
|
3494
|
+
function validateMetricDefinitions(value, path, errors) {
|
|
3495
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3496
|
+
if (!arrayValue(value, path, errors)) return keys;
|
|
3497
|
+
value.forEach((definition, index) => {
|
|
3498
|
+
const itemPath = `${path}[${index}]`;
|
|
3499
|
+
if (!recordValue(definition, itemPath, errors)) return;
|
|
3500
|
+
nonEmptyString(definition.key, `${itemPath}.key`, errors);
|
|
3501
|
+
nonEmptyString(definition.label, `${itemPath}.label`, errors);
|
|
3502
|
+
nonEmptyString(definition.description, `${itemPath}.description`, errors);
|
|
3503
|
+
nonEmptyString(definition.unit, `${itemPath}.unit`, errors);
|
|
3504
|
+
enumValue(definition.semantic, SEMANTICS, `${itemPath}.semantic`, errors);
|
|
3505
|
+
enumValue(definition.aggregation, AGGREGATIONS, `${itemPath}.aggregation`, errors);
|
|
3506
|
+
addUniqueKey(definition.key, itemPath, keys, errors);
|
|
3507
|
+
});
|
|
3508
|
+
return keys;
|
|
3509
|
+
}
|
|
3510
|
+
function validateSeriesDefinitions(value, path, metricKeys, errors) {
|
|
3511
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3512
|
+
if (!arrayValue(value, path, errors)) return keys;
|
|
3513
|
+
value.forEach((definition, index) => {
|
|
3514
|
+
const itemPath = `${path}[${index}]`;
|
|
3515
|
+
if (!recordValue(definition, itemPath, errors)) return;
|
|
3516
|
+
nonEmptyString(definition.key, `${itemPath}.key`, errors);
|
|
3517
|
+
nonEmptyString(definition.label, `${itemPath}.label`, errors);
|
|
3518
|
+
nonEmptyString(definition.metricKey, `${itemPath}.metricKey`, errors);
|
|
3519
|
+
nonEmptyString(definition.unit, `${itemPath}.unit`, errors);
|
|
3520
|
+
addUniqueKey(definition.key, itemPath, keys, errors);
|
|
3521
|
+
if (typeof definition.metricKey === "string" && !metricKeys.has(definition.metricKey)) {
|
|
3522
|
+
errors.push(`${itemPath}.metricKey must reference a declared metric definition`);
|
|
3523
|
+
}
|
|
3524
|
+
});
|
|
3525
|
+
return keys;
|
|
3526
|
+
}
|
|
3527
|
+
function validateDimensionDefinitions(value, path, errors) {
|
|
3528
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3529
|
+
if (!arrayValue(value, path, errors)) return keys;
|
|
3530
|
+
value.forEach((definition, index) => {
|
|
3531
|
+
const itemPath = `${path}[${index}]`;
|
|
3532
|
+
if (!recordValue(definition, itemPath, errors)) return;
|
|
3533
|
+
nonEmptyString(definition.key, `${itemPath}.key`, errors);
|
|
3534
|
+
nonEmptyString(definition.label, `${itemPath}.label`, errors);
|
|
3535
|
+
nonEmptyString(definition.description, `${itemPath}.description`, errors);
|
|
3536
|
+
enumValue(definition.valueType, DIMENSION_VALUE_TYPES, `${itemPath}.valueType`, errors);
|
|
3537
|
+
addUniqueKey(definition.key, itemPath, keys, errors);
|
|
3538
|
+
});
|
|
3539
|
+
return keys;
|
|
3540
|
+
}
|
|
3541
|
+
function validateLifecycleStages(value, path, errors) {
|
|
3542
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3543
|
+
const orders = /* @__PURE__ */ new Set();
|
|
3544
|
+
if (!arrayValue(value, path, errors)) return keys;
|
|
3545
|
+
value.forEach((stage, index) => {
|
|
3546
|
+
const itemPath = `${path}[${index}]`;
|
|
3547
|
+
if (!recordValue(stage, itemPath, errors)) return;
|
|
3548
|
+
nonEmptyString(stage.key, `${itemPath}.key`, errors);
|
|
3549
|
+
nonEmptyString(stage.label, `${itemPath}.label`, errors);
|
|
3550
|
+
nonNegativeInteger(stage.order, `${itemPath}.order`, errors);
|
|
3551
|
+
booleanValue(stage.terminal, `${itemPath}.terminal`, errors);
|
|
3552
|
+
addUniqueKey(stage.key, itemPath, keys, errors);
|
|
3553
|
+
if (typeof stage.order === "number") {
|
|
3554
|
+
if (orders.has(stage.order)) errors.push(`${itemPath}.order must be unique`);
|
|
3555
|
+
orders.add(stage.order);
|
|
3556
|
+
}
|
|
3557
|
+
});
|
|
3558
|
+
return keys;
|
|
3559
|
+
}
|
|
3560
|
+
function validateEventDefinitions(value, path, errors) {
|
|
3561
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3562
|
+
if (!arrayValue(value, path, errors)) return keys;
|
|
3563
|
+
value.forEach((event, index) => {
|
|
3564
|
+
const itemPath = `${path}[${index}]`;
|
|
3565
|
+
if (!recordValue(event, itemPath, errors)) return;
|
|
3566
|
+
nonEmptyString(event.key, `${itemPath}.key`, errors);
|
|
3567
|
+
nonEmptyString(event.label, `${itemPath}.label`, errors);
|
|
3568
|
+
nonEmptyString(event.description, `${itemPath}.description`, errors);
|
|
3569
|
+
addUniqueKey(event.key, itemPath, keys, errors);
|
|
3570
|
+
});
|
|
3571
|
+
return keys;
|
|
3572
|
+
}
|
|
3573
|
+
function validateDatasets(value, path, references, errors) {
|
|
3574
|
+
const ids = /* @__PURE__ */ new Set();
|
|
3575
|
+
if (!arrayValue(value, path, errors, true)) return;
|
|
3576
|
+
value.forEach((dataset, index) => {
|
|
3577
|
+
const itemPath = `${path}[${index}]`;
|
|
3578
|
+
if (!recordValue(dataset, itemPath, errors)) return;
|
|
3579
|
+
nonEmptyString(dataset.id, `${itemPath}.id`, errors);
|
|
3580
|
+
nonEmptyString(dataset.label, `${itemPath}.label`, errors);
|
|
3581
|
+
nonEmptyString(dataset.description, `${itemPath}.description`, errors);
|
|
3582
|
+
nonEmptyString(dataset.grain, `${itemPath}.grain`, errors);
|
|
3583
|
+
addUniqueKey(dataset.id, itemPath, ids, errors);
|
|
3584
|
+
const fields = ["metricKeys", "seriesKeys", "dimensionKeys", "eventKeys", "actionIds"];
|
|
3585
|
+
for (const field of fields) stringArray2(dataset[field], `${itemPath}.${field}`, errors);
|
|
3586
|
+
const totalReferences = fields.reduce((total, field) => total + (Array.isArray(dataset[field]) ? dataset[field].length : 0), 0);
|
|
3587
|
+
if (totalReferences === 0) errors.push(`${itemPath} must reference at least one declared metric, series, dimension, event, or action`);
|
|
3588
|
+
validateReferences(dataset.metricKeys, references.metricKeys, `${itemPath}.metricKeys`, errors);
|
|
3589
|
+
validateReferences(dataset.seriesKeys, references.seriesKeys, `${itemPath}.seriesKeys`, errors);
|
|
3590
|
+
validateReferences(dataset.dimensionKeys, references.dimensionKeys, `${itemPath}.dimensionKeys`, errors);
|
|
3591
|
+
validateReferences(dataset.eventKeys, references.eventKeys, `${itemPath}.eventKeys`, errors);
|
|
3592
|
+
validateReferences(dataset.actionIds, references.actionKeys, `${itemPath}.actionIds`, errors);
|
|
3593
|
+
});
|
|
3594
|
+
}
|
|
3595
|
+
function validateReferences(value, known, path, errors) {
|
|
3596
|
+
if (!Array.isArray(value)) return;
|
|
3597
|
+
for (const reference of value) {
|
|
3598
|
+
if (typeof reference === "string" && !known.has(reference)) errors.push(`${path} references undeclared key ${reference}`);
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
function widgetActionKeys(widget) {
|
|
3602
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3603
|
+
for (const collection of [widget.controls, widget.actions]) {
|
|
3604
|
+
if (!Array.isArray(collection)) continue;
|
|
3605
|
+
for (const action of collection) if (isRecord5(action) && typeof action.id === "string") keys.add(action.id);
|
|
3606
|
+
}
|
|
3607
|
+
return keys;
|
|
3608
|
+
}
|
|
3609
|
+
function validateRuntimeSemantics(widget, contributionPath, declared, errors) {
|
|
3610
|
+
const metrics = Array.isArray(widget.metrics) ? widget.metrics : [];
|
|
3611
|
+
for (const metric of metrics) {
|
|
3612
|
+
if (!isRecord5(metric) || typeof metric.key !== "string") continue;
|
|
3613
|
+
if (!declared.metricKeys.has(metric.key)) errors.push(`${contributionPath}.metricDefinitions is missing runtime metric ${metric.key}`);
|
|
3614
|
+
validateRuntimeDimensions(metric.dimensions, declared.dimensionKeys, contributionPath, errors);
|
|
3615
|
+
if (isRecord5(metric.series)) {
|
|
3616
|
+
if (typeof metric.series.id === "string" && !declared.seriesKeys.has(metric.series.id)) errors.push(`${contributionPath}.seriesDefinitions is missing runtime series ${metric.series.id}`);
|
|
3617
|
+
validateSeriesDimensions(metric.series, declared.dimensionKeys, contributionPath, errors);
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
const series2 = Array.isArray(widget.series) ? widget.series : [];
|
|
3621
|
+
for (const item of series2) {
|
|
3622
|
+
if (!isRecord5(item)) continue;
|
|
3623
|
+
if (typeof item.id === "string" && !declared.seriesKeys.has(item.id)) errors.push(`${contributionPath}.seriesDefinitions is missing runtime series ${item.id}`);
|
|
3624
|
+
validateSeriesDimensions(item, declared.dimensionKeys, contributionPath, errors);
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
function validateSeriesDimensions(series2, known, path, errors) {
|
|
3628
|
+
if (!Array.isArray(series2.points)) return;
|
|
3629
|
+
for (const point of series2.points) if (isRecord5(point)) validateRuntimeDimensions(point.dimensions, known, path, errors);
|
|
3630
|
+
}
|
|
3631
|
+
function validateRuntimeDimensions(value, known, path, errors) {
|
|
3632
|
+
if (!Array.isArray(value)) return;
|
|
3633
|
+
for (const dimension2 of value) {
|
|
3634
|
+
if (isRecord5(dimension2) && typeof dimension2.key === "string" && !known.has(dimension2.key)) {
|
|
3635
|
+
errors.push(`${path}.dimensions is missing runtime dimension ${dimension2.key}`);
|
|
3636
|
+
}
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3639
|
+
function addUniqueKey(value, path, keys, errors) {
|
|
3640
|
+
if (typeof value !== "string" || value.trim().length === 0) return;
|
|
3641
|
+
if (keys.has(value)) errors.push(`${path}.key must be unique`);
|
|
3642
|
+
keys.add(value);
|
|
3643
|
+
}
|
|
3438
3644
|
function validateMetrics(value, path, errors, requireOne) {
|
|
3439
3645
|
if (!arrayValue(value, path, errors, requireOne)) return;
|
|
3440
3646
|
value.forEach((metric, index) => {
|
|
@@ -3463,12 +3669,12 @@ function validatePeriod(value, path, errors) {
|
|
|
3463
3669
|
}
|
|
3464
3670
|
function validateDimensions(value, path, errors) {
|
|
3465
3671
|
if (!arrayValue(value, path, errors)) return;
|
|
3466
|
-
value.forEach((
|
|
3672
|
+
value.forEach((dimension2, index) => {
|
|
3467
3673
|
const itemPath = `${path}[${index}]`;
|
|
3468
|
-
if (!recordValue(
|
|
3469
|
-
nonEmptyString(
|
|
3470
|
-
nonEmptyString(
|
|
3471
|
-
nonEmptyString(
|
|
3674
|
+
if (!recordValue(dimension2, itemPath, errors)) return;
|
|
3675
|
+
nonEmptyString(dimension2.key, `${itemPath}.key`, errors);
|
|
3676
|
+
nonEmptyString(dimension2.label, `${itemPath}.label`, errors);
|
|
3677
|
+
nonEmptyString(dimension2.value, `${itemPath}.value`, errors);
|
|
3472
3678
|
});
|
|
3473
3679
|
}
|
|
3474
3680
|
function validateComparison(value, path, errors) {
|
|
@@ -3482,7 +3688,7 @@ function validateComparison(value, path, errors) {
|
|
|
3482
3688
|
}
|
|
3483
3689
|
function validateSeriesCollection(value, path, errors, requireOne) {
|
|
3484
3690
|
if (!arrayValue(value, path, errors, requireOne)) return;
|
|
3485
|
-
value.forEach((
|
|
3691
|
+
value.forEach((series2, index) => validateSeries(series2, `${path}[${index}]`, errors));
|
|
3486
3692
|
}
|
|
3487
3693
|
function validateSeries(value, path, errors) {
|
|
3488
3694
|
if (!recordValue(value, path, errors)) return;
|
|
@@ -3602,7 +3808,7 @@ function isRecord5(value) {
|
|
|
3602
3808
|
// src/widgets.ts
|
|
3603
3809
|
var TOPOLO_WIDGET_ENDPOINT = "/api/widget";
|
|
3604
3810
|
var TOPOLO_WIDGET_REFRESH_INTERVAL_MS = 6e4;
|
|
3605
|
-
var TOPOLO_WIDGET_CONTRACT_VERSION = "
|
|
3811
|
+
var TOPOLO_WIDGET_CONTRACT_VERSION = "3.0.0";
|
|
3606
3812
|
function defineTopoloStatsWidget(widget) {
|
|
3607
3813
|
return { ...widget, type: "stats" };
|
|
3608
3814
|
}
|
|
@@ -3680,6 +3886,478 @@ function toIsoTimestamp(input) {
|
|
|
3680
3886
|
return input ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
3681
3887
|
}
|
|
3682
3888
|
|
|
3889
|
+
// src/widget-output-schema.ts
|
|
3890
|
+
var nonEmptyString2 = { type: "string", minLength: 1 };
|
|
3891
|
+
var stringArray3 = { type: "array", items: nonEmptyString2 };
|
|
3892
|
+
var actionBinding = {
|
|
3893
|
+
type: "object",
|
|
3894
|
+
properties: {
|
|
3895
|
+
id: nonEmptyString2,
|
|
3896
|
+
label: nonEmptyString2,
|
|
3897
|
+
actionId: nonEmptyString2,
|
|
3898
|
+
resourceType: nonEmptyString2,
|
|
3899
|
+
resourceId: nonEmptyString2,
|
|
3900
|
+
input: { type: "object" },
|
|
3901
|
+
requiresConfirmation: { type: "boolean" },
|
|
3902
|
+
destructive: { type: "boolean" },
|
|
3903
|
+
effects: stringArray3,
|
|
3904
|
+
verification: stringArray3,
|
|
3905
|
+
recovery: {
|
|
3906
|
+
type: "object",
|
|
3907
|
+
properties: {
|
|
3908
|
+
mode: { enum: ["not_applicable", "retry", "compensating_action"] },
|
|
3909
|
+
actionId: nonEmptyString2,
|
|
3910
|
+
instructions: nonEmptyString2
|
|
3911
|
+
},
|
|
3912
|
+
required: ["mode", "instructions"],
|
|
3913
|
+
additionalProperties: false
|
|
3914
|
+
}
|
|
3915
|
+
},
|
|
3916
|
+
required: [
|
|
3917
|
+
"id",
|
|
3918
|
+
"label",
|
|
3919
|
+
"actionId",
|
|
3920
|
+
"resourceType",
|
|
3921
|
+
"input",
|
|
3922
|
+
"requiresConfirmation",
|
|
3923
|
+
"destructive",
|
|
3924
|
+
"effects",
|
|
3925
|
+
"verification",
|
|
3926
|
+
"recovery"
|
|
3927
|
+
],
|
|
3928
|
+
additionalProperties: false
|
|
3929
|
+
};
|
|
3930
|
+
var dimension = {
|
|
3931
|
+
type: "object",
|
|
3932
|
+
properties: { key: nonEmptyString2, label: nonEmptyString2, value: nonEmptyString2 },
|
|
3933
|
+
required: ["key", "label", "value"],
|
|
3934
|
+
additionalProperties: false
|
|
3935
|
+
};
|
|
3936
|
+
var period = {
|
|
3937
|
+
type: "object",
|
|
3938
|
+
properties: {
|
|
3939
|
+
start: nonEmptyString2,
|
|
3940
|
+
end: nonEmptyString2,
|
|
3941
|
+
timezone: nonEmptyString2
|
|
3942
|
+
},
|
|
3943
|
+
required: ["start", "end", "timezone"],
|
|
3944
|
+
additionalProperties: false
|
|
3945
|
+
};
|
|
3946
|
+
var series = {
|
|
3947
|
+
type: "object",
|
|
3948
|
+
properties: {
|
|
3949
|
+
id: nonEmptyString2,
|
|
3950
|
+
label: nonEmptyString2,
|
|
3951
|
+
unit: nonEmptyString2,
|
|
3952
|
+
points: {
|
|
3953
|
+
type: "array",
|
|
3954
|
+
items: {
|
|
3955
|
+
type: "object",
|
|
3956
|
+
properties: {
|
|
3957
|
+
timestamp: nonEmptyString2,
|
|
3958
|
+
value: { type: "number" },
|
|
3959
|
+
dimensions: { type: "array", items: dimension }
|
|
3960
|
+
},
|
|
3961
|
+
required: ["timestamp", "value", "dimensions"],
|
|
3962
|
+
additionalProperties: false
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
},
|
|
3966
|
+
required: ["id", "label", "unit", "points"],
|
|
3967
|
+
additionalProperties: false
|
|
3968
|
+
};
|
|
3969
|
+
var contribution = {
|
|
3970
|
+
type: "object",
|
|
3971
|
+
properties: {
|
|
3972
|
+
summary: nonEmptyString2,
|
|
3973
|
+
identity: {
|
|
3974
|
+
type: "object",
|
|
3975
|
+
properties: { iconSource: { const: "catalog" } },
|
|
3976
|
+
required: ["iconSource"],
|
|
3977
|
+
additionalProperties: false
|
|
3978
|
+
},
|
|
3979
|
+
workspaceSelector: {
|
|
3980
|
+
type: "object",
|
|
3981
|
+
properties: {
|
|
3982
|
+
mode: { enum: ["none", "optional", "required"] },
|
|
3983
|
+
resourceType: nonEmptyString2,
|
|
3984
|
+
label: nonEmptyString2,
|
|
3985
|
+
supportsMultiple: { type: "boolean" }
|
|
3986
|
+
},
|
|
3987
|
+
required: ["mode", "resourceType", "label", "supportsMultiple"],
|
|
3988
|
+
additionalProperties: false
|
|
3989
|
+
},
|
|
3990
|
+
metricDefinitions: {
|
|
3991
|
+
type: "array",
|
|
3992
|
+
items: {
|
|
3993
|
+
type: "object",
|
|
3994
|
+
properties: {
|
|
3995
|
+
key: nonEmptyString2,
|
|
3996
|
+
label: nonEmptyString2,
|
|
3997
|
+
description: nonEmptyString2,
|
|
3998
|
+
unit: nonEmptyString2,
|
|
3999
|
+
semantic: {
|
|
4000
|
+
enum: ["gauge", "counter", "rate", "duration", "currency", "percentage"]
|
|
4001
|
+
},
|
|
4002
|
+
aggregation: {
|
|
4003
|
+
enum: ["last", "sum", "average", "minimum", "maximum", "count", "distinct_count"]
|
|
4004
|
+
}
|
|
4005
|
+
},
|
|
4006
|
+
required: ["key", "label", "description", "unit", "semantic", "aggregation"],
|
|
4007
|
+
additionalProperties: false
|
|
4008
|
+
}
|
|
4009
|
+
},
|
|
4010
|
+
seriesDefinitions: {
|
|
4011
|
+
type: "array",
|
|
4012
|
+
items: {
|
|
4013
|
+
type: "object",
|
|
4014
|
+
properties: {
|
|
4015
|
+
key: nonEmptyString2,
|
|
4016
|
+
label: nonEmptyString2,
|
|
4017
|
+
metricKey: nonEmptyString2,
|
|
4018
|
+
unit: nonEmptyString2
|
|
4019
|
+
},
|
|
4020
|
+
required: ["key", "label", "metricKey", "unit"],
|
|
4021
|
+
additionalProperties: false
|
|
4022
|
+
}
|
|
4023
|
+
},
|
|
4024
|
+
dimensions: {
|
|
4025
|
+
type: "array",
|
|
4026
|
+
items: {
|
|
4027
|
+
type: "object",
|
|
4028
|
+
properties: {
|
|
4029
|
+
key: nonEmptyString2,
|
|
4030
|
+
label: nonEmptyString2,
|
|
4031
|
+
description: nonEmptyString2,
|
|
4032
|
+
valueType: { enum: ["string", "number", "boolean", "date", "datetime"] }
|
|
4033
|
+
},
|
|
4034
|
+
required: ["key", "label", "description", "valueType"],
|
|
4035
|
+
additionalProperties: false
|
|
4036
|
+
}
|
|
4037
|
+
},
|
|
4038
|
+
lifecycleStages: {
|
|
4039
|
+
type: "array",
|
|
4040
|
+
items: {
|
|
4041
|
+
type: "object",
|
|
4042
|
+
properties: {
|
|
4043
|
+
key: nonEmptyString2,
|
|
4044
|
+
label: nonEmptyString2,
|
|
4045
|
+
order: { type: "number" },
|
|
4046
|
+
terminal: { type: "boolean" }
|
|
4047
|
+
},
|
|
4048
|
+
required: ["key", "label", "order", "terminal"],
|
|
4049
|
+
additionalProperties: false
|
|
4050
|
+
}
|
|
4051
|
+
},
|
|
4052
|
+
events: {
|
|
4053
|
+
type: "array",
|
|
4054
|
+
items: {
|
|
4055
|
+
type: "object",
|
|
4056
|
+
properties: {
|
|
4057
|
+
key: nonEmptyString2,
|
|
4058
|
+
label: nonEmptyString2,
|
|
4059
|
+
description: nonEmptyString2
|
|
4060
|
+
},
|
|
4061
|
+
required: ["key", "label", "description"],
|
|
4062
|
+
additionalProperties: false
|
|
4063
|
+
}
|
|
4064
|
+
},
|
|
4065
|
+
datasets: {
|
|
4066
|
+
type: "array",
|
|
4067
|
+
minItems: 1,
|
|
4068
|
+
items: {
|
|
4069
|
+
type: "object",
|
|
4070
|
+
properties: {
|
|
4071
|
+
id: nonEmptyString2,
|
|
4072
|
+
label: nonEmptyString2,
|
|
4073
|
+
description: nonEmptyString2,
|
|
4074
|
+
grain: nonEmptyString2,
|
|
4075
|
+
metricKeys: stringArray3,
|
|
4076
|
+
seriesKeys: stringArray3,
|
|
4077
|
+
dimensionKeys: stringArray3,
|
|
4078
|
+
eventKeys: stringArray3,
|
|
4079
|
+
actionIds: stringArray3
|
|
4080
|
+
},
|
|
4081
|
+
required: [
|
|
4082
|
+
"id",
|
|
4083
|
+
"label",
|
|
4084
|
+
"description",
|
|
4085
|
+
"grain",
|
|
4086
|
+
"metricKeys",
|
|
4087
|
+
"seriesKeys",
|
|
4088
|
+
"dimensionKeys",
|
|
4089
|
+
"eventKeys",
|
|
4090
|
+
"actionIds"
|
|
4091
|
+
],
|
|
4092
|
+
additionalProperties: false
|
|
4093
|
+
}
|
|
4094
|
+
},
|
|
4095
|
+
compatibleVisualizations: {
|
|
4096
|
+
type: "array",
|
|
4097
|
+
minItems: 1,
|
|
4098
|
+
items: {
|
|
4099
|
+
enum: ["number", "line", "area", "bar", "donut", "table", "funnel", "timeline", "actions"]
|
|
4100
|
+
}
|
|
4101
|
+
},
|
|
4102
|
+
defaultVisualization: {
|
|
4103
|
+
enum: ["number", "line", "area", "bar", "donut", "table", "funnel", "timeline", "actions"]
|
|
4104
|
+
}
|
|
4105
|
+
},
|
|
4106
|
+
required: [
|
|
4107
|
+
"summary",
|
|
4108
|
+
"identity",
|
|
4109
|
+
"workspaceSelector",
|
|
4110
|
+
"metricDefinitions",
|
|
4111
|
+
"seriesDefinitions",
|
|
4112
|
+
"dimensions",
|
|
4113
|
+
"lifecycleStages",
|
|
4114
|
+
"events",
|
|
4115
|
+
"datasets",
|
|
4116
|
+
"compatibleVisualizations",
|
|
4117
|
+
"defaultVisualization"
|
|
4118
|
+
],
|
|
4119
|
+
additionalProperties: false
|
|
4120
|
+
};
|
|
4121
|
+
var widgetItem = {
|
|
4122
|
+
type: "object",
|
|
4123
|
+
properties: {
|
|
4124
|
+
id: nonEmptyString2,
|
|
4125
|
+
version: nonEmptyString2,
|
|
4126
|
+
appId: nonEmptyString2,
|
|
4127
|
+
serviceName: nonEmptyString2,
|
|
4128
|
+
lastUpdated: nonEmptyString2,
|
|
4129
|
+
type: { enum: ["stats", "chart", "activity", "notifications", "actions"] },
|
|
4130
|
+
presentation: {
|
|
4131
|
+
type: "object",
|
|
4132
|
+
properties: {
|
|
4133
|
+
title: nonEmptyString2,
|
|
4134
|
+
description: nonEmptyString2,
|
|
4135
|
+
contexts: {
|
|
4136
|
+
type: "array",
|
|
4137
|
+
minItems: 1,
|
|
4138
|
+
items: { enum: ["personal", "organization", "workspace", "resource"] }
|
|
4139
|
+
},
|
|
4140
|
+
supportedSizes: {
|
|
4141
|
+
type: "array",
|
|
4142
|
+
minItems: 1,
|
|
4143
|
+
items: { enum: ["compact", "medium", "wide", "full"] }
|
|
4144
|
+
},
|
|
4145
|
+
defaultSize: { enum: ["compact", "medium", "wide", "full"] }
|
|
4146
|
+
},
|
|
4147
|
+
required: ["title", "contexts", "supportedSizes", "defaultSize"],
|
|
4148
|
+
additionalProperties: false
|
|
4149
|
+
},
|
|
4150
|
+
resource: {
|
|
4151
|
+
type: "object",
|
|
4152
|
+
properties: {
|
|
4153
|
+
resourceType: nonEmptyString2,
|
|
4154
|
+
resourceId: nonEmptyString2,
|
|
4155
|
+
requiredPermissions: stringArray3
|
|
4156
|
+
},
|
|
4157
|
+
required: ["resourceType", "requiredPermissions"],
|
|
4158
|
+
additionalProperties: false
|
|
4159
|
+
},
|
|
4160
|
+
state: {
|
|
4161
|
+
type: "object",
|
|
4162
|
+
properties: {
|
|
4163
|
+
status: { enum: ["ready", "empty", "unavailable", "stale", "error"] },
|
|
4164
|
+
observedAt: nonEmptyString2,
|
|
4165
|
+
lastSuccessfulAt: nonEmptyString2,
|
|
4166
|
+
code: nonEmptyString2,
|
|
4167
|
+
message: nonEmptyString2
|
|
4168
|
+
},
|
|
4169
|
+
required: ["status", "observedAt"],
|
|
4170
|
+
additionalProperties: false
|
|
4171
|
+
},
|
|
4172
|
+
refresh: {
|
|
4173
|
+
type: "object",
|
|
4174
|
+
properties: {
|
|
4175
|
+
intervalSeconds: { type: "number" },
|
|
4176
|
+
timeoutSeconds: { type: "number" },
|
|
4177
|
+
maxAgeSeconds: { type: "number" },
|
|
4178
|
+
staleWhileRevalidateSeconds: { type: "number" }
|
|
4179
|
+
},
|
|
4180
|
+
required: ["intervalSeconds", "timeoutSeconds", "maxAgeSeconds", "staleWhileRevalidateSeconds"],
|
|
4181
|
+
additionalProperties: false
|
|
4182
|
+
},
|
|
4183
|
+
configuration: {
|
|
4184
|
+
type: "object",
|
|
4185
|
+
properties: {
|
|
4186
|
+
allowMultipleInstances: { type: "boolean" },
|
|
4187
|
+
fields: {
|
|
4188
|
+
type: "array",
|
|
4189
|
+
items: {
|
|
4190
|
+
type: "object",
|
|
4191
|
+
properties: {
|
|
4192
|
+
key: nonEmptyString2,
|
|
4193
|
+
label: nonEmptyString2,
|
|
4194
|
+
type: { enum: ["string", "number", "boolean", "select", "multi-select", "date-range"] },
|
|
4195
|
+
required: { type: "boolean" },
|
|
4196
|
+
options: {
|
|
4197
|
+
type: "array",
|
|
4198
|
+
items: {
|
|
4199
|
+
type: "object",
|
|
4200
|
+
properties: { value: nonEmptyString2, label: nonEmptyString2 },
|
|
4201
|
+
required: ["value", "label"],
|
|
4202
|
+
additionalProperties: false
|
|
4203
|
+
}
|
|
4204
|
+
}
|
|
4205
|
+
},
|
|
4206
|
+
required: ["key", "label", "type", "required"],
|
|
4207
|
+
additionalProperties: false
|
|
4208
|
+
}
|
|
4209
|
+
},
|
|
4210
|
+
defaults: { type: "object" }
|
|
4211
|
+
},
|
|
4212
|
+
required: ["allowMultipleInstances", "fields", "defaults"],
|
|
4213
|
+
additionalProperties: false
|
|
4214
|
+
},
|
|
4215
|
+
drilldowns: {
|
|
4216
|
+
type: "array",
|
|
4217
|
+
items: {
|
|
4218
|
+
type: "object",
|
|
4219
|
+
properties: { id: nonEmptyString2, label: nonEmptyString2, href: nonEmptyString2 },
|
|
4220
|
+
required: ["id", "label", "href"],
|
|
4221
|
+
additionalProperties: false
|
|
4222
|
+
}
|
|
4223
|
+
},
|
|
4224
|
+
controls: { type: "array", items: actionBinding },
|
|
4225
|
+
localization: {
|
|
4226
|
+
type: "object",
|
|
4227
|
+
properties: {
|
|
4228
|
+
locale: nonEmptyString2,
|
|
4229
|
+
titleKey: nonEmptyString2,
|
|
4230
|
+
descriptionKey: nonEmptyString2,
|
|
4231
|
+
title: nonEmptyString2,
|
|
4232
|
+
description: nonEmptyString2
|
|
4233
|
+
},
|
|
4234
|
+
required: ["locale", "titleKey"],
|
|
4235
|
+
additionalProperties: false
|
|
4236
|
+
},
|
|
4237
|
+
accessibility: {
|
|
4238
|
+
type: "object",
|
|
4239
|
+
properties: { label: nonEmptyString2, description: nonEmptyString2 },
|
|
4240
|
+
required: ["label"],
|
|
4241
|
+
additionalProperties: false
|
|
4242
|
+
},
|
|
4243
|
+
contribution,
|
|
4244
|
+
metrics: {
|
|
4245
|
+
type: "array",
|
|
4246
|
+
items: {
|
|
4247
|
+
type: "object",
|
|
4248
|
+
properties: {
|
|
4249
|
+
key: nonEmptyString2,
|
|
4250
|
+
label: nonEmptyString2,
|
|
4251
|
+
value: { type: "number" },
|
|
4252
|
+
unit: nonEmptyString2,
|
|
4253
|
+
semantic: {
|
|
4254
|
+
enum: ["gauge", "counter", "rate", "duration", "currency", "percentage"]
|
|
4255
|
+
},
|
|
4256
|
+
aggregation: {
|
|
4257
|
+
enum: ["last", "sum", "average", "minimum", "maximum", "count", "distinct_count"]
|
|
4258
|
+
},
|
|
4259
|
+
period,
|
|
4260
|
+
dimensions: { type: "array", items: dimension },
|
|
4261
|
+
series
|
|
4262
|
+
},
|
|
4263
|
+
required: ["key", "label", "value", "unit", "semantic", "aggregation", "period", "dimensions"],
|
|
4264
|
+
additionalProperties: false
|
|
4265
|
+
}
|
|
4266
|
+
},
|
|
4267
|
+
chartType: { enum: ["line", "bar", "area", "pie", "donut"] },
|
|
4268
|
+
series: { type: "array", items: series },
|
|
4269
|
+
activities: { type: "array", items: { type: "object" } },
|
|
4270
|
+
notifications: { type: "array", items: { type: "object" } },
|
|
4271
|
+
unreadCount: { type: "number" },
|
|
4272
|
+
actions: { type: "array", items: actionBinding }
|
|
4273
|
+
},
|
|
4274
|
+
required: [
|
|
4275
|
+
"id",
|
|
4276
|
+
"version",
|
|
4277
|
+
"appId",
|
|
4278
|
+
"serviceName",
|
|
4279
|
+
"lastUpdated",
|
|
4280
|
+
"type",
|
|
4281
|
+
"presentation",
|
|
4282
|
+
"resource",
|
|
4283
|
+
"state",
|
|
4284
|
+
"refresh",
|
|
4285
|
+
"configuration",
|
|
4286
|
+
"drilldowns",
|
|
4287
|
+
"controls",
|
|
4288
|
+
"localization",
|
|
4289
|
+
"accessibility",
|
|
4290
|
+
"contribution"
|
|
4291
|
+
],
|
|
4292
|
+
allOf: [
|
|
4293
|
+
{ if: { properties: { type: { const: "stats" } } }, then: { required: ["metrics"] } },
|
|
4294
|
+
{ if: { properties: { type: { const: "chart" } } }, then: { required: ["chartType", "series"] } },
|
|
4295
|
+
{ if: { properties: { type: { const: "activity" } } }, then: { required: ["activities"] } },
|
|
4296
|
+
{
|
|
4297
|
+
if: { properties: { type: { const: "notifications" } } },
|
|
4298
|
+
then: { required: ["notifications", "unreadCount"] }
|
|
4299
|
+
},
|
|
4300
|
+
{ if: { properties: { type: { const: "actions" } } }, then: { required: ["actions"] } }
|
|
4301
|
+
],
|
|
4302
|
+
additionalProperties: false
|
|
4303
|
+
};
|
|
4304
|
+
var TOPOLO_WIDGET_OUTPUT_SCHEMA = Object.freeze({
|
|
4305
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
4306
|
+
type: "object",
|
|
4307
|
+
properties: {
|
|
4308
|
+
success: { type: "boolean", const: true },
|
|
4309
|
+
contractVersion: { type: "string", const: "3.0.0" },
|
|
4310
|
+
appId: nonEmptyString2,
|
|
4311
|
+
serviceName: nonEmptyString2,
|
|
4312
|
+
generatedAt: nonEmptyString2,
|
|
4313
|
+
widgets: { type: "array", minItems: 1, items: widgetItem },
|
|
4314
|
+
workspace: {
|
|
4315
|
+
anyOf: [
|
|
4316
|
+
{
|
|
4317
|
+
type: "object",
|
|
4318
|
+
properties: {
|
|
4319
|
+
id: { anyOf: [{ type: "string" }, { type: "number" }] },
|
|
4320
|
+
name: nonEmptyString2
|
|
4321
|
+
},
|
|
4322
|
+
required: ["id", "name"],
|
|
4323
|
+
additionalProperties: true
|
|
4324
|
+
},
|
|
4325
|
+
{ type: "null" }
|
|
4326
|
+
]
|
|
4327
|
+
},
|
|
4328
|
+
workspaces: {
|
|
4329
|
+
type: "array",
|
|
4330
|
+
items: {
|
|
4331
|
+
type: "object",
|
|
4332
|
+
properties: {
|
|
4333
|
+
id: { anyOf: [{ type: "string" }, { type: "number" }] },
|
|
4334
|
+
name: nonEmptyString2,
|
|
4335
|
+
isDefault: { type: "boolean" }
|
|
4336
|
+
},
|
|
4337
|
+
required: ["id", "name"],
|
|
4338
|
+
additionalProperties: false
|
|
4339
|
+
}
|
|
4340
|
+
}
|
|
4341
|
+
},
|
|
4342
|
+
required: ["success", "contractVersion", "appId", "serviceName", "generatedAt", "widgets"],
|
|
4343
|
+
additionalProperties: false
|
|
4344
|
+
});
|
|
4345
|
+
function isTopoloWidgetOutputSchema(schema) {
|
|
4346
|
+
if (!isRecord6(schema) || !isRecord6(schema.properties)) return false;
|
|
4347
|
+
const properties = schema.properties;
|
|
4348
|
+
const widgetItemSchema = isRecord6(properties.widgets) && isRecord6(properties.widgets.items) ? properties.widgets.items : void 0;
|
|
4349
|
+
const widgetProperties = widgetItemSchema && isRecord6(widgetItemSchema.properties) ? widgetItemSchema.properties : void 0;
|
|
4350
|
+
const contributionSchema = widgetProperties && isRecord6(widgetProperties.contribution) ? widgetProperties.contribution : void 0;
|
|
4351
|
+
const contractVersion = isRecord6(properties.contractVersion) ? properties.contractVersion.const : void 0;
|
|
4352
|
+
return schema.type === "object" && contractVersion === "3.0.0" && isRecord6(properties.widgets) && properties.widgets.type === "array" && widgetItemSchema?.type === "object" && hasRequired(schema, "contractVersion") && hasRequired(schema, "widgets") && hasRequired(widgetItemSchema, "contribution") && hasRequired(contributionSchema, "datasets") && hasRequired(contributionSchema, "compatibleVisualizations") && hasRequired(contributionSchema, "defaultVisualization");
|
|
4353
|
+
}
|
|
4354
|
+
function isRecord6(value) {
|
|
4355
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4356
|
+
}
|
|
4357
|
+
function hasRequired(schema, field) {
|
|
4358
|
+
return isRecord6(schema) && Array.isArray(schema.required) && schema.required.includes(field);
|
|
4359
|
+
}
|
|
4360
|
+
|
|
3683
4361
|
// src/index.ts
|
|
3684
4362
|
function createTopolo(options) {
|
|
3685
4363
|
const client = new TopoloClient(options);
|
|
@@ -3700,6 +4378,7 @@ export {
|
|
|
3700
4378
|
TOPOLO_RUNTIME_ENVIRONMENTS,
|
|
3701
4379
|
TOPOLO_WIDGET_CONTRACT_VERSION,
|
|
3702
4380
|
TOPOLO_WIDGET_ENDPOINT,
|
|
4381
|
+
TOPOLO_WIDGET_OUTPUT_SCHEMA,
|
|
3703
4382
|
TOPOLO_WIDGET_REFRESH_INTERVAL_MS,
|
|
3704
4383
|
TopoloAuthError,
|
|
3705
4384
|
TopoloClient,
|
|
@@ -3737,6 +4416,7 @@ export {
|
|
|
3737
4416
|
extractTopoloServiceErrorDetails,
|
|
3738
4417
|
formatDirectoryApplicationIds,
|
|
3739
4418
|
friendlyAppId,
|
|
4419
|
+
isTopoloWidgetOutputSchema,
|
|
3740
4420
|
listApplicationDirectory,
|
|
3741
4421
|
parseTopoloActionUploadContract,
|
|
3742
4422
|
preferExactActionMatches,
|