@topolo/sdk 0.4.6 → 0.4.8
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 +161 -144
- package/dist/index.d.cts +96 -104
- package/dist/index.d.ts +96 -104
- package/dist/index.js +161 -144
- package/package.json +1 -1
- package/src/application-requirements.ts +12 -6
- package/src/applications.generated.ts +61 -114
- package/src/client.test.ts +74 -0
- package/src/client.ts +101 -0
- package/src/index.test.ts +69 -0
- package/src/index.ts +1 -0
- package/src/modules/crm.test.ts +208 -0
- package/src/modules/identity.test.ts +165 -0
- package/src/modules/p2p.test.ts +286 -0
- package/src/oauth.test.ts +103 -0
- package/src/services.generated.ts +14 -15
- package/src/services.test.ts +19 -8
- package/src/widgets.test.ts +255 -1
- package/src/widgets.ts +5 -3
package/dist/index.js
CHANGED
|
@@ -58,54 +58,53 @@ var TopoloHttpError = class extends TopoloSdkError {
|
|
|
58
58
|
|
|
59
59
|
// src/services.generated.ts
|
|
60
60
|
var SERVICES = {
|
|
61
|
-
agent: "https://agent
|
|
61
|
+
agent: "https://agent.topolo.app",
|
|
62
62
|
auth: "https://auth.topolo.app",
|
|
63
63
|
backup: "https://backup.topolo.app",
|
|
64
64
|
books: "https://books.topolo.app",
|
|
65
65
|
bugfix: "https://bugfix.topolo.app",
|
|
66
|
-
bytes: "https://bytes
|
|
66
|
+
bytes: "https://bytes.topolo.app",
|
|
67
67
|
calendar: "https://calendar.topolo.app",
|
|
68
68
|
capacity: "https://capacity.topolo.app",
|
|
69
69
|
chat: "https://chat.topolo.app",
|
|
70
|
-
commerce: "https://commerce
|
|
70
|
+
commerce: "https://commerce.topolo.app",
|
|
71
71
|
compose: "https://compose.topolo.app",
|
|
72
72
|
consent: "https://consent.topolo.app",
|
|
73
|
-
crm: "https://crm
|
|
73
|
+
crm: "https://crm.topolo.app",
|
|
74
74
|
developers: "https://developers.topolo.app",
|
|
75
75
|
director: "https://director.topolo.app",
|
|
76
|
-
feed: "https://feed
|
|
76
|
+
feed: "https://feed.topolo.app",
|
|
77
77
|
flow: "https://flow.topolo.app",
|
|
78
|
-
forecast: "https://forecast
|
|
78
|
+
forecast: "https://forecast.topolo.app",
|
|
79
79
|
forms: "https://forms.topolo.app",
|
|
80
80
|
home: "https://home.topolo.app",
|
|
81
81
|
insights: "https://insights.topolo.app",
|
|
82
82
|
inventory: "https://inventory.topolo.app",
|
|
83
|
-
learn: "https://learn
|
|
83
|
+
learn: "https://learn.topolo.app",
|
|
84
84
|
localize: "https://localize.topolo.app",
|
|
85
|
-
mail: "https://mail
|
|
86
|
-
mdm: "https://mdm
|
|
85
|
+
mail: "https://mail.topolo.app",
|
|
86
|
+
mdm: "https://mdm.topolo.app",
|
|
87
87
|
messages: "https://messages.topolo.app",
|
|
88
88
|
nexus: "https://nexus-api.topolo.app",
|
|
89
89
|
notify: "https://notify.topolo.app",
|
|
90
90
|
observability_watch: "https://observability-watch.topolo.app",
|
|
91
|
-
one: "https://
|
|
91
|
+
one: "https://www.topolo.app",
|
|
92
92
|
p2p: "https://p2p.topolo.app",
|
|
93
93
|
pay: "https://pay.topolo.app",
|
|
94
94
|
people: "https://people.topolo.app",
|
|
95
|
-
pulse: "https://pulse.topolo.app",
|
|
96
95
|
"quro.api": "https://api.ol0.me",
|
|
97
96
|
"quro.redirect": "https://ol0.me",
|
|
98
|
-
roadmapper: "https://roadmapper
|
|
97
|
+
roadmapper: "https://roadmapper.topolo.app",
|
|
99
98
|
sign: "https://sign.topolo.app",
|
|
100
|
-
social_studio: "https://studio
|
|
101
|
-
socialize: "https://socialize
|
|
99
|
+
social_studio: "https://studio.topolo.app",
|
|
100
|
+
socialize: "https://socialize.topolo.app",
|
|
102
101
|
spaces: "https://spaces.topolo.app",
|
|
103
102
|
status: "https://status.topolo.app",
|
|
104
103
|
success: "https://success.topolo.app",
|
|
105
104
|
support: "https://support.topolo.app",
|
|
106
105
|
survey: "https://survey.topolo.app",
|
|
107
106
|
voice: "https://voice.topolo.app",
|
|
108
|
-
web: "https://web
|
|
107
|
+
web: "https://web.topolo.app"
|
|
109
108
|
};
|
|
110
109
|
|
|
111
110
|
// src/applications.generated.ts
|
|
@@ -156,17 +155,15 @@ var APPLICATIONS = {
|
|
|
156
155
|
"agent.topolo.app"
|
|
157
156
|
],
|
|
158
157
|
"routes": [],
|
|
159
|
-
"serviceId":
|
|
158
|
+
"serviceId": "agent"
|
|
160
159
|
},
|
|
161
160
|
{
|
|
162
161
|
"name": "topolo-agent-api",
|
|
163
162
|
"kind": "worker",
|
|
164
|
-
"apiUrl":
|
|
165
|
-
"domains": [
|
|
166
|
-
"agent-api.topolo.app"
|
|
167
|
-
],
|
|
163
|
+
"apiUrl": null,
|
|
164
|
+
"domains": [],
|
|
168
165
|
"routes": [],
|
|
169
|
-
"serviceId":
|
|
166
|
+
"serviceId": null
|
|
170
167
|
}
|
|
171
168
|
]
|
|
172
169
|
},
|
|
@@ -286,17 +283,15 @@ var APPLICATIONS = {
|
|
|
286
283
|
"bytes.topolo.app"
|
|
287
284
|
],
|
|
288
285
|
"routes": [],
|
|
289
|
-
"serviceId":
|
|
286
|
+
"serviceId": "bytes"
|
|
290
287
|
},
|
|
291
288
|
{
|
|
292
289
|
"name": "topolo-bytes-api",
|
|
293
290
|
"kind": "worker",
|
|
294
|
-
"apiUrl":
|
|
295
|
-
"domains": [
|
|
296
|
-
"bytes-api.topolo.app"
|
|
297
|
-
],
|
|
291
|
+
"apiUrl": null,
|
|
292
|
+
"domains": [],
|
|
298
293
|
"routes": [],
|
|
299
|
-
"serviceId":
|
|
294
|
+
"serviceId": null
|
|
300
295
|
}
|
|
301
296
|
]
|
|
302
297
|
},
|
|
@@ -395,12 +390,10 @@ var APPLICATIONS = {
|
|
|
395
390
|
{
|
|
396
391
|
"name": "topolo-commerce-api",
|
|
397
392
|
"kind": "worker",
|
|
398
|
-
"apiUrl":
|
|
399
|
-
"domains": [
|
|
400
|
-
"commerce-api.topolo.app"
|
|
401
|
-
],
|
|
393
|
+
"apiUrl": null,
|
|
394
|
+
"domains": [],
|
|
402
395
|
"routes": [],
|
|
403
|
-
"serviceId":
|
|
396
|
+
"serviceId": null
|
|
404
397
|
},
|
|
405
398
|
{
|
|
406
399
|
"name": "topolo-commerce-guest-web",
|
|
@@ -420,7 +413,7 @@ var APPLICATIONS = {
|
|
|
420
413
|
"commerce.topolo.app"
|
|
421
414
|
],
|
|
422
415
|
"routes": [],
|
|
423
|
-
"serviceId":
|
|
416
|
+
"serviceId": "commerce"
|
|
424
417
|
},
|
|
425
418
|
{
|
|
426
419
|
"name": "topolo-commerce-station-web",
|
|
@@ -507,12 +500,10 @@ var APPLICATIONS = {
|
|
|
507
500
|
{
|
|
508
501
|
"name": "topolo-crm-api",
|
|
509
502
|
"kind": "worker",
|
|
510
|
-
"apiUrl":
|
|
511
|
-
"domains": [
|
|
512
|
-
"crm-api.topolo.app"
|
|
513
|
-
],
|
|
503
|
+
"apiUrl": null,
|
|
504
|
+
"domains": [],
|
|
514
505
|
"routes": [],
|
|
515
|
-
"serviceId":
|
|
506
|
+
"serviceId": null
|
|
516
507
|
},
|
|
517
508
|
{
|
|
518
509
|
"name": "topolo-crm-app",
|
|
@@ -522,7 +513,7 @@ var APPLICATIONS = {
|
|
|
522
513
|
"crm.topolo.app"
|
|
523
514
|
],
|
|
524
515
|
"routes": [],
|
|
525
|
-
"serviceId":
|
|
516
|
+
"serviceId": "crm"
|
|
526
517
|
}
|
|
527
518
|
]
|
|
528
519
|
},
|
|
@@ -645,12 +636,10 @@ var APPLICATIONS = {
|
|
|
645
636
|
{
|
|
646
637
|
"name": "topolo-feed-api",
|
|
647
638
|
"kind": "worker",
|
|
648
|
-
"apiUrl":
|
|
649
|
-
"domains": [
|
|
650
|
-
"feed-api.topolo.app"
|
|
651
|
-
],
|
|
639
|
+
"apiUrl": null,
|
|
640
|
+
"domains": [],
|
|
652
641
|
"routes": [],
|
|
653
|
-
"serviceId":
|
|
642
|
+
"serviceId": null
|
|
654
643
|
},
|
|
655
644
|
{
|
|
656
645
|
"name": "topolo-feed-web",
|
|
@@ -660,7 +649,7 @@ var APPLICATIONS = {
|
|
|
660
649
|
"feed.topolo.app"
|
|
661
650
|
],
|
|
662
651
|
"routes": [],
|
|
663
|
-
"serviceId":
|
|
652
|
+
"serviceId": "feed"
|
|
664
653
|
}
|
|
665
654
|
]
|
|
666
655
|
},
|
|
@@ -712,17 +701,15 @@ var APPLICATIONS = {
|
|
|
712
701
|
"forecast.topolo.app"
|
|
713
702
|
],
|
|
714
703
|
"routes": [],
|
|
715
|
-
"serviceId":
|
|
704
|
+
"serviceId": "forecast"
|
|
716
705
|
},
|
|
717
706
|
{
|
|
718
707
|
"name": "topolo-forecast-api",
|
|
719
708
|
"kind": "worker",
|
|
720
|
-
"apiUrl":
|
|
721
|
-
"domains": [
|
|
722
|
-
"forecast-api.topolo.app"
|
|
723
|
-
],
|
|
709
|
+
"apiUrl": null,
|
|
710
|
+
"domains": [],
|
|
724
711
|
"routes": [],
|
|
725
|
-
"serviceId":
|
|
712
|
+
"serviceId": null
|
|
726
713
|
}
|
|
727
714
|
]
|
|
728
715
|
},
|
|
@@ -864,17 +851,15 @@ var APPLICATIONS = {
|
|
|
864
851
|
"learn.topolo.app"
|
|
865
852
|
],
|
|
866
853
|
"routes": [],
|
|
867
|
-
"serviceId":
|
|
854
|
+
"serviceId": "learn"
|
|
868
855
|
},
|
|
869
856
|
{
|
|
870
857
|
"name": "topolo-learn-api",
|
|
871
858
|
"kind": "worker",
|
|
872
|
-
"apiUrl":
|
|
873
|
-
"domains": [
|
|
874
|
-
"learn-api.topolo.app"
|
|
875
|
-
],
|
|
859
|
+
"apiUrl": null,
|
|
860
|
+
"domains": [],
|
|
876
861
|
"routes": [],
|
|
877
|
-
"serviceId":
|
|
862
|
+
"serviceId": null
|
|
878
863
|
}
|
|
879
864
|
]
|
|
880
865
|
},
|
|
@@ -920,17 +905,15 @@ var APPLICATIONS = {
|
|
|
920
905
|
"mail.topolo.app"
|
|
921
906
|
],
|
|
922
907
|
"routes": [],
|
|
923
|
-
"serviceId":
|
|
908
|
+
"serviceId": "mail"
|
|
924
909
|
},
|
|
925
910
|
{
|
|
926
911
|
"name": "topolo-mail-api",
|
|
927
912
|
"kind": "worker",
|
|
928
|
-
"apiUrl":
|
|
929
|
-
"domains": [
|
|
930
|
-
"mail-api.topolo.app"
|
|
931
|
-
],
|
|
913
|
+
"apiUrl": null,
|
|
914
|
+
"domains": [],
|
|
932
915
|
"routes": [],
|
|
933
|
-
"serviceId":
|
|
916
|
+
"serviceId": null
|
|
934
917
|
}
|
|
935
918
|
]
|
|
936
919
|
},
|
|
@@ -947,12 +930,10 @@ var APPLICATIONS = {
|
|
|
947
930
|
{
|
|
948
931
|
"name": "topolo-mdm-api",
|
|
949
932
|
"kind": "worker",
|
|
950
|
-
"apiUrl":
|
|
951
|
-
"domains": [
|
|
952
|
-
"mdm-api.topolo.app"
|
|
953
|
-
],
|
|
933
|
+
"apiUrl": null,
|
|
934
|
+
"domains": [],
|
|
954
935
|
"routes": [],
|
|
955
|
-
"serviceId":
|
|
936
|
+
"serviceId": null
|
|
956
937
|
},
|
|
957
938
|
{
|
|
958
939
|
"name": "topolo-mdm-console",
|
|
@@ -962,7 +943,7 @@ var APPLICATIONS = {
|
|
|
962
943
|
"mdm.topolo.app"
|
|
963
944
|
],
|
|
964
945
|
"routes": [],
|
|
965
|
-
"serviceId":
|
|
946
|
+
"serviceId": "mdm"
|
|
966
947
|
}
|
|
967
948
|
]
|
|
968
949
|
},
|
|
@@ -1095,20 +1076,23 @@ var APPLICATIONS = {
|
|
|
1095
1076
|
{
|
|
1096
1077
|
"name": "topolo-one",
|
|
1097
1078
|
"kind": "worker",
|
|
1098
|
-
"apiUrl":
|
|
1099
|
-
"domains": [
|
|
1100
|
-
|
|
1079
|
+
"apiUrl": "https://one.topolo.app",
|
|
1080
|
+
"domains": [
|
|
1081
|
+
"one.topolo.app"
|
|
1082
|
+
],
|
|
1083
|
+
"routes": [
|
|
1084
|
+
"one.topolo.app/*"
|
|
1085
|
+
],
|
|
1101
1086
|
"serviceId": null
|
|
1102
1087
|
},
|
|
1103
1088
|
{
|
|
1104
1089
|
"name": "topolo-one-api",
|
|
1105
1090
|
"kind": "worker",
|
|
1106
|
-
"apiUrl": "https://
|
|
1091
|
+
"apiUrl": "https://www.topolo.app",
|
|
1107
1092
|
"domains": [
|
|
1108
|
-
"
|
|
1093
|
+
"www.topolo.app"
|
|
1109
1094
|
],
|
|
1110
1095
|
"routes": [
|
|
1111
|
-
"one.topolo.app/*",
|
|
1112
1096
|
"www.topolo.app/*"
|
|
1113
1097
|
],
|
|
1114
1098
|
"serviceId": "one"
|
|
@@ -1218,36 +1202,6 @@ var APPLICATIONS = {
|
|
|
1218
1202
|
}
|
|
1219
1203
|
]
|
|
1220
1204
|
},
|
|
1221
|
-
"pulse": {
|
|
1222
|
-
"id": "pulse",
|
|
1223
|
-
"appDir": "TopoloPulse",
|
|
1224
|
-
"name": "topolo-pulse",
|
|
1225
|
-
"packageName": "topolo-pulse",
|
|
1226
|
-
"productionUrl": "https://pulse.topolo.app",
|
|
1227
|
-
"services": [
|
|
1228
|
-
"pulse"
|
|
1229
|
-
],
|
|
1230
|
-
"deployTargets": [
|
|
1231
|
-
{
|
|
1232
|
-
"name": "topolo-pulse",
|
|
1233
|
-
"kind": "worker",
|
|
1234
|
-
"apiUrl": "https://pulse.topolo.app",
|
|
1235
|
-
"domains": [
|
|
1236
|
-
"pulse.topolo.app"
|
|
1237
|
-
],
|
|
1238
|
-
"routes": [],
|
|
1239
|
-
"serviceId": "pulse"
|
|
1240
|
-
},
|
|
1241
|
-
{
|
|
1242
|
-
"name": "topolo-pulse-api",
|
|
1243
|
-
"kind": "worker",
|
|
1244
|
-
"apiUrl": null,
|
|
1245
|
-
"domains": [],
|
|
1246
|
-
"routes": [],
|
|
1247
|
-
"serviceId": null
|
|
1248
|
-
}
|
|
1249
|
-
]
|
|
1250
|
-
},
|
|
1251
1205
|
"quro": {
|
|
1252
1206
|
"id": "quro",
|
|
1253
1207
|
"appDir": "TopoloQuro",
|
|
@@ -1313,17 +1267,15 @@ var APPLICATIONS = {
|
|
|
1313
1267
|
"roadmapper.topolo.app"
|
|
1314
1268
|
],
|
|
1315
1269
|
"routes": [],
|
|
1316
|
-
"serviceId":
|
|
1270
|
+
"serviceId": "roadmapper"
|
|
1317
1271
|
},
|
|
1318
1272
|
{
|
|
1319
1273
|
"name": "topolo-roadmapper-api",
|
|
1320
1274
|
"kind": "worker",
|
|
1321
|
-
"apiUrl":
|
|
1322
|
-
"domains": [
|
|
1323
|
-
"roadmapper-api.topolo.app"
|
|
1324
|
-
],
|
|
1275
|
+
"apiUrl": null,
|
|
1276
|
+
"domains": [],
|
|
1325
1277
|
"routes": [],
|
|
1326
|
-
"serviceId":
|
|
1278
|
+
"serviceId": null
|
|
1327
1279
|
}
|
|
1328
1280
|
]
|
|
1329
1281
|
},
|
|
@@ -1375,17 +1327,15 @@ var APPLICATIONS = {
|
|
|
1375
1327
|
"studio.topolo.app"
|
|
1376
1328
|
],
|
|
1377
1329
|
"routes": [],
|
|
1378
|
-
"serviceId":
|
|
1330
|
+
"serviceId": "social_studio"
|
|
1379
1331
|
},
|
|
1380
1332
|
{
|
|
1381
1333
|
"name": "topolo-social-studio-api",
|
|
1382
1334
|
"kind": "worker",
|
|
1383
|
-
"apiUrl":
|
|
1384
|
-
"domains": [
|
|
1385
|
-
"studio-api.topolo.app"
|
|
1386
|
-
],
|
|
1335
|
+
"apiUrl": null,
|
|
1336
|
+
"domains": [],
|
|
1387
1337
|
"routes": [],
|
|
1388
|
-
"serviceId":
|
|
1338
|
+
"serviceId": null
|
|
1389
1339
|
},
|
|
1390
1340
|
{
|
|
1391
1341
|
"name": "topolo-social-studio-queue",
|
|
@@ -1415,17 +1365,15 @@ var APPLICATIONS = {
|
|
|
1415
1365
|
"socialize.topolo.app"
|
|
1416
1366
|
],
|
|
1417
1367
|
"routes": [],
|
|
1418
|
-
"serviceId":
|
|
1368
|
+
"serviceId": "socialize"
|
|
1419
1369
|
},
|
|
1420
1370
|
{
|
|
1421
1371
|
"name": "topolo-socialize-api",
|
|
1422
1372
|
"kind": "worker",
|
|
1423
|
-
"apiUrl":
|
|
1424
|
-
"domains": [
|
|
1425
|
-
"socialize-api.topolo.app"
|
|
1426
|
-
],
|
|
1373
|
+
"apiUrl": null,
|
|
1374
|
+
"domains": [],
|
|
1427
1375
|
"routes": [],
|
|
1428
|
-
"serviceId":
|
|
1376
|
+
"serviceId": null
|
|
1429
1377
|
},
|
|
1430
1378
|
{
|
|
1431
1379
|
"name": "topolo-socialize-scheduler",
|
|
@@ -1626,12 +1574,10 @@ var APPLICATIONS = {
|
|
|
1626
1574
|
{
|
|
1627
1575
|
"name": "topolo-web-api",
|
|
1628
1576
|
"kind": "worker",
|
|
1629
|
-
"apiUrl":
|
|
1630
|
-
"domains": [
|
|
1631
|
-
"web-api.topolo.app"
|
|
1632
|
-
],
|
|
1577
|
+
"apiUrl": null,
|
|
1578
|
+
"domains": [],
|
|
1633
1579
|
"routes": [],
|
|
1634
|
-
"serviceId":
|
|
1580
|
+
"serviceId": null
|
|
1635
1581
|
},
|
|
1636
1582
|
{
|
|
1637
1583
|
"name": "topolo-web-runtime",
|
|
@@ -1654,14 +1600,14 @@ var APPLICATIONS = {
|
|
|
1654
1600
|
"web.topolo.app"
|
|
1655
1601
|
],
|
|
1656
1602
|
"routes": [],
|
|
1657
|
-
"serviceId":
|
|
1603
|
+
"serviceId": "web"
|
|
1658
1604
|
}
|
|
1659
1605
|
]
|
|
1660
1606
|
}
|
|
1661
1607
|
};
|
|
1662
1608
|
|
|
1663
1609
|
// src/application-requirements.ts
|
|
1664
|
-
var APPLICATION_REQUIREMENTS_VERSION = "2026-
|
|
1610
|
+
var APPLICATION_REQUIREMENTS_VERSION = "2026-06-07.1";
|
|
1665
1611
|
var APPLICATION_REQUIREMENTS = [
|
|
1666
1612
|
{
|
|
1667
1613
|
id: "platform-metadata",
|
|
@@ -1717,16 +1663,20 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1717
1663
|
summary: "Browser applications should feel like one platform and should not create isolated navigation or account surfaces.",
|
|
1718
1664
|
appliesTo: ["browser"],
|
|
1719
1665
|
evidence: [
|
|
1720
|
-
"@topolo/
|
|
1721
|
-
"
|
|
1722
|
-
"Account menu and sign-out behavior use TopoloAppShell or TopoloAccountMenu",
|
|
1666
|
+
"@topolo-io/app-shell is used for the platform shell where the app has authenticated UI",
|
|
1667
|
+
"@topolo-io/app-launcher keeps the shared launcher/app switcher reachable from authenticated app chrome",
|
|
1668
|
+
"Account menu and sign-out behavior use TopoloAppShell or the ui-kit TopoloAccountMenu primitive",
|
|
1669
|
+
"Repeated app body surfaces use shared TopoloAppLayout primitives instead of local stat cards, empty states, or status badges",
|
|
1670
|
+
"Local preview supports deterministic visual QA fixtures for overview, list, detail, settings, and empty/loading states",
|
|
1723
1671
|
"Authenticated app body content stays inside the viewport on mobile and desktop widths"
|
|
1724
1672
|
],
|
|
1725
1673
|
implementation: [
|
|
1726
|
-
"Use TopoloAppShell for authenticated app layouts",
|
|
1727
|
-
"Use TopoloAccountMenu when a partial-shell surface still needs account chrome",
|
|
1674
|
+
"Use @topolo-io/app-shell TopoloAppShell for authenticated app layouts",
|
|
1675
|
+
"Use the @topolo-io/ui-kit TopoloAccountMenu primitive when a partial-shell surface still needs account chrome",
|
|
1728
1676
|
"Pass app-specific account actions as additive menu items instead of forking dropdowns",
|
|
1729
1677
|
"Use shared design tokens and platform UI primitives before creating local equivalents",
|
|
1678
|
+
"Use TopoloAppMetricCard, TopoloAppEmptyState, TopoloAppStatusBadge, TopoloAppGrid, and TopoloAppSection for repeated app body patterns",
|
|
1679
|
+
"Keep visual QA fixtures available through visualQa=1 or __devpreview=1 so screenshot checks do not depend on live API state",
|
|
1730
1680
|
"Keep mobile and desktop shell behavior aligned with the platform UI kit",
|
|
1731
1681
|
"Constrain app-owned workspace wrappers with min-width: 0, width: auto, and viewport-aware max-width so shell padding cannot create page-level horizontal overflow"
|
|
1732
1682
|
]
|
|
@@ -1805,11 +1755,13 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1805
1755
|
evidence: [
|
|
1806
1756
|
"The app-owned API exposes GET /api/widget",
|
|
1807
1757
|
"The endpoint returns TopoloWidgetApiResponse from @topolo/sdk",
|
|
1758
|
+
"Every returned widget includes snapshot.summary with app-owned operational prose",
|
|
1808
1759
|
"The endpoint derives organization/user context from the app auth boundary"
|
|
1809
1760
|
],
|
|
1810
1761
|
implementation: [
|
|
1811
1762
|
"Import createTopoloWidgetResponse from @topolo/sdk in the app backend",
|
|
1812
1763
|
"Return native app metrics or action widgets instead of generic launch-card fallbacks",
|
|
1764
|
+
"Populate snapshot.summary in the producing app for every widget instead of synthesizing summaries in TopoloOne",
|
|
1813
1765
|
"Add a route-level test that validates the response with validateTopoloWidgetResponse"
|
|
1814
1766
|
]
|
|
1815
1767
|
},
|
|
@@ -2106,6 +2058,8 @@ function firstString(...values) {
|
|
|
2106
2058
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
2107
2059
|
var TOPOLO_ACTION_ID_HEADER = "X-Topolo-Action-Id";
|
|
2108
2060
|
var TOPOLO_ACTION_NAME_HEADER = "X-Topolo-Action-Name";
|
|
2061
|
+
var TOPOLO_RESOURCE_TYPE_HEADER = "X-Topolo-Resource-Type";
|
|
2062
|
+
var TOPOLO_RESOURCE_ID_HEADER = "X-Topolo-Resource-ID";
|
|
2109
2063
|
var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
2110
2064
|
var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
|
|
2111
2065
|
var CATALOG_CACHE_TTL_MS = 60 * 1e3;
|
|
@@ -2184,6 +2138,18 @@ var TopoloClient = class _TopoloClient {
|
|
|
2184
2138
|
if (opts.headers) {
|
|
2185
2139
|
for (const [k, v] of Object.entries(opts.headers)) headers.set(k, v);
|
|
2186
2140
|
}
|
|
2141
|
+
if (opts.resource) {
|
|
2142
|
+
const resourceType = opts.resource.resourceType.trim();
|
|
2143
|
+
const resourceId = opts.resource.resourceId.trim();
|
|
2144
|
+
if (!resourceType || !resourceId) {
|
|
2145
|
+
throw new TopoloSdkError(
|
|
2146
|
+
"invalid_resource_context",
|
|
2147
|
+
"Both resource.resourceType and resource.resourceId are required when resource context is provided."
|
|
2148
|
+
);
|
|
2149
|
+
}
|
|
2150
|
+
headers.set(TOPOLO_RESOURCE_TYPE_HEADER, resourceType);
|
|
2151
|
+
headers.set(TOPOLO_RESOURCE_ID_HEADER, resourceId);
|
|
2152
|
+
}
|
|
2187
2153
|
const controller = new AbortController();
|
|
2188
2154
|
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
2189
2155
|
const signal = opts.signal ? mergeSignals(opts.signal, controller.signal) : controller.signal;
|
|
@@ -2366,6 +2332,11 @@ var TopoloClient = class _TopoloClient {
|
|
|
2366
2332
|
const serviceId = typeof s.service_id === "string" ? s.service_id : typeof s.id === "string" ? s.id : null;
|
|
2367
2333
|
if (!serviceId) continue;
|
|
2368
2334
|
const permissions = Array.isArray(s.granted_permissions) ? s.granted_permissions.filter((permission) => typeof permission === "string" && permission.trim().length > 0) : [];
|
|
2335
|
+
const catalogApiKeyResources = normalizeApiKeyResourceMetadataList(
|
|
2336
|
+
s.api_key_resources ?? s.apiKeyResources
|
|
2337
|
+
);
|
|
2338
|
+
const apiKeyResource = normalizeApiKeyResourceMetadata(s.api_key_resource ?? s.apiKeyResource) ?? catalogApiKeyResources[0] ?? null;
|
|
2339
|
+
const apiKeyResources = catalogApiKeyResources.length > 0 ? catalogApiKeyResources : apiKeyResource ? [apiKeyResource] : [];
|
|
2369
2340
|
entries.push({
|
|
2370
2341
|
serviceId,
|
|
2371
2342
|
slug: typeof s.app_slug === "string" ? s.app_slug : null,
|
|
@@ -2376,7 +2347,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2376
2347
|
status: typeof s.status === "string" ? s.status : null,
|
|
2377
2348
|
surfaceKind: typeof s.surface_kind === "string" ? s.surface_kind : null,
|
|
2378
2349
|
launchable: s.launchable === true,
|
|
2379
|
-
permissions
|
|
2350
|
+
permissions,
|
|
2351
|
+
apiKeyResource,
|
|
2352
|
+
apiKeyResources
|
|
2380
2353
|
});
|
|
2381
2354
|
}
|
|
2382
2355
|
this.serviceCatalogCache = {
|
|
@@ -2462,7 +2435,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2462
2435
|
status: "bundled",
|
|
2463
2436
|
surfaceKind: "application",
|
|
2464
2437
|
launchable: Boolean(app.productionUrl),
|
|
2465
|
-
permissions: []
|
|
2438
|
+
permissions: [],
|
|
2439
|
+
apiKeyResource: null,
|
|
2440
|
+
apiKeyResources: []
|
|
2466
2441
|
}));
|
|
2467
2442
|
}
|
|
2468
2443
|
/**
|
|
@@ -2511,6 +2486,46 @@ function resolveConfiguredServiceId(slug, serviceIds) {
|
|
|
2511
2486
|
}
|
|
2512
2487
|
return null;
|
|
2513
2488
|
}
|
|
2489
|
+
function normalizeApiKeyResourceMetadata(input) {
|
|
2490
|
+
if (!isRecord(input)) return null;
|
|
2491
|
+
const resourceType = readString(input.resourceType ?? input.resource_type);
|
|
2492
|
+
const label = readString(input.label);
|
|
2493
|
+
const emptyLabel = readString(input.emptyLabel ?? input.empty_label);
|
|
2494
|
+
const resourceConcept = readString(input.resourceConcept ?? input.resource_concept);
|
|
2495
|
+
const canonicalResourceType = readString(input.canonicalResourceType ?? input.canonical_resource_type);
|
|
2496
|
+
const defaultEntitlement = readString(input.defaultEntitlement ?? input.default_entitlement);
|
|
2497
|
+
const exceptionPolicy = readString(input.exceptionPolicy ?? input.exception_policy);
|
|
2498
|
+
if (!resourceType || !label || !emptyLabel || resourceConcept !== "workspace" || canonicalResourceType !== "workspace" || defaultEntitlement !== "enterprise" || exceptionPolicy !== "app_or_organization") {
|
|
2499
|
+
return null;
|
|
2500
|
+
}
|
|
2501
|
+
return {
|
|
2502
|
+
resourceType,
|
|
2503
|
+
label,
|
|
2504
|
+
emptyLabel,
|
|
2505
|
+
resourceConcept,
|
|
2506
|
+
canonicalResourceType,
|
|
2507
|
+
defaultEntitlement,
|
|
2508
|
+
exceptionPolicy
|
|
2509
|
+
};
|
|
2510
|
+
}
|
|
2511
|
+
function normalizeApiKeyResourceMetadataList(input) {
|
|
2512
|
+
if (!Array.isArray(input)) return [];
|
|
2513
|
+
const resources = [];
|
|
2514
|
+
const seenTypes = /* @__PURE__ */ new Set();
|
|
2515
|
+
for (const item of input) {
|
|
2516
|
+
const resource = normalizeApiKeyResourceMetadata(item);
|
|
2517
|
+
if (!resource || seenTypes.has(resource.resourceType)) continue;
|
|
2518
|
+
seenTypes.add(resource.resourceType);
|
|
2519
|
+
resources.push(resource);
|
|
2520
|
+
}
|
|
2521
|
+
return resources;
|
|
2522
|
+
}
|
|
2523
|
+
function readString(value) {
|
|
2524
|
+
return typeof value === "string" ? value.trim() : "";
|
|
2525
|
+
}
|
|
2526
|
+
function isRecord(value) {
|
|
2527
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2528
|
+
}
|
|
2514
2529
|
function resolveConfiguredServiceUrl(slug, serviceUrls) {
|
|
2515
2530
|
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
2516
2531
|
const configured = serviceUrls?.[serviceKey];
|
|
@@ -3078,7 +3093,7 @@ function createTopoloWidgetError(error) {
|
|
|
3078
3093
|
}
|
|
3079
3094
|
function validateTopoloWidgetResponse(response) {
|
|
3080
3095
|
const errors = [];
|
|
3081
|
-
if (!
|
|
3096
|
+
if (!isRecord2(response)) {
|
|
3082
3097
|
return { ok: false, errors: ["response must be an object"] };
|
|
3083
3098
|
}
|
|
3084
3099
|
if (typeof response.success !== "boolean") {
|
|
@@ -3097,7 +3112,7 @@ function validateTopoloWidgetResponse(response) {
|
|
|
3097
3112
|
return { ok: errors.length === 0, errors };
|
|
3098
3113
|
}
|
|
3099
3114
|
function validateWidget(widget, path, errors) {
|
|
3100
|
-
if (!
|
|
3115
|
+
if (!isRecord2(widget)) {
|
|
3101
3116
|
errors.push(`${path} must be an object`);
|
|
3102
3117
|
return;
|
|
3103
3118
|
}
|
|
@@ -3124,7 +3139,7 @@ function validateWidget(widget, path, errors) {
|
|
|
3124
3139
|
case "chart":
|
|
3125
3140
|
validateNonEmptyString(widget.chartType, `${path}.chartType`, errors);
|
|
3126
3141
|
validateNonEmptyString(widget.title, `${path}.title`, errors);
|
|
3127
|
-
if (!
|
|
3142
|
+
if (!isRecord2(widget.data)) {
|
|
3128
3143
|
errors.push(`${path}.data must be an object`);
|
|
3129
3144
|
} else {
|
|
3130
3145
|
validateArray(widget.data.labels, `${path}.data.labels`, errors);
|
|
@@ -3137,12 +3152,14 @@ function validateWidget(widget, path, errors) {
|
|
|
3137
3152
|
}
|
|
3138
3153
|
function validateSnapshotMetadata(snapshot, path, errors) {
|
|
3139
3154
|
if (snapshot === void 0) {
|
|
3155
|
+
errors.push(`${path} must be an object`);
|
|
3140
3156
|
return;
|
|
3141
3157
|
}
|
|
3142
|
-
if (!
|
|
3143
|
-
errors.push(`${path} must be an object
|
|
3158
|
+
if (!isRecord2(snapshot)) {
|
|
3159
|
+
errors.push(`${path} must be an object`);
|
|
3144
3160
|
return;
|
|
3145
3161
|
}
|
|
3162
|
+
validateNonEmptyString(snapshot.summary, `${path}.summary`, errors);
|
|
3146
3163
|
if (snapshot.defaultMetricKeys !== void 0 && !Array.isArray(snapshot.defaultMetricKeys)) {
|
|
3147
3164
|
errors.push(`${path}.defaultMetricKeys must be an array when provided`);
|
|
3148
3165
|
}
|
|
@@ -3158,7 +3175,7 @@ function validateSnapshotMetadata(snapshot, path, errors) {
|
|
|
3158
3175
|
}
|
|
3159
3176
|
snapshot.availableMetrics.forEach((metric, index) => {
|
|
3160
3177
|
const metricPath = `${path}.availableMetrics[${index}]`;
|
|
3161
|
-
if (!
|
|
3178
|
+
if (!isRecord2(metric)) {
|
|
3162
3179
|
errors.push(`${metricPath} must be an object`);
|
|
3163
3180
|
return;
|
|
3164
3181
|
}
|
|
@@ -3179,7 +3196,7 @@ function validateArray(value, path, errors) {
|
|
|
3179
3196
|
errors.push(`${path} must be an array`);
|
|
3180
3197
|
}
|
|
3181
3198
|
}
|
|
3182
|
-
function
|
|
3199
|
+
function isRecord2(value) {
|
|
3183
3200
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3184
3201
|
}
|
|
3185
3202
|
function toIsoTimestamp(input) {
|