@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.cjs
CHANGED
|
@@ -113,54 +113,53 @@ var TopoloHttpError = class extends TopoloSdkError {
|
|
|
113
113
|
|
|
114
114
|
// src/services.generated.ts
|
|
115
115
|
var SERVICES = {
|
|
116
|
-
agent: "https://agent
|
|
116
|
+
agent: "https://agent.topolo.app",
|
|
117
117
|
auth: "https://auth.topolo.app",
|
|
118
118
|
backup: "https://backup.topolo.app",
|
|
119
119
|
books: "https://books.topolo.app",
|
|
120
120
|
bugfix: "https://bugfix.topolo.app",
|
|
121
|
-
bytes: "https://bytes
|
|
121
|
+
bytes: "https://bytes.topolo.app",
|
|
122
122
|
calendar: "https://calendar.topolo.app",
|
|
123
123
|
capacity: "https://capacity.topolo.app",
|
|
124
124
|
chat: "https://chat.topolo.app",
|
|
125
|
-
commerce: "https://commerce
|
|
125
|
+
commerce: "https://commerce.topolo.app",
|
|
126
126
|
compose: "https://compose.topolo.app",
|
|
127
127
|
consent: "https://consent.topolo.app",
|
|
128
|
-
crm: "https://crm
|
|
128
|
+
crm: "https://crm.topolo.app",
|
|
129
129
|
developers: "https://developers.topolo.app",
|
|
130
130
|
director: "https://director.topolo.app",
|
|
131
|
-
feed: "https://feed
|
|
131
|
+
feed: "https://feed.topolo.app",
|
|
132
132
|
flow: "https://flow.topolo.app",
|
|
133
|
-
forecast: "https://forecast
|
|
133
|
+
forecast: "https://forecast.topolo.app",
|
|
134
134
|
forms: "https://forms.topolo.app",
|
|
135
135
|
home: "https://home.topolo.app",
|
|
136
136
|
insights: "https://insights.topolo.app",
|
|
137
137
|
inventory: "https://inventory.topolo.app",
|
|
138
|
-
learn: "https://learn
|
|
138
|
+
learn: "https://learn.topolo.app",
|
|
139
139
|
localize: "https://localize.topolo.app",
|
|
140
|
-
mail: "https://mail
|
|
141
|
-
mdm: "https://mdm
|
|
140
|
+
mail: "https://mail.topolo.app",
|
|
141
|
+
mdm: "https://mdm.topolo.app",
|
|
142
142
|
messages: "https://messages.topolo.app",
|
|
143
143
|
nexus: "https://nexus-api.topolo.app",
|
|
144
144
|
notify: "https://notify.topolo.app",
|
|
145
145
|
observability_watch: "https://observability-watch.topolo.app",
|
|
146
|
-
one: "https://
|
|
146
|
+
one: "https://www.topolo.app",
|
|
147
147
|
p2p: "https://p2p.topolo.app",
|
|
148
148
|
pay: "https://pay.topolo.app",
|
|
149
149
|
people: "https://people.topolo.app",
|
|
150
|
-
pulse: "https://pulse.topolo.app",
|
|
151
150
|
"quro.api": "https://api.ol0.me",
|
|
152
151
|
"quro.redirect": "https://ol0.me",
|
|
153
|
-
roadmapper: "https://roadmapper
|
|
152
|
+
roadmapper: "https://roadmapper.topolo.app",
|
|
154
153
|
sign: "https://sign.topolo.app",
|
|
155
|
-
social_studio: "https://studio
|
|
156
|
-
socialize: "https://socialize
|
|
154
|
+
social_studio: "https://studio.topolo.app",
|
|
155
|
+
socialize: "https://socialize.topolo.app",
|
|
157
156
|
spaces: "https://spaces.topolo.app",
|
|
158
157
|
status: "https://status.topolo.app",
|
|
159
158
|
success: "https://success.topolo.app",
|
|
160
159
|
support: "https://support.topolo.app",
|
|
161
160
|
survey: "https://survey.topolo.app",
|
|
162
161
|
voice: "https://voice.topolo.app",
|
|
163
|
-
web: "https://web
|
|
162
|
+
web: "https://web.topolo.app"
|
|
164
163
|
};
|
|
165
164
|
|
|
166
165
|
// src/applications.generated.ts
|
|
@@ -211,17 +210,15 @@ var APPLICATIONS = {
|
|
|
211
210
|
"agent.topolo.app"
|
|
212
211
|
],
|
|
213
212
|
"routes": [],
|
|
214
|
-
"serviceId":
|
|
213
|
+
"serviceId": "agent"
|
|
215
214
|
},
|
|
216
215
|
{
|
|
217
216
|
"name": "topolo-agent-api",
|
|
218
217
|
"kind": "worker",
|
|
219
|
-
"apiUrl":
|
|
220
|
-
"domains": [
|
|
221
|
-
"agent-api.topolo.app"
|
|
222
|
-
],
|
|
218
|
+
"apiUrl": null,
|
|
219
|
+
"domains": [],
|
|
223
220
|
"routes": [],
|
|
224
|
-
"serviceId":
|
|
221
|
+
"serviceId": null
|
|
225
222
|
}
|
|
226
223
|
]
|
|
227
224
|
},
|
|
@@ -341,17 +338,15 @@ var APPLICATIONS = {
|
|
|
341
338
|
"bytes.topolo.app"
|
|
342
339
|
],
|
|
343
340
|
"routes": [],
|
|
344
|
-
"serviceId":
|
|
341
|
+
"serviceId": "bytes"
|
|
345
342
|
},
|
|
346
343
|
{
|
|
347
344
|
"name": "topolo-bytes-api",
|
|
348
345
|
"kind": "worker",
|
|
349
|
-
"apiUrl":
|
|
350
|
-
"domains": [
|
|
351
|
-
"bytes-api.topolo.app"
|
|
352
|
-
],
|
|
346
|
+
"apiUrl": null,
|
|
347
|
+
"domains": [],
|
|
353
348
|
"routes": [],
|
|
354
|
-
"serviceId":
|
|
349
|
+
"serviceId": null
|
|
355
350
|
}
|
|
356
351
|
]
|
|
357
352
|
},
|
|
@@ -450,12 +445,10 @@ var APPLICATIONS = {
|
|
|
450
445
|
{
|
|
451
446
|
"name": "topolo-commerce-api",
|
|
452
447
|
"kind": "worker",
|
|
453
|
-
"apiUrl":
|
|
454
|
-
"domains": [
|
|
455
|
-
"commerce-api.topolo.app"
|
|
456
|
-
],
|
|
448
|
+
"apiUrl": null,
|
|
449
|
+
"domains": [],
|
|
457
450
|
"routes": [],
|
|
458
|
-
"serviceId":
|
|
451
|
+
"serviceId": null
|
|
459
452
|
},
|
|
460
453
|
{
|
|
461
454
|
"name": "topolo-commerce-guest-web",
|
|
@@ -475,7 +468,7 @@ var APPLICATIONS = {
|
|
|
475
468
|
"commerce.topolo.app"
|
|
476
469
|
],
|
|
477
470
|
"routes": [],
|
|
478
|
-
"serviceId":
|
|
471
|
+
"serviceId": "commerce"
|
|
479
472
|
},
|
|
480
473
|
{
|
|
481
474
|
"name": "topolo-commerce-station-web",
|
|
@@ -562,12 +555,10 @@ var APPLICATIONS = {
|
|
|
562
555
|
{
|
|
563
556
|
"name": "topolo-crm-api",
|
|
564
557
|
"kind": "worker",
|
|
565
|
-
"apiUrl":
|
|
566
|
-
"domains": [
|
|
567
|
-
"crm-api.topolo.app"
|
|
568
|
-
],
|
|
558
|
+
"apiUrl": null,
|
|
559
|
+
"domains": [],
|
|
569
560
|
"routes": [],
|
|
570
|
-
"serviceId":
|
|
561
|
+
"serviceId": null
|
|
571
562
|
},
|
|
572
563
|
{
|
|
573
564
|
"name": "topolo-crm-app",
|
|
@@ -577,7 +568,7 @@ var APPLICATIONS = {
|
|
|
577
568
|
"crm.topolo.app"
|
|
578
569
|
],
|
|
579
570
|
"routes": [],
|
|
580
|
-
"serviceId":
|
|
571
|
+
"serviceId": "crm"
|
|
581
572
|
}
|
|
582
573
|
]
|
|
583
574
|
},
|
|
@@ -700,12 +691,10 @@ var APPLICATIONS = {
|
|
|
700
691
|
{
|
|
701
692
|
"name": "topolo-feed-api",
|
|
702
693
|
"kind": "worker",
|
|
703
|
-
"apiUrl":
|
|
704
|
-
"domains": [
|
|
705
|
-
"feed-api.topolo.app"
|
|
706
|
-
],
|
|
694
|
+
"apiUrl": null,
|
|
695
|
+
"domains": [],
|
|
707
696
|
"routes": [],
|
|
708
|
-
"serviceId":
|
|
697
|
+
"serviceId": null
|
|
709
698
|
},
|
|
710
699
|
{
|
|
711
700
|
"name": "topolo-feed-web",
|
|
@@ -715,7 +704,7 @@ var APPLICATIONS = {
|
|
|
715
704
|
"feed.topolo.app"
|
|
716
705
|
],
|
|
717
706
|
"routes": [],
|
|
718
|
-
"serviceId":
|
|
707
|
+
"serviceId": "feed"
|
|
719
708
|
}
|
|
720
709
|
]
|
|
721
710
|
},
|
|
@@ -767,17 +756,15 @@ var APPLICATIONS = {
|
|
|
767
756
|
"forecast.topolo.app"
|
|
768
757
|
],
|
|
769
758
|
"routes": [],
|
|
770
|
-
"serviceId":
|
|
759
|
+
"serviceId": "forecast"
|
|
771
760
|
},
|
|
772
761
|
{
|
|
773
762
|
"name": "topolo-forecast-api",
|
|
774
763
|
"kind": "worker",
|
|
775
|
-
"apiUrl":
|
|
776
|
-
"domains": [
|
|
777
|
-
"forecast-api.topolo.app"
|
|
778
|
-
],
|
|
764
|
+
"apiUrl": null,
|
|
765
|
+
"domains": [],
|
|
779
766
|
"routes": [],
|
|
780
|
-
"serviceId":
|
|
767
|
+
"serviceId": null
|
|
781
768
|
}
|
|
782
769
|
]
|
|
783
770
|
},
|
|
@@ -919,17 +906,15 @@ var APPLICATIONS = {
|
|
|
919
906
|
"learn.topolo.app"
|
|
920
907
|
],
|
|
921
908
|
"routes": [],
|
|
922
|
-
"serviceId":
|
|
909
|
+
"serviceId": "learn"
|
|
923
910
|
},
|
|
924
911
|
{
|
|
925
912
|
"name": "topolo-learn-api",
|
|
926
913
|
"kind": "worker",
|
|
927
|
-
"apiUrl":
|
|
928
|
-
"domains": [
|
|
929
|
-
"learn-api.topolo.app"
|
|
930
|
-
],
|
|
914
|
+
"apiUrl": null,
|
|
915
|
+
"domains": [],
|
|
931
916
|
"routes": [],
|
|
932
|
-
"serviceId":
|
|
917
|
+
"serviceId": null
|
|
933
918
|
}
|
|
934
919
|
]
|
|
935
920
|
},
|
|
@@ -975,17 +960,15 @@ var APPLICATIONS = {
|
|
|
975
960
|
"mail.topolo.app"
|
|
976
961
|
],
|
|
977
962
|
"routes": [],
|
|
978
|
-
"serviceId":
|
|
963
|
+
"serviceId": "mail"
|
|
979
964
|
},
|
|
980
965
|
{
|
|
981
966
|
"name": "topolo-mail-api",
|
|
982
967
|
"kind": "worker",
|
|
983
|
-
"apiUrl":
|
|
984
|
-
"domains": [
|
|
985
|
-
"mail-api.topolo.app"
|
|
986
|
-
],
|
|
968
|
+
"apiUrl": null,
|
|
969
|
+
"domains": [],
|
|
987
970
|
"routes": [],
|
|
988
|
-
"serviceId":
|
|
971
|
+
"serviceId": null
|
|
989
972
|
}
|
|
990
973
|
]
|
|
991
974
|
},
|
|
@@ -1002,12 +985,10 @@ var APPLICATIONS = {
|
|
|
1002
985
|
{
|
|
1003
986
|
"name": "topolo-mdm-api",
|
|
1004
987
|
"kind": "worker",
|
|
1005
|
-
"apiUrl":
|
|
1006
|
-
"domains": [
|
|
1007
|
-
"mdm-api.topolo.app"
|
|
1008
|
-
],
|
|
988
|
+
"apiUrl": null,
|
|
989
|
+
"domains": [],
|
|
1009
990
|
"routes": [],
|
|
1010
|
-
"serviceId":
|
|
991
|
+
"serviceId": null
|
|
1011
992
|
},
|
|
1012
993
|
{
|
|
1013
994
|
"name": "topolo-mdm-console",
|
|
@@ -1017,7 +998,7 @@ var APPLICATIONS = {
|
|
|
1017
998
|
"mdm.topolo.app"
|
|
1018
999
|
],
|
|
1019
1000
|
"routes": [],
|
|
1020
|
-
"serviceId":
|
|
1001
|
+
"serviceId": "mdm"
|
|
1021
1002
|
}
|
|
1022
1003
|
]
|
|
1023
1004
|
},
|
|
@@ -1150,20 +1131,23 @@ var APPLICATIONS = {
|
|
|
1150
1131
|
{
|
|
1151
1132
|
"name": "topolo-one",
|
|
1152
1133
|
"kind": "worker",
|
|
1153
|
-
"apiUrl":
|
|
1154
|
-
"domains": [
|
|
1155
|
-
|
|
1134
|
+
"apiUrl": "https://one.topolo.app",
|
|
1135
|
+
"domains": [
|
|
1136
|
+
"one.topolo.app"
|
|
1137
|
+
],
|
|
1138
|
+
"routes": [
|
|
1139
|
+
"one.topolo.app/*"
|
|
1140
|
+
],
|
|
1156
1141
|
"serviceId": null
|
|
1157
1142
|
},
|
|
1158
1143
|
{
|
|
1159
1144
|
"name": "topolo-one-api",
|
|
1160
1145
|
"kind": "worker",
|
|
1161
|
-
"apiUrl": "https://
|
|
1146
|
+
"apiUrl": "https://www.topolo.app",
|
|
1162
1147
|
"domains": [
|
|
1163
|
-
"
|
|
1148
|
+
"www.topolo.app"
|
|
1164
1149
|
],
|
|
1165
1150
|
"routes": [
|
|
1166
|
-
"one.topolo.app/*",
|
|
1167
1151
|
"www.topolo.app/*"
|
|
1168
1152
|
],
|
|
1169
1153
|
"serviceId": "one"
|
|
@@ -1273,36 +1257,6 @@ var APPLICATIONS = {
|
|
|
1273
1257
|
}
|
|
1274
1258
|
]
|
|
1275
1259
|
},
|
|
1276
|
-
"pulse": {
|
|
1277
|
-
"id": "pulse",
|
|
1278
|
-
"appDir": "TopoloPulse",
|
|
1279
|
-
"name": "topolo-pulse",
|
|
1280
|
-
"packageName": "topolo-pulse",
|
|
1281
|
-
"productionUrl": "https://pulse.topolo.app",
|
|
1282
|
-
"services": [
|
|
1283
|
-
"pulse"
|
|
1284
|
-
],
|
|
1285
|
-
"deployTargets": [
|
|
1286
|
-
{
|
|
1287
|
-
"name": "topolo-pulse",
|
|
1288
|
-
"kind": "worker",
|
|
1289
|
-
"apiUrl": "https://pulse.topolo.app",
|
|
1290
|
-
"domains": [
|
|
1291
|
-
"pulse.topolo.app"
|
|
1292
|
-
],
|
|
1293
|
-
"routes": [],
|
|
1294
|
-
"serviceId": "pulse"
|
|
1295
|
-
},
|
|
1296
|
-
{
|
|
1297
|
-
"name": "topolo-pulse-api",
|
|
1298
|
-
"kind": "worker",
|
|
1299
|
-
"apiUrl": null,
|
|
1300
|
-
"domains": [],
|
|
1301
|
-
"routes": [],
|
|
1302
|
-
"serviceId": null
|
|
1303
|
-
}
|
|
1304
|
-
]
|
|
1305
|
-
},
|
|
1306
1260
|
"quro": {
|
|
1307
1261
|
"id": "quro",
|
|
1308
1262
|
"appDir": "TopoloQuro",
|
|
@@ -1368,17 +1322,15 @@ var APPLICATIONS = {
|
|
|
1368
1322
|
"roadmapper.topolo.app"
|
|
1369
1323
|
],
|
|
1370
1324
|
"routes": [],
|
|
1371
|
-
"serviceId":
|
|
1325
|
+
"serviceId": "roadmapper"
|
|
1372
1326
|
},
|
|
1373
1327
|
{
|
|
1374
1328
|
"name": "topolo-roadmapper-api",
|
|
1375
1329
|
"kind": "worker",
|
|
1376
|
-
"apiUrl":
|
|
1377
|
-
"domains": [
|
|
1378
|
-
"roadmapper-api.topolo.app"
|
|
1379
|
-
],
|
|
1330
|
+
"apiUrl": null,
|
|
1331
|
+
"domains": [],
|
|
1380
1332
|
"routes": [],
|
|
1381
|
-
"serviceId":
|
|
1333
|
+
"serviceId": null
|
|
1382
1334
|
}
|
|
1383
1335
|
]
|
|
1384
1336
|
},
|
|
@@ -1430,17 +1382,15 @@ var APPLICATIONS = {
|
|
|
1430
1382
|
"studio.topolo.app"
|
|
1431
1383
|
],
|
|
1432
1384
|
"routes": [],
|
|
1433
|
-
"serviceId":
|
|
1385
|
+
"serviceId": "social_studio"
|
|
1434
1386
|
},
|
|
1435
1387
|
{
|
|
1436
1388
|
"name": "topolo-social-studio-api",
|
|
1437
1389
|
"kind": "worker",
|
|
1438
|
-
"apiUrl":
|
|
1439
|
-
"domains": [
|
|
1440
|
-
"studio-api.topolo.app"
|
|
1441
|
-
],
|
|
1390
|
+
"apiUrl": null,
|
|
1391
|
+
"domains": [],
|
|
1442
1392
|
"routes": [],
|
|
1443
|
-
"serviceId":
|
|
1393
|
+
"serviceId": null
|
|
1444
1394
|
},
|
|
1445
1395
|
{
|
|
1446
1396
|
"name": "topolo-social-studio-queue",
|
|
@@ -1470,17 +1420,15 @@ var APPLICATIONS = {
|
|
|
1470
1420
|
"socialize.topolo.app"
|
|
1471
1421
|
],
|
|
1472
1422
|
"routes": [],
|
|
1473
|
-
"serviceId":
|
|
1423
|
+
"serviceId": "socialize"
|
|
1474
1424
|
},
|
|
1475
1425
|
{
|
|
1476
1426
|
"name": "topolo-socialize-api",
|
|
1477
1427
|
"kind": "worker",
|
|
1478
|
-
"apiUrl":
|
|
1479
|
-
"domains": [
|
|
1480
|
-
"socialize-api.topolo.app"
|
|
1481
|
-
],
|
|
1428
|
+
"apiUrl": null,
|
|
1429
|
+
"domains": [],
|
|
1482
1430
|
"routes": [],
|
|
1483
|
-
"serviceId":
|
|
1431
|
+
"serviceId": null
|
|
1484
1432
|
},
|
|
1485
1433
|
{
|
|
1486
1434
|
"name": "topolo-socialize-scheduler",
|
|
@@ -1681,12 +1629,10 @@ var APPLICATIONS = {
|
|
|
1681
1629
|
{
|
|
1682
1630
|
"name": "topolo-web-api",
|
|
1683
1631
|
"kind": "worker",
|
|
1684
|
-
"apiUrl":
|
|
1685
|
-
"domains": [
|
|
1686
|
-
"web-api.topolo.app"
|
|
1687
|
-
],
|
|
1632
|
+
"apiUrl": null,
|
|
1633
|
+
"domains": [],
|
|
1688
1634
|
"routes": [],
|
|
1689
|
-
"serviceId":
|
|
1635
|
+
"serviceId": null
|
|
1690
1636
|
},
|
|
1691
1637
|
{
|
|
1692
1638
|
"name": "topolo-web-runtime",
|
|
@@ -1709,14 +1655,14 @@ var APPLICATIONS = {
|
|
|
1709
1655
|
"web.topolo.app"
|
|
1710
1656
|
],
|
|
1711
1657
|
"routes": [],
|
|
1712
|
-
"serviceId":
|
|
1658
|
+
"serviceId": "web"
|
|
1713
1659
|
}
|
|
1714
1660
|
]
|
|
1715
1661
|
}
|
|
1716
1662
|
};
|
|
1717
1663
|
|
|
1718
1664
|
// src/application-requirements.ts
|
|
1719
|
-
var APPLICATION_REQUIREMENTS_VERSION = "2026-
|
|
1665
|
+
var APPLICATION_REQUIREMENTS_VERSION = "2026-06-07.1";
|
|
1720
1666
|
var APPLICATION_REQUIREMENTS = [
|
|
1721
1667
|
{
|
|
1722
1668
|
id: "platform-metadata",
|
|
@@ -1772,16 +1718,20 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1772
1718
|
summary: "Browser applications should feel like one platform and should not create isolated navigation or account surfaces.",
|
|
1773
1719
|
appliesTo: ["browser"],
|
|
1774
1720
|
evidence: [
|
|
1775
|
-
"@topolo/
|
|
1776
|
-
"
|
|
1777
|
-
"Account menu and sign-out behavior use TopoloAppShell or TopoloAccountMenu",
|
|
1721
|
+
"@topolo-io/app-shell is used for the platform shell where the app has authenticated UI",
|
|
1722
|
+
"@topolo-io/app-launcher keeps the shared launcher/app switcher reachable from authenticated app chrome",
|
|
1723
|
+
"Account menu and sign-out behavior use TopoloAppShell or the ui-kit TopoloAccountMenu primitive",
|
|
1724
|
+
"Repeated app body surfaces use shared TopoloAppLayout primitives instead of local stat cards, empty states, or status badges",
|
|
1725
|
+
"Local preview supports deterministic visual QA fixtures for overview, list, detail, settings, and empty/loading states",
|
|
1778
1726
|
"Authenticated app body content stays inside the viewport on mobile and desktop widths"
|
|
1779
1727
|
],
|
|
1780
1728
|
implementation: [
|
|
1781
|
-
"Use TopoloAppShell for authenticated app layouts",
|
|
1782
|
-
"Use TopoloAccountMenu when a partial-shell surface still needs account chrome",
|
|
1729
|
+
"Use @topolo-io/app-shell TopoloAppShell for authenticated app layouts",
|
|
1730
|
+
"Use the @topolo-io/ui-kit TopoloAccountMenu primitive when a partial-shell surface still needs account chrome",
|
|
1783
1731
|
"Pass app-specific account actions as additive menu items instead of forking dropdowns",
|
|
1784
1732
|
"Use shared design tokens and platform UI primitives before creating local equivalents",
|
|
1733
|
+
"Use TopoloAppMetricCard, TopoloAppEmptyState, TopoloAppStatusBadge, TopoloAppGrid, and TopoloAppSection for repeated app body patterns",
|
|
1734
|
+
"Keep visual QA fixtures available through visualQa=1 or __devpreview=1 so screenshot checks do not depend on live API state",
|
|
1785
1735
|
"Keep mobile and desktop shell behavior aligned with the platform UI kit",
|
|
1786
1736
|
"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"
|
|
1787
1737
|
]
|
|
@@ -1860,11 +1810,13 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1860
1810
|
evidence: [
|
|
1861
1811
|
"The app-owned API exposes GET /api/widget",
|
|
1862
1812
|
"The endpoint returns TopoloWidgetApiResponse from @topolo/sdk",
|
|
1813
|
+
"Every returned widget includes snapshot.summary with app-owned operational prose",
|
|
1863
1814
|
"The endpoint derives organization/user context from the app auth boundary"
|
|
1864
1815
|
],
|
|
1865
1816
|
implementation: [
|
|
1866
1817
|
"Import createTopoloWidgetResponse from @topolo/sdk in the app backend",
|
|
1867
1818
|
"Return native app metrics or action widgets instead of generic launch-card fallbacks",
|
|
1819
|
+
"Populate snapshot.summary in the producing app for every widget instead of synthesizing summaries in TopoloOne",
|
|
1868
1820
|
"Add a route-level test that validates the response with validateTopoloWidgetResponse"
|
|
1869
1821
|
]
|
|
1870
1822
|
},
|
|
@@ -2161,6 +2113,8 @@ function firstString(...values) {
|
|
|
2161
2113
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
2162
2114
|
var TOPOLO_ACTION_ID_HEADER = "X-Topolo-Action-Id";
|
|
2163
2115
|
var TOPOLO_ACTION_NAME_HEADER = "X-Topolo-Action-Name";
|
|
2116
|
+
var TOPOLO_RESOURCE_TYPE_HEADER = "X-Topolo-Resource-Type";
|
|
2117
|
+
var TOPOLO_RESOURCE_ID_HEADER = "X-Topolo-Resource-ID";
|
|
2164
2118
|
var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
2165
2119
|
var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
|
|
2166
2120
|
var CATALOG_CACHE_TTL_MS = 60 * 1e3;
|
|
@@ -2239,6 +2193,18 @@ var TopoloClient = class _TopoloClient {
|
|
|
2239
2193
|
if (opts.headers) {
|
|
2240
2194
|
for (const [k, v] of Object.entries(opts.headers)) headers.set(k, v);
|
|
2241
2195
|
}
|
|
2196
|
+
if (opts.resource) {
|
|
2197
|
+
const resourceType = opts.resource.resourceType.trim();
|
|
2198
|
+
const resourceId = opts.resource.resourceId.trim();
|
|
2199
|
+
if (!resourceType || !resourceId) {
|
|
2200
|
+
throw new TopoloSdkError(
|
|
2201
|
+
"invalid_resource_context",
|
|
2202
|
+
"Both resource.resourceType and resource.resourceId are required when resource context is provided."
|
|
2203
|
+
);
|
|
2204
|
+
}
|
|
2205
|
+
headers.set(TOPOLO_RESOURCE_TYPE_HEADER, resourceType);
|
|
2206
|
+
headers.set(TOPOLO_RESOURCE_ID_HEADER, resourceId);
|
|
2207
|
+
}
|
|
2242
2208
|
const controller = new AbortController();
|
|
2243
2209
|
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
2244
2210
|
const signal = opts.signal ? mergeSignals(opts.signal, controller.signal) : controller.signal;
|
|
@@ -2421,6 +2387,11 @@ var TopoloClient = class _TopoloClient {
|
|
|
2421
2387
|
const serviceId = typeof s.service_id === "string" ? s.service_id : typeof s.id === "string" ? s.id : null;
|
|
2422
2388
|
if (!serviceId) continue;
|
|
2423
2389
|
const permissions = Array.isArray(s.granted_permissions) ? s.granted_permissions.filter((permission) => typeof permission === "string" && permission.trim().length > 0) : [];
|
|
2390
|
+
const catalogApiKeyResources = normalizeApiKeyResourceMetadataList(
|
|
2391
|
+
s.api_key_resources ?? s.apiKeyResources
|
|
2392
|
+
);
|
|
2393
|
+
const apiKeyResource = normalizeApiKeyResourceMetadata(s.api_key_resource ?? s.apiKeyResource) ?? catalogApiKeyResources[0] ?? null;
|
|
2394
|
+
const apiKeyResources = catalogApiKeyResources.length > 0 ? catalogApiKeyResources : apiKeyResource ? [apiKeyResource] : [];
|
|
2424
2395
|
entries.push({
|
|
2425
2396
|
serviceId,
|
|
2426
2397
|
slug: typeof s.app_slug === "string" ? s.app_slug : null,
|
|
@@ -2431,7 +2402,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2431
2402
|
status: typeof s.status === "string" ? s.status : null,
|
|
2432
2403
|
surfaceKind: typeof s.surface_kind === "string" ? s.surface_kind : null,
|
|
2433
2404
|
launchable: s.launchable === true,
|
|
2434
|
-
permissions
|
|
2405
|
+
permissions,
|
|
2406
|
+
apiKeyResource,
|
|
2407
|
+
apiKeyResources
|
|
2435
2408
|
});
|
|
2436
2409
|
}
|
|
2437
2410
|
this.serviceCatalogCache = {
|
|
@@ -2517,7 +2490,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2517
2490
|
status: "bundled",
|
|
2518
2491
|
surfaceKind: "application",
|
|
2519
2492
|
launchable: Boolean(app.productionUrl),
|
|
2520
|
-
permissions: []
|
|
2493
|
+
permissions: [],
|
|
2494
|
+
apiKeyResource: null,
|
|
2495
|
+
apiKeyResources: []
|
|
2521
2496
|
}));
|
|
2522
2497
|
}
|
|
2523
2498
|
/**
|
|
@@ -2566,6 +2541,46 @@ function resolveConfiguredServiceId(slug, serviceIds) {
|
|
|
2566
2541
|
}
|
|
2567
2542
|
return null;
|
|
2568
2543
|
}
|
|
2544
|
+
function normalizeApiKeyResourceMetadata(input) {
|
|
2545
|
+
if (!isRecord(input)) return null;
|
|
2546
|
+
const resourceType = readString(input.resourceType ?? input.resource_type);
|
|
2547
|
+
const label = readString(input.label);
|
|
2548
|
+
const emptyLabel = readString(input.emptyLabel ?? input.empty_label);
|
|
2549
|
+
const resourceConcept = readString(input.resourceConcept ?? input.resource_concept);
|
|
2550
|
+
const canonicalResourceType = readString(input.canonicalResourceType ?? input.canonical_resource_type);
|
|
2551
|
+
const defaultEntitlement = readString(input.defaultEntitlement ?? input.default_entitlement);
|
|
2552
|
+
const exceptionPolicy = readString(input.exceptionPolicy ?? input.exception_policy);
|
|
2553
|
+
if (!resourceType || !label || !emptyLabel || resourceConcept !== "workspace" || canonicalResourceType !== "workspace" || defaultEntitlement !== "enterprise" || exceptionPolicy !== "app_or_organization") {
|
|
2554
|
+
return null;
|
|
2555
|
+
}
|
|
2556
|
+
return {
|
|
2557
|
+
resourceType,
|
|
2558
|
+
label,
|
|
2559
|
+
emptyLabel,
|
|
2560
|
+
resourceConcept,
|
|
2561
|
+
canonicalResourceType,
|
|
2562
|
+
defaultEntitlement,
|
|
2563
|
+
exceptionPolicy
|
|
2564
|
+
};
|
|
2565
|
+
}
|
|
2566
|
+
function normalizeApiKeyResourceMetadataList(input) {
|
|
2567
|
+
if (!Array.isArray(input)) return [];
|
|
2568
|
+
const resources = [];
|
|
2569
|
+
const seenTypes = /* @__PURE__ */ new Set();
|
|
2570
|
+
for (const item of input) {
|
|
2571
|
+
const resource = normalizeApiKeyResourceMetadata(item);
|
|
2572
|
+
if (!resource || seenTypes.has(resource.resourceType)) continue;
|
|
2573
|
+
seenTypes.add(resource.resourceType);
|
|
2574
|
+
resources.push(resource);
|
|
2575
|
+
}
|
|
2576
|
+
return resources;
|
|
2577
|
+
}
|
|
2578
|
+
function readString(value) {
|
|
2579
|
+
return typeof value === "string" ? value.trim() : "";
|
|
2580
|
+
}
|
|
2581
|
+
function isRecord(value) {
|
|
2582
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2583
|
+
}
|
|
2569
2584
|
function resolveConfiguredServiceUrl(slug, serviceUrls) {
|
|
2570
2585
|
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
2571
2586
|
const configured = serviceUrls?.[serviceKey];
|
|
@@ -3133,7 +3148,7 @@ function createTopoloWidgetError(error) {
|
|
|
3133
3148
|
}
|
|
3134
3149
|
function validateTopoloWidgetResponse(response) {
|
|
3135
3150
|
const errors = [];
|
|
3136
|
-
if (!
|
|
3151
|
+
if (!isRecord2(response)) {
|
|
3137
3152
|
return { ok: false, errors: ["response must be an object"] };
|
|
3138
3153
|
}
|
|
3139
3154
|
if (typeof response.success !== "boolean") {
|
|
@@ -3152,7 +3167,7 @@ function validateTopoloWidgetResponse(response) {
|
|
|
3152
3167
|
return { ok: errors.length === 0, errors };
|
|
3153
3168
|
}
|
|
3154
3169
|
function validateWidget(widget, path, errors) {
|
|
3155
|
-
if (!
|
|
3170
|
+
if (!isRecord2(widget)) {
|
|
3156
3171
|
errors.push(`${path} must be an object`);
|
|
3157
3172
|
return;
|
|
3158
3173
|
}
|
|
@@ -3179,7 +3194,7 @@ function validateWidget(widget, path, errors) {
|
|
|
3179
3194
|
case "chart":
|
|
3180
3195
|
validateNonEmptyString(widget.chartType, `${path}.chartType`, errors);
|
|
3181
3196
|
validateNonEmptyString(widget.title, `${path}.title`, errors);
|
|
3182
|
-
if (!
|
|
3197
|
+
if (!isRecord2(widget.data)) {
|
|
3183
3198
|
errors.push(`${path}.data must be an object`);
|
|
3184
3199
|
} else {
|
|
3185
3200
|
validateArray(widget.data.labels, `${path}.data.labels`, errors);
|
|
@@ -3192,12 +3207,14 @@ function validateWidget(widget, path, errors) {
|
|
|
3192
3207
|
}
|
|
3193
3208
|
function validateSnapshotMetadata(snapshot, path, errors) {
|
|
3194
3209
|
if (snapshot === void 0) {
|
|
3210
|
+
errors.push(`${path} must be an object`);
|
|
3195
3211
|
return;
|
|
3196
3212
|
}
|
|
3197
|
-
if (!
|
|
3198
|
-
errors.push(`${path} must be an object
|
|
3213
|
+
if (!isRecord2(snapshot)) {
|
|
3214
|
+
errors.push(`${path} must be an object`);
|
|
3199
3215
|
return;
|
|
3200
3216
|
}
|
|
3217
|
+
validateNonEmptyString(snapshot.summary, `${path}.summary`, errors);
|
|
3201
3218
|
if (snapshot.defaultMetricKeys !== void 0 && !Array.isArray(snapshot.defaultMetricKeys)) {
|
|
3202
3219
|
errors.push(`${path}.defaultMetricKeys must be an array when provided`);
|
|
3203
3220
|
}
|
|
@@ -3213,7 +3230,7 @@ function validateSnapshotMetadata(snapshot, path, errors) {
|
|
|
3213
3230
|
}
|
|
3214
3231
|
snapshot.availableMetrics.forEach((metric, index) => {
|
|
3215
3232
|
const metricPath = `${path}.availableMetrics[${index}]`;
|
|
3216
|
-
if (!
|
|
3233
|
+
if (!isRecord2(metric)) {
|
|
3217
3234
|
errors.push(`${metricPath} must be an object`);
|
|
3218
3235
|
return;
|
|
3219
3236
|
}
|
|
@@ -3234,7 +3251,7 @@ function validateArray(value, path, errors) {
|
|
|
3234
3251
|
errors.push(`${path} must be an array`);
|
|
3235
3252
|
}
|
|
3236
3253
|
}
|
|
3237
|
-
function
|
|
3254
|
+
function isRecord2(value) {
|
|
3238
3255
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3239
3256
|
}
|
|
3240
3257
|
function toIsoTimestamp(input) {
|