@topolo/sdk 0.4.7 → 0.4.9
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 +163 -137
- package/dist/index.d.cts +83 -91
- package/dist/index.d.ts +83 -91
- package/dist/index.js +163 -137
- package/package.json +1 -1
- package/src/application-requirements.ts +9 -5
- package/src/applications.generated.ts +50 -102
- package/src/client.test.ts +108 -19
- package/src/client.ts +137 -4
- 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 +18 -7
- package/src/widgets.test.ts +216 -0
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
|
-
nexus: "https://nexus
|
|
143
|
+
nexus: "https://nexus.topolo.app",
|
|
144
144
|
notify: "https://notify.topolo.app",
|
|
145
145
|
observability_watch: "https://observability-watch.topolo.app",
|
|
146
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
|
},
|
|
@@ -705,7 +696,7 @@ var APPLICATIONS = {
|
|
|
705
696
|
"feed-api.topolo.app"
|
|
706
697
|
],
|
|
707
698
|
"routes": [],
|
|
708
|
-
"serviceId":
|
|
699
|
+
"serviceId": null
|
|
709
700
|
},
|
|
710
701
|
{
|
|
711
702
|
"name": "topolo-feed-web",
|
|
@@ -715,7 +706,7 @@ var APPLICATIONS = {
|
|
|
715
706
|
"feed.topolo.app"
|
|
716
707
|
],
|
|
717
708
|
"routes": [],
|
|
718
|
-
"serviceId":
|
|
709
|
+
"serviceId": "feed"
|
|
719
710
|
}
|
|
720
711
|
]
|
|
721
712
|
},
|
|
@@ -767,17 +758,15 @@ var APPLICATIONS = {
|
|
|
767
758
|
"forecast.topolo.app"
|
|
768
759
|
],
|
|
769
760
|
"routes": [],
|
|
770
|
-
"serviceId":
|
|
761
|
+
"serviceId": "forecast"
|
|
771
762
|
},
|
|
772
763
|
{
|
|
773
764
|
"name": "topolo-forecast-api",
|
|
774
765
|
"kind": "worker",
|
|
775
|
-
"apiUrl":
|
|
776
|
-
"domains": [
|
|
777
|
-
"forecast-api.topolo.app"
|
|
778
|
-
],
|
|
766
|
+
"apiUrl": null,
|
|
767
|
+
"domains": [],
|
|
779
768
|
"routes": [],
|
|
780
|
-
"serviceId":
|
|
769
|
+
"serviceId": null
|
|
781
770
|
}
|
|
782
771
|
]
|
|
783
772
|
},
|
|
@@ -919,17 +908,15 @@ var APPLICATIONS = {
|
|
|
919
908
|
"learn.topolo.app"
|
|
920
909
|
],
|
|
921
910
|
"routes": [],
|
|
922
|
-
"serviceId":
|
|
911
|
+
"serviceId": "learn"
|
|
923
912
|
},
|
|
924
913
|
{
|
|
925
914
|
"name": "topolo-learn-api",
|
|
926
915
|
"kind": "worker",
|
|
927
|
-
"apiUrl":
|
|
928
|
-
"domains": [
|
|
929
|
-
"learn-api.topolo.app"
|
|
930
|
-
],
|
|
916
|
+
"apiUrl": null,
|
|
917
|
+
"domains": [],
|
|
931
918
|
"routes": [],
|
|
932
|
-
"serviceId":
|
|
919
|
+
"serviceId": null
|
|
933
920
|
}
|
|
934
921
|
]
|
|
935
922
|
},
|
|
@@ -975,17 +962,15 @@ var APPLICATIONS = {
|
|
|
975
962
|
"mail.topolo.app"
|
|
976
963
|
],
|
|
977
964
|
"routes": [],
|
|
978
|
-
"serviceId":
|
|
965
|
+
"serviceId": "mail"
|
|
979
966
|
},
|
|
980
967
|
{
|
|
981
968
|
"name": "topolo-mail-api",
|
|
982
969
|
"kind": "worker",
|
|
983
|
-
"apiUrl":
|
|
984
|
-
"domains": [
|
|
985
|
-
"mail-api.topolo.app"
|
|
986
|
-
],
|
|
970
|
+
"apiUrl": null,
|
|
971
|
+
"domains": [],
|
|
987
972
|
"routes": [],
|
|
988
|
-
"serviceId":
|
|
973
|
+
"serviceId": null
|
|
989
974
|
}
|
|
990
975
|
]
|
|
991
976
|
},
|
|
@@ -1002,12 +987,10 @@ var APPLICATIONS = {
|
|
|
1002
987
|
{
|
|
1003
988
|
"name": "topolo-mdm-api",
|
|
1004
989
|
"kind": "worker",
|
|
1005
|
-
"apiUrl":
|
|
1006
|
-
"domains": [
|
|
1007
|
-
"mdm-api.topolo.app"
|
|
1008
|
-
],
|
|
990
|
+
"apiUrl": null,
|
|
991
|
+
"domains": [],
|
|
1009
992
|
"routes": [],
|
|
1010
|
-
"serviceId":
|
|
993
|
+
"serviceId": null
|
|
1011
994
|
},
|
|
1012
995
|
{
|
|
1013
996
|
"name": "topolo-mdm-console",
|
|
@@ -1017,7 +1000,7 @@ var APPLICATIONS = {
|
|
|
1017
1000
|
"mdm.topolo.app"
|
|
1018
1001
|
],
|
|
1019
1002
|
"routes": [],
|
|
1020
|
-
"serviceId":
|
|
1003
|
+
"serviceId": "mdm"
|
|
1021
1004
|
}
|
|
1022
1005
|
]
|
|
1023
1006
|
},
|
|
@@ -1082,9 +1065,9 @@ var APPLICATIONS = {
|
|
|
1082
1065
|
{
|
|
1083
1066
|
"name": "topolo-nexus-gateway",
|
|
1084
1067
|
"kind": "worker",
|
|
1085
|
-
"apiUrl": "https://nexus
|
|
1068
|
+
"apiUrl": "https://nexus.topolo.app",
|
|
1086
1069
|
"domains": [
|
|
1087
|
-
"nexus
|
|
1070
|
+
"nexus.topolo.app"
|
|
1088
1071
|
],
|
|
1089
1072
|
"routes": [],
|
|
1090
1073
|
"serviceId": "nexus"
|
|
@@ -1276,36 +1259,6 @@ var APPLICATIONS = {
|
|
|
1276
1259
|
}
|
|
1277
1260
|
]
|
|
1278
1261
|
},
|
|
1279
|
-
"pulse": {
|
|
1280
|
-
"id": "pulse",
|
|
1281
|
-
"appDir": "TopoloPulse",
|
|
1282
|
-
"name": "topolo-pulse",
|
|
1283
|
-
"packageName": "topolo-pulse",
|
|
1284
|
-
"productionUrl": "https://pulse.topolo.app",
|
|
1285
|
-
"services": [
|
|
1286
|
-
"pulse"
|
|
1287
|
-
],
|
|
1288
|
-
"deployTargets": [
|
|
1289
|
-
{
|
|
1290
|
-
"name": "topolo-pulse",
|
|
1291
|
-
"kind": "worker",
|
|
1292
|
-
"apiUrl": "https://pulse.topolo.app",
|
|
1293
|
-
"domains": [
|
|
1294
|
-
"pulse.topolo.app"
|
|
1295
|
-
],
|
|
1296
|
-
"routes": [],
|
|
1297
|
-
"serviceId": "pulse"
|
|
1298
|
-
},
|
|
1299
|
-
{
|
|
1300
|
-
"name": "topolo-pulse-api",
|
|
1301
|
-
"kind": "worker",
|
|
1302
|
-
"apiUrl": null,
|
|
1303
|
-
"domains": [],
|
|
1304
|
-
"routes": [],
|
|
1305
|
-
"serviceId": null
|
|
1306
|
-
}
|
|
1307
|
-
]
|
|
1308
|
-
},
|
|
1309
1262
|
"quro": {
|
|
1310
1263
|
"id": "quro",
|
|
1311
1264
|
"appDir": "TopoloQuro",
|
|
@@ -1371,17 +1324,15 @@ var APPLICATIONS = {
|
|
|
1371
1324
|
"roadmapper.topolo.app"
|
|
1372
1325
|
],
|
|
1373
1326
|
"routes": [],
|
|
1374
|
-
"serviceId":
|
|
1327
|
+
"serviceId": "roadmapper"
|
|
1375
1328
|
},
|
|
1376
1329
|
{
|
|
1377
1330
|
"name": "topolo-roadmapper-api",
|
|
1378
1331
|
"kind": "worker",
|
|
1379
|
-
"apiUrl":
|
|
1380
|
-
"domains": [
|
|
1381
|
-
"roadmapper-api.topolo.app"
|
|
1382
|
-
],
|
|
1332
|
+
"apiUrl": null,
|
|
1333
|
+
"domains": [],
|
|
1383
1334
|
"routes": [],
|
|
1384
|
-
"serviceId":
|
|
1335
|
+
"serviceId": null
|
|
1385
1336
|
}
|
|
1386
1337
|
]
|
|
1387
1338
|
},
|
|
@@ -1433,17 +1384,15 @@ var APPLICATIONS = {
|
|
|
1433
1384
|
"studio.topolo.app"
|
|
1434
1385
|
],
|
|
1435
1386
|
"routes": [],
|
|
1436
|
-
"serviceId":
|
|
1387
|
+
"serviceId": "social_studio"
|
|
1437
1388
|
},
|
|
1438
1389
|
{
|
|
1439
1390
|
"name": "topolo-social-studio-api",
|
|
1440
1391
|
"kind": "worker",
|
|
1441
|
-
"apiUrl":
|
|
1442
|
-
"domains": [
|
|
1443
|
-
"studio-api.topolo.app"
|
|
1444
|
-
],
|
|
1392
|
+
"apiUrl": null,
|
|
1393
|
+
"domains": [],
|
|
1445
1394
|
"routes": [],
|
|
1446
|
-
"serviceId":
|
|
1395
|
+
"serviceId": null
|
|
1447
1396
|
},
|
|
1448
1397
|
{
|
|
1449
1398
|
"name": "topolo-social-studio-queue",
|
|
@@ -1473,7 +1422,7 @@ var APPLICATIONS = {
|
|
|
1473
1422
|
"socialize.topolo.app"
|
|
1474
1423
|
],
|
|
1475
1424
|
"routes": [],
|
|
1476
|
-
"serviceId":
|
|
1425
|
+
"serviceId": "socialize"
|
|
1477
1426
|
},
|
|
1478
1427
|
{
|
|
1479
1428
|
"name": "topolo-socialize-api",
|
|
@@ -1483,7 +1432,7 @@ var APPLICATIONS = {
|
|
|
1483
1432
|
"socialize-api.topolo.app"
|
|
1484
1433
|
],
|
|
1485
1434
|
"routes": [],
|
|
1486
|
-
"serviceId":
|
|
1435
|
+
"serviceId": null
|
|
1487
1436
|
},
|
|
1488
1437
|
{
|
|
1489
1438
|
"name": "topolo-socialize-scheduler",
|
|
@@ -1684,12 +1633,10 @@ var APPLICATIONS = {
|
|
|
1684
1633
|
{
|
|
1685
1634
|
"name": "topolo-web-api",
|
|
1686
1635
|
"kind": "worker",
|
|
1687
|
-
"apiUrl":
|
|
1688
|
-
"domains": [
|
|
1689
|
-
"web-api.topolo.app"
|
|
1690
|
-
],
|
|
1636
|
+
"apiUrl": null,
|
|
1637
|
+
"domains": [],
|
|
1691
1638
|
"routes": [],
|
|
1692
|
-
"serviceId":
|
|
1639
|
+
"serviceId": null
|
|
1693
1640
|
},
|
|
1694
1641
|
{
|
|
1695
1642
|
"name": "topolo-web-runtime",
|
|
@@ -1712,7 +1659,7 @@ var APPLICATIONS = {
|
|
|
1712
1659
|
"web.topolo.app"
|
|
1713
1660
|
],
|
|
1714
1661
|
"routes": [],
|
|
1715
|
-
"serviceId":
|
|
1662
|
+
"serviceId": "web"
|
|
1716
1663
|
}
|
|
1717
1664
|
]
|
|
1718
1665
|
}
|
|
@@ -1775,16 +1722,20 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1775
1722
|
summary: "Browser applications should feel like one platform and should not create isolated navigation or account surfaces.",
|
|
1776
1723
|
appliesTo: ["browser"],
|
|
1777
1724
|
evidence: [
|
|
1778
|
-
"@topolo/
|
|
1779
|
-
"
|
|
1780
|
-
"Account menu and sign-out behavior use TopoloAppShell or TopoloAccountMenu",
|
|
1725
|
+
"@topolo-io/app-shell is used for the platform shell where the app has authenticated UI",
|
|
1726
|
+
"@topolo-io/app-launcher keeps the shared launcher/app switcher reachable from authenticated app chrome",
|
|
1727
|
+
"Account menu and sign-out behavior use TopoloAppShell or the ui-kit TopoloAccountMenu primitive",
|
|
1728
|
+
"Repeated app body surfaces use shared TopoloAppLayout primitives instead of local stat cards, empty states, or status badges",
|
|
1729
|
+
"Local preview supports deterministic visual QA fixtures for overview, list, detail, settings, and empty/loading states",
|
|
1781
1730
|
"Authenticated app body content stays inside the viewport on mobile and desktop widths"
|
|
1782
1731
|
],
|
|
1783
1732
|
implementation: [
|
|
1784
|
-
"Use TopoloAppShell for authenticated app layouts",
|
|
1785
|
-
"Use TopoloAccountMenu when a partial-shell surface still needs account chrome",
|
|
1733
|
+
"Use @topolo-io/app-shell TopoloAppShell for authenticated app layouts",
|
|
1734
|
+
"Use the @topolo-io/ui-kit TopoloAccountMenu primitive when a partial-shell surface still needs account chrome",
|
|
1786
1735
|
"Pass app-specific account actions as additive menu items instead of forking dropdowns",
|
|
1787
1736
|
"Use shared design tokens and platform UI primitives before creating local equivalents",
|
|
1737
|
+
"Use TopoloAppMetricCard, TopoloAppEmptyState, TopoloAppStatusBadge, TopoloAppGrid, and TopoloAppSection for repeated app body patterns",
|
|
1738
|
+
"Keep visual QA fixtures available through visualQa=1 or __devpreview=1 so screenshot checks do not depend on live API state",
|
|
1788
1739
|
"Keep mobile and desktop shell behavior aligned with the platform UI kit",
|
|
1789
1740
|
"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"
|
|
1790
1741
|
]
|
|
@@ -2166,6 +2117,8 @@ function firstString(...values) {
|
|
|
2166
2117
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
2167
2118
|
var TOPOLO_ACTION_ID_HEADER = "X-Topolo-Action-Id";
|
|
2168
2119
|
var TOPOLO_ACTION_NAME_HEADER = "X-Topolo-Action-Name";
|
|
2120
|
+
var TOPOLO_RESOURCE_TYPE_HEADER = "X-Topolo-Resource-Type";
|
|
2121
|
+
var TOPOLO_RESOURCE_ID_HEADER = "X-Topolo-Resource-ID";
|
|
2169
2122
|
var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
2170
2123
|
var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
|
|
2171
2124
|
var CATALOG_CACHE_TTL_MS = 60 * 1e3;
|
|
@@ -2244,6 +2197,18 @@ var TopoloClient = class _TopoloClient {
|
|
|
2244
2197
|
if (opts.headers) {
|
|
2245
2198
|
for (const [k, v] of Object.entries(opts.headers)) headers.set(k, v);
|
|
2246
2199
|
}
|
|
2200
|
+
if (opts.resource) {
|
|
2201
|
+
const resourceType = opts.resource.resourceType.trim();
|
|
2202
|
+
const resourceId = opts.resource.resourceId.trim();
|
|
2203
|
+
if (!resourceType || !resourceId) {
|
|
2204
|
+
throw new TopoloSdkError(
|
|
2205
|
+
"invalid_resource_context",
|
|
2206
|
+
"Both resource.resourceType and resource.resourceId are required when resource context is provided."
|
|
2207
|
+
);
|
|
2208
|
+
}
|
|
2209
|
+
headers.set(TOPOLO_RESOURCE_TYPE_HEADER, resourceType);
|
|
2210
|
+
headers.set(TOPOLO_RESOURCE_ID_HEADER, resourceId);
|
|
2211
|
+
}
|
|
2247
2212
|
const controller = new AbortController();
|
|
2248
2213
|
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
2249
2214
|
const signal = opts.signal ? mergeSignals(opts.signal, controller.signal) : controller.signal;
|
|
@@ -2315,10 +2280,14 @@ var TopoloClient = class _TopoloClient {
|
|
|
2315
2280
|
if (!serviceKey) {
|
|
2316
2281
|
throw new TopoloSdkError("unknown_service", "service is required");
|
|
2317
2282
|
}
|
|
2318
|
-
if (serviceKey === "auth") {
|
|
2283
|
+
if (serviceKey === "auth" || serviceKey === "developers") {
|
|
2319
2284
|
const overrideUrl = resolveConfiguredServiceUrl(serviceKey, this.serviceUrls);
|
|
2320
2285
|
if (overrideUrl) return { serviceKey, baseUrl: overrideUrl };
|
|
2321
|
-
|
|
2286
|
+
if (serviceKey === "developers") {
|
|
2287
|
+
const derived = deriveDevelopersFromAuth(resolveConfiguredServiceUrl("auth", this.serviceUrls));
|
|
2288
|
+
if (derived) return { serviceKey, baseUrl: derived };
|
|
2289
|
+
}
|
|
2290
|
+
return { serviceKey, baseUrl: DEFAULT_SERVICE_URLS[serviceKey] };
|
|
2322
2291
|
}
|
|
2323
2292
|
const live = await this.resolveLiveCallableService(serviceKey);
|
|
2324
2293
|
if (live) {
|
|
@@ -2358,7 +2327,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2358
2327
|
if (!normalized) return null;
|
|
2359
2328
|
const configuredServiceId = resolveConfiguredServiceId(normalized, this.serviceIds);
|
|
2360
2329
|
if (configuredServiceId) return configuredServiceId;
|
|
2361
|
-
const authBase = resolveServiceUrl("
|
|
2330
|
+
const authBase = resolveServiceUrl("developers", this.serviceUrls);
|
|
2362
2331
|
const cacheKey = `${authBase}|${normalized}`;
|
|
2363
2332
|
const now = Date.now();
|
|
2364
2333
|
const cached = _TopoloClient.serviceIdCache.get(cacheKey);
|
|
@@ -2412,7 +2381,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2412
2381
|
if (this.serviceCatalogCache && this.serviceCatalogCache.expiresAt > now) {
|
|
2413
2382
|
return this.serviceCatalogCache.entries;
|
|
2414
2383
|
}
|
|
2415
|
-
const res = await this.request({ service: "
|
|
2384
|
+
const res = await this.request({ service: "developers", method: "GET", path: "/api/services/catalog" });
|
|
2416
2385
|
const raw = res.data?.services ?? res.services;
|
|
2417
2386
|
if (!Array.isArray(raw)) {
|
|
2418
2387
|
throw new TopoloSdkError(
|
|
@@ -2426,6 +2395,11 @@ var TopoloClient = class _TopoloClient {
|
|
|
2426
2395
|
const serviceId = typeof s.service_id === "string" ? s.service_id : typeof s.id === "string" ? s.id : null;
|
|
2427
2396
|
if (!serviceId) continue;
|
|
2428
2397
|
const permissions = Array.isArray(s.granted_permissions) ? s.granted_permissions.filter((permission) => typeof permission === "string" && permission.trim().length > 0) : [];
|
|
2398
|
+
const catalogApiKeyResources = normalizeApiKeyResourceMetadataList(
|
|
2399
|
+
s.api_key_resources ?? s.apiKeyResources
|
|
2400
|
+
);
|
|
2401
|
+
const apiKeyResource = normalizeApiKeyResourceMetadata(s.api_key_resource ?? s.apiKeyResource) ?? catalogApiKeyResources[0] ?? null;
|
|
2402
|
+
const apiKeyResources = catalogApiKeyResources.length > 0 ? catalogApiKeyResources : apiKeyResource ? [apiKeyResource] : [];
|
|
2429
2403
|
entries.push({
|
|
2430
2404
|
serviceId,
|
|
2431
2405
|
slug: typeof s.app_slug === "string" ? s.app_slug : null,
|
|
@@ -2436,7 +2410,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2436
2410
|
status: typeof s.status === "string" ? s.status : null,
|
|
2437
2411
|
surfaceKind: typeof s.surface_kind === "string" ? s.surface_kind : null,
|
|
2438
2412
|
launchable: s.launchable === true,
|
|
2439
|
-
permissions
|
|
2413
|
+
permissions,
|
|
2414
|
+
apiKeyResource,
|
|
2415
|
+
apiKeyResources
|
|
2440
2416
|
});
|
|
2441
2417
|
}
|
|
2442
2418
|
this.serviceCatalogCache = {
|
|
@@ -2522,7 +2498,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2522
2498
|
status: "bundled",
|
|
2523
2499
|
surfaceKind: "application",
|
|
2524
2500
|
launchable: Boolean(app.productionUrl),
|
|
2525
|
-
permissions: []
|
|
2501
|
+
permissions: [],
|
|
2502
|
+
apiKeyResource: null,
|
|
2503
|
+
apiKeyResources: []
|
|
2526
2504
|
}));
|
|
2527
2505
|
}
|
|
2528
2506
|
/**
|
|
@@ -2571,6 +2549,46 @@ function resolveConfiguredServiceId(slug, serviceIds) {
|
|
|
2571
2549
|
}
|
|
2572
2550
|
return null;
|
|
2573
2551
|
}
|
|
2552
|
+
function normalizeApiKeyResourceMetadata(input) {
|
|
2553
|
+
if (!isRecord(input)) return null;
|
|
2554
|
+
const resourceType = readString(input.resourceType ?? input.resource_type);
|
|
2555
|
+
const label = readString(input.label);
|
|
2556
|
+
const emptyLabel = readString(input.emptyLabel ?? input.empty_label);
|
|
2557
|
+
const resourceConcept = readString(input.resourceConcept ?? input.resource_concept);
|
|
2558
|
+
const canonicalResourceType = readString(input.canonicalResourceType ?? input.canonical_resource_type);
|
|
2559
|
+
const defaultEntitlement = readString(input.defaultEntitlement ?? input.default_entitlement);
|
|
2560
|
+
const exceptionPolicy = readString(input.exceptionPolicy ?? input.exception_policy);
|
|
2561
|
+
if (!resourceType || !label || !emptyLabel || resourceConcept !== "workspace" || canonicalResourceType !== "workspace" || defaultEntitlement !== "enterprise" || exceptionPolicy !== "app_or_organization") {
|
|
2562
|
+
return null;
|
|
2563
|
+
}
|
|
2564
|
+
return {
|
|
2565
|
+
resourceType,
|
|
2566
|
+
label,
|
|
2567
|
+
emptyLabel,
|
|
2568
|
+
resourceConcept,
|
|
2569
|
+
canonicalResourceType,
|
|
2570
|
+
defaultEntitlement,
|
|
2571
|
+
exceptionPolicy
|
|
2572
|
+
};
|
|
2573
|
+
}
|
|
2574
|
+
function normalizeApiKeyResourceMetadataList(input) {
|
|
2575
|
+
if (!Array.isArray(input)) return [];
|
|
2576
|
+
const resources = [];
|
|
2577
|
+
const seenTypes = /* @__PURE__ */ new Set();
|
|
2578
|
+
for (const item of input) {
|
|
2579
|
+
const resource = normalizeApiKeyResourceMetadata(item);
|
|
2580
|
+
if (!resource || seenTypes.has(resource.resourceType)) continue;
|
|
2581
|
+
seenTypes.add(resource.resourceType);
|
|
2582
|
+
resources.push(resource);
|
|
2583
|
+
}
|
|
2584
|
+
return resources;
|
|
2585
|
+
}
|
|
2586
|
+
function readString(value) {
|
|
2587
|
+
return typeof value === "string" ? value.trim() : "";
|
|
2588
|
+
}
|
|
2589
|
+
function isRecord(value) {
|
|
2590
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2591
|
+
}
|
|
2574
2592
|
function resolveConfiguredServiceUrl(slug, serviceUrls) {
|
|
2575
2593
|
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
2576
2594
|
const configured = serviceUrls?.[serviceKey];
|
|
@@ -2594,6 +2612,17 @@ function serviceKeyCandidates2(slug) {
|
|
|
2594
2612
|
function normalizeLookupKey(value) {
|
|
2595
2613
|
return String(value || "").trim().toLowerCase().replace(/\s+/g, "-");
|
|
2596
2614
|
}
|
|
2615
|
+
function deriveDevelopersFromAuth(authUrl) {
|
|
2616
|
+
if (!authUrl) return null;
|
|
2617
|
+
try {
|
|
2618
|
+
const url = new URL(authUrl);
|
|
2619
|
+
if (!/^auth\./i.test(url.hostname)) return null;
|
|
2620
|
+
url.hostname = url.hostname.replace(/^auth\./i, "developers.");
|
|
2621
|
+
return url.origin;
|
|
2622
|
+
} catch {
|
|
2623
|
+
return null;
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2597
2626
|
function catalogEntryMatches(entry, needle) {
|
|
2598
2627
|
return catalogEntryLookupKeys(entry).includes(needle);
|
|
2599
2628
|
}
|
|
@@ -2741,7 +2770,6 @@ var CrmModule = class {
|
|
|
2741
2770
|
constructor(client) {
|
|
2742
2771
|
this.client = client;
|
|
2743
2772
|
}
|
|
2744
|
-
client;
|
|
2745
2773
|
async listContacts(options = {}) {
|
|
2746
2774
|
const res = await this.client.request({
|
|
2747
2775
|
service: "crm",
|
|
@@ -2789,7 +2817,6 @@ var IdentityModule = class {
|
|
|
2789
2817
|
constructor(client) {
|
|
2790
2818
|
this.client = client;
|
|
2791
2819
|
}
|
|
2792
|
-
client;
|
|
2793
2820
|
/** Returns the resolved user, organization, and permission set for the
|
|
2794
2821
|
* current credential. Equivalent to `TopoloClient.introspect()` — exposed
|
|
2795
2822
|
* on this module for symmetry with the other domain modules. */
|
|
@@ -2803,7 +2830,6 @@ var P2PModule = class {
|
|
|
2803
2830
|
constructor(client) {
|
|
2804
2831
|
this.client = client;
|
|
2805
2832
|
}
|
|
2806
|
-
client;
|
|
2807
2833
|
// Directory ----------------------------------------------------------------
|
|
2808
2834
|
async listDirectory(options = {}) {
|
|
2809
2835
|
const res = await this.client.request({
|
|
@@ -3138,7 +3164,7 @@ function createTopoloWidgetError(error) {
|
|
|
3138
3164
|
}
|
|
3139
3165
|
function validateTopoloWidgetResponse(response) {
|
|
3140
3166
|
const errors = [];
|
|
3141
|
-
if (!
|
|
3167
|
+
if (!isRecord2(response)) {
|
|
3142
3168
|
return { ok: false, errors: ["response must be an object"] };
|
|
3143
3169
|
}
|
|
3144
3170
|
if (typeof response.success !== "boolean") {
|
|
@@ -3157,7 +3183,7 @@ function validateTopoloWidgetResponse(response) {
|
|
|
3157
3183
|
return { ok: errors.length === 0, errors };
|
|
3158
3184
|
}
|
|
3159
3185
|
function validateWidget(widget, path, errors) {
|
|
3160
|
-
if (!
|
|
3186
|
+
if (!isRecord2(widget)) {
|
|
3161
3187
|
errors.push(`${path} must be an object`);
|
|
3162
3188
|
return;
|
|
3163
3189
|
}
|
|
@@ -3184,7 +3210,7 @@ function validateWidget(widget, path, errors) {
|
|
|
3184
3210
|
case "chart":
|
|
3185
3211
|
validateNonEmptyString(widget.chartType, `${path}.chartType`, errors);
|
|
3186
3212
|
validateNonEmptyString(widget.title, `${path}.title`, errors);
|
|
3187
|
-
if (!
|
|
3213
|
+
if (!isRecord2(widget.data)) {
|
|
3188
3214
|
errors.push(`${path}.data must be an object`);
|
|
3189
3215
|
} else {
|
|
3190
3216
|
validateArray(widget.data.labels, `${path}.data.labels`, errors);
|
|
@@ -3200,7 +3226,7 @@ function validateSnapshotMetadata(snapshot, path, errors) {
|
|
|
3200
3226
|
errors.push(`${path} must be an object`);
|
|
3201
3227
|
return;
|
|
3202
3228
|
}
|
|
3203
|
-
if (!
|
|
3229
|
+
if (!isRecord2(snapshot)) {
|
|
3204
3230
|
errors.push(`${path} must be an object`);
|
|
3205
3231
|
return;
|
|
3206
3232
|
}
|
|
@@ -3220,7 +3246,7 @@ function validateSnapshotMetadata(snapshot, path, errors) {
|
|
|
3220
3246
|
}
|
|
3221
3247
|
snapshot.availableMetrics.forEach((metric, index) => {
|
|
3222
3248
|
const metricPath = `${path}.availableMetrics[${index}]`;
|
|
3223
|
-
if (!
|
|
3249
|
+
if (!isRecord2(metric)) {
|
|
3224
3250
|
errors.push(`${metricPath} must be an object`);
|
|
3225
3251
|
return;
|
|
3226
3252
|
}
|
|
@@ -3241,7 +3267,7 @@ function validateArray(value, path, errors) {
|
|
|
3241
3267
|
errors.push(`${path} must be an array`);
|
|
3242
3268
|
}
|
|
3243
3269
|
}
|
|
3244
|
-
function
|
|
3270
|
+
function isRecord2(value) {
|
|
3245
3271
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3246
3272
|
}
|
|
3247
3273
|
function toIsoTimestamp(input) {
|