@topolo/mcp 0.4.10 → 0.6.0
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 +1 -1
- package/dist/dispatch.js +21 -21
- package/dist/http.d.ts +2 -2
- package/dist/http.js +22 -22
- package/dist/index.js +529 -190
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ var TopoloHttpError = class extends TopoloSdkError {
|
|
|
58
58
|
this.path = path;
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
-
var
|
|
61
|
+
var APP_API_URLS = {
|
|
62
62
|
agent: "https://agent.topolo.app",
|
|
63
63
|
auth: "https://auth.topolo.app",
|
|
64
64
|
backup: "https://backup.topolo.app",
|
|
@@ -124,7 +124,7 @@ var APPLICATIONS = {
|
|
|
124
124
|
"admin.topolo.app"
|
|
125
125
|
],
|
|
126
126
|
"routes": [],
|
|
127
|
-
"
|
|
127
|
+
"appId": null
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"name": "topolo-admin-api",
|
|
@@ -132,7 +132,7 @@ var APPLICATIONS = {
|
|
|
132
132
|
"apiUrl": null,
|
|
133
133
|
"domains": [],
|
|
134
134
|
"routes": [],
|
|
135
|
-
"
|
|
135
|
+
"appId": null
|
|
136
136
|
}
|
|
137
137
|
]
|
|
138
138
|
},
|
|
@@ -154,7 +154,7 @@ var APPLICATIONS = {
|
|
|
154
154
|
"agent.topolo.app"
|
|
155
155
|
],
|
|
156
156
|
"routes": [],
|
|
157
|
-
"
|
|
157
|
+
"appId": "agent"
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
160
|
"name": "topolo-agent-api",
|
|
@@ -162,7 +162,7 @@ var APPLICATIONS = {
|
|
|
162
162
|
"apiUrl": null,
|
|
163
163
|
"domains": [],
|
|
164
164
|
"routes": [],
|
|
165
|
-
"
|
|
165
|
+
"appId": null
|
|
166
166
|
}
|
|
167
167
|
]
|
|
168
168
|
},
|
|
@@ -186,7 +186,7 @@ var APPLICATIONS = {
|
|
|
186
186
|
"routes": [
|
|
187
187
|
"auth.topolo.app"
|
|
188
188
|
],
|
|
189
|
-
"
|
|
189
|
+
"appId": "auth"
|
|
190
190
|
}
|
|
191
191
|
]
|
|
192
192
|
},
|
|
@@ -208,7 +208,7 @@ var APPLICATIONS = {
|
|
|
208
208
|
"backup.topolo.app"
|
|
209
209
|
],
|
|
210
210
|
"routes": [],
|
|
211
|
-
"
|
|
211
|
+
"appId": "backup"
|
|
212
212
|
}
|
|
213
213
|
]
|
|
214
214
|
},
|
|
@@ -230,7 +230,7 @@ var APPLICATIONS = {
|
|
|
230
230
|
"books.topolo.app"
|
|
231
231
|
],
|
|
232
232
|
"routes": [],
|
|
233
|
-
"
|
|
233
|
+
"appId": "books"
|
|
234
234
|
},
|
|
235
235
|
{
|
|
236
236
|
"name": "topolo-books-api",
|
|
@@ -238,7 +238,7 @@ var APPLICATIONS = {
|
|
|
238
238
|
"apiUrl": null,
|
|
239
239
|
"domains": [],
|
|
240
240
|
"routes": [],
|
|
241
|
-
"
|
|
241
|
+
"appId": null
|
|
242
242
|
}
|
|
243
243
|
]
|
|
244
244
|
},
|
|
@@ -260,7 +260,7 @@ var APPLICATIONS = {
|
|
|
260
260
|
"bugfix.topolo.app"
|
|
261
261
|
],
|
|
262
262
|
"routes": [],
|
|
263
|
-
"
|
|
263
|
+
"appId": "bugfix"
|
|
264
264
|
}
|
|
265
265
|
]
|
|
266
266
|
},
|
|
@@ -282,7 +282,7 @@ var APPLICATIONS = {
|
|
|
282
282
|
"bytes.topolo.app"
|
|
283
283
|
],
|
|
284
284
|
"routes": [],
|
|
285
|
-
"
|
|
285
|
+
"appId": "bytes"
|
|
286
286
|
},
|
|
287
287
|
{
|
|
288
288
|
"name": "topolo-bytes-api",
|
|
@@ -290,7 +290,7 @@ var APPLICATIONS = {
|
|
|
290
290
|
"apiUrl": null,
|
|
291
291
|
"domains": [],
|
|
292
292
|
"routes": [],
|
|
293
|
-
"
|
|
293
|
+
"appId": null
|
|
294
294
|
}
|
|
295
295
|
]
|
|
296
296
|
},
|
|
@@ -312,7 +312,7 @@ var APPLICATIONS = {
|
|
|
312
312
|
"calendar.topolo.app"
|
|
313
313
|
],
|
|
314
314
|
"routes": [],
|
|
315
|
-
"
|
|
315
|
+
"appId": "calendar"
|
|
316
316
|
},
|
|
317
317
|
{
|
|
318
318
|
"name": "topolo-calendar-api",
|
|
@@ -320,7 +320,7 @@ var APPLICATIONS = {
|
|
|
320
320
|
"apiUrl": null,
|
|
321
321
|
"domains": [],
|
|
322
322
|
"routes": [],
|
|
323
|
-
"
|
|
323
|
+
"appId": null
|
|
324
324
|
}
|
|
325
325
|
]
|
|
326
326
|
},
|
|
@@ -342,7 +342,7 @@ var APPLICATIONS = {
|
|
|
342
342
|
"capacity.topolo.app"
|
|
343
343
|
],
|
|
344
344
|
"routes": [],
|
|
345
|
-
"
|
|
345
|
+
"appId": "capacity"
|
|
346
346
|
}
|
|
347
347
|
]
|
|
348
348
|
},
|
|
@@ -364,7 +364,7 @@ var APPLICATIONS = {
|
|
|
364
364
|
"chat.topolo.app"
|
|
365
365
|
],
|
|
366
366
|
"routes": [],
|
|
367
|
-
"
|
|
367
|
+
"appId": "chat"
|
|
368
368
|
},
|
|
369
369
|
{
|
|
370
370
|
"name": "topolo-chat-api",
|
|
@@ -372,7 +372,7 @@ var APPLICATIONS = {
|
|
|
372
372
|
"apiUrl": null,
|
|
373
373
|
"domains": [],
|
|
374
374
|
"routes": [],
|
|
375
|
-
"
|
|
375
|
+
"appId": null
|
|
376
376
|
}
|
|
377
377
|
]
|
|
378
378
|
},
|
|
@@ -392,7 +392,7 @@ var APPLICATIONS = {
|
|
|
392
392
|
"apiUrl": null,
|
|
393
393
|
"domains": [],
|
|
394
394
|
"routes": [],
|
|
395
|
-
"
|
|
395
|
+
"appId": null
|
|
396
396
|
},
|
|
397
397
|
{
|
|
398
398
|
"name": "topolo-commerce-guest-web",
|
|
@@ -402,7 +402,7 @@ var APPLICATIONS = {
|
|
|
402
402
|
"guest.topolo.app"
|
|
403
403
|
],
|
|
404
404
|
"routes": [],
|
|
405
|
-
"
|
|
405
|
+
"appId": null
|
|
406
406
|
},
|
|
407
407
|
{
|
|
408
408
|
"name": "topolo-commerce-ops-web",
|
|
@@ -412,7 +412,7 @@ var APPLICATIONS = {
|
|
|
412
412
|
"commerce.topolo.app"
|
|
413
413
|
],
|
|
414
414
|
"routes": [],
|
|
415
|
-
"
|
|
415
|
+
"appId": "commerce"
|
|
416
416
|
},
|
|
417
417
|
{
|
|
418
418
|
"name": "topolo-commerce-station-web",
|
|
@@ -422,7 +422,7 @@ var APPLICATIONS = {
|
|
|
422
422
|
"station-commerce.topolo.app"
|
|
423
423
|
],
|
|
424
424
|
"routes": [],
|
|
425
|
-
"
|
|
425
|
+
"appId": null
|
|
426
426
|
}
|
|
427
427
|
]
|
|
428
428
|
},
|
|
@@ -444,7 +444,7 @@ var APPLICATIONS = {
|
|
|
444
444
|
"compose.topolo.app"
|
|
445
445
|
],
|
|
446
446
|
"routes": [],
|
|
447
|
-
"
|
|
447
|
+
"appId": "compose"
|
|
448
448
|
},
|
|
449
449
|
{
|
|
450
450
|
"name": "topolo-compose-api",
|
|
@@ -452,7 +452,7 @@ var APPLICATIONS = {
|
|
|
452
452
|
"apiUrl": null,
|
|
453
453
|
"domains": [],
|
|
454
454
|
"routes": [],
|
|
455
|
-
"
|
|
455
|
+
"appId": null
|
|
456
456
|
}
|
|
457
457
|
]
|
|
458
458
|
},
|
|
@@ -474,7 +474,7 @@ var APPLICATIONS = {
|
|
|
474
474
|
"consent.topolo.app"
|
|
475
475
|
],
|
|
476
476
|
"routes": [],
|
|
477
|
-
"
|
|
477
|
+
"appId": "consent"
|
|
478
478
|
},
|
|
479
479
|
{
|
|
480
480
|
"name": "topolo-consent-api",
|
|
@@ -482,7 +482,7 @@ var APPLICATIONS = {
|
|
|
482
482
|
"apiUrl": null,
|
|
483
483
|
"domains": [],
|
|
484
484
|
"routes": [],
|
|
485
|
-
"
|
|
485
|
+
"appId": null
|
|
486
486
|
}
|
|
487
487
|
]
|
|
488
488
|
},
|
|
@@ -502,7 +502,7 @@ var APPLICATIONS = {
|
|
|
502
502
|
"apiUrl": null,
|
|
503
503
|
"domains": [],
|
|
504
504
|
"routes": [],
|
|
505
|
-
"
|
|
505
|
+
"appId": null
|
|
506
506
|
},
|
|
507
507
|
{
|
|
508
508
|
"name": "topolo-crm-app",
|
|
@@ -512,7 +512,7 @@ var APPLICATIONS = {
|
|
|
512
512
|
"crm.topolo.app"
|
|
513
513
|
],
|
|
514
514
|
"routes": [],
|
|
515
|
-
"
|
|
515
|
+
"appId": "crm"
|
|
516
516
|
}
|
|
517
517
|
]
|
|
518
518
|
},
|
|
@@ -532,7 +532,7 @@ var APPLICATIONS = {
|
|
|
532
532
|
"apiUrl": null,
|
|
533
533
|
"domains": [],
|
|
534
534
|
"routes": [],
|
|
535
|
-
"
|
|
535
|
+
"appId": null
|
|
536
536
|
},
|
|
537
537
|
{
|
|
538
538
|
"name": "topolo-developers",
|
|
@@ -542,7 +542,7 @@ var APPLICATIONS = {
|
|
|
542
542
|
"developers.topolo.app"
|
|
543
543
|
],
|
|
544
544
|
"routes": [],
|
|
545
|
-
"
|
|
545
|
+
"appId": "developers"
|
|
546
546
|
},
|
|
547
547
|
{
|
|
548
548
|
"name": "topolo-developers-api",
|
|
@@ -550,7 +550,7 @@ var APPLICATIONS = {
|
|
|
550
550
|
"apiUrl": null,
|
|
551
551
|
"domains": [],
|
|
552
552
|
"routes": [],
|
|
553
|
-
"
|
|
553
|
+
"appId": null
|
|
554
554
|
}
|
|
555
555
|
]
|
|
556
556
|
},
|
|
@@ -572,7 +572,7 @@ var APPLICATIONS = {
|
|
|
572
572
|
"director.topolo.app"
|
|
573
573
|
],
|
|
574
574
|
"routes": [],
|
|
575
|
-
"
|
|
575
|
+
"appId": "director"
|
|
576
576
|
},
|
|
577
577
|
{
|
|
578
578
|
"name": "topolo-director-api",
|
|
@@ -580,7 +580,7 @@ var APPLICATIONS = {
|
|
|
580
580
|
"apiUrl": null,
|
|
581
581
|
"domains": [],
|
|
582
582
|
"routes": [],
|
|
583
|
-
"
|
|
583
|
+
"appId": null
|
|
584
584
|
}
|
|
585
585
|
]
|
|
586
586
|
},
|
|
@@ -600,7 +600,7 @@ var APPLICATIONS = {
|
|
|
600
600
|
"docs.topolo.app"
|
|
601
601
|
],
|
|
602
602
|
"routes": [],
|
|
603
|
-
"
|
|
603
|
+
"appId": null
|
|
604
604
|
},
|
|
605
605
|
{
|
|
606
606
|
"name": "topolo-docs-api",
|
|
@@ -608,7 +608,7 @@ var APPLICATIONS = {
|
|
|
608
608
|
"apiUrl": null,
|
|
609
609
|
"domains": [],
|
|
610
610
|
"routes": [],
|
|
611
|
-
"
|
|
611
|
+
"appId": null
|
|
612
612
|
}
|
|
613
613
|
]
|
|
614
614
|
},
|
|
@@ -630,7 +630,7 @@ var APPLICATIONS = {
|
|
|
630
630
|
"feed-analytics-api.topolo.app"
|
|
631
631
|
],
|
|
632
632
|
"routes": [],
|
|
633
|
-
"
|
|
633
|
+
"appId": null
|
|
634
634
|
},
|
|
635
635
|
{
|
|
636
636
|
"name": "topolo-feed-api",
|
|
@@ -640,7 +640,7 @@ var APPLICATIONS = {
|
|
|
640
640
|
"feed-api.topolo.app"
|
|
641
641
|
],
|
|
642
642
|
"routes": [],
|
|
643
|
-
"
|
|
643
|
+
"appId": null
|
|
644
644
|
},
|
|
645
645
|
{
|
|
646
646
|
"name": "topolo-feed-web",
|
|
@@ -650,7 +650,7 @@ var APPLICATIONS = {
|
|
|
650
650
|
"feed.topolo.app"
|
|
651
651
|
],
|
|
652
652
|
"routes": [],
|
|
653
|
-
"
|
|
653
|
+
"appId": "feed"
|
|
654
654
|
}
|
|
655
655
|
]
|
|
656
656
|
},
|
|
@@ -672,7 +672,7 @@ var APPLICATIONS = {
|
|
|
672
672
|
"flow.topolo.app"
|
|
673
673
|
],
|
|
674
674
|
"routes": [],
|
|
675
|
-
"
|
|
675
|
+
"appId": "flow"
|
|
676
676
|
},
|
|
677
677
|
{
|
|
678
678
|
"name": "topolo-flow-api",
|
|
@@ -680,7 +680,7 @@ var APPLICATIONS = {
|
|
|
680
680
|
"apiUrl": null,
|
|
681
681
|
"domains": [],
|
|
682
682
|
"routes": [],
|
|
683
|
-
"
|
|
683
|
+
"appId": null
|
|
684
684
|
}
|
|
685
685
|
]
|
|
686
686
|
},
|
|
@@ -702,7 +702,7 @@ var APPLICATIONS = {
|
|
|
702
702
|
"forecast.topolo.app"
|
|
703
703
|
],
|
|
704
704
|
"routes": [],
|
|
705
|
-
"
|
|
705
|
+
"appId": "forecast"
|
|
706
706
|
},
|
|
707
707
|
{
|
|
708
708
|
"name": "topolo-forecast-api",
|
|
@@ -710,7 +710,7 @@ var APPLICATIONS = {
|
|
|
710
710
|
"apiUrl": null,
|
|
711
711
|
"domains": [],
|
|
712
712
|
"routes": [],
|
|
713
|
-
"
|
|
713
|
+
"appId": null
|
|
714
714
|
}
|
|
715
715
|
]
|
|
716
716
|
},
|
|
@@ -732,7 +732,7 @@ var APPLICATIONS = {
|
|
|
732
732
|
"forms.topolo.app"
|
|
733
733
|
],
|
|
734
734
|
"routes": [],
|
|
735
|
-
"
|
|
735
|
+
"appId": "forms"
|
|
736
736
|
},
|
|
737
737
|
{
|
|
738
738
|
"name": "topolo-forms-api",
|
|
@@ -740,7 +740,7 @@ var APPLICATIONS = {
|
|
|
740
740
|
"apiUrl": null,
|
|
741
741
|
"domains": [],
|
|
742
742
|
"routes": [],
|
|
743
|
-
"
|
|
743
|
+
"appId": null
|
|
744
744
|
}
|
|
745
745
|
]
|
|
746
746
|
},
|
|
@@ -762,7 +762,7 @@ var APPLICATIONS = {
|
|
|
762
762
|
"home.topolo.app"
|
|
763
763
|
],
|
|
764
764
|
"routes": [],
|
|
765
|
-
"
|
|
765
|
+
"appId": "home"
|
|
766
766
|
},
|
|
767
767
|
{
|
|
768
768
|
"name": "topolo-home-api",
|
|
@@ -770,7 +770,7 @@ var APPLICATIONS = {
|
|
|
770
770
|
"apiUrl": null,
|
|
771
771
|
"domains": [],
|
|
772
772
|
"routes": [],
|
|
773
|
-
"
|
|
773
|
+
"appId": null
|
|
774
774
|
}
|
|
775
775
|
]
|
|
776
776
|
},
|
|
@@ -792,7 +792,7 @@ var APPLICATIONS = {
|
|
|
792
792
|
"insights.topolo.app"
|
|
793
793
|
],
|
|
794
794
|
"routes": [],
|
|
795
|
-
"
|
|
795
|
+
"appId": "insights"
|
|
796
796
|
},
|
|
797
797
|
{
|
|
798
798
|
"name": "topolo-insights-api",
|
|
@@ -800,7 +800,7 @@ var APPLICATIONS = {
|
|
|
800
800
|
"apiUrl": null,
|
|
801
801
|
"domains": [],
|
|
802
802
|
"routes": [],
|
|
803
|
-
"
|
|
803
|
+
"appId": null
|
|
804
804
|
}
|
|
805
805
|
]
|
|
806
806
|
},
|
|
@@ -822,7 +822,7 @@ var APPLICATIONS = {
|
|
|
822
822
|
"inventory.topolo.app"
|
|
823
823
|
],
|
|
824
824
|
"routes": [],
|
|
825
|
-
"
|
|
825
|
+
"appId": "inventory"
|
|
826
826
|
},
|
|
827
827
|
{
|
|
828
828
|
"name": "topolo-inventory-api",
|
|
@@ -830,7 +830,7 @@ var APPLICATIONS = {
|
|
|
830
830
|
"apiUrl": null,
|
|
831
831
|
"domains": [],
|
|
832
832
|
"routes": [],
|
|
833
|
-
"
|
|
833
|
+
"appId": null
|
|
834
834
|
}
|
|
835
835
|
]
|
|
836
836
|
},
|
|
@@ -852,7 +852,7 @@ var APPLICATIONS = {
|
|
|
852
852
|
"learn.topolo.app"
|
|
853
853
|
],
|
|
854
854
|
"routes": [],
|
|
855
|
-
"
|
|
855
|
+
"appId": "learn"
|
|
856
856
|
},
|
|
857
857
|
{
|
|
858
858
|
"name": "topolo-learn-api",
|
|
@@ -860,7 +860,7 @@ var APPLICATIONS = {
|
|
|
860
860
|
"apiUrl": null,
|
|
861
861
|
"domains": [],
|
|
862
862
|
"routes": [],
|
|
863
|
-
"
|
|
863
|
+
"appId": null
|
|
864
864
|
}
|
|
865
865
|
]
|
|
866
866
|
},
|
|
@@ -884,7 +884,7 @@ var APPLICATIONS = {
|
|
|
884
884
|
"routes": [
|
|
885
885
|
"localize.topolo.app"
|
|
886
886
|
],
|
|
887
|
-
"
|
|
887
|
+
"appId": "localize"
|
|
888
888
|
}
|
|
889
889
|
]
|
|
890
890
|
},
|
|
@@ -906,7 +906,7 @@ var APPLICATIONS = {
|
|
|
906
906
|
"mail.topolo.app"
|
|
907
907
|
],
|
|
908
908
|
"routes": [],
|
|
909
|
-
"
|
|
909
|
+
"appId": "mail"
|
|
910
910
|
},
|
|
911
911
|
{
|
|
912
912
|
"name": "topolo-mail-api",
|
|
@@ -914,7 +914,7 @@ var APPLICATIONS = {
|
|
|
914
914
|
"apiUrl": null,
|
|
915
915
|
"domains": [],
|
|
916
916
|
"routes": [],
|
|
917
|
-
"
|
|
917
|
+
"appId": null
|
|
918
918
|
}
|
|
919
919
|
]
|
|
920
920
|
},
|
|
@@ -934,7 +934,7 @@ var APPLICATIONS = {
|
|
|
934
934
|
"apiUrl": null,
|
|
935
935
|
"domains": [],
|
|
936
936
|
"routes": [],
|
|
937
|
-
"
|
|
937
|
+
"appId": null
|
|
938
938
|
},
|
|
939
939
|
{
|
|
940
940
|
"name": "topolo-mdm-console",
|
|
@@ -944,7 +944,7 @@ var APPLICATIONS = {
|
|
|
944
944
|
"mdm.topolo.app"
|
|
945
945
|
],
|
|
946
946
|
"routes": [],
|
|
947
|
-
"
|
|
947
|
+
"appId": "mdm"
|
|
948
948
|
}
|
|
949
949
|
]
|
|
950
950
|
},
|
|
@@ -966,7 +966,7 @@ var APPLICATIONS = {
|
|
|
966
966
|
"messages.topolo.app"
|
|
967
967
|
],
|
|
968
968
|
"routes": [],
|
|
969
|
-
"
|
|
969
|
+
"appId": "messages"
|
|
970
970
|
},
|
|
971
971
|
{
|
|
972
972
|
"name": "topolo-messages-api",
|
|
@@ -974,7 +974,7 @@ var APPLICATIONS = {
|
|
|
974
974
|
"apiUrl": null,
|
|
975
975
|
"domains": [],
|
|
976
976
|
"routes": [],
|
|
977
|
-
"
|
|
977
|
+
"appId": null
|
|
978
978
|
},
|
|
979
979
|
{
|
|
980
980
|
"name": "topolo-messages-dispatch",
|
|
@@ -982,7 +982,7 @@ var APPLICATIONS = {
|
|
|
982
982
|
"apiUrl": null,
|
|
983
983
|
"domains": [],
|
|
984
984
|
"routes": [],
|
|
985
|
-
"
|
|
985
|
+
"appId": null
|
|
986
986
|
}
|
|
987
987
|
]
|
|
988
988
|
},
|
|
@@ -1004,7 +1004,7 @@ var APPLICATIONS = {
|
|
|
1004
1004
|
"nexus.topolo.app"
|
|
1005
1005
|
],
|
|
1006
1006
|
"routes": [],
|
|
1007
|
-
"
|
|
1007
|
+
"appId": null
|
|
1008
1008
|
},
|
|
1009
1009
|
{
|
|
1010
1010
|
"name": "topolo-nexus-gateway",
|
|
@@ -1014,7 +1014,7 @@ var APPLICATIONS = {
|
|
|
1014
1014
|
"nexus.topolo.app"
|
|
1015
1015
|
],
|
|
1016
1016
|
"routes": [],
|
|
1017
|
-
"
|
|
1017
|
+
"appId": "nexus"
|
|
1018
1018
|
}
|
|
1019
1019
|
]
|
|
1020
1020
|
},
|
|
@@ -1038,7 +1038,7 @@ var APPLICATIONS = {
|
|
|
1038
1038
|
"routes": [
|
|
1039
1039
|
"notify.topolo.app"
|
|
1040
1040
|
],
|
|
1041
|
-
"
|
|
1041
|
+
"appId": "notify"
|
|
1042
1042
|
}
|
|
1043
1043
|
]
|
|
1044
1044
|
},
|
|
@@ -1060,7 +1060,7 @@ var APPLICATIONS = {
|
|
|
1060
1060
|
"observability-watch.topolo.app"
|
|
1061
1061
|
],
|
|
1062
1062
|
"routes": [],
|
|
1063
|
-
"
|
|
1063
|
+
"appId": "observability_watch"
|
|
1064
1064
|
}
|
|
1065
1065
|
]
|
|
1066
1066
|
},
|
|
@@ -1084,7 +1084,7 @@ var APPLICATIONS = {
|
|
|
1084
1084
|
"routes": [
|
|
1085
1085
|
"one.topolo.app/*"
|
|
1086
1086
|
],
|
|
1087
|
-
"
|
|
1087
|
+
"appId": null
|
|
1088
1088
|
},
|
|
1089
1089
|
{
|
|
1090
1090
|
"name": "topolo-one-api",
|
|
@@ -1096,7 +1096,7 @@ var APPLICATIONS = {
|
|
|
1096
1096
|
"routes": [
|
|
1097
1097
|
"www.topolo.app/*"
|
|
1098
1098
|
],
|
|
1099
|
-
"
|
|
1099
|
+
"appId": "one"
|
|
1100
1100
|
},
|
|
1101
1101
|
{
|
|
1102
1102
|
"name": "topolo-one-website",
|
|
@@ -1109,7 +1109,7 @@ var APPLICATIONS = {
|
|
|
1109
1109
|
"topolo.io",
|
|
1110
1110
|
"www.topolo.io"
|
|
1111
1111
|
],
|
|
1112
|
-
"
|
|
1112
|
+
"appId": null
|
|
1113
1113
|
}
|
|
1114
1114
|
]
|
|
1115
1115
|
},
|
|
@@ -1131,7 +1131,7 @@ var APPLICATIONS = {
|
|
|
1131
1131
|
"p2p.topolo.app"
|
|
1132
1132
|
],
|
|
1133
1133
|
"routes": [],
|
|
1134
|
-
"
|
|
1134
|
+
"appId": "p2p"
|
|
1135
1135
|
},
|
|
1136
1136
|
{
|
|
1137
1137
|
"name": "topolo-p2p-api",
|
|
@@ -1139,7 +1139,7 @@ var APPLICATIONS = {
|
|
|
1139
1139
|
"apiUrl": null,
|
|
1140
1140
|
"domains": [],
|
|
1141
1141
|
"routes": [],
|
|
1142
|
-
"
|
|
1142
|
+
"appId": null
|
|
1143
1143
|
}
|
|
1144
1144
|
]
|
|
1145
1145
|
},
|
|
@@ -1161,7 +1161,7 @@ var APPLICATIONS = {
|
|
|
1161
1161
|
"pay.topolo.app"
|
|
1162
1162
|
],
|
|
1163
1163
|
"routes": [],
|
|
1164
|
-
"
|
|
1164
|
+
"appId": "pay"
|
|
1165
1165
|
},
|
|
1166
1166
|
{
|
|
1167
1167
|
"name": "topolo-pay-api",
|
|
@@ -1169,7 +1169,7 @@ var APPLICATIONS = {
|
|
|
1169
1169
|
"apiUrl": null,
|
|
1170
1170
|
"domains": [],
|
|
1171
1171
|
"routes": [],
|
|
1172
|
-
"
|
|
1172
|
+
"appId": null
|
|
1173
1173
|
}
|
|
1174
1174
|
]
|
|
1175
1175
|
},
|
|
@@ -1191,7 +1191,7 @@ var APPLICATIONS = {
|
|
|
1191
1191
|
"people.topolo.app"
|
|
1192
1192
|
],
|
|
1193
1193
|
"routes": [],
|
|
1194
|
-
"
|
|
1194
|
+
"appId": "people"
|
|
1195
1195
|
},
|
|
1196
1196
|
{
|
|
1197
1197
|
"name": "topolo-people-api",
|
|
@@ -1199,7 +1199,7 @@ var APPLICATIONS = {
|
|
|
1199
1199
|
"apiUrl": null,
|
|
1200
1200
|
"domains": [],
|
|
1201
1201
|
"routes": [],
|
|
1202
|
-
"
|
|
1202
|
+
"appId": null
|
|
1203
1203
|
}
|
|
1204
1204
|
]
|
|
1205
1205
|
},
|
|
@@ -1224,7 +1224,7 @@ var APPLICATIONS = {
|
|
|
1224
1224
|
"routes": [
|
|
1225
1225
|
"api.ol0.me/*"
|
|
1226
1226
|
],
|
|
1227
|
-
"
|
|
1227
|
+
"appId": "quro.api"
|
|
1228
1228
|
},
|
|
1229
1229
|
{
|
|
1230
1230
|
"name": "quro-redirect-system",
|
|
@@ -1236,7 +1236,7 @@ var APPLICATIONS = {
|
|
|
1236
1236
|
"routes": [
|
|
1237
1237
|
"ol0.me/*"
|
|
1238
1238
|
],
|
|
1239
|
-
"
|
|
1239
|
+
"appId": "quro.redirect"
|
|
1240
1240
|
},
|
|
1241
1241
|
{
|
|
1242
1242
|
"name": "quro-ui",
|
|
@@ -1246,7 +1246,7 @@ var APPLICATIONS = {
|
|
|
1246
1246
|
"quro.topolo.app"
|
|
1247
1247
|
],
|
|
1248
1248
|
"routes": [],
|
|
1249
|
-
"
|
|
1249
|
+
"appId": null
|
|
1250
1250
|
}
|
|
1251
1251
|
]
|
|
1252
1252
|
},
|
|
@@ -1268,7 +1268,7 @@ var APPLICATIONS = {
|
|
|
1268
1268
|
"roadmapper.topolo.app"
|
|
1269
1269
|
],
|
|
1270
1270
|
"routes": [],
|
|
1271
|
-
"
|
|
1271
|
+
"appId": "roadmapper"
|
|
1272
1272
|
},
|
|
1273
1273
|
{
|
|
1274
1274
|
"name": "topolo-roadmapper-api",
|
|
@@ -1276,7 +1276,7 @@ var APPLICATIONS = {
|
|
|
1276
1276
|
"apiUrl": null,
|
|
1277
1277
|
"domains": [],
|
|
1278
1278
|
"routes": [],
|
|
1279
|
-
"
|
|
1279
|
+
"appId": null
|
|
1280
1280
|
}
|
|
1281
1281
|
]
|
|
1282
1282
|
},
|
|
@@ -1298,7 +1298,7 @@ var APPLICATIONS = {
|
|
|
1298
1298
|
"sign.topolo.app"
|
|
1299
1299
|
],
|
|
1300
1300
|
"routes": [],
|
|
1301
|
-
"
|
|
1301
|
+
"appId": "sign"
|
|
1302
1302
|
},
|
|
1303
1303
|
{
|
|
1304
1304
|
"name": "topolo-sign-api",
|
|
@@ -1306,7 +1306,7 @@ var APPLICATIONS = {
|
|
|
1306
1306
|
"apiUrl": null,
|
|
1307
1307
|
"domains": [],
|
|
1308
1308
|
"routes": [],
|
|
1309
|
-
"
|
|
1309
|
+
"appId": null
|
|
1310
1310
|
}
|
|
1311
1311
|
]
|
|
1312
1312
|
},
|
|
@@ -1328,7 +1328,7 @@ var APPLICATIONS = {
|
|
|
1328
1328
|
"studio.topolo.app"
|
|
1329
1329
|
],
|
|
1330
1330
|
"routes": [],
|
|
1331
|
-
"
|
|
1331
|
+
"appId": "social_studio"
|
|
1332
1332
|
},
|
|
1333
1333
|
{
|
|
1334
1334
|
"name": "topolo-social-studio-api",
|
|
@@ -1336,7 +1336,7 @@ var APPLICATIONS = {
|
|
|
1336
1336
|
"apiUrl": null,
|
|
1337
1337
|
"domains": [],
|
|
1338
1338
|
"routes": [],
|
|
1339
|
-
"
|
|
1339
|
+
"appId": null
|
|
1340
1340
|
},
|
|
1341
1341
|
{
|
|
1342
1342
|
"name": "topolo-social-studio-queue",
|
|
@@ -1344,7 +1344,7 @@ var APPLICATIONS = {
|
|
|
1344
1344
|
"apiUrl": null,
|
|
1345
1345
|
"domains": [],
|
|
1346
1346
|
"routes": [],
|
|
1347
|
-
"
|
|
1347
|
+
"appId": null
|
|
1348
1348
|
}
|
|
1349
1349
|
]
|
|
1350
1350
|
},
|
|
@@ -1366,7 +1366,7 @@ var APPLICATIONS = {
|
|
|
1366
1366
|
"socialize.topolo.app"
|
|
1367
1367
|
],
|
|
1368
1368
|
"routes": [],
|
|
1369
|
-
"
|
|
1369
|
+
"appId": "socialize"
|
|
1370
1370
|
},
|
|
1371
1371
|
{
|
|
1372
1372
|
"name": "topolo-socialize-api",
|
|
@@ -1376,7 +1376,7 @@ var APPLICATIONS = {
|
|
|
1376
1376
|
"socialize-api.topolo.app"
|
|
1377
1377
|
],
|
|
1378
1378
|
"routes": [],
|
|
1379
|
-
"
|
|
1379
|
+
"appId": null
|
|
1380
1380
|
},
|
|
1381
1381
|
{
|
|
1382
1382
|
"name": "topolo-socialize-scheduler",
|
|
@@ -1384,7 +1384,7 @@ var APPLICATIONS = {
|
|
|
1384
1384
|
"apiUrl": null,
|
|
1385
1385
|
"domains": [],
|
|
1386
1386
|
"routes": [],
|
|
1387
|
-
"
|
|
1387
|
+
"appId": null
|
|
1388
1388
|
}
|
|
1389
1389
|
]
|
|
1390
1390
|
},
|
|
@@ -1406,7 +1406,7 @@ var APPLICATIONS = {
|
|
|
1406
1406
|
"spaces.topolo.app"
|
|
1407
1407
|
],
|
|
1408
1408
|
"routes": [],
|
|
1409
|
-
"
|
|
1409
|
+
"appId": "spaces"
|
|
1410
1410
|
},
|
|
1411
1411
|
{
|
|
1412
1412
|
"name": "topolo-spaces-api",
|
|
@@ -1414,7 +1414,7 @@ var APPLICATIONS = {
|
|
|
1414
1414
|
"apiUrl": null,
|
|
1415
1415
|
"domains": [],
|
|
1416
1416
|
"routes": [],
|
|
1417
|
-
"
|
|
1417
|
+
"appId": null
|
|
1418
1418
|
}
|
|
1419
1419
|
]
|
|
1420
1420
|
},
|
|
@@ -1436,7 +1436,7 @@ var APPLICATIONS = {
|
|
|
1436
1436
|
"status.topolo.app"
|
|
1437
1437
|
],
|
|
1438
1438
|
"routes": [],
|
|
1439
|
-
"
|
|
1439
|
+
"appId": "status"
|
|
1440
1440
|
}
|
|
1441
1441
|
]
|
|
1442
1442
|
},
|
|
@@ -1460,7 +1460,7 @@ var APPLICATIONS = {
|
|
|
1460
1460
|
"routes": [
|
|
1461
1461
|
"success.topolo.app"
|
|
1462
1462
|
],
|
|
1463
|
-
"
|
|
1463
|
+
"appId": "success"
|
|
1464
1464
|
},
|
|
1465
1465
|
{
|
|
1466
1466
|
"name": "topolo-success-api",
|
|
@@ -1468,7 +1468,7 @@ var APPLICATIONS = {
|
|
|
1468
1468
|
"apiUrl": null,
|
|
1469
1469
|
"domains": [],
|
|
1470
1470
|
"routes": [],
|
|
1471
|
-
"
|
|
1471
|
+
"appId": null
|
|
1472
1472
|
}
|
|
1473
1473
|
]
|
|
1474
1474
|
},
|
|
@@ -1492,7 +1492,7 @@ var APPLICATIONS = {
|
|
|
1492
1492
|
"routes": [
|
|
1493
1493
|
"support.topolo.app/*"
|
|
1494
1494
|
],
|
|
1495
|
-
"
|
|
1495
|
+
"appId": "support"
|
|
1496
1496
|
},
|
|
1497
1497
|
{
|
|
1498
1498
|
"name": "topolo-support-api",
|
|
@@ -1500,7 +1500,7 @@ var APPLICATIONS = {
|
|
|
1500
1500
|
"apiUrl": null,
|
|
1501
1501
|
"domains": [],
|
|
1502
1502
|
"routes": [],
|
|
1503
|
-
"
|
|
1503
|
+
"appId": null
|
|
1504
1504
|
}
|
|
1505
1505
|
]
|
|
1506
1506
|
},
|
|
@@ -1522,7 +1522,7 @@ var APPLICATIONS = {
|
|
|
1522
1522
|
"survey.topolo.app"
|
|
1523
1523
|
],
|
|
1524
1524
|
"routes": [],
|
|
1525
|
-
"
|
|
1525
|
+
"appId": "survey"
|
|
1526
1526
|
},
|
|
1527
1527
|
{
|
|
1528
1528
|
"name": "topolo-survey-api",
|
|
@@ -1530,7 +1530,7 @@ var APPLICATIONS = {
|
|
|
1530
1530
|
"apiUrl": null,
|
|
1531
1531
|
"domains": [],
|
|
1532
1532
|
"routes": [],
|
|
1533
|
-
"
|
|
1533
|
+
"appId": null
|
|
1534
1534
|
}
|
|
1535
1535
|
]
|
|
1536
1536
|
},
|
|
@@ -1552,7 +1552,7 @@ var APPLICATIONS = {
|
|
|
1552
1552
|
"voice.topolo.app"
|
|
1553
1553
|
],
|
|
1554
1554
|
"routes": [],
|
|
1555
|
-
"
|
|
1555
|
+
"appId": "voice"
|
|
1556
1556
|
},
|
|
1557
1557
|
{
|
|
1558
1558
|
"name": "topolo-voice-api",
|
|
@@ -1560,7 +1560,7 @@ var APPLICATIONS = {
|
|
|
1560
1560
|
"apiUrl": null,
|
|
1561
1561
|
"domains": [],
|
|
1562
1562
|
"routes": [],
|
|
1563
|
-
"
|
|
1563
|
+
"appId": null
|
|
1564
1564
|
}
|
|
1565
1565
|
]
|
|
1566
1566
|
},
|
|
@@ -1580,7 +1580,7 @@ var APPLICATIONS = {
|
|
|
1580
1580
|
"apiUrl": null,
|
|
1581
1581
|
"domains": [],
|
|
1582
1582
|
"routes": [],
|
|
1583
|
-
"
|
|
1583
|
+
"appId": null
|
|
1584
1584
|
},
|
|
1585
1585
|
{
|
|
1586
1586
|
"name": "topolo-web-runtime",
|
|
@@ -1593,7 +1593,7 @@ var APPLICATIONS = {
|
|
|
1593
1593
|
"*.sites.topolo.app/*",
|
|
1594
1594
|
"sites.topolo.app"
|
|
1595
1595
|
],
|
|
1596
|
-
"
|
|
1596
|
+
"appId": null
|
|
1597
1597
|
},
|
|
1598
1598
|
{
|
|
1599
1599
|
"name": "topolo-web-studio",
|
|
@@ -1603,7 +1603,7 @@ var APPLICATIONS = {
|
|
|
1603
1603
|
"web.topolo.app"
|
|
1604
1604
|
],
|
|
1605
1605
|
"routes": [],
|
|
1606
|
-
"
|
|
1606
|
+
"appId": "web"
|
|
1607
1607
|
}
|
|
1608
1608
|
]
|
|
1609
1609
|
}
|
|
@@ -1645,12 +1645,12 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1645
1645
|
{
|
|
1646
1646
|
id: "shared-auth-boundary",
|
|
1647
1647
|
title: "Use the shared Topolo auth boundary",
|
|
1648
|
-
summary: "Applications must derive identity, organization, scopes, and
|
|
1648
|
+
summary: "Applications must derive identity, organization, scopes, and app entitlement from TopoloAuth rather than inventing parallel auth state.",
|
|
1649
1649
|
appliesTo: ["browser", "api", "tooling", "agent_surface"],
|
|
1650
1650
|
evidence: [
|
|
1651
1651
|
"@topolo/auth-client or @topolo-io/worker-runtime is used where applicable",
|
|
1652
1652
|
"No public command, tool, or SDK method accepts orgId",
|
|
1653
|
-
"
|
|
1653
|
+
"App slug and Auth app registration are documented for protected APIs"
|
|
1654
1654
|
],
|
|
1655
1655
|
implementation: [
|
|
1656
1656
|
"Use shared auth/runtime packages instead of copying token parsing, gateway, or browser storage flows",
|
|
@@ -1683,20 +1683,20 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1683
1683
|
]
|
|
1684
1684
|
},
|
|
1685
1685
|
{
|
|
1686
|
-
id: "
|
|
1687
|
-
title: "Register protected APIs as platform
|
|
1688
|
-
summary: "Callable app APIs need a stable
|
|
1686
|
+
id: "app-registration-and-scopes",
|
|
1687
|
+
title: "Register protected APIs as platform apps",
|
|
1688
|
+
summary: "Callable app APIs need a stable app ID, app slug, permissions, role bundles, and API-key scopes before agents or users rely on them.",
|
|
1689
1689
|
appliesTo: ["api"],
|
|
1690
1690
|
evidence: [
|
|
1691
|
-
"Auth
|
|
1692
|
-
"Permissions, role bundles, and API-key scopes exist for the
|
|
1693
|
-
"SDK, CLI, and MCP
|
|
1694
|
-
"CloudControl production HTTP targets classify agent reachability with
|
|
1691
|
+
"Auth app catalog contains the app ID and slug",
|
|
1692
|
+
"Permissions, role bundles, and API-key scopes exist for the app",
|
|
1693
|
+
"SDK, CLI, and MCP app discovery include the callable production API",
|
|
1694
|
+
"CloudControl production HTTP targets classify agent reachability with sdk_app_id or agent_callable:false"
|
|
1695
1695
|
],
|
|
1696
1696
|
implementation: [
|
|
1697
|
-
"Add production Worker api_url metadata and
|
|
1697
|
+
"Add production Worker api_url metadata and sdk_app_id for every agent-callable API target",
|
|
1698
1698
|
"Mark browser, documentation, and runtime-only Worker targets with agent_callable:false",
|
|
1699
|
-
"Expose stable
|
|
1699
|
+
"Expose stable app IDs through generated DEFAULT_APP_URLS and live catalog discovery",
|
|
1700
1700
|
"Keep typed SDK/CLI/MCP surfaces in sync when an API contract stabilizes"
|
|
1701
1701
|
]
|
|
1702
1702
|
},
|
|
@@ -1805,7 +1805,7 @@ function applicationRequirementScopes(application) {
|
|
|
1805
1805
|
const hasBrowserSurface = Boolean(application.productionUrl) || // String() keeps this guard valid after the Pages->Worker migration narrowed
|
|
1806
1806
|
// the generated kind union to "worker" (no "pages" literal remains).
|
|
1807
1807
|
application.deployTargets.some((target) => String(target.kind) === "pages");
|
|
1808
|
-
const hasApiSurface = application.services.length > 0 || application.deployTargets.some((target) => Boolean(target.
|
|
1808
|
+
const hasApiSurface = application.services.length > 0 || application.deployTargets.some((target) => Boolean(target.appId));
|
|
1809
1809
|
if (hasBrowserSurface) scopes.add("browser");
|
|
1810
1810
|
if (hasApiSurface) scopes.add("api");
|
|
1811
1811
|
if (appId === "cli" || appId === "mcp" || appId === "cloudcontrol") {
|
|
@@ -1902,7 +1902,7 @@ function evaluateRequirement(application, requirement) {
|
|
|
1902
1902
|
"Catalog metadata cannot verify shared shell, launcher, and account menu adoption.",
|
|
1903
1903
|
evidence
|
|
1904
1904
|
);
|
|
1905
|
-
case "
|
|
1905
|
+
case "app-registration-and-scopes": {
|
|
1906
1906
|
if (application.services.length > 0) {
|
|
1907
1907
|
evidence.push(`services=${application.services.join(",")}`);
|
|
1908
1908
|
return finding(
|
|
@@ -1912,7 +1912,7 @@ function evaluateRequirement(application, requirement) {
|
|
|
1912
1912
|
evidence
|
|
1913
1913
|
);
|
|
1914
1914
|
}
|
|
1915
|
-
return finding(requirement, "missing", "No SDK
|
|
1915
|
+
return finding(requirement, "missing", "No SDK app API id is registered for this callable API surface.", evidence);
|
|
1916
1916
|
}
|
|
1917
1917
|
case "organization-scoped-data":
|
|
1918
1918
|
return finding(
|
|
@@ -1997,7 +1997,7 @@ function statusRank(status) {
|
|
|
1997
1997
|
if (status === "partial") return 1;
|
|
1998
1998
|
return 2;
|
|
1999
1999
|
}
|
|
2000
|
-
var
|
|
2000
|
+
var DEFAULT_APP_URLS = APP_API_URLS;
|
|
2001
2001
|
function resolveCatalogServiceUrl(entry, options = {}) {
|
|
2002
2002
|
const keys = catalogServiceKeyCandidates(entry, options.serviceKey);
|
|
2003
2003
|
const override = resolveServiceUrlOverride(keys, options.overrides);
|
|
@@ -2009,10 +2009,10 @@ function resolveCatalogServiceUrl(entry, options = {}) {
|
|
|
2009
2009
|
function resolveServiceUrl(service, overrides) {
|
|
2010
2010
|
const override = resolveServiceUrlOverride([service], overrides);
|
|
2011
2011
|
if (override) return override;
|
|
2012
|
-
return
|
|
2012
|
+
return DEFAULT_APP_URLS[service];
|
|
2013
2013
|
}
|
|
2014
2014
|
function catalogServiceKeyCandidates(entry, preferred) {
|
|
2015
|
-
const values = [preferred, entry.slug, entry.name, entry.
|
|
2015
|
+
const values = [preferred, entry.slug, entry.name, entry.appId].filter(
|
|
2016
2016
|
(value) => typeof value === "string" && value.trim().length > 0
|
|
2017
2017
|
);
|
|
2018
2018
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -2040,7 +2040,7 @@ function resolveServiceUrlOverride(keys, overrides) {
|
|
|
2040
2040
|
if (envStyle) return envStyle;
|
|
2041
2041
|
}
|
|
2042
2042
|
for (const key of keys) {
|
|
2043
|
-
const envKey = `
|
|
2043
|
+
const envKey = `TOPOLO_APP_URL_${key.replace(/\./g, "_").toUpperCase()}`;
|
|
2044
2044
|
const envValue = typeof process !== "undefined" ? process.env?.[envKey] : void 0;
|
|
2045
2045
|
if (envValue) return envValue;
|
|
2046
2046
|
}
|
|
@@ -2064,7 +2064,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2064
2064
|
credential;
|
|
2065
2065
|
agent;
|
|
2066
2066
|
serviceUrls;
|
|
2067
|
-
|
|
2067
|
+
appIds;
|
|
2068
2068
|
requireConfirmForWrites;
|
|
2069
2069
|
timeoutMs;
|
|
2070
2070
|
fetchImpl;
|
|
@@ -2072,18 +2072,18 @@ var TopoloClient = class _TopoloClient {
|
|
|
2072
2072
|
serviceCatalogCache = null;
|
|
2073
2073
|
actionCatalogCache = null;
|
|
2074
2074
|
/**
|
|
2075
|
-
* Process-wide cache for slug →
|
|
2075
|
+
* Process-wide cache for slug → app-id lookups. Keyed by
|
|
2076
2076
|
* `${authBaseUrl}|${slug}` so multiple `TopoloClient` instances pointing at
|
|
2077
2077
|
* the same Auth share, but staging vs prod don't poison each other.
|
|
2078
|
-
* Cleared via `TopoloClient.
|
|
2078
|
+
* Cleared via `TopoloClient.clearAppIdCache()` if a test needs it.
|
|
2079
2079
|
*/
|
|
2080
|
-
static
|
|
2080
|
+
static appIdCache = /* @__PURE__ */ new Map();
|
|
2081
2081
|
/**
|
|
2082
|
-
* Drop the slug→
|
|
2082
|
+
* Drop the slug→app-id cache. Test-only — production callers should
|
|
2083
2083
|
* let the 5-minute TTL expire naturally.
|
|
2084
2084
|
*/
|
|
2085
|
-
static
|
|
2086
|
-
_TopoloClient.
|
|
2085
|
+
static clearAppIdCache() {
|
|
2086
|
+
_TopoloClient.appIdCache.clear();
|
|
2087
2087
|
}
|
|
2088
2088
|
constructor(options) {
|
|
2089
2089
|
if (!options.credential) throw new TopoloAuthError("credential is required");
|
|
@@ -2091,7 +2091,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2091
2091
|
this.credential = options.credential;
|
|
2092
2092
|
this.agent = options.agent;
|
|
2093
2093
|
this.serviceUrls = options.serviceUrls;
|
|
2094
|
-
this.
|
|
2094
|
+
this.appIds = options.appIds;
|
|
2095
2095
|
this.requireConfirmForWrites = options.requireConfirmForWrites !== false;
|
|
2096
2096
|
this.timeoutMs = options.timeoutMs ?? 3e4;
|
|
2097
2097
|
this.fetchImpl = options.fetch ?? fetch;
|
|
@@ -2127,8 +2127,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2127
2127
|
const headers = new Headers();
|
|
2128
2128
|
headers.set("Accept", "application/json");
|
|
2129
2129
|
if (opts.body !== void 0) headers.set("Content-Type", "application/json");
|
|
2130
|
-
const
|
|
2131
|
-
if (
|
|
2130
|
+
const platformAppId = resolveConfiguredAppId(resolvedService.serviceKey, this.appIds);
|
|
2131
|
+
if (platformAppId) headers.set("X-App-ID", platformAppId);
|
|
2132
2132
|
applyAuthHeaders(headers, this.credential);
|
|
2133
2133
|
const requestId = generateRequestId();
|
|
2134
2134
|
applyAuditHeaders(headers, this.agent, requestId);
|
|
@@ -2225,7 +2225,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2225
2225
|
const derived = deriveDevelopersFromAuth(resolveConfiguredServiceUrl("auth", this.serviceUrls));
|
|
2226
2226
|
if (derived) return { serviceKey, baseUrl: derived };
|
|
2227
2227
|
}
|
|
2228
|
-
return { serviceKey, baseUrl:
|
|
2228
|
+
return { serviceKey, baseUrl: DEFAULT_APP_URLS[serviceKey] };
|
|
2229
2229
|
}
|
|
2230
2230
|
const live = await this.resolveLiveCallableService(serviceKey);
|
|
2231
2231
|
if (live) {
|
|
@@ -2234,7 +2234,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2234
2234
|
}
|
|
2235
2235
|
throw new TopoloSdkError(
|
|
2236
2236
|
"unknown_service",
|
|
2237
|
-
`Unknown Topolo
|
|
2237
|
+
`Unknown Topolo app API "${service}". Run app discovery first and pass a callable app id or slug.`
|
|
2238
2238
|
);
|
|
2239
2239
|
}
|
|
2240
2240
|
async resolveLiveCallableService(serviceKey) {
|
|
@@ -2248,7 +2248,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2248
2248
|
return baseUrl ? { serviceKey, baseUrl } : null;
|
|
2249
2249
|
}
|
|
2250
2250
|
/**
|
|
2251
|
-
* Resolve a service-slug → opaque
|
|
2251
|
+
* Resolve a service-slug → opaque app-id via caller config or TopoloAuth.
|
|
2252
2252
|
*
|
|
2253
2253
|
* Cache: 5 minutes per process per `(slug, auth_base_url)`. Negative
|
|
2254
2254
|
* results (404) are cached for 60s so a typo doesn't hot-loop the
|
|
@@ -2259,16 +2259,16 @@ var TopoloClient = class _TopoloClient {
|
|
|
2259
2259
|
* This keeps the resolver usable during early bootstrap before a caller
|
|
2260
2260
|
* has acquired an access token.
|
|
2261
2261
|
*/
|
|
2262
|
-
async
|
|
2262
|
+
async getAppIdBySlug(slug) {
|
|
2263
2263
|
if (typeof slug !== "string") return null;
|
|
2264
2264
|
const normalized = slug.trim().toLowerCase();
|
|
2265
2265
|
if (!normalized) return null;
|
|
2266
|
-
const
|
|
2267
|
-
if (
|
|
2266
|
+
const configuredAppId = resolveConfiguredAppId(normalized, this.appIds);
|
|
2267
|
+
if (configuredAppId) return configuredAppId;
|
|
2268
2268
|
const authBase = resolveServiceUrl("developers", this.serviceUrls);
|
|
2269
2269
|
const cacheKey = `${authBase}|${normalized}`;
|
|
2270
2270
|
const now = Date.now();
|
|
2271
|
-
const cached = _TopoloClient.
|
|
2271
|
+
const cached = _TopoloClient.appIdCache.get(cacheKey);
|
|
2272
2272
|
if (cached && cached.expiresAt > now) {
|
|
2273
2273
|
return cached.value;
|
|
2274
2274
|
}
|
|
@@ -2286,7 +2286,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2286
2286
|
return null;
|
|
2287
2287
|
}
|
|
2288
2288
|
if (res.status === 404) {
|
|
2289
|
-
_TopoloClient.
|
|
2289
|
+
_TopoloClient.appIdCache.set(cacheKey, {
|
|
2290
2290
|
value: null,
|
|
2291
2291
|
expiresAt: now + NEGATIVE_CACHE_TTL_MS
|
|
2292
2292
|
});
|
|
@@ -2296,9 +2296,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2296
2296
|
return null;
|
|
2297
2297
|
}
|
|
2298
2298
|
const body = await res.json().catch(() => null);
|
|
2299
|
-
const
|
|
2300
|
-
const value = typeof
|
|
2301
|
-
_TopoloClient.
|
|
2299
|
+
const appId = body?.data?.app_id;
|
|
2300
|
+
const value = typeof appId === "string" && appId ? appId : null;
|
|
2301
|
+
_TopoloClient.appIdCache.set(cacheKey, {
|
|
2302
2302
|
value,
|
|
2303
2303
|
expiresAt: now + POSITIVE_CACHE_TTL_MS
|
|
2304
2304
|
});
|
|
@@ -2330,8 +2330,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2330
2330
|
const entries = [];
|
|
2331
2331
|
for (const item of raw) {
|
|
2332
2332
|
const s = item;
|
|
2333
|
-
const
|
|
2334
|
-
if (!
|
|
2333
|
+
const appId = typeof s.app_id === "string" ? s.app_id : typeof s.id === "string" ? s.id : null;
|
|
2334
|
+
if (!appId) continue;
|
|
2335
2335
|
const permissions = Array.isArray(s.granted_permissions) ? s.granted_permissions.filter((permission) => typeof permission === "string" && permission.trim().length > 0) : [];
|
|
2336
2336
|
const catalogApiKeyResources = normalizeApiKeyResourceMetadataList(
|
|
2337
2337
|
s.api_key_resources ?? s.apiKeyResources
|
|
@@ -2339,7 +2339,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2339
2339
|
const apiKeyResource = normalizeApiKeyResourceMetadata(s.api_key_resource ?? s.apiKeyResource) ?? catalogApiKeyResources[0] ?? null;
|
|
2340
2340
|
const apiKeyResources = catalogApiKeyResources.length > 0 ? catalogApiKeyResources : apiKeyResource ? [apiKeyResource] : [];
|
|
2341
2341
|
entries.push({
|
|
2342
|
-
|
|
2342
|
+
appId,
|
|
2343
2343
|
slug: typeof s.app_slug === "string" ? s.app_slug : null,
|
|
2344
2344
|
name: typeof s.name === "string" ? s.name : null,
|
|
2345
2345
|
description: typeof s.description === "string" ? s.description : null,
|
|
@@ -2407,7 +2407,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2407
2407
|
async callAction(action, input = {}, options = {}) {
|
|
2408
2408
|
const entry = await this.getAction(action);
|
|
2409
2409
|
const mapped = mapActionInput(entry, input);
|
|
2410
|
-
const service = entry.
|
|
2410
|
+
const service = entry.appSlug || entry.appId;
|
|
2411
2411
|
return this.request({
|
|
2412
2412
|
service,
|
|
2413
2413
|
method: entry.method,
|
|
@@ -2428,7 +2428,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2428
2428
|
listBundledServices() {
|
|
2429
2429
|
const apps = Object.values(APPLICATIONS);
|
|
2430
2430
|
return apps.map((app) => ({
|
|
2431
|
-
|
|
2431
|
+
appId: app.id,
|
|
2432
2432
|
slug: app.id,
|
|
2433
2433
|
name: app.name ?? app.id,
|
|
2434
2434
|
description: null,
|
|
@@ -2478,11 +2478,11 @@ var TopoloClient = class _TopoloClient {
|
|
|
2478
2478
|
};
|
|
2479
2479
|
}
|
|
2480
2480
|
};
|
|
2481
|
-
function
|
|
2481
|
+
function resolveConfiguredAppId(slug, appIds) {
|
|
2482
2482
|
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
2483
|
-
const configured =
|
|
2483
|
+
const configured = appIds?.[serviceKey];
|
|
2484
2484
|
if (typeof configured === "string" && configured.trim()) return configured.trim();
|
|
2485
|
-
const envKey = `
|
|
2485
|
+
const envKey = `TOPOLO_APP_ID_${serviceKey.replace(/\./g, "_").toUpperCase()}`;
|
|
2486
2486
|
const envValue = typeof process !== "undefined" ? process.env?.[envKey] : void 0;
|
|
2487
2487
|
if (typeof envValue === "string" && envValue.trim()) return envValue.trim();
|
|
2488
2488
|
}
|
|
@@ -2566,7 +2566,7 @@ function catalogEntryMatches(entry, needle) {
|
|
|
2566
2566
|
return catalogEntryLookupKeys(entry).includes(needle);
|
|
2567
2567
|
}
|
|
2568
2568
|
function catalogEntryLookupKeys(entry) {
|
|
2569
|
-
const values = [entry.
|
|
2569
|
+
const values = [entry.appId, entry.slug, entry.name].filter((value) => typeof value === "string" && value.trim().length > 0);
|
|
2570
2570
|
const keys = /* @__PURE__ */ new Set();
|
|
2571
2571
|
for (const value of values) {
|
|
2572
2572
|
const normalized = normalizeLookupKey(value);
|
|
@@ -2582,10 +2582,10 @@ function normalizeActionCatalogEntry(item) {
|
|
|
2582
2582
|
const a = item;
|
|
2583
2583
|
const actionId = pickActionString(a.action_id) ?? pickActionString(a.actionId);
|
|
2584
2584
|
const name = pickActionString(a.name);
|
|
2585
|
-
const
|
|
2585
|
+
const appId = pickActionString(a.app_id) ?? pickActionString(a.appId);
|
|
2586
2586
|
const method = pickActionString(a.method)?.toUpperCase();
|
|
2587
2587
|
const path = pickActionString(a.path);
|
|
2588
|
-
if (!actionId || !name || !
|
|
2588
|
+
if (!actionId || !name || !appId || !method || !path || !isHttpMethod(method)) {
|
|
2589
2589
|
return null;
|
|
2590
2590
|
}
|
|
2591
2591
|
return {
|
|
@@ -2594,9 +2594,9 @@ function normalizeActionCatalogEntry(item) {
|
|
|
2594
2594
|
toolName: pickActionString(a.tool_name) ?? pickActionString(a.toolName) ?? null,
|
|
2595
2595
|
title: pickActionString(a.title) ?? name,
|
|
2596
2596
|
description: pickActionString(a.description) ?? "",
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2597
|
+
appId,
|
|
2598
|
+
appSlug: pickActionString(a.app_slug) ?? pickActionString(a.appSlug) ?? null,
|
|
2599
|
+
appName: pickActionString(a.app_name) ?? pickActionString(a.appName) ?? null,
|
|
2600
2600
|
method,
|
|
2601
2601
|
path,
|
|
2602
2602
|
permissionName: pickActionString(a.permission_name) ?? pickActionString(a.permissionName) ?? "",
|
|
@@ -2711,6 +2711,7 @@ var CrmModule = class {
|
|
|
2711
2711
|
constructor(client) {
|
|
2712
2712
|
this.client = client;
|
|
2713
2713
|
}
|
|
2714
|
+
client;
|
|
2714
2715
|
async listContacts(options = {}) {
|
|
2715
2716
|
const res = await this.client.request({
|
|
2716
2717
|
service: "crm",
|
|
@@ -2756,6 +2757,7 @@ var IdentityModule = class {
|
|
|
2756
2757
|
constructor(client) {
|
|
2757
2758
|
this.client = client;
|
|
2758
2759
|
}
|
|
2760
|
+
client;
|
|
2759
2761
|
/** Returns the resolved user, organization, and permission set for the
|
|
2760
2762
|
* current credential. Equivalent to `TopoloClient.introspect()` — exposed
|
|
2761
2763
|
* on this module for symmetry with the other domain modules. */
|
|
@@ -2772,22 +2774,353 @@ function createTopolo(options) {
|
|
|
2772
2774
|
};
|
|
2773
2775
|
}
|
|
2774
2776
|
|
|
2775
|
-
//
|
|
2776
|
-
|
|
2777
|
-
|
|
2777
|
+
// ../topolo-sdk/dist/node/credential-store.js
|
|
2778
|
+
import { mkdir, readFile, writeFile, chmod } from "fs/promises";
|
|
2779
|
+
import { existsSync } from "fs";
|
|
2780
|
+
import { homedir, platform } from "os";
|
|
2781
|
+
import { dirname, join } from "path";
|
|
2782
|
+
var TopoloSdkError2 = class extends Error {
|
|
2783
|
+
code;
|
|
2784
|
+
constructor(code, message) {
|
|
2785
|
+
super(message);
|
|
2786
|
+
this.name = "TopoloSdkError";
|
|
2787
|
+
this.code = code;
|
|
2788
|
+
}
|
|
2789
|
+
};
|
|
2790
|
+
var TopoloAuthError2 = class extends TopoloSdkError2 {
|
|
2791
|
+
constructor(message, code = "auth_error") {
|
|
2792
|
+
super(code, message);
|
|
2793
|
+
this.name = "TopoloAuthError";
|
|
2794
|
+
}
|
|
2795
|
+
};
|
|
2796
|
+
var TopoloHttpError2 = class extends TopoloSdkError2 {
|
|
2797
|
+
status;
|
|
2798
|
+
body;
|
|
2799
|
+
service;
|
|
2800
|
+
path;
|
|
2801
|
+
constructor(service, path, status, body, message) {
|
|
2802
|
+
super("http_error", message ?? `HTTP ${status} from ${service}${path}`);
|
|
2803
|
+
this.name = "TopoloHttpError";
|
|
2804
|
+
this.status = status;
|
|
2805
|
+
this.body = body;
|
|
2806
|
+
this.service = service;
|
|
2807
|
+
this.path = path;
|
|
2808
|
+
}
|
|
2809
|
+
};
|
|
2810
|
+
var APP_API_URLS2 = {
|
|
2811
|
+
agent: "https://agent.topolo.app",
|
|
2812
|
+
auth: "https://auth.topolo.app",
|
|
2813
|
+
backup: "https://backup.topolo.app",
|
|
2814
|
+
books: "https://books.topolo.app",
|
|
2815
|
+
bugfix: "https://bugfix.topolo.app",
|
|
2816
|
+
bytes: "https://bytes.topolo.app",
|
|
2817
|
+
calendar: "https://calendar.topolo.app",
|
|
2818
|
+
capacity: "https://capacity.topolo.app",
|
|
2819
|
+
chat: "https://chat.topolo.app",
|
|
2820
|
+
commerce: "https://commerce.topolo.app",
|
|
2821
|
+
compose: "https://compose.topolo.app",
|
|
2822
|
+
consent: "https://consent.topolo.app",
|
|
2823
|
+
crm: "https://crm.topolo.app",
|
|
2824
|
+
developers: "https://developers.topolo.app",
|
|
2825
|
+
director: "https://director.topolo.app",
|
|
2826
|
+
feed: "https://feed.topolo.app",
|
|
2827
|
+
flow: "https://flow.topolo.app",
|
|
2828
|
+
forecast: "https://forecast.topolo.app",
|
|
2829
|
+
forms: "https://forms.topolo.app",
|
|
2830
|
+
home: "https://home.topolo.app",
|
|
2831
|
+
insights: "https://insights.topolo.app",
|
|
2832
|
+
inventory: "https://inventory.topolo.app",
|
|
2833
|
+
learn: "https://learn.topolo.app",
|
|
2834
|
+
localize: "https://localize.topolo.app",
|
|
2835
|
+
mail: "https://mail.topolo.app",
|
|
2836
|
+
mdm: "https://mdm.topolo.app",
|
|
2837
|
+
messages: "https://messages.topolo.app",
|
|
2838
|
+
nexus: "https://nexus.topolo.app",
|
|
2839
|
+
notify: "https://notify.topolo.app",
|
|
2840
|
+
observability_watch: "https://observability-watch.topolo.app",
|
|
2841
|
+
one: "https://www.topolo.app",
|
|
2842
|
+
p2p: "https://p2p.topolo.app",
|
|
2843
|
+
pay: "https://pay.topolo.app",
|
|
2844
|
+
people: "https://people.topolo.app",
|
|
2845
|
+
"quro.api": "https://api.ol0.me",
|
|
2846
|
+
"quro.redirect": "https://ol0.me",
|
|
2847
|
+
roadmapper: "https://roadmapper.topolo.app",
|
|
2848
|
+
sign: "https://sign.topolo.app",
|
|
2849
|
+
social_studio: "https://studio.topolo.app",
|
|
2850
|
+
socialize: "https://socialize.topolo.app",
|
|
2851
|
+
spaces: "https://spaces.topolo.app",
|
|
2852
|
+
status: "https://status.topolo.app",
|
|
2853
|
+
success: "https://success.topolo.app",
|
|
2854
|
+
support: "https://support.topolo.app",
|
|
2855
|
+
survey: "https://survey.topolo.app",
|
|
2856
|
+
voice: "https://voice.topolo.app",
|
|
2857
|
+
web: "https://web.topolo.app"
|
|
2858
|
+
};
|
|
2859
|
+
var DEFAULT_APP_URLS2 = APP_API_URLS2;
|
|
2860
|
+
function resolveServiceUrl2(service, overrides) {
|
|
2861
|
+
const override = resolveServiceUrlOverride2([service], overrides);
|
|
2862
|
+
if (override) return override;
|
|
2863
|
+
return DEFAULT_APP_URLS2[service];
|
|
2864
|
+
}
|
|
2865
|
+
function resolveServiceUrlOverride2(keys, overrides) {
|
|
2866
|
+
for (const key of keys) {
|
|
2867
|
+
const direct = overrides?.[key];
|
|
2868
|
+
if (direct) return direct;
|
|
2869
|
+
const envStyleKey = key.replace(/\./g, "_");
|
|
2870
|
+
const envStyle = overrides?.[envStyleKey];
|
|
2871
|
+
if (envStyle) return envStyle;
|
|
2872
|
+
}
|
|
2873
|
+
for (const key of keys) {
|
|
2874
|
+
const envKey = `TOPOLO_APP_URL_${key.replace(/\./g, "_").toUpperCase()}`;
|
|
2875
|
+
const envValue = typeof process !== "undefined" ? process.env?.[envKey] : void 0;
|
|
2876
|
+
if (envValue) return envValue;
|
|
2877
|
+
}
|
|
2878
|
+
return null;
|
|
2879
|
+
}
|
|
2880
|
+
var DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
2881
|
+
var TopoloOAuth = class {
|
|
2882
|
+
baseUrl;
|
|
2883
|
+
fetchImpl;
|
|
2884
|
+
constructor(options = {}) {
|
|
2885
|
+
this.baseUrl = resolveServiceUrl2("auth", options.serviceUrls);
|
|
2886
|
+
this.fetchImpl = options.fetch ?? fetch;
|
|
2887
|
+
}
|
|
2888
|
+
/**
|
|
2889
|
+
* RFC 8628 device authorization grant — starts the flow by asking the server
|
|
2890
|
+
* for a device_code + user_code. The caller prints the user_code +
|
|
2891
|
+
* verification_uri and then polls `pollDeviceToken` until approval.
|
|
2892
|
+
*/
|
|
2893
|
+
async requestDeviceCode(params) {
|
|
2894
|
+
const body = new URLSearchParams();
|
|
2895
|
+
body.set("client_id", params.clientId);
|
|
2896
|
+
if (params.scope) {
|
|
2897
|
+
body.set("scope", Array.isArray(params.scope) ? params.scope.join(" ") : params.scope);
|
|
2898
|
+
}
|
|
2899
|
+
return this.#postForm("/api/developer-oauth/device_authorization", body);
|
|
2900
|
+
}
|
|
2901
|
+
/**
|
|
2902
|
+
* Polls the token endpoint once. Returns the token pair on success, or
|
|
2903
|
+
* throws a `TopoloAuthError` whose `code` is one of the RFC 8628 poll
|
|
2904
|
+
* states: `authorization_pending`, `slow_down`, `access_denied`,
|
|
2905
|
+
* `expired_token`. Callers should back off on `slow_down`, wait at least
|
|
2906
|
+
* one `interval` on `authorization_pending`, and give up on the rest.
|
|
2907
|
+
*/
|
|
2908
|
+
async pollDeviceToken(params) {
|
|
2909
|
+
const body = new URLSearchParams();
|
|
2910
|
+
body.set("grant_type", DEVICE_GRANT);
|
|
2911
|
+
body.set("client_id", params.clientId);
|
|
2912
|
+
body.set("device_code", params.deviceCode);
|
|
2913
|
+
if (params.clientSecret) body.set("client_secret", params.clientSecret);
|
|
2914
|
+
return this.#postForm("/api/developer-oauth/token", body);
|
|
2915
|
+
}
|
|
2916
|
+
/** Exchange an authorization code (with PKCE) for tokens. */
|
|
2917
|
+
async exchangeAuthorizationCode(params) {
|
|
2918
|
+
const body = new URLSearchParams();
|
|
2919
|
+
body.set("grant_type", "authorization_code");
|
|
2920
|
+
body.set("client_id", params.clientId);
|
|
2921
|
+
body.set("code", params.code);
|
|
2922
|
+
body.set("redirect_uri", params.redirectUri);
|
|
2923
|
+
if (params.codeVerifier) body.set("code_verifier", params.codeVerifier);
|
|
2924
|
+
if (params.clientSecret) body.set("client_secret", params.clientSecret);
|
|
2925
|
+
return this.#postForm("/api/developer-oauth/token", body);
|
|
2926
|
+
}
|
|
2927
|
+
/** Rotate a refresh token for a new token pair. */
|
|
2928
|
+
async refreshToken(params) {
|
|
2929
|
+
const body = new URLSearchParams();
|
|
2930
|
+
body.set("grant_type", "refresh_token");
|
|
2931
|
+
body.set("client_id", params.clientId);
|
|
2932
|
+
body.set("refresh_token", params.refreshToken);
|
|
2933
|
+
if (params.clientSecret) body.set("client_secret", params.clientSecret);
|
|
2934
|
+
return this.#postForm("/api/developer-oauth/token", body);
|
|
2935
|
+
}
|
|
2936
|
+
async #postForm(path, body) {
|
|
2937
|
+
const url = new URL(path, this.baseUrl.endsWith("/") ? this.baseUrl : `${this.baseUrl}/`);
|
|
2938
|
+
const res = await this.fetchImpl(url.toString(), {
|
|
2939
|
+
method: "POST",
|
|
2940
|
+
headers: {
|
|
2941
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
2942
|
+
Accept: "application/json"
|
|
2943
|
+
},
|
|
2944
|
+
body: body.toString()
|
|
2945
|
+
});
|
|
2946
|
+
const contentType = res.headers.get("Content-Type") ?? "";
|
|
2947
|
+
const parsed = contentType.includes("application/json") ? await res.json().catch(() => null) : await res.text().catch(() => null);
|
|
2948
|
+
if (!res.ok) {
|
|
2949
|
+
if (parsed && typeof parsed === "object" && "error" in parsed) {
|
|
2950
|
+
const err = parsed;
|
|
2951
|
+
throw new TopoloAuthError2(err.error_description || err.error, err.error);
|
|
2952
|
+
}
|
|
2953
|
+
throw new TopoloHttpError2("auth", path, res.status, parsed);
|
|
2954
|
+
}
|
|
2955
|
+
return parsed;
|
|
2956
|
+
}
|
|
2957
|
+
};
|
|
2958
|
+
var ENVIRONMENT_DEFAULT_SERVICE_URLS = {
|
|
2959
|
+
production: {
|
|
2960
|
+
developers: "https://developers.topolo.app"
|
|
2961
|
+
},
|
|
2962
|
+
staging: {
|
|
2963
|
+
auth: "https://auth.stg.topolo.us",
|
|
2964
|
+
developers: "https://developers.stg.topolo.us",
|
|
2965
|
+
seed: "https://seed.stg.topolo.us"
|
|
2966
|
+
},
|
|
2967
|
+
development: {
|
|
2968
|
+
auth: "https://auth.topolo.dev",
|
|
2969
|
+
developers: "https://developers.topolo.dev"
|
|
2970
|
+
},
|
|
2971
|
+
local: {}
|
|
2972
|
+
};
|
|
2973
|
+
function configPath() {
|
|
2974
|
+
const override = process.env.TOPOLO_CONFIG_PATH;
|
|
2975
|
+
if (override) return override;
|
|
2976
|
+
const base = process.env.XDG_CONFIG_HOME || (platform() === "win32" ? join(homedir(), "AppData", "Roaming") : join(homedir(), ".config"));
|
|
2977
|
+
return join(base, "topolo", "config.json");
|
|
2978
|
+
}
|
|
2979
|
+
async function readConfig() {
|
|
2980
|
+
const path = configPath();
|
|
2981
|
+
if (!existsSync(path)) return {};
|
|
2982
|
+
try {
|
|
2983
|
+
const raw = await readFile(path, "utf8");
|
|
2984
|
+
return JSON.parse(raw);
|
|
2985
|
+
} catch {
|
|
2986
|
+
return {};
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
async function writeConfig(config) {
|
|
2990
|
+
const path = configPath();
|
|
2991
|
+
await mkdir(dirname(path), { recursive: true });
|
|
2992
|
+
await writeFile(path, JSON.stringify(config, null, 2) + "\n", "utf8");
|
|
2993
|
+
if (platform() !== "win32") {
|
|
2994
|
+
try {
|
|
2995
|
+
await chmod(path, 384);
|
|
2996
|
+
} catch {
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
function normalizeEnvironment(value) {
|
|
3001
|
+
const normalized = (value ?? "production").trim().toLowerCase();
|
|
3002
|
+
if (normalized === "" || normalized === "production" || normalized === "prod") {
|
|
3003
|
+
return "production";
|
|
3004
|
+
}
|
|
3005
|
+
if (normalized === "staging" || normalized === "stage" || normalized === "stg") {
|
|
3006
|
+
return "staging";
|
|
3007
|
+
}
|
|
3008
|
+
if (normalized === "development" || normalized === "dev") {
|
|
3009
|
+
return "development";
|
|
3010
|
+
}
|
|
3011
|
+
if (normalized === "local" || normalized === "localhost") {
|
|
3012
|
+
return "local";
|
|
3013
|
+
}
|
|
3014
|
+
throw new Error(
|
|
3015
|
+
`Unknown Topolo environment "${value}". Expected production, staging, development, or local.`
|
|
3016
|
+
);
|
|
3017
|
+
}
|
|
3018
|
+
function selectedEnvironment() {
|
|
3019
|
+
return normalizeEnvironment(process.env.TOPOLO_ENV);
|
|
3020
|
+
}
|
|
3021
|
+
function envVarPrefix(environment) {
|
|
3022
|
+
if (environment === "production") return "TOPOLO_PRODUCTION";
|
|
3023
|
+
if (environment === "staging") return "TOPOLO_STAGING";
|
|
3024
|
+
if (environment === "development") return "TOPOLO_DEVELOPMENT";
|
|
3025
|
+
return "TOPOLO_LOCAL";
|
|
3026
|
+
}
|
|
3027
|
+
function profileForEnvironment(config, environment = selectedEnvironment()) {
|
|
3028
|
+
const profile = config.profiles?.[environment] ?? {};
|
|
3029
|
+
if (environment === "production") {
|
|
3030
|
+
return {
|
|
3031
|
+
credential: config.credential,
|
|
3032
|
+
oauthClientId: config.oauthClientId,
|
|
3033
|
+
...profile,
|
|
3034
|
+
serviceUrls: {
|
|
3035
|
+
...config.serviceUrls ?? {},
|
|
3036
|
+
...profile.serviceUrls ?? {}
|
|
3037
|
+
},
|
|
3038
|
+
agentName: profile.agentName ?? config.agentName
|
|
3039
|
+
};
|
|
3040
|
+
}
|
|
3041
|
+
return profile;
|
|
3042
|
+
}
|
|
3043
|
+
function writeProfileConfig(config, environment, profile) {
|
|
3044
|
+
const profiles = { ...config.profiles ?? {} };
|
|
3045
|
+
profiles[environment] = {
|
|
3046
|
+
...profiles[environment] ?? {},
|
|
3047
|
+
...profile
|
|
3048
|
+
};
|
|
3049
|
+
return { ...config, profiles };
|
|
3050
|
+
}
|
|
3051
|
+
async function resolveCredential(environment = selectedEnvironment()) {
|
|
3052
|
+
const prefix = envVarPrefix(environment);
|
|
3053
|
+
const apiKey = process.env[`${prefix}_API_KEY`] ?? process.env.TOPOLO_API_KEY;
|
|
2778
3054
|
if (apiKey) return { kind: "api_key", apiKey };
|
|
2779
|
-
const accessToken = process.env.TOPOLO_ACCESS_TOKEN;
|
|
3055
|
+
const accessToken = process.env[`${prefix}_ACCESS_TOKEN`] ?? process.env.TOPOLO_ACCESS_TOKEN;
|
|
2780
3056
|
if (accessToken) return { kind: "access_token", accessToken };
|
|
2781
|
-
|
|
3057
|
+
const config = await readConfig();
|
|
3058
|
+
return profileForEnvironment(config, environment).credential ?? null;
|
|
3059
|
+
}
|
|
3060
|
+
var REFRESH_SKEW_SECONDS = 60;
|
|
3061
|
+
async function refreshCredentialIfNeeded(environment = selectedEnvironment()) {
|
|
3062
|
+
const prefix = envVarPrefix(environment);
|
|
3063
|
+
if (process.env[`${prefix}_API_KEY`] || process.env[`${prefix}_ACCESS_TOKEN`] || process.env.TOPOLO_API_KEY || process.env.TOPOLO_ACCESS_TOKEN) {
|
|
3064
|
+
return resolveCredential(environment);
|
|
3065
|
+
}
|
|
3066
|
+
const config = await readConfig();
|
|
3067
|
+
const profile = profileForEnvironment(config, environment);
|
|
3068
|
+
const cred = profile.credential;
|
|
3069
|
+
if (!cred || cred.kind !== "access_token") return cred ?? null;
|
|
3070
|
+
if (!cred.refreshToken || !cred.expiresAt || !profile.oauthClientId) return cred;
|
|
3071
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
3072
|
+
if (cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
|
|
3073
|
+
try {
|
|
3074
|
+
const oauth = new TopoloOAuth({
|
|
3075
|
+
serviceUrls: resolveServiceUrls(profile.serviceUrls, environment)
|
|
3076
|
+
});
|
|
3077
|
+
const tokens = await oauth.refreshToken({
|
|
3078
|
+
clientId: profile.oauthClientId,
|
|
3079
|
+
refreshToken: cred.refreshToken
|
|
3080
|
+
});
|
|
3081
|
+
const refreshed = {
|
|
3082
|
+
kind: "access_token",
|
|
3083
|
+
accessToken: tokens.access_token,
|
|
3084
|
+
...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: cred.refreshToken },
|
|
3085
|
+
expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
|
|
3086
|
+
};
|
|
3087
|
+
await writeConfig(
|
|
3088
|
+
environment === "production" && !config.profiles?.production ? { ...config, credential: refreshed } : writeProfileConfig(config, environment, { credential: refreshed })
|
|
3089
|
+
);
|
|
3090
|
+
return refreshed;
|
|
3091
|
+
} catch {
|
|
3092
|
+
return cred;
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
function resolveAgentName(configAgentName) {
|
|
3096
|
+
return process.env.TOPOLO_AGENT_NAME ?? configAgentName;
|
|
2782
3097
|
}
|
|
2783
|
-
function
|
|
2784
|
-
const
|
|
3098
|
+
function resolveServiceUrls(configUrls, environment = selectedEnvironment()) {
|
|
3099
|
+
const merged = {
|
|
3100
|
+
...ENVIRONMENT_DEFAULT_SERVICE_URLS[environment],
|
|
3101
|
+
...configUrls ?? {}
|
|
3102
|
+
};
|
|
3103
|
+
const prefix = `${envVarPrefix(environment)}_SERVICE_URL_`;
|
|
3104
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
3105
|
+
if (k.startsWith(prefix) && v) {
|
|
3106
|
+
merged[k.slice(prefix.length).toLowerCase()] = v;
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
2785
3109
|
for (const [k, v] of Object.entries(process.env)) {
|
|
2786
3110
|
if (k.startsWith("TOPOLO_SERVICE_URL_") && v) {
|
|
2787
|
-
|
|
3111
|
+
merged[k.slice("TOPOLO_SERVICE_URL_".length).toLowerCase()] = v;
|
|
2788
3112
|
}
|
|
2789
3113
|
}
|
|
2790
|
-
return Object.keys(
|
|
3114
|
+
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3117
|
+
// src/auth.ts
|
|
3118
|
+
function resolveCredentialFromEnv() {
|
|
3119
|
+
const apiKey = process.env.TOPOLO_API_KEY;
|
|
3120
|
+
if (apiKey) return { kind: "api_key", apiKey };
|
|
3121
|
+
const accessToken = process.env.TOPOLO_ACCESS_TOKEN;
|
|
3122
|
+
if (accessToken) return { kind: "access_token", accessToken };
|
|
3123
|
+
return null;
|
|
2791
3124
|
}
|
|
2792
3125
|
|
|
2793
3126
|
// src/server.ts
|
|
@@ -2806,13 +3139,13 @@ function hasScope(set, required) {
|
|
|
2806
3139
|
if (set.permissions.includes("*")) return true;
|
|
2807
3140
|
const [servicePart, actionPart] = splitPermission(required);
|
|
2808
3141
|
if (!servicePart) return set.permissions.includes(required);
|
|
2809
|
-
const [
|
|
3142
|
+
const [appId, resource] = splitService(servicePart);
|
|
2810
3143
|
const candidates = new Set([
|
|
2811
3144
|
required,
|
|
2812
3145
|
"*",
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
3146
|
+
appId ? `${appId}.*` : null,
|
|
3147
|
+
appId && resource && actionPart ? `${appId}.${resource}:*` : null,
|
|
3148
|
+
appId && resource && actionPart ? `${appId}.${resource}.${actionPart}` : null,
|
|
2816
3149
|
resource && actionPart ? `${resource}:*` : null,
|
|
2817
3150
|
resource && actionPart ? `${resource}.${actionPart}` : null,
|
|
2818
3151
|
resource && actionPart ? `${resource}:${actionPart}` : null
|
|
@@ -2864,10 +3197,10 @@ var TOOLS = [
|
|
|
2864
3197
|
},
|
|
2865
3198
|
handler: async (topolo) => {
|
|
2866
3199
|
const services = (await topolo.client.listServices()).map((entry) => {
|
|
2867
|
-
const id =
|
|
3200
|
+
const id = displayAppId(entry);
|
|
2868
3201
|
return {
|
|
2869
3202
|
id,
|
|
2870
|
-
|
|
3203
|
+
appId: entry.appId,
|
|
2871
3204
|
slug: entry.slug,
|
|
2872
3205
|
name: entry.name,
|
|
2873
3206
|
apiBaseUrl: entry.apiBaseUrl,
|
|
@@ -2894,7 +3227,7 @@ var TOOLS = [
|
|
|
2894
3227
|
properties: {
|
|
2895
3228
|
service: {
|
|
2896
3229
|
type: "string",
|
|
2897
|
-
description: "Optional
|
|
3230
|
+
description: "Optional app id, slug, or name filter."
|
|
2898
3231
|
}
|
|
2899
3232
|
},
|
|
2900
3233
|
additionalProperties: false
|
|
@@ -2923,7 +3256,7 @@ var TOOLS = [
|
|
|
2923
3256
|
{
|
|
2924
3257
|
name: "topolo_get_application",
|
|
2925
3258
|
title: "Describe one Topolo platform application",
|
|
2926
|
-
description: "Returns one live application catalog entry (
|
|
3259
|
+
description: "Returns one live application catalog entry (app id, slug, name, API URL, launch URL, status). Accepts the app id, slug, or name. Resolved against the live registry so newly-registered apps work without a client rebuild.",
|
|
2927
3260
|
requiredScopes: [],
|
|
2928
3261
|
destructive: false,
|
|
2929
3262
|
inputSchema: {
|
|
@@ -2931,7 +3264,7 @@ var TOOLS = [
|
|
|
2931
3264
|
properties: {
|
|
2932
3265
|
application: {
|
|
2933
3266
|
type: "string",
|
|
2934
|
-
description: "Application identifier:
|
|
3267
|
+
description: "Application identifier: app id, slug, or name from topolo_list_applications."
|
|
2935
3268
|
}
|
|
2936
3269
|
},
|
|
2937
3270
|
required: ["application"],
|
|
@@ -2945,10 +3278,10 @@ var TOOLS = [
|
|
|
2945
3278
|
const needle = application.trim().toLowerCase();
|
|
2946
3279
|
const catalog = await topolo.client.listServices();
|
|
2947
3280
|
const match = catalog.find(
|
|
2948
|
-
(e) => e.
|
|
3281
|
+
(e) => e.appId.toLowerCase() === needle || e.slug && e.slug.toLowerCase() === needle || e.name && e.name.toLowerCase() === needle
|
|
2949
3282
|
);
|
|
2950
3283
|
if (!match) {
|
|
2951
|
-
const known = catalog.map((e) => e.slug || e.
|
|
3284
|
+
const known = catalog.map((e) => e.slug || e.appId).sort().filter((value) => typeof value === "string" && value.length > 0);
|
|
2952
3285
|
throw new Error(
|
|
2953
3286
|
`Unknown application "${application}". ${formatKnownValues(known, "applications")}`
|
|
2954
3287
|
);
|
|
@@ -3041,7 +3374,7 @@ var TOOLS = [
|
|
|
3041
3374
|
{
|
|
3042
3375
|
name: "topolo_api_call",
|
|
3043
3376
|
title: "Call any Topolo platform service",
|
|
3044
|
-
description: "Low-level passthrough to any Topolo service. Use when no domain-specific tool exists for the operation you need. The request is signed with the current credential and scoped to the caller's organization \u2014 the target service will return 403 if your scopes do not permit the operation, even though this tool is advertised. Mutating calls (non-GET methods) require confirm:true. Call topolo_list_services first to discover callable
|
|
3377
|
+
description: "Low-level passthrough to any Topolo service. Use when no domain-specific tool exists for the operation you need. The request is signed with the current credential and scoped to the caller's organization \u2014 the target service will return 403 if your scopes do not permit the operation, even though this tool is advertised. Mutating calls (non-GET methods) require confirm:true. Call topolo_list_services first to discover callable app IDs; the SDK can also resolve live Auth-catalog app ids/slugs for newly registered API surfaces.",
|
|
3045
3378
|
requiredScopes: [],
|
|
3046
3379
|
destructive: true,
|
|
3047
3380
|
inputSchema: {
|
|
@@ -3049,7 +3382,7 @@ var TOOLS = [
|
|
|
3049
3382
|
properties: {
|
|
3050
3383
|
service: {
|
|
3051
3384
|
type: "string",
|
|
3052
|
-
description: "Target
|
|
3385
|
+
description: "Target app ID from the platform registry."
|
|
3053
3386
|
},
|
|
3054
3387
|
method: {
|
|
3055
3388
|
type: "string",
|
|
@@ -3154,7 +3487,7 @@ function actionsToToolDefs(actions) {
|
|
|
3154
3487
|
}));
|
|
3155
3488
|
}
|
|
3156
3489
|
function toolNameForAction(action) {
|
|
3157
|
-
const service = (action.
|
|
3490
|
+
const service = (action.appSlug || action.appId || "service").replace(/^topolo-/, "").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
3158
3491
|
const name = action.name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
3159
3492
|
return ["topolo", service, name].filter(Boolean).join("_").slice(0, 96);
|
|
3160
3493
|
}
|
|
@@ -3215,18 +3548,18 @@ function statusesAtOrWorse(threshold) {
|
|
|
3215
3548
|
if (threshold === "needs_review") return ["missing", "needs_review"];
|
|
3216
3549
|
return ["missing", "needs_review", "partial"];
|
|
3217
3550
|
}
|
|
3218
|
-
function
|
|
3219
|
-
for (const value of [entry.slug, entry.name, entry.
|
|
3551
|
+
function displayAppId(entry) {
|
|
3552
|
+
for (const value of [entry.slug, entry.name, entry.appId]) {
|
|
3220
3553
|
if (typeof value !== "string" || !value.trim()) continue;
|
|
3221
|
-
for (const candidate of
|
|
3222
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
3554
|
+
for (const candidate of appIdCandidates(value)) {
|
|
3555
|
+
if (Object.prototype.hasOwnProperty.call(DEFAULT_APP_URLS, candidate)) {
|
|
3223
3556
|
return candidate;
|
|
3224
3557
|
}
|
|
3225
3558
|
}
|
|
3226
3559
|
}
|
|
3227
|
-
return
|
|
3560
|
+
return appIdCandidates(entry.slug || entry.appId)[0] || entry.appId;
|
|
3228
3561
|
}
|
|
3229
|
-
function
|
|
3562
|
+
function appIdCandidates(value) {
|
|
3230
3563
|
const normalized = value.trim().toLowerCase().replace(/\s+/g, "-");
|
|
3231
3564
|
const withoutTopolo = normalized.startsWith("topolo-") ? normalized.slice("topolo-".length) : normalized;
|
|
3232
3565
|
return [.../* @__PURE__ */ new Set([
|
|
@@ -3245,14 +3578,14 @@ function formatKnownValues(values, label) {
|
|
|
3245
3578
|
|
|
3246
3579
|
// src/version.ts
|
|
3247
3580
|
import { readFileSync } from "fs";
|
|
3248
|
-
import { dirname, join } from "path";
|
|
3581
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
3249
3582
|
import { fileURLToPath } from "url";
|
|
3250
3583
|
function readMcpVersion() {
|
|
3251
3584
|
try {
|
|
3252
|
-
const here =
|
|
3585
|
+
const here = dirname2(fileURLToPath(import.meta.url));
|
|
3253
3586
|
const candidates = [
|
|
3254
|
-
|
|
3255
|
-
|
|
3587
|
+
join2(here, "package.json"),
|
|
3588
|
+
join2(here, "..", "package.json")
|
|
3256
3589
|
];
|
|
3257
3590
|
for (const path of candidates) {
|
|
3258
3591
|
try {
|
|
@@ -3331,15 +3664,21 @@ function toolError(message) {
|
|
|
3331
3664
|
|
|
3332
3665
|
// src/index.ts
|
|
3333
3666
|
async function main() {
|
|
3334
|
-
const
|
|
3667
|
+
const environment = normalizeEnvironment(process.env.TOPOLO_ENV);
|
|
3668
|
+
let credential = resolveCredentialFromEnv();
|
|
3669
|
+
if (!credential) {
|
|
3670
|
+
credential = await refreshCredentialIfNeeded(environment);
|
|
3671
|
+
}
|
|
3335
3672
|
if (!credential) {
|
|
3336
3673
|
process.stderr.write(
|
|
3337
|
-
"TopoloMCP:
|
|
3674
|
+
"TopoloMCP: no Topolo credential. Run `topolo auth login`, or set TOPOLO_API_KEY / TOPOLO_ACCESS_TOKEN.\n"
|
|
3338
3675
|
);
|
|
3339
3676
|
process.exit(1);
|
|
3340
3677
|
}
|
|
3341
|
-
const
|
|
3342
|
-
const
|
|
3678
|
+
const config = await readConfig();
|
|
3679
|
+
const profile = profileForEnvironment(config, environment);
|
|
3680
|
+
const agentName = resolveAgentName(profile.agentName);
|
|
3681
|
+
const serviceUrls = resolveServiceUrls(profile.serviceUrls, environment);
|
|
3343
3682
|
const topolo = createTopolo({
|
|
3344
3683
|
credential,
|
|
3345
3684
|
agent: {
|
|
@@ -3356,7 +3695,7 @@ async function main() {
|
|
|
3356
3695
|
await server.connect(transport);
|
|
3357
3696
|
const toolNames = await advertisedToolNames(topolo, scopes);
|
|
3358
3697
|
process.stderr.write(
|
|
3359
|
-
`TopoloMCP v${MCP_VERSION} connected. Tools available: ${toolNames.join(", ") || "(none)"}
|
|
3698
|
+
`TopoloMCP v${MCP_VERSION} connected (${environment}). Tools available: ${toolNames.join(", ") || "(none)"}
|
|
3360
3699
|
`
|
|
3361
3700
|
);
|
|
3362
3701
|
}
|