@topolo/sdk 0.2.5 → 0.2.7
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 +23 -0
- package/dist/index.cjs +277 -3
- package/dist/index.d.cts +182 -2
- package/dist/index.d.ts +182 -2
- package/dist/index.js +266 -2
- package/package.json +1 -1
- package/src/application-requirements.ts +25 -1
- package/src/applications.generated.ts +71 -0
- package/src/index.ts +46 -10
- package/src/services.generated.ts +5 -0
- package/src/services.test.ts +7 -0
- package/src/widgets.test.ts +162 -0
- package/src/widgets.ts +359 -0
package/README.md
CHANGED
|
@@ -94,6 +94,29 @@ that contract into catalog-backed conformance reports and migration-queue items.
|
|
|
94
94
|
Catalog-visible evidence is marked directly; implementation details that require
|
|
95
95
|
code or docs inspection are deliberately marked `needs_review`.
|
|
96
96
|
|
|
97
|
+
## Native dashboard widgets
|
|
98
|
+
|
|
99
|
+
Launchable first-party applications populate the TopoloOne live workspace through
|
|
100
|
+
their own `GET /api/widget` endpoint. The SDK owns the shared payload contract:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { createTopoloWidgetResponse } from '@topolo/sdk';
|
|
104
|
+
|
|
105
|
+
return Response.json(createTopoloWidgetResponse({
|
|
106
|
+
serviceId: 'srv_topolo_example',
|
|
107
|
+
serviceName: 'Example',
|
|
108
|
+
widgets: [
|
|
109
|
+
{
|
|
110
|
+
type: 'stats',
|
|
111
|
+
stats: [{ label: 'Open items', value: 3 }],
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
}));
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Use `validateTopoloWidgetResponse()` in endpoint tests to prevent app-local
|
|
118
|
+
payload drift.
|
|
119
|
+
|
|
97
120
|
## Escape hatch
|
|
98
121
|
|
|
99
122
|
```ts
|
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,8 @@ __export(index_exports, {
|
|
|
27
27
|
DEFAULT_SERVICE_URLS: () => DEFAULT_SERVICE_URLS,
|
|
28
28
|
IdentityModule: () => IdentityModule,
|
|
29
29
|
PLATFORM_SERVICE_IDS: () => PLATFORM_SERVICE_IDS,
|
|
30
|
+
TOPOLO_WIDGET_ENDPOINT: () => TOPOLO_WIDGET_ENDPOINT,
|
|
31
|
+
TOPOLO_WIDGET_REFRESH_INTERVAL_MS: () => TOPOLO_WIDGET_REFRESH_INTERVAL_MS,
|
|
30
32
|
TopoloAuthError: () => TopoloAuthError,
|
|
31
33
|
TopoloClient: () => TopoloClient,
|
|
32
34
|
TopoloHttpError: () => TopoloHttpError,
|
|
@@ -37,8 +39,16 @@ __export(index_exports, {
|
|
|
37
39
|
auditAllApplicationRequirements: () => auditAllApplicationRequirements,
|
|
38
40
|
auditApplicationRequirements: () => auditApplicationRequirements,
|
|
39
41
|
createTopolo: () => createTopolo,
|
|
42
|
+
createTopoloWidgetError: () => createTopoloWidgetError,
|
|
43
|
+
createTopoloWidgetResponse: () => createTopoloWidgetResponse,
|
|
44
|
+
defineTopoloChartWidget: () => defineTopoloChartWidget,
|
|
45
|
+
defineTopoloNotificationsWidget: () => defineTopoloNotificationsWidget,
|
|
46
|
+
defineTopoloQuickActionsWidget: () => defineTopoloQuickActionsWidget,
|
|
47
|
+
defineTopoloRecentActivityWidget: () => defineTopoloRecentActivityWidget,
|
|
48
|
+
defineTopoloStatsWidget: () => defineTopoloStatsWidget,
|
|
40
49
|
requirementsForApplication: () => requirementsForApplication,
|
|
41
|
-
resolveServiceUrl: () => resolveServiceUrl
|
|
50
|
+
resolveServiceUrl: () => resolveServiceUrl,
|
|
51
|
+
validateTopoloWidgetResponse: () => validateTopoloWidgetResponse
|
|
42
52
|
});
|
|
43
53
|
module.exports = __toCommonJS(index_exports);
|
|
44
54
|
|
|
@@ -108,8 +118,10 @@ var SERVICES = {
|
|
|
108
118
|
bugfix: "https://bugfix.topolo.app",
|
|
109
119
|
bytes: "https://r2-media-manager-worker.topolo.workers.dev",
|
|
110
120
|
calendar: "https://calendar.topolo.app",
|
|
121
|
+
capacity: "https://topolo-capacity.topolo.workers.dev",
|
|
111
122
|
chat: "https://chat.topolo.app",
|
|
112
123
|
commerce: "https://topolo-commerce-api.topolo.workers.dev",
|
|
124
|
+
compose: "https://compose.topolo.app",
|
|
113
125
|
crm: "https://crm-api.topolo.app",
|
|
114
126
|
customer_success: "https://customer-success.topolo.app",
|
|
115
127
|
feed: "https://topolo-feed-api.topolo.app",
|
|
@@ -123,6 +135,7 @@ var SERVICES = {
|
|
|
123
135
|
mdm: "https://topolo-mdm-api.topolo.app",
|
|
124
136
|
messaging: "https://messages.topolo.app",
|
|
125
137
|
nexus: "https://topolo-nexus-gateway.topolo.workers.dev",
|
|
138
|
+
notify: "https://notify.topolo.app",
|
|
126
139
|
one: "https://one.topolo.app",
|
|
127
140
|
pay: "https://topolo-pay.topolo.workers.dev",
|
|
128
141
|
people: "https://people.topolo.app",
|
|
@@ -139,12 +152,14 @@ var SERVICES = {
|
|
|
139
152
|
};
|
|
140
153
|
var PLATFORM_SERVICE_IDS = {
|
|
141
154
|
books: "srv_topolo_books",
|
|
155
|
+
compose: "srv_topolo_compose",
|
|
142
156
|
crm: "srv_iCwM4jGXcwlj",
|
|
143
157
|
customer_success: "srv_topolo_customer_success",
|
|
144
158
|
flow: "srv_topolo_flow",
|
|
145
159
|
forms: "srv_topolo_forms",
|
|
146
160
|
insights: "srv_topolo_insights",
|
|
147
161
|
inventory: "srv_topolo_inventory",
|
|
162
|
+
notify: "svc_topolo_notify",
|
|
148
163
|
people: "srv_topolo_people",
|
|
149
164
|
sign: "srv_topolo_sign",
|
|
150
165
|
survey: "srv_topolo_survey",
|
|
@@ -323,6 +338,29 @@ var APPLICATIONS = {
|
|
|
323
338
|
}
|
|
324
339
|
]
|
|
325
340
|
},
|
|
341
|
+
"capacity": {
|
|
342
|
+
"id": "capacity",
|
|
343
|
+
"appDir": "TopoloCapacity",
|
|
344
|
+
"name": "topolo-capacity",
|
|
345
|
+
"packageName": "topolo-capacity",
|
|
346
|
+
"productionUrl": "https://capacity.topolo.app",
|
|
347
|
+
"services": [
|
|
348
|
+
"capacity"
|
|
349
|
+
],
|
|
350
|
+
"deployTargets": [
|
|
351
|
+
{
|
|
352
|
+
"name": "topolo-capacity",
|
|
353
|
+
"kind": "worker",
|
|
354
|
+
"apiUrl": "https://topolo-capacity.topolo.workers.dev",
|
|
355
|
+
"domains": [
|
|
356
|
+
"capacity.topolo.app",
|
|
357
|
+
"topolo-capacity.topolo.workers.dev"
|
|
358
|
+
],
|
|
359
|
+
"routes": [],
|
|
360
|
+
"serviceId": "capacity"
|
|
361
|
+
}
|
|
362
|
+
]
|
|
363
|
+
},
|
|
326
364
|
"chat": {
|
|
327
365
|
"id": "chat",
|
|
328
366
|
"appDir": "TopoloChat",
|
|
@@ -420,6 +458,30 @@ var APPLICATIONS = {
|
|
|
420
458
|
}
|
|
421
459
|
]
|
|
422
460
|
},
|
|
461
|
+
"compose": {
|
|
462
|
+
"id": "compose",
|
|
463
|
+
"appDir": "TopoloCompose",
|
|
464
|
+
"name": "topolo-compose",
|
|
465
|
+
"packageName": "@topolo/compose",
|
|
466
|
+
"productionUrl": "https://compose.topolo.app",
|
|
467
|
+
"services": [
|
|
468
|
+
"compose"
|
|
469
|
+
],
|
|
470
|
+
"deployTargets": [
|
|
471
|
+
{
|
|
472
|
+
"name": "topolo-compose",
|
|
473
|
+
"kind": "worker",
|
|
474
|
+
"apiUrl": "https://compose.topolo.app",
|
|
475
|
+
"domains": [
|
|
476
|
+
"compose.topolo.app"
|
|
477
|
+
],
|
|
478
|
+
"routes": [
|
|
479
|
+
"compose.topolo.app"
|
|
480
|
+
],
|
|
481
|
+
"serviceId": "compose"
|
|
482
|
+
}
|
|
483
|
+
]
|
|
484
|
+
},
|
|
423
485
|
"crm": {
|
|
424
486
|
"id": "crm",
|
|
425
487
|
"appDir": "TopoloCRM",
|
|
@@ -837,6 +899,30 @@ var APPLICATIONS = {
|
|
|
837
899
|
}
|
|
838
900
|
]
|
|
839
901
|
},
|
|
902
|
+
"notify": {
|
|
903
|
+
"id": "notify",
|
|
904
|
+
"appDir": "TopoloNotify",
|
|
905
|
+
"name": "topolo-notify",
|
|
906
|
+
"packageName": "@topolo/notify",
|
|
907
|
+
"productionUrl": "https://notify.topolo.app",
|
|
908
|
+
"services": [
|
|
909
|
+
"notify"
|
|
910
|
+
],
|
|
911
|
+
"deployTargets": [
|
|
912
|
+
{
|
|
913
|
+
"name": "topolo-notify",
|
|
914
|
+
"kind": "worker",
|
|
915
|
+
"apiUrl": "https://notify.topolo.app",
|
|
916
|
+
"domains": [
|
|
917
|
+
"notify.topolo.app"
|
|
918
|
+
],
|
|
919
|
+
"routes": [
|
|
920
|
+
"notify.topolo.app"
|
|
921
|
+
],
|
|
922
|
+
"serviceId": "notify"
|
|
923
|
+
}
|
|
924
|
+
]
|
|
925
|
+
},
|
|
840
926
|
"one": {
|
|
841
927
|
"id": "one",
|
|
842
928
|
"appDir": "TopoloOne",
|
|
@@ -1219,7 +1305,7 @@ var APPLICATIONS = {
|
|
|
1219
1305
|
};
|
|
1220
1306
|
|
|
1221
1307
|
// src/application-requirements.ts
|
|
1222
|
-
var APPLICATION_REQUIREMENTS_VERSION = "2026-04-
|
|
1308
|
+
var APPLICATION_REQUIREMENTS_VERSION = "2026-04-25.1";
|
|
1223
1309
|
var APPLICATION_REQUIREMENTS = [
|
|
1224
1310
|
{
|
|
1225
1311
|
id: "platform-metadata",
|
|
@@ -1351,6 +1437,22 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1351
1437
|
"Keep command output JSON-stable for agents and human-readable with --no-json"
|
|
1352
1438
|
]
|
|
1353
1439
|
},
|
|
1440
|
+
{
|
|
1441
|
+
id: "native-dashboard-widget",
|
|
1442
|
+
title: "Expose a native dashboard widget contract",
|
|
1443
|
+
summary: "Launchable first-party applications must populate TopoloOne live workspace through an app-owned /api/widget endpoint using the SDK widget response contract.",
|
|
1444
|
+
appliesTo: ["api"],
|
|
1445
|
+
evidence: [
|
|
1446
|
+
"The app-owned API exposes GET /api/widget",
|
|
1447
|
+
"The endpoint returns TopoloWidgetApiResponse from @topolo/sdk",
|
|
1448
|
+
"The endpoint derives organization/user context from the app auth boundary"
|
|
1449
|
+
],
|
|
1450
|
+
implementation: [
|
|
1451
|
+
"Import createTopoloWidgetResponse from @topolo/sdk in the app backend",
|
|
1452
|
+
"Return native app metrics or action widgets instead of generic launch-card fallbacks",
|
|
1453
|
+
"Add a route-level test that validates the response with validateTopoloWidgetResponse"
|
|
1454
|
+
]
|
|
1455
|
+
},
|
|
1354
1456
|
{
|
|
1355
1457
|
id: "observability-and-audit",
|
|
1356
1458
|
title: "Emit platform audit and debugging signals",
|
|
@@ -1522,6 +1624,13 @@ function evaluateRequirement(application, requirement) {
|
|
|
1522
1624
|
}
|
|
1523
1625
|
return finding(requirement, "missing", "No SDK service or tooling surface is registered.", evidence);
|
|
1524
1626
|
}
|
|
1627
|
+
case "native-dashboard-widget":
|
|
1628
|
+
return finding(
|
|
1629
|
+
requirement,
|
|
1630
|
+
"needs_review",
|
|
1631
|
+
"Catalog metadata cannot verify app-owned /api/widget implementation details.",
|
|
1632
|
+
evidence
|
|
1633
|
+
);
|
|
1525
1634
|
case "observability-and-audit":
|
|
1526
1635
|
return finding(
|
|
1527
1636
|
requirement,
|
|
@@ -1920,6 +2029,161 @@ var TopoloOAuth = class {
|
|
|
1920
2029
|
}
|
|
1921
2030
|
};
|
|
1922
2031
|
|
|
2032
|
+
// src/widgets.ts
|
|
2033
|
+
var TOPOLO_WIDGET_ENDPOINT = "/api/widget";
|
|
2034
|
+
var TOPOLO_WIDGET_REFRESH_INTERVAL_MS = 6e4;
|
|
2035
|
+
function defineTopoloStatsWidget(widget) {
|
|
2036
|
+
return { ...widget, type: "stats" };
|
|
2037
|
+
}
|
|
2038
|
+
function defineTopoloRecentActivityWidget(widget) {
|
|
2039
|
+
return { ...widget, type: "recent-activity" };
|
|
2040
|
+
}
|
|
2041
|
+
function defineTopoloQuickActionsWidget(widget) {
|
|
2042
|
+
return { ...widget, type: "quick-actions" };
|
|
2043
|
+
}
|
|
2044
|
+
function defineTopoloNotificationsWidget(widget) {
|
|
2045
|
+
return { ...widget, type: "notifications" };
|
|
2046
|
+
}
|
|
2047
|
+
function defineTopoloChartWidget(widget) {
|
|
2048
|
+
return { ...widget, type: "chart" };
|
|
2049
|
+
}
|
|
2050
|
+
function createTopoloWidgetResponse({
|
|
2051
|
+
serviceId,
|
|
2052
|
+
serviceName,
|
|
2053
|
+
widgets,
|
|
2054
|
+
now
|
|
2055
|
+
}) {
|
|
2056
|
+
const lastUpdated = toIsoTimestamp(now);
|
|
2057
|
+
return {
|
|
2058
|
+
success: true,
|
|
2059
|
+
widgets: widgets.map((widget) => ({
|
|
2060
|
+
...widget,
|
|
2061
|
+
serviceId: widget.serviceId?.trim() || serviceId,
|
|
2062
|
+
serviceName: widget.serviceName?.trim() || serviceName,
|
|
2063
|
+
lastUpdated: widget.lastUpdated?.trim() || lastUpdated
|
|
2064
|
+
}))
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
function createTopoloWidgetError(error) {
|
|
2068
|
+
return {
|
|
2069
|
+
success: false,
|
|
2070
|
+
widgets: [],
|
|
2071
|
+
error
|
|
2072
|
+
};
|
|
2073
|
+
}
|
|
2074
|
+
function validateTopoloWidgetResponse(response) {
|
|
2075
|
+
const errors = [];
|
|
2076
|
+
if (!isRecord(response)) {
|
|
2077
|
+
return { ok: false, errors: ["response must be an object"] };
|
|
2078
|
+
}
|
|
2079
|
+
if (typeof response.success !== "boolean") {
|
|
2080
|
+
errors.push("success must be a boolean");
|
|
2081
|
+
}
|
|
2082
|
+
if (!Array.isArray(response.widgets)) {
|
|
2083
|
+
errors.push("widgets must be an array");
|
|
2084
|
+
return { ok: errors.length === 0, errors };
|
|
2085
|
+
}
|
|
2086
|
+
response.widgets.forEach((widget, index) => {
|
|
2087
|
+
validateWidget(widget, `widgets[${index}]`, errors);
|
|
2088
|
+
});
|
|
2089
|
+
if (response.success === false && response.error !== void 0 && typeof response.error !== "string") {
|
|
2090
|
+
errors.push("error must be a string when provided");
|
|
2091
|
+
}
|
|
2092
|
+
return { ok: errors.length === 0, errors };
|
|
2093
|
+
}
|
|
2094
|
+
function validateWidget(widget, path, errors) {
|
|
2095
|
+
if (!isRecord(widget)) {
|
|
2096
|
+
errors.push(`${path} must be an object`);
|
|
2097
|
+
return;
|
|
2098
|
+
}
|
|
2099
|
+
validateNonEmptyString(widget.serviceId, `${path}.serviceId`, errors);
|
|
2100
|
+
validateNonEmptyString(widget.serviceName, `${path}.serviceName`, errors);
|
|
2101
|
+
validateNonEmptyString(widget.lastUpdated, `${path}.lastUpdated`, errors);
|
|
2102
|
+
validateSnapshotMetadata(widget.snapshot, `${path}.snapshot`, errors);
|
|
2103
|
+
switch (widget.type) {
|
|
2104
|
+
case "stats":
|
|
2105
|
+
validateArray(widget.stats, `${path}.stats`, errors);
|
|
2106
|
+
break;
|
|
2107
|
+
case "recent-activity":
|
|
2108
|
+
validateArray(widget.activities, `${path}.activities`, errors);
|
|
2109
|
+
break;
|
|
2110
|
+
case "quick-actions":
|
|
2111
|
+
validateArray(widget.actions, `${path}.actions`, errors);
|
|
2112
|
+
break;
|
|
2113
|
+
case "notifications":
|
|
2114
|
+
validateArray(widget.notifications, `${path}.notifications`, errors);
|
|
2115
|
+
if (typeof widget.unreadCount !== "number") {
|
|
2116
|
+
errors.push(`${path}.unreadCount must be a number`);
|
|
2117
|
+
}
|
|
2118
|
+
break;
|
|
2119
|
+
case "chart":
|
|
2120
|
+
validateNonEmptyString(widget.chartType, `${path}.chartType`, errors);
|
|
2121
|
+
validateNonEmptyString(widget.title, `${path}.title`, errors);
|
|
2122
|
+
if (!isRecord(widget.data)) {
|
|
2123
|
+
errors.push(`${path}.data must be an object`);
|
|
2124
|
+
} else {
|
|
2125
|
+
validateArray(widget.data.labels, `${path}.data.labels`, errors);
|
|
2126
|
+
validateArray(widget.data.values, `${path}.data.values`, errors);
|
|
2127
|
+
}
|
|
2128
|
+
break;
|
|
2129
|
+
default:
|
|
2130
|
+
errors.push(`${path}.type must be a supported Topolo widget type`);
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
function validateSnapshotMetadata(snapshot, path, errors) {
|
|
2134
|
+
if (snapshot === void 0) {
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if (!isRecord(snapshot)) {
|
|
2138
|
+
errors.push(`${path} must be an object when provided`);
|
|
2139
|
+
return;
|
|
2140
|
+
}
|
|
2141
|
+
if (snapshot.defaultMetricKeys !== void 0 && !Array.isArray(snapshot.defaultMetricKeys)) {
|
|
2142
|
+
errors.push(`${path}.defaultMetricKeys must be an array when provided`);
|
|
2143
|
+
}
|
|
2144
|
+
if (snapshot.highlights !== void 0 && !Array.isArray(snapshot.highlights)) {
|
|
2145
|
+
errors.push(`${path}.highlights must be an array when provided`);
|
|
2146
|
+
}
|
|
2147
|
+
if (snapshot.availableMetrics === void 0) {
|
|
2148
|
+
return;
|
|
2149
|
+
}
|
|
2150
|
+
if (!Array.isArray(snapshot.availableMetrics)) {
|
|
2151
|
+
errors.push(`${path}.availableMetrics must be an array when provided`);
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
snapshot.availableMetrics.forEach((metric, index) => {
|
|
2155
|
+
const metricPath = `${path}.availableMetrics[${index}]`;
|
|
2156
|
+
if (!isRecord(metric)) {
|
|
2157
|
+
errors.push(`${metricPath} must be an object`);
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
validateNonEmptyString(metric.key, `${metricPath}.key`, errors);
|
|
2161
|
+
validateNonEmptyString(metric.label, `${metricPath}.label`, errors);
|
|
2162
|
+
if (typeof metric.value !== "number" || Number.isNaN(metric.value)) {
|
|
2163
|
+
errors.push(`${metricPath}.value must be a number`);
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
function validateNonEmptyString(value, path, errors) {
|
|
2168
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
2169
|
+
errors.push(`${path} must be a non-empty string`);
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
function validateArray(value, path, errors) {
|
|
2173
|
+
if (!Array.isArray(value)) {
|
|
2174
|
+
errors.push(`${path} must be an array`);
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
function isRecord(value) {
|
|
2178
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2179
|
+
}
|
|
2180
|
+
function toIsoTimestamp(input) {
|
|
2181
|
+
if (input instanceof Date) {
|
|
2182
|
+
return input.toISOString();
|
|
2183
|
+
}
|
|
2184
|
+
return input ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2185
|
+
}
|
|
2186
|
+
|
|
1923
2187
|
// src/index.ts
|
|
1924
2188
|
function createTopolo(options) {
|
|
1925
2189
|
const client = new TopoloClient(options);
|
|
@@ -1938,6 +2202,8 @@ function createTopolo(options) {
|
|
|
1938
2202
|
DEFAULT_SERVICE_URLS,
|
|
1939
2203
|
IdentityModule,
|
|
1940
2204
|
PLATFORM_SERVICE_IDS,
|
|
2205
|
+
TOPOLO_WIDGET_ENDPOINT,
|
|
2206
|
+
TOPOLO_WIDGET_REFRESH_INTERVAL_MS,
|
|
1941
2207
|
TopoloAuthError,
|
|
1942
2208
|
TopoloClient,
|
|
1943
2209
|
TopoloHttpError,
|
|
@@ -1948,6 +2214,14 @@ function createTopolo(options) {
|
|
|
1948
2214
|
auditAllApplicationRequirements,
|
|
1949
2215
|
auditApplicationRequirements,
|
|
1950
2216
|
createTopolo,
|
|
2217
|
+
createTopoloWidgetError,
|
|
2218
|
+
createTopoloWidgetResponse,
|
|
2219
|
+
defineTopoloChartWidget,
|
|
2220
|
+
defineTopoloNotificationsWidget,
|
|
2221
|
+
defineTopoloQuickActionsWidget,
|
|
2222
|
+
defineTopoloRecentActivityWidget,
|
|
2223
|
+
defineTopoloStatsWidget,
|
|
1951
2224
|
requirementsForApplication,
|
|
1952
|
-
resolveServiceUrl
|
|
2225
|
+
resolveServiceUrl,
|
|
2226
|
+
validateTopoloWidgetResponse
|
|
1953
2227
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -38,8 +38,10 @@ declare const SERVICES: {
|
|
|
38
38
|
readonly bugfix: "https://bugfix.topolo.app";
|
|
39
39
|
readonly bytes: "https://r2-media-manager-worker.topolo.workers.dev";
|
|
40
40
|
readonly calendar: "https://calendar.topolo.app";
|
|
41
|
+
readonly capacity: "https://topolo-capacity.topolo.workers.dev";
|
|
41
42
|
readonly chat: "https://chat.topolo.app";
|
|
42
43
|
readonly commerce: "https://topolo-commerce-api.topolo.workers.dev";
|
|
44
|
+
readonly compose: "https://compose.topolo.app";
|
|
43
45
|
readonly crm: "https://crm-api.topolo.app";
|
|
44
46
|
readonly customer_success: "https://customer-success.topolo.app";
|
|
45
47
|
readonly feed: "https://topolo-feed-api.topolo.app";
|
|
@@ -53,6 +55,7 @@ declare const SERVICES: {
|
|
|
53
55
|
readonly mdm: "https://topolo-mdm-api.topolo.app";
|
|
54
56
|
readonly messaging: "https://messages.topolo.app";
|
|
55
57
|
readonly nexus: "https://topolo-nexus-gateway.topolo.workers.dev";
|
|
58
|
+
readonly notify: "https://notify.topolo.app";
|
|
56
59
|
readonly one: "https://one.topolo.app";
|
|
57
60
|
readonly pay: "https://topolo-pay.topolo.workers.dev";
|
|
58
61
|
readonly people: "https://people.topolo.app";
|
|
@@ -197,6 +200,22 @@ declare const APPLICATIONS: {
|
|
|
197
200
|
readonly serviceId: "calendar";
|
|
198
201
|
}];
|
|
199
202
|
};
|
|
203
|
+
readonly capacity: {
|
|
204
|
+
readonly id: "capacity";
|
|
205
|
+
readonly appDir: "TopoloCapacity";
|
|
206
|
+
readonly name: "topolo-capacity";
|
|
207
|
+
readonly packageName: "topolo-capacity";
|
|
208
|
+
readonly productionUrl: "https://capacity.topolo.app";
|
|
209
|
+
readonly services: readonly ["capacity"];
|
|
210
|
+
readonly deployTargets: readonly [{
|
|
211
|
+
readonly name: "topolo-capacity";
|
|
212
|
+
readonly kind: "worker";
|
|
213
|
+
readonly apiUrl: "https://topolo-capacity.topolo.workers.dev";
|
|
214
|
+
readonly domains: readonly ["capacity.topolo.app", "topolo-capacity.topolo.workers.dev"];
|
|
215
|
+
readonly routes: readonly [];
|
|
216
|
+
readonly serviceId: "capacity";
|
|
217
|
+
}];
|
|
218
|
+
};
|
|
200
219
|
readonly chat: {
|
|
201
220
|
readonly id: "chat";
|
|
202
221
|
readonly appDir: "TopoloChat";
|
|
@@ -268,6 +287,22 @@ declare const APPLICATIONS: {
|
|
|
268
287
|
readonly serviceId: null;
|
|
269
288
|
}];
|
|
270
289
|
};
|
|
290
|
+
readonly compose: {
|
|
291
|
+
readonly id: "compose";
|
|
292
|
+
readonly appDir: "TopoloCompose";
|
|
293
|
+
readonly name: "topolo-compose";
|
|
294
|
+
readonly packageName: "@topolo/compose";
|
|
295
|
+
readonly productionUrl: "https://compose.topolo.app";
|
|
296
|
+
readonly services: readonly ["compose"];
|
|
297
|
+
readonly deployTargets: readonly [{
|
|
298
|
+
readonly name: "topolo-compose";
|
|
299
|
+
readonly kind: "worker";
|
|
300
|
+
readonly apiUrl: "https://compose.topolo.app";
|
|
301
|
+
readonly domains: readonly ["compose.topolo.app"];
|
|
302
|
+
readonly routes: readonly ["compose.topolo.app"];
|
|
303
|
+
readonly serviceId: "compose";
|
|
304
|
+
}];
|
|
305
|
+
};
|
|
271
306
|
readonly crm: {
|
|
272
307
|
readonly id: "crm";
|
|
273
308
|
readonly appDir: "TopoloCRM";
|
|
@@ -566,6 +601,22 @@ declare const APPLICATIONS: {
|
|
|
566
601
|
readonly serviceId: "nexus";
|
|
567
602
|
}];
|
|
568
603
|
};
|
|
604
|
+
readonly notify: {
|
|
605
|
+
readonly id: "notify";
|
|
606
|
+
readonly appDir: "TopoloNotify";
|
|
607
|
+
readonly name: "topolo-notify";
|
|
608
|
+
readonly packageName: "@topolo/notify";
|
|
609
|
+
readonly productionUrl: "https://notify.topolo.app";
|
|
610
|
+
readonly services: readonly ["notify"];
|
|
611
|
+
readonly deployTargets: readonly [{
|
|
612
|
+
readonly name: "topolo-notify";
|
|
613
|
+
readonly kind: "worker";
|
|
614
|
+
readonly apiUrl: "https://notify.topolo.app";
|
|
615
|
+
readonly domains: readonly ["notify.topolo.app"];
|
|
616
|
+
readonly routes: readonly ["notify.topolo.app"];
|
|
617
|
+
readonly serviceId: "notify";
|
|
618
|
+
}];
|
|
619
|
+
};
|
|
569
620
|
readonly one: {
|
|
570
621
|
readonly id: "one";
|
|
571
622
|
readonly appDir: "TopoloOne";
|
|
@@ -847,7 +898,7 @@ type ApplicationId = keyof typeof APPLICATIONS;
|
|
|
847
898
|
type ApplicationCatalogEntry = (typeof APPLICATIONS)[ApplicationId];
|
|
848
899
|
type ApplicationDeployTarget = ApplicationCatalogEntry['deployTargets'][number];
|
|
849
900
|
|
|
850
|
-
declare const APPLICATION_REQUIREMENTS_VERSION = "2026-04-
|
|
901
|
+
declare const APPLICATION_REQUIREMENTS_VERSION = "2026-04-25.1";
|
|
851
902
|
type ApplicationRequirementScope = 'all' | 'browser' | 'api' | 'tooling' | 'agent_surface';
|
|
852
903
|
interface ApplicationRequirement {
|
|
853
904
|
id: string;
|
|
@@ -951,6 +1002,13 @@ declare const APPLICATION_REQUIREMENTS: readonly [{
|
|
|
951
1002
|
readonly appliesTo: readonly ["api", "tooling", "agent_surface"];
|
|
952
1003
|
readonly evidence: readonly ["Read operations have typed SDK/CLI/MCP surfaces once their contract stabilizes", "Mutating generic calls require --confirm or confirm:true", "MCP tools never accept orgId and advertise only appropriate scope-gated tools"];
|
|
953
1004
|
readonly implementation: readonly ["Add SDK types first, then CLI commands and MCP tools for durable workflows", "Use generic API passthrough only as a temporary escape hatch", "Keep command output JSON-stable for agents and human-readable with --no-json"];
|
|
1005
|
+
}, {
|
|
1006
|
+
readonly id: "native-dashboard-widget";
|
|
1007
|
+
readonly title: "Expose a native dashboard widget contract";
|
|
1008
|
+
readonly summary: "Launchable first-party applications must populate TopoloOne live workspace through an app-owned /api/widget endpoint using the SDK widget response contract.";
|
|
1009
|
+
readonly appliesTo: readonly ["api"];
|
|
1010
|
+
readonly evidence: readonly ["The app-owned API exposes GET /api/widget", "The endpoint returns TopoloWidgetApiResponse from @topolo/sdk", "The endpoint derives organization/user context from the app auth boundary"];
|
|
1011
|
+
readonly implementation: readonly ["Import createTopoloWidgetResponse from @topolo/sdk in the app backend", "Return native app metrics or action widgets instead of generic launch-card fallbacks", "Add a route-level test that validates the response with validateTopoloWidgetResponse"];
|
|
954
1012
|
}, {
|
|
955
1013
|
readonly id: "observability-and-audit";
|
|
956
1014
|
readonly title: "Emit platform audit and debugging signals";
|
|
@@ -1235,6 +1293,128 @@ declare class TopoloOAuth {
|
|
|
1235
1293
|
}): Promise<TokenResponse>;
|
|
1236
1294
|
}
|
|
1237
1295
|
|
|
1296
|
+
declare const TOPOLO_WIDGET_ENDPOINT = "/api/widget";
|
|
1297
|
+
declare const TOPOLO_WIDGET_REFRESH_INTERVAL_MS = 60000;
|
|
1298
|
+
type TopoloWidgetType = "stats" | "recent-activity" | "quick-actions" | "notifications" | "chart";
|
|
1299
|
+
interface TopoloWidgetBase {
|
|
1300
|
+
serviceId: string;
|
|
1301
|
+
serviceName: string;
|
|
1302
|
+
serviceIcon?: string;
|
|
1303
|
+
type: TopoloWidgetType;
|
|
1304
|
+
lastUpdated: string;
|
|
1305
|
+
snapshot?: TopoloWidgetSnapshotMetadata;
|
|
1306
|
+
}
|
|
1307
|
+
interface TopoloWidgetMetric {
|
|
1308
|
+
label: string;
|
|
1309
|
+
value: string | number;
|
|
1310
|
+
change?: number;
|
|
1311
|
+
changeLabel?: string;
|
|
1312
|
+
icon?: string;
|
|
1313
|
+
}
|
|
1314
|
+
interface TopoloWidgetSnapshotMetric {
|
|
1315
|
+
key: string;
|
|
1316
|
+
label: string;
|
|
1317
|
+
value: number;
|
|
1318
|
+
unit?: string;
|
|
1319
|
+
change?: number;
|
|
1320
|
+
changeLabel?: string;
|
|
1321
|
+
}
|
|
1322
|
+
interface TopoloWidgetSnapshotMetadata {
|
|
1323
|
+
presetKey?: string;
|
|
1324
|
+
audience?: string;
|
|
1325
|
+
scope?: string;
|
|
1326
|
+
scopeLabel?: string;
|
|
1327
|
+
generatedAt?: string;
|
|
1328
|
+
summary?: string;
|
|
1329
|
+
defaultMetricKeys?: string[];
|
|
1330
|
+
availableMetrics?: TopoloWidgetSnapshotMetric[];
|
|
1331
|
+
highlights?: string[];
|
|
1332
|
+
}
|
|
1333
|
+
interface TopoloStatsWidget extends TopoloWidgetBase {
|
|
1334
|
+
type: "stats";
|
|
1335
|
+
stats: TopoloWidgetMetric[];
|
|
1336
|
+
}
|
|
1337
|
+
interface TopoloWidgetActivityItem {
|
|
1338
|
+
id: string;
|
|
1339
|
+
title: string;
|
|
1340
|
+
description?: string;
|
|
1341
|
+
timestamp: string;
|
|
1342
|
+
icon?: string;
|
|
1343
|
+
link?: string;
|
|
1344
|
+
}
|
|
1345
|
+
interface TopoloRecentActivityWidget extends TopoloWidgetBase {
|
|
1346
|
+
type: "recent-activity";
|
|
1347
|
+
activities: TopoloWidgetActivityItem[];
|
|
1348
|
+
}
|
|
1349
|
+
interface TopoloWidgetActionItem {
|
|
1350
|
+
id: string;
|
|
1351
|
+
label: string;
|
|
1352
|
+
icon?: string;
|
|
1353
|
+
link: string;
|
|
1354
|
+
primary?: boolean;
|
|
1355
|
+
}
|
|
1356
|
+
interface TopoloQuickActionsWidget extends TopoloWidgetBase {
|
|
1357
|
+
type: "quick-actions";
|
|
1358
|
+
actions: TopoloWidgetActionItem[];
|
|
1359
|
+
}
|
|
1360
|
+
interface TopoloWidgetNotificationItem {
|
|
1361
|
+
id: string;
|
|
1362
|
+
title: string;
|
|
1363
|
+
message: string;
|
|
1364
|
+
type: "info" | "warning" | "error" | "success";
|
|
1365
|
+
timestamp: string;
|
|
1366
|
+
read: boolean;
|
|
1367
|
+
link?: string;
|
|
1368
|
+
}
|
|
1369
|
+
interface TopoloNotificationsWidget extends TopoloWidgetBase {
|
|
1370
|
+
type: "notifications";
|
|
1371
|
+
notifications: TopoloWidgetNotificationItem[];
|
|
1372
|
+
unreadCount: number;
|
|
1373
|
+
}
|
|
1374
|
+
interface TopoloChartWidget extends TopoloWidgetBase {
|
|
1375
|
+
type: "chart";
|
|
1376
|
+
chartType: "line" | "bar" | "pie" | "donut";
|
|
1377
|
+
title: string;
|
|
1378
|
+
data: {
|
|
1379
|
+
labels: string[];
|
|
1380
|
+
values: number[];
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
type TopoloWidget = TopoloStatsWidget | TopoloRecentActivityWidget | TopoloQuickActionsWidget | TopoloNotificationsWidget | TopoloChartWidget;
|
|
1384
|
+
type TopoloWidgetWithOptionalMetadata<T extends TopoloWidget> = Omit<T, "serviceId" | "serviceName" | "lastUpdated"> & Partial<Pick<TopoloWidgetBase, "serviceId" | "serviceName" | "lastUpdated">>;
|
|
1385
|
+
type TopoloWidgetDraft = TopoloWidget extends infer Widget ? Widget extends TopoloWidget ? TopoloWidgetWithOptionalMetadata<Widget> : never : never;
|
|
1386
|
+
interface TopoloWidgetApiResponse {
|
|
1387
|
+
success: boolean;
|
|
1388
|
+
widgets: TopoloWidget[];
|
|
1389
|
+
error?: string;
|
|
1390
|
+
}
|
|
1391
|
+
interface TopoloWidgetResponseOptions {
|
|
1392
|
+
serviceId: string;
|
|
1393
|
+
serviceName: string;
|
|
1394
|
+
widgets: TopoloWidgetDraft[];
|
|
1395
|
+
now?: Date | string;
|
|
1396
|
+
}
|
|
1397
|
+
interface TopoloWidgetValidationResult {
|
|
1398
|
+
ok: boolean;
|
|
1399
|
+
errors: string[];
|
|
1400
|
+
}
|
|
1401
|
+
interface TopoloWidgetConfig {
|
|
1402
|
+
serviceId: string;
|
|
1403
|
+
serviceName: string;
|
|
1404
|
+
baseUrl: string;
|
|
1405
|
+
widgetEndpoint: string;
|
|
1406
|
+
enabled: boolean;
|
|
1407
|
+
refreshInterval: number;
|
|
1408
|
+
}
|
|
1409
|
+
declare function defineTopoloStatsWidget(widget: Omit<TopoloStatsWidget, "type">): TopoloStatsWidget;
|
|
1410
|
+
declare function defineTopoloRecentActivityWidget(widget: Omit<TopoloRecentActivityWidget, "type">): TopoloRecentActivityWidget;
|
|
1411
|
+
declare function defineTopoloQuickActionsWidget(widget: Omit<TopoloQuickActionsWidget, "type">): TopoloQuickActionsWidget;
|
|
1412
|
+
declare function defineTopoloNotificationsWidget(widget: Omit<TopoloNotificationsWidget, "type">): TopoloNotificationsWidget;
|
|
1413
|
+
declare function defineTopoloChartWidget(widget: Omit<TopoloChartWidget, "type">): TopoloChartWidget;
|
|
1414
|
+
declare function createTopoloWidgetResponse({ serviceId, serviceName, widgets, now, }: TopoloWidgetResponseOptions): TopoloWidgetApiResponse;
|
|
1415
|
+
declare function createTopoloWidgetError(error: string): TopoloWidgetApiResponse;
|
|
1416
|
+
declare function validateTopoloWidgetResponse(response: unknown): TopoloWidgetValidationResult;
|
|
1417
|
+
|
|
1238
1418
|
/**
|
|
1239
1419
|
* Convenience factory that returns a ready-to-use typed Topolo client plus
|
|
1240
1420
|
* domain module surfaces (identity, crm, ...).
|
|
@@ -1249,4 +1429,4 @@ declare function createTopolo(options: TopoloClientOptions): {
|
|
|
1249
1429
|
};
|
|
1250
1430
|
type Topolo = ReturnType<typeof createTopolo>;
|
|
1251
1431
|
|
|
1252
|
-
export { APPLICATIONS, APPLICATION_REQUIREMENTS, APPLICATION_REQUIREMENTS_VERSION, type AgentIdentity, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationId, type ApplicationRequirement, type ApplicationRequirementAudit, type ApplicationRequirementFinding, type ApplicationRequirementMigrationItem, type ApplicationRequirementScope, type ApplicationRequirementScore, type ApplicationRequirementStatus, type ApplicationRequirementsAuditReport, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_SERVICE_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, PLATFORM_SERVICE_IDS, type RequestOptions, type ServiceId, type TokenResponse, type Topolo, TopoloAuthError, TopoloClient, type TopoloClientOptions, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, TopoloOAuth, TopoloPermissionError, TopoloSdkError, applicationRequirementScopes, auditAllApplicationRequirements, auditApplicationRequirements, createTopolo, requirementsForApplication, resolveServiceUrl };
|
|
1432
|
+
export { APPLICATIONS, APPLICATION_REQUIREMENTS, APPLICATION_REQUIREMENTS_VERSION, type AgentIdentity, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationId, type ApplicationRequirement, type ApplicationRequirementAudit, type ApplicationRequirementFinding, type ApplicationRequirementMigrationItem, type ApplicationRequirementScope, type ApplicationRequirementScore, type ApplicationRequirementStatus, type ApplicationRequirementsAuditReport, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_SERVICE_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, PLATFORM_SERVICE_IDS, type RequestOptions, type ServiceId, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, TopoloAuthError, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloQuickActionsWidget, type TopoloRecentActivityWidget, TopoloSdkError, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetActionItem, type TopoloWidgetActivityItem, type TopoloWidgetApiResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetDraft, type TopoloWidgetMetric, type TopoloWidgetNotificationItem, type TopoloWidgetResponseOptions, type TopoloWidgetSnapshotMetadata, type TopoloWidgetSnapshotMetric, type TopoloWidgetType, type TopoloWidgetValidationResult, applicationRequirementScopes, auditAllApplicationRequirements, auditApplicationRequirements, createTopolo, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloQuickActionsWidget, defineTopoloRecentActivityWidget, defineTopoloStatsWidget, requirementsForApplication, resolveServiceUrl, validateTopoloWidgetResponse };
|