@settlemint/dalp-cli 3.1.32-main.42342404882 → 3.1.32-main.42350939226
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/dalp.js +119 -39
- package/dist/dalp.js.map +15 -15
- package/dist/{openapi-surface-stybx89d.json → openapi-surface-zqngh5wn.json} +97 -1
- package/package.json +4 -4
- package/src/commands/login.ts +1 -1
- package/src/generated/openapi-surface.json +97 -1
- package/src/lib/cli-cta.ts +59 -18
- package/src/lib/register-operations.ts +6 -4
- package/src/lib/sdk-cli-schema.ts +2 -2
|
@@ -2079,7 +2079,7 @@
|
|
|
2079
2079
|
"name": "Prefer",
|
|
2080
2080
|
"in": "header",
|
|
2081
2081
|
"required": false,
|
|
2082
|
-
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting.",
|
|
2082
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
2083
2083
|
"type": "string",
|
|
2084
2084
|
"enum": null,
|
|
2085
2085
|
"pattern": null,
|
|
@@ -2808,6 +2808,58 @@
|
|
|
2808
2808
|
}
|
|
2809
2809
|
]
|
|
2810
2810
|
},
|
|
2811
|
+
"addons/tradingVenue/orderPlacementRead": {
|
|
2812
|
+
"name": "addons/tradingVenue/orderPlacementRead",
|
|
2813
|
+
"method": "GET",
|
|
2814
|
+
"url": "/api/v2/addons/trading-venues/{venueAddress}/order-placements/{orderId}",
|
|
2815
|
+
"summary": null,
|
|
2816
|
+
"description": null,
|
|
2817
|
+
"help": "addons/tradingVenue/orderPlacementRead",
|
|
2818
|
+
"tags": [
|
|
2819
|
+
"Trading venue"
|
|
2820
|
+
],
|
|
2821
|
+
"pathParams": [
|
|
2822
|
+
{
|
|
2823
|
+
"name": "venueAddress",
|
|
2824
|
+
"in": "path",
|
|
2825
|
+
"required": true,
|
|
2826
|
+
"description": "A valid Ethereum address (42 characters, starting with 0x)",
|
|
2827
|
+
"type": "string",
|
|
2828
|
+
"enum": null,
|
|
2829
|
+
"pattern": "^0x[a-fA-F0-9]{40}$",
|
|
2830
|
+
"examples": [
|
|
2831
|
+
"0x71C7656EC7ab88b098defB751B7401B5f6d8976F"
|
|
2832
|
+
],
|
|
2833
|
+
"fields": []
|
|
2834
|
+
},
|
|
2835
|
+
{
|
|
2836
|
+
"name": "orderId",
|
|
2837
|
+
"in": "path",
|
|
2838
|
+
"required": true,
|
|
2839
|
+
"description": "Trading Venue order identifier",
|
|
2840
|
+
"type": "string",
|
|
2841
|
+
"enum": null,
|
|
2842
|
+
"pattern": null,
|
|
2843
|
+
"examples": [],
|
|
2844
|
+
"fields": []
|
|
2845
|
+
}
|
|
2846
|
+
],
|
|
2847
|
+
"queryParams": [],
|
|
2848
|
+
"headerParams": [],
|
|
2849
|
+
"requestBodyDescription": null,
|
|
2850
|
+
"hasRequestBody": false,
|
|
2851
|
+
"bodyIsComplex": false,
|
|
2852
|
+
"bodyFields": [],
|
|
2853
|
+
"examples": [
|
|
2854
|
+
{
|
|
2855
|
+
"description": "addons/tradingVenue/orderPlacementRead",
|
|
2856
|
+
"path": {
|
|
2857
|
+
"venueAddress": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
|
|
2858
|
+
"orderId": "<orderId>"
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
]
|
|
2862
|
+
},
|
|
2811
2863
|
"addons/tradingVenue/orderRead": {
|
|
2812
2864
|
"name": "addons/tradingVenue/orderRead",
|
|
2813
2865
|
"method": "GET",
|
|
@@ -2982,6 +3034,17 @@
|
|
|
2982
3034
|
"pattern": null,
|
|
2983
3035
|
"examples": [],
|
|
2984
3036
|
"fields": []
|
|
3037
|
+
},
|
|
3038
|
+
{
|
|
3039
|
+
"name": "Prefer",
|
|
3040
|
+
"in": "header",
|
|
3041
|
+
"required": false,
|
|
3042
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
3043
|
+
"type": "string",
|
|
3044
|
+
"enum": null,
|
|
3045
|
+
"pattern": null,
|
|
3046
|
+
"examples": [],
|
|
3047
|
+
"fields": []
|
|
2985
3048
|
}
|
|
2986
3049
|
],
|
|
2987
3050
|
"requestBodyDescription": null,
|
|
@@ -3068,6 +3131,17 @@
|
|
|
3068
3131
|
"pattern": null,
|
|
3069
3132
|
"examples": [],
|
|
3070
3133
|
"fields": []
|
|
3134
|
+
},
|
|
3135
|
+
{
|
|
3136
|
+
"name": "Prefer",
|
|
3137
|
+
"in": "header",
|
|
3138
|
+
"required": false,
|
|
3139
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
3140
|
+
"type": "string",
|
|
3141
|
+
"enum": null,
|
|
3142
|
+
"pattern": null,
|
|
3143
|
+
"examples": [],
|
|
3144
|
+
"fields": []
|
|
3071
3145
|
}
|
|
3072
3146
|
],
|
|
3073
3147
|
"requestBodyDescription": null,
|
|
@@ -3456,6 +3530,17 @@
|
|
|
3456
3530
|
"pattern": null,
|
|
3457
3531
|
"examples": [],
|
|
3458
3532
|
"fields": []
|
|
3533
|
+
},
|
|
3534
|
+
{
|
|
3535
|
+
"name": "Prefer",
|
|
3536
|
+
"in": "header",
|
|
3537
|
+
"required": false,
|
|
3538
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
3539
|
+
"type": "string",
|
|
3540
|
+
"enum": null,
|
|
3541
|
+
"pattern": null,
|
|
3542
|
+
"examples": [],
|
|
3543
|
+
"fields": []
|
|
3459
3544
|
}
|
|
3460
3545
|
],
|
|
3461
3546
|
"requestBodyDescription": "A signed intent is placed as signed. An intent without maker and signature is signed by the caller's custody wallet inside this request, under the request's one wallet verification, and may name expiryDate instead of expiry.",
|
|
@@ -4030,6 +4115,17 @@
|
|
|
4030
4115
|
"pattern": null,
|
|
4031
4116
|
"examples": [],
|
|
4032
4117
|
"fields": []
|
|
4118
|
+
},
|
|
4119
|
+
{
|
|
4120
|
+
"name": "Prefer",
|
|
4121
|
+
"in": "header",
|
|
4122
|
+
"required": false,
|
|
4123
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
4124
|
+
"type": "string",
|
|
4125
|
+
"enum": null,
|
|
4126
|
+
"pattern": null,
|
|
4127
|
+
"examples": [],
|
|
4128
|
+
"fields": []
|
|
4033
4129
|
}
|
|
4034
4130
|
],
|
|
4035
4131
|
"requestBodyDescription": null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@settlemint/dalp-cli",
|
|
3
|
-
"version": "3.1.32-main.
|
|
3
|
+
"version": "3.1.32-main.42350939226",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "CLI for the Digital Asset Lifecycle Platform — manage tokens, identities, compliance, and more from the command line.",
|
|
6
6
|
"homepage": "https://settlemint.com",
|
|
@@ -50,14 +50,14 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@modelcontextprotocol/server": "2.0.0-alpha.4",
|
|
53
|
-
"@settlemint/dalp-sdk": "3.1.32-main.
|
|
53
|
+
"@settlemint/dalp-sdk": "3.1.32-main.42350939226",
|
|
54
54
|
"incur": "0.7.1",
|
|
55
55
|
"zod": "4.6.7"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@arethetypeswrong/cli": "0.18.5",
|
|
59
|
-
"@testkit/effect-bun-test": "3.1.32-main.
|
|
60
|
-
"@tools/typescript-config": "3.1.32-main.
|
|
59
|
+
"@testkit/effect-bun-test": "3.1.32-main.42350939226",
|
|
60
|
+
"@tools/typescript-config": "3.1.32-main.42350939226",
|
|
61
61
|
"@types/bun": "1.4.4",
|
|
62
62
|
"publint": "0.3.25"
|
|
63
63
|
},
|
package/src/commands/login.ts
CHANGED
|
@@ -442,7 +442,7 @@ export const loginCommand = Cli.create("login", {
|
|
|
442
442
|
commands: [
|
|
443
443
|
{ command: "whoami", description: "View current user" },
|
|
444
444
|
{ command: "org switch", description: "Save the key's organization as active" },
|
|
445
|
-
{ command: "tokens
|
|
445
|
+
{ command: "get tokens index", description: "List tokens" },
|
|
446
446
|
],
|
|
447
447
|
},
|
|
448
448
|
}
|
|
@@ -2079,7 +2079,7 @@
|
|
|
2079
2079
|
"name": "Prefer",
|
|
2080
2080
|
"in": "header",
|
|
2081
2081
|
"required": false,
|
|
2082
|
-
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting.",
|
|
2082
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
2083
2083
|
"type": "string",
|
|
2084
2084
|
"enum": null,
|
|
2085
2085
|
"pattern": null,
|
|
@@ -2808,6 +2808,58 @@
|
|
|
2808
2808
|
}
|
|
2809
2809
|
]
|
|
2810
2810
|
},
|
|
2811
|
+
"addons/tradingVenue/orderPlacementRead": {
|
|
2812
|
+
"name": "addons/tradingVenue/orderPlacementRead",
|
|
2813
|
+
"method": "GET",
|
|
2814
|
+
"url": "/api/v2/addons/trading-venues/{venueAddress}/order-placements/{orderId}",
|
|
2815
|
+
"summary": null,
|
|
2816
|
+
"description": null,
|
|
2817
|
+
"help": "addons/tradingVenue/orderPlacementRead",
|
|
2818
|
+
"tags": [
|
|
2819
|
+
"Trading venue"
|
|
2820
|
+
],
|
|
2821
|
+
"pathParams": [
|
|
2822
|
+
{
|
|
2823
|
+
"name": "venueAddress",
|
|
2824
|
+
"in": "path",
|
|
2825
|
+
"required": true,
|
|
2826
|
+
"description": "A valid Ethereum address (42 characters, starting with 0x)",
|
|
2827
|
+
"type": "string",
|
|
2828
|
+
"enum": null,
|
|
2829
|
+
"pattern": "^0x[a-fA-F0-9]{40}$",
|
|
2830
|
+
"examples": [
|
|
2831
|
+
"0x71C7656EC7ab88b098defB751B7401B5f6d8976F"
|
|
2832
|
+
],
|
|
2833
|
+
"fields": []
|
|
2834
|
+
},
|
|
2835
|
+
{
|
|
2836
|
+
"name": "orderId",
|
|
2837
|
+
"in": "path",
|
|
2838
|
+
"required": true,
|
|
2839
|
+
"description": "Trading Venue order identifier",
|
|
2840
|
+
"type": "string",
|
|
2841
|
+
"enum": null,
|
|
2842
|
+
"pattern": null,
|
|
2843
|
+
"examples": [],
|
|
2844
|
+
"fields": []
|
|
2845
|
+
}
|
|
2846
|
+
],
|
|
2847
|
+
"queryParams": [],
|
|
2848
|
+
"headerParams": [],
|
|
2849
|
+
"requestBodyDescription": null,
|
|
2850
|
+
"hasRequestBody": false,
|
|
2851
|
+
"bodyIsComplex": false,
|
|
2852
|
+
"bodyFields": [],
|
|
2853
|
+
"examples": [
|
|
2854
|
+
{
|
|
2855
|
+
"description": "addons/tradingVenue/orderPlacementRead",
|
|
2856
|
+
"path": {
|
|
2857
|
+
"venueAddress": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
|
|
2858
|
+
"orderId": "<orderId>"
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
]
|
|
2862
|
+
},
|
|
2811
2863
|
"addons/tradingVenue/orderRead": {
|
|
2812
2864
|
"name": "addons/tradingVenue/orderRead",
|
|
2813
2865
|
"method": "GET",
|
|
@@ -2982,6 +3034,17 @@
|
|
|
2982
3034
|
"pattern": null,
|
|
2983
3035
|
"examples": [],
|
|
2984
3036
|
"fields": []
|
|
3037
|
+
},
|
|
3038
|
+
{
|
|
3039
|
+
"name": "Prefer",
|
|
3040
|
+
"in": "header",
|
|
3041
|
+
"required": false,
|
|
3042
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
3043
|
+
"type": "string",
|
|
3044
|
+
"enum": null,
|
|
3045
|
+
"pattern": null,
|
|
3046
|
+
"examples": [],
|
|
3047
|
+
"fields": []
|
|
2985
3048
|
}
|
|
2986
3049
|
],
|
|
2987
3050
|
"requestBodyDescription": null,
|
|
@@ -3068,6 +3131,17 @@
|
|
|
3068
3131
|
"pattern": null,
|
|
3069
3132
|
"examples": [],
|
|
3070
3133
|
"fields": []
|
|
3134
|
+
},
|
|
3135
|
+
{
|
|
3136
|
+
"name": "Prefer",
|
|
3137
|
+
"in": "header",
|
|
3138
|
+
"required": false,
|
|
3139
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
3140
|
+
"type": "string",
|
|
3141
|
+
"enum": null,
|
|
3142
|
+
"pattern": null,
|
|
3143
|
+
"examples": [],
|
|
3144
|
+
"fields": []
|
|
3071
3145
|
}
|
|
3072
3146
|
],
|
|
3073
3147
|
"requestBodyDescription": null,
|
|
@@ -3456,6 +3530,17 @@
|
|
|
3456
3530
|
"pattern": null,
|
|
3457
3531
|
"examples": [],
|
|
3458
3532
|
"fields": []
|
|
3533
|
+
},
|
|
3534
|
+
{
|
|
3535
|
+
"name": "Prefer",
|
|
3536
|
+
"in": "header",
|
|
3537
|
+
"required": false,
|
|
3538
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
3539
|
+
"type": "string",
|
|
3540
|
+
"enum": null,
|
|
3541
|
+
"pattern": null,
|
|
3542
|
+
"examples": [],
|
|
3543
|
+
"fields": []
|
|
3459
3544
|
}
|
|
3460
3545
|
],
|
|
3461
3546
|
"requestBodyDescription": "A signed intent is placed as signed. An intent without maker and signature is signed by the caller's custody wallet inside this request, under the request's one wallet verification, and may name expiryDate instead of expiry.",
|
|
@@ -4030,6 +4115,17 @@
|
|
|
4030
4115
|
"pattern": null,
|
|
4031
4116
|
"examples": [],
|
|
4032
4117
|
"fields": []
|
|
4118
|
+
},
|
|
4119
|
+
{
|
|
4120
|
+
"name": "Prefer",
|
|
4121
|
+
"in": "header",
|
|
4122
|
+
"required": false,
|
|
4123
|
+
"description": "RFC 7240 preference; separate directives with commas. Absent or `respond-async` answers 202 Accepted at once with the queued transaction's status URL. `wait` waits for settlement up to 99 seconds; `wait=N` waits up to N seconds, clamped to 5 through 99. Every wait also ends before the request deadline. A write that settles in time answers with its settled result; one that has not answers the same 202 as async. `Preference-Applied` echoes the directives honoured. Poll `Location` after 202 instead of resubmitting. `dalp-no-funding-pause` fails a transaction the chain refuses for gas at once, instead of pausing it until its wallet is funded.",
|
|
4124
|
+
"type": "string",
|
|
4125
|
+
"enum": null,
|
|
4126
|
+
"pattern": null,
|
|
4127
|
+
"examples": [],
|
|
4128
|
+
"fields": []
|
|
4033
4129
|
}
|
|
4034
4130
|
],
|
|
4035
4131
|
"requestBodyDescription": null,
|
package/src/lib/cli-cta.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "incur";
|
|
2
|
-
import {
|
|
2
|
+
import { cliCommandFor, routeTable } from "@settlemint/dalp-sdk/routes";
|
|
3
3
|
|
|
4
4
|
export interface CliCtaCommandObject {
|
|
5
5
|
readonly command: string;
|
|
@@ -78,10 +78,49 @@ function parseHref(href: string): { pathname: string; searchParams: URLSearchPar
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
const API_PREFIX = /^\/api(?:\/v2)?(?=\/)/u;
|
|
82
|
+
const BRACKETED_KEY = /^([^[\]]+)\[([^\]]+)\]$/u;
|
|
83
|
+
|
|
84
|
+
const readRoutes = Object.entries(routeTable.routes).flatMap(([routeId, row]) =>
|
|
85
|
+
row === undefined || row.method.toUpperCase() !== "GET"
|
|
86
|
+
? []
|
|
87
|
+
: [{ routeId, segments: row.path.split("/").filter((segment) => segment.length > 0) }]
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const isParameterSegment = (segment: string): boolean =>
|
|
91
|
+
(segment.startsWith("{") && segment.endsWith("}")) || segment.startsWith(":");
|
|
92
|
+
|
|
93
|
+
function matchReadRoute(
|
|
94
|
+
pathname: string
|
|
95
|
+
): { readonly routeId: string; readonly params: Record<string, string> } | undefined {
|
|
96
|
+
const hrefSegments = pathname
|
|
97
|
+
.replace(API_PREFIX, "")
|
|
98
|
+
.split("/")
|
|
99
|
+
.filter((segment) => segment.length > 0);
|
|
100
|
+
let best: { routeId: string; params: Record<string, string>; statics: number } | undefined;
|
|
101
|
+
for (const { routeId, segments } of readRoutes) {
|
|
102
|
+
if (segments.length !== hrefSegments.length) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const params: Record<string, string> = {};
|
|
106
|
+
let statics = 0;
|
|
107
|
+
const matches = segments.every((segment, index) => {
|
|
108
|
+
const actual = hrefSegments[index]!;
|
|
109
|
+
if (!isParameterSegment(segment)) {
|
|
110
|
+
statics += 1;
|
|
111
|
+
return segment === actual;
|
|
112
|
+
}
|
|
113
|
+
params[segment.startsWith(":") ? segment.slice(1) : segment.slice(1, -1)] = decodeURIComponent(actual);
|
|
114
|
+
return true;
|
|
115
|
+
});
|
|
116
|
+
if (matches && (best === undefined || statics > best.statics)) {
|
|
117
|
+
best = { routeId, params, statics };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return best;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function mapApiHrefToCliCommand(href: string): { readonly command: string } | undefined {
|
|
85
124
|
const parsed = parseHref(href);
|
|
86
125
|
if (parsed === undefined) {
|
|
87
126
|
return undefined;
|
|
@@ -90,19 +129,23 @@ export function mapApiHrefToCliCommand(
|
|
|
90
129
|
if (!(pathname.includes("/api/v2/") || pathname.startsWith("/api/"))) {
|
|
91
130
|
return undefined;
|
|
92
131
|
}
|
|
93
|
-
const
|
|
94
|
-
if (
|
|
132
|
+
const route = matchReadRoute(pathname);
|
|
133
|
+
if (route === undefined) {
|
|
95
134
|
return undefined;
|
|
96
135
|
}
|
|
97
|
-
const
|
|
136
|
+
const query: Record<string, string | Record<string, string>> = {};
|
|
98
137
|
for (const [key, value] of searchParams.entries()) {
|
|
99
|
-
const
|
|
100
|
-
|
|
138
|
+
const bracketed = BRACKETED_KEY.exec(key);
|
|
139
|
+
if (bracketed === null) {
|
|
140
|
+
query[key] = value;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const [, name, member] = bracketed;
|
|
144
|
+
const nested = query[name!];
|
|
145
|
+
query[name!] = { ...(typeof nested === "object" ? nested : {}), [member!]: value };
|
|
101
146
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
...(Object.keys(options).length > 0 ? { options } : {}),
|
|
105
|
-
};
|
|
147
|
+
const command = cliCommandFor(route.routeId, { params: route.params, query });
|
|
148
|
+
return command === null ? undefined : { command: command.text };
|
|
106
149
|
}
|
|
107
150
|
|
|
108
151
|
export function commandsFromLinks(links: ResourceLinks | undefined): Array<CliCtaCommandObject> {
|
|
@@ -126,14 +169,12 @@ export function commandsFromLinks(links: ResourceLinks | undefined): Array<CliCt
|
|
|
126
169
|
if (mapped === undefined) {
|
|
127
170
|
continue;
|
|
128
171
|
}
|
|
129
|
-
|
|
130
|
-
if (seen.has(signature)) {
|
|
172
|
+
if (seen.has(mapped.command)) {
|
|
131
173
|
continue;
|
|
132
174
|
}
|
|
133
|
-
seen.add(
|
|
175
|
+
seen.add(mapped.command);
|
|
134
176
|
commands.push({
|
|
135
177
|
command: mapped.command,
|
|
136
|
-
...(mapped.options === undefined ? {} : { options: mapped.options }),
|
|
137
178
|
description: REL_DESCRIPTION[rel] ?? `Follow ${rel} link`,
|
|
138
179
|
});
|
|
139
180
|
}
|
|
@@ -222,15 +222,17 @@ function mcpMetadataFor(ops: ReadonlyArray<OperationDescriptor>) {
|
|
|
222
222
|
function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
|
|
223
223
|
const primary = pickPrimaryOp(ops);
|
|
224
224
|
const { surface } = primary;
|
|
225
|
-
const
|
|
226
|
-
|
|
225
|
+
const optionalPathParams = new Set(
|
|
226
|
+
surface.pathParams
|
|
227
|
+
.map((param) => param.name)
|
|
228
|
+
.filter((name) => ops.some((op) => !op.surface.pathParams.some((param) => param.name === name)))
|
|
229
|
+
);
|
|
227
230
|
const mutation = ops.some((op) => isMutationMethod(op.method));
|
|
228
231
|
|
|
229
|
-
const pathSchema = ops.map((op) => op.pathSchema).find((schema) => schema !== undefined);
|
|
230
232
|
const querySchema = ops.map((op) => op.querySchema).find((schema) => schema !== undefined);
|
|
231
233
|
const bodySchema = ops.map((op) => op.bodySchema).find((schema) => schema !== undefined);
|
|
232
234
|
|
|
233
|
-
const argsSchema = buildArgsFromSdkPath(
|
|
235
|
+
const argsSchema = buildArgsFromSdkPath(primary.pathSchema, surface, optionalPathParams);
|
|
234
236
|
const optionsSchema = buildOptionsFromSdk(querySchema, bodySchema, surface, {
|
|
235
237
|
...(mutation
|
|
236
238
|
? {
|
|
@@ -172,7 +172,7 @@ function formatSurfaceDescribe(
|
|
|
172
172
|
export function buildArgsFromSdkPath(
|
|
173
173
|
pathSchema: ZodTypeAny | undefined,
|
|
174
174
|
surface: SurfaceOperation | undefined,
|
|
175
|
-
|
|
175
|
+
optionalNames: ReadonlySet<string>
|
|
176
176
|
): z.ZodObject<ZodShape> | undefined {
|
|
177
177
|
const shape = objectShape(pathSchema);
|
|
178
178
|
if (shape === undefined || Object.keys(shape).length === 0) {
|
|
@@ -181,7 +181,7 @@ export function buildArgsFromSdkPath(
|
|
|
181
181
|
const out: ZodShape = {};
|
|
182
182
|
for (const [name, fieldSchema] of Object.entries(shape)) {
|
|
183
183
|
const described = asCliField(fieldSchema, openApiFieldDescription(surface, "path", name));
|
|
184
|
-
out[name] =
|
|
184
|
+
out[name] = optionalNames.has(name) ? described.optional() : described;
|
|
185
185
|
}
|
|
186
186
|
return z.object(out);
|
|
187
187
|
}
|