mmt-mcp 1.45.0-pre → 1.45.2-pre
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/examples/intermediate/16_bruno_files/README.md +1 -1
- package/dist/examples/intermediate/28_http_body_formats/README.md +1 -1
- package/dist/examples/intermediate/28_http_body_formats/post_xml.mmt +1 -1
- package/dist/examples/intermediate/28_http_body_formats/post_xmle.mmt +1 -1
- package/dist/examples/professional/11_token_resolution/README.md +1 -1
- package/dist/examples/professional/11_token_resolution/api/current_xml_body.mmt +15 -15
- package/dist/examples/professional/11_token_resolution/api/env_xml_body.mmt +17 -17
- package/dist/examples/professional/11_token_resolution/api/input_xml_body.mmt +25 -25
- package/dist/examples/professional/11_token_resolution/api/random_xml_body.mmt +14 -14
- package/dist/server.cjs +70 -13
- package/dist/server.js +70 -13
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@ Use {{btn:list-tree}} in the header to pick **All** (one test) or a single reque
|
|
|
11
11
|
- `get_profile.bru`: a simple Bruno GET request with variables, headers, bearer auth, query params, and assertions.
|
|
12
12
|
- `create_user_json.bru`: a POST request with a JSON body and bearer auth.
|
|
13
13
|
- `update_profile_form.bru`: a PUT request with a form-urlencoded body.
|
|
14
|
-
- `xml_echo.bru`: a POST request with an XML text body.
|
|
14
|
+
- `xml_echo.bru`: a POST request with an XML text body to `test.mmt.dev/echo/xml`.
|
|
15
15
|
- `import_bruno_in_test.mmt`: a Multimeter test that imports a `.bru` file and calls it like any other test import.
|
|
16
16
|
|
|
17
17
|
## Importing Bruno Files From MMT
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Intermediate example covering every HTTP request `format:` — `json`, `xml`, `xmle`, `text`, `urlencoded`, `binary`, and `multipart`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Most requests POST to [test.mmt.dev/echo](https://test.mmt.dev/echo). XML formats (`post_xml.mmt`, `post_xmle.mmt`) use [test.mmt.dev/echo/xml](https://test.mmt.dev/echo/xml) so the response is `application/xml`.
|
|
6
6
|
|
|
7
7
|
## Files
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Token resolution
|
|
2
2
|
|
|
3
|
-
Professional samples of `e:`, `i:`, `r:`, and `c:` against [test.mmt.dev/echo](https://test.mmt.dev/echo).
|
|
3
|
+
Professional samples of `e:`, `i:`, `r:`, and `c:` against [test.mmt.dev/echo](https://test.mmt.dev/echo). XML body samples use [test.mmt.dev/echo/xml](https://test.mmt.dev/echo/xml) and read fields from the XML echo (`body.echo.body.body…`).
|
|
4
4
|
|
|
5
5
|
A whole field in a **JSON** body keeps the value's type. **XML**, **urlencoded**, **headers**, and **query** always send text. A quoted token such as `"e:account_age"` is the literal text. `omit` removes the field. `"omit"` sends the word omit. A missing `e:`, `i:`, `r:`, or `c:` token is sent as its own text, for example `e:region` or `i:nickname`.
|
|
6
6
|
|
|
@@ -2,22 +2,22 @@ type: api
|
|
|
2
2
|
title: Current tokens in an XML body
|
|
3
3
|
description: "XML element text is always a string, including c:epoch."
|
|
4
4
|
outputs:
|
|
5
|
-
day_name: body.body.day_name
|
|
6
|
-
epoch_seconds: body.body.epoch_seconds
|
|
7
|
-
city: body.body.city
|
|
8
|
-
missing_token: body.body.missing_token
|
|
9
|
-
literal_token: body.body.literal_token
|
|
10
|
-
literal_omit: body.body.literal_omit
|
|
11
|
-
angle_whole: body.body.angle_whole
|
|
12
|
-
quoted_angle: body.body.quoted_angle
|
|
13
|
-
angle_prefix: body.body.angle_prefix
|
|
14
|
-
angle_suffix: body.body.angle_suffix
|
|
15
|
-
angle_both: body.body.angle_both
|
|
16
|
-
quoted_curly: body.body.quoted_curly
|
|
17
|
-
curly_whole: body.body.curly_whole
|
|
18
|
-
text_slice: body.body.text_slice
|
|
5
|
+
day_name: body.echo.body.body.day_name
|
|
6
|
+
epoch_seconds: body.echo.body.body.epoch_seconds
|
|
7
|
+
city: body.echo.body.body.city
|
|
8
|
+
missing_token: body.echo.body.body.missing_token
|
|
9
|
+
literal_token: body.echo.body.body.literal_token
|
|
10
|
+
literal_omit: body.echo.body.body.literal_omit
|
|
11
|
+
angle_whole: body.echo.body.body.angle_whole
|
|
12
|
+
quoted_angle: body.echo.body.body.quoted_angle
|
|
13
|
+
angle_prefix: body.echo.body.body.angle_prefix
|
|
14
|
+
angle_suffix: body.echo.body.body.angle_suffix
|
|
15
|
+
angle_both: body.echo.body.body.angle_both
|
|
16
|
+
quoted_curly: body.echo.body.body.quoted_curly
|
|
17
|
+
curly_whole: body.echo.body.body.curly_whole
|
|
18
|
+
text_slice: body.echo.body.body.text_slice
|
|
19
19
|
status_code: status
|
|
20
|
-
url: https://test.mmt.dev/echo
|
|
20
|
+
url: https://test.mmt.dev/echo/xml
|
|
21
21
|
method: post
|
|
22
22
|
format: xml
|
|
23
23
|
body:
|
|
@@ -2,24 +2,24 @@ type: api
|
|
|
2
2
|
title: Env tokens in an XML body
|
|
3
3
|
description: "XML element text is always a string, including numbers and booleans from e:."
|
|
4
4
|
outputs:
|
|
5
|
-
account_age: body.body.account_age
|
|
6
|
-
feature_enabled: body.body.feature_enabled
|
|
7
|
-
plan_code: body.body.plan_code
|
|
8
|
-
plan_label: body.body.plan_label
|
|
9
|
-
service_url: body.body.service_url
|
|
10
|
-
missing_region: body.body.missing_region
|
|
11
|
-
literal_token: body.body.literal_token
|
|
12
|
-
literal_omit: body.body.literal_omit
|
|
13
|
-
angle_whole: body.body.angle_whole
|
|
14
|
-
quoted_angle: body.body.quoted_angle
|
|
15
|
-
angle_prefix: body.body.angle_prefix
|
|
16
|
-
angle_suffix: body.body.angle_suffix
|
|
17
|
-
angle_both: body.body.angle_both
|
|
18
|
-
quoted_curly: body.body.quoted_curly
|
|
19
|
-
curly_whole: body.body.curly_whole
|
|
20
|
-
text_slice: body.body.text_slice
|
|
5
|
+
account_age: body.echo.body.body.account_age
|
|
6
|
+
feature_enabled: body.echo.body.body.feature_enabled
|
|
7
|
+
plan_code: body.echo.body.body.plan_code
|
|
8
|
+
plan_label: body.echo.body.body.plan_label
|
|
9
|
+
service_url: body.echo.body.body.service_url
|
|
10
|
+
missing_region: body.echo.body.body.missing_region
|
|
11
|
+
literal_token: body.echo.body.body.literal_token
|
|
12
|
+
literal_omit: body.echo.body.body.literal_omit
|
|
13
|
+
angle_whole: body.echo.body.body.angle_whole
|
|
14
|
+
quoted_angle: body.echo.body.body.quoted_angle
|
|
15
|
+
angle_prefix: body.echo.body.body.angle_prefix
|
|
16
|
+
angle_suffix: body.echo.body.body.angle_suffix
|
|
17
|
+
angle_both: body.echo.body.body.angle_both
|
|
18
|
+
quoted_curly: body.echo.body.body.quoted_curly
|
|
19
|
+
curly_whole: body.echo.body.body.curly_whole
|
|
20
|
+
text_slice: body.echo.body.body.text_slice
|
|
21
21
|
status_code: status
|
|
22
|
-
url: https://test.mmt.dev/echo
|
|
22
|
+
url: https://test.mmt.dev/echo/xml
|
|
23
23
|
method: post
|
|
24
24
|
format: xml
|
|
25
25
|
body:
|
|
@@ -9,32 +9,32 @@ inputs:
|
|
|
9
9
|
version: "1.0"
|
|
10
10
|
price: 9.5
|
|
11
11
|
outputs:
|
|
12
|
-
username: body.body.username
|
|
13
|
-
age: body.body.age
|
|
14
|
-
active: body.body.active
|
|
15
|
-
city: body.body.city
|
|
16
|
-
missing_nickname: body.body.missing_nickname
|
|
17
|
-
literal_token: body.body.literal_token
|
|
18
|
-
literal_omit: body.body.literal_omit
|
|
19
|
-
angle_whole: body.body.angle_whole
|
|
20
|
-
quoted_angle: body.body.quoted_angle
|
|
21
|
-
angle_prefix: body.body.angle_prefix
|
|
22
|
-
angle_suffix: body.body.angle_suffix
|
|
23
|
-
angle_both: body.body.angle_both
|
|
24
|
-
quoted_curly: body.body.quoted_curly
|
|
25
|
-
curly_whole: body.body.curly_whole
|
|
26
|
-
text_slice: body.body.text_slice
|
|
27
|
-
missing_embed: body.body.missing_embed
|
|
28
|
-
attr_number: body.body.item.number
|
|
29
|
-
attr_bool: body.body.item.flag
|
|
30
|
-
attr_text: body.body.item.version
|
|
31
|
-
attr_angle: body.body.item.angle
|
|
32
|
-
attr_embedded: body.body.item.embedded
|
|
33
|
-
attr_literal: body.body.item.literal
|
|
34
|
-
attr_decimal: body.body.item.decimal
|
|
35
|
-
price_text: body.body.price
|
|
12
|
+
username: body.echo.body.body.username
|
|
13
|
+
age: body.echo.body.body.age
|
|
14
|
+
active: body.echo.body.body.active
|
|
15
|
+
city: body.echo.body.body.city
|
|
16
|
+
missing_nickname: body.echo.body.body.missing_nickname
|
|
17
|
+
literal_token: body.echo.body.body.literal_token
|
|
18
|
+
literal_omit: body.echo.body.body.literal_omit
|
|
19
|
+
angle_whole: body.echo.body.body.angle_whole
|
|
20
|
+
quoted_angle: body.echo.body.body.quoted_angle
|
|
21
|
+
angle_prefix: body.echo.body.body.angle_prefix
|
|
22
|
+
angle_suffix: body.echo.body.body.angle_suffix
|
|
23
|
+
angle_both: body.echo.body.body.angle_both
|
|
24
|
+
quoted_curly: body.echo.body.body.quoted_curly
|
|
25
|
+
curly_whole: body.echo.body.body.curly_whole
|
|
26
|
+
text_slice: body.echo.body.body.text_slice
|
|
27
|
+
missing_embed: body.echo.body.body.missing_embed
|
|
28
|
+
attr_number: body.echo.body.body.item.number
|
|
29
|
+
attr_bool: body.echo.body.body.item.flag
|
|
30
|
+
attr_text: body.echo.body.body.item.version
|
|
31
|
+
attr_angle: body.echo.body.body.item.angle
|
|
32
|
+
attr_embedded: body.echo.body.body.item.embedded
|
|
33
|
+
attr_literal: body.echo.body.body.item.literal
|
|
34
|
+
attr_decimal: body.echo.body.body.item.decimal
|
|
35
|
+
price_text: body.echo.body.body.price
|
|
36
36
|
status_code: status
|
|
37
|
-
url: https://test.mmt.dev/echo
|
|
37
|
+
url: https://test.mmt.dev/echo/xml
|
|
38
38
|
method: post
|
|
39
39
|
format: xml
|
|
40
40
|
body:
|
|
@@ -2,21 +2,21 @@ type: api
|
|
|
2
2
|
title: Random tokens in an XML body
|
|
3
3
|
description: "XML element text is always a string, including r:int and r:bool."
|
|
4
4
|
outputs:
|
|
5
|
-
request_id: body.body.request_id
|
|
6
|
-
lucky_number: body.body.lucky_number
|
|
7
|
-
active: body.body.active
|
|
8
|
-
missing_token: body.body.missing_token
|
|
9
|
-
literal_token: body.body.literal_token
|
|
10
|
-
literal_omit: body.body.literal_omit
|
|
11
|
-
angle_whole: body.body.angle_whole
|
|
12
|
-
quoted_angle: body.body.quoted_angle
|
|
13
|
-
angle_prefix: body.body.angle_prefix
|
|
14
|
-
angle_suffix: body.body.angle_suffix
|
|
15
|
-
angle_both: body.body.angle_both
|
|
16
|
-
quoted_curly: body.body.quoted_curly
|
|
17
|
-
curly_whole: body.body.curly_whole
|
|
5
|
+
request_id: body.echo.body.body.request_id
|
|
6
|
+
lucky_number: body.echo.body.body.lucky_number
|
|
7
|
+
active: body.echo.body.body.active
|
|
8
|
+
missing_token: body.echo.body.body.missing_token
|
|
9
|
+
literal_token: body.echo.body.body.literal_token
|
|
10
|
+
literal_omit: body.echo.body.body.literal_omit
|
|
11
|
+
angle_whole: body.echo.body.body.angle_whole
|
|
12
|
+
quoted_angle: body.echo.body.body.quoted_angle
|
|
13
|
+
angle_prefix: body.echo.body.body.angle_prefix
|
|
14
|
+
angle_suffix: body.echo.body.body.angle_suffix
|
|
15
|
+
angle_both: body.echo.body.body.angle_both
|
|
16
|
+
quoted_curly: body.echo.body.body.quoted_curly
|
|
17
|
+
curly_whole: body.echo.body.body.curly_whole
|
|
18
18
|
status_code: status
|
|
19
|
-
url: https://test.mmt.dev/echo
|
|
19
|
+
url: https://test.mmt.dev/echo/xml
|
|
20
20
|
method: post
|
|
21
21
|
format: xml
|
|
22
22
|
body:
|
package/dist/server.cjs
CHANGED
|
@@ -13865,7 +13865,9 @@ function formatHtmlBody(html) {
|
|
|
13865
13865
|
|
|
13866
13866
|
// ../core/src/expectOperatorYaml.ts
|
|
13867
13867
|
var YAML_UNSAFE_OPS = opsList.filter((op) => op.startsWith("!") || op.startsWith(">")).sort((a, b) => b.length - a.length);
|
|
13868
|
+
var EMIT_UNQUOTE_OPS = [...opsList].sort((a, b) => b.length - a.length);
|
|
13868
13869
|
var FUZZY_PERCENT_OP_RE = /^[>](?:0|[1-9][0-9]?|100)%(?:\s|$)/;
|
|
13870
|
+
var EMIT_FUZZY_PERCENT_OP_RE = /^[<>](?:0|[1-9][0-9]?|100)%(?:\s|$)/;
|
|
13869
13871
|
var TIME_TILDE_OP_RE = new RegExp(`^${TIME_OPERATOR_PATTERN}(?:\\s|$)`);
|
|
13870
13872
|
var EXACT_TIME_TILDE_OP_RE = new RegExp(`^${TIME_OPERATOR_PATTERN}$`);
|
|
13871
13873
|
var MAP_ENTRY_RE = /^([^:]+?:\s+)(.+)$/;
|
|
@@ -13899,7 +13901,6 @@ function quoteExpectOperators(yaml) {
|
|
|
13899
13901
|
}
|
|
13900
13902
|
return joinLines(lines, eol);
|
|
13901
13903
|
}
|
|
13902
|
-
var YAML_BANG_UNSAFE_OPS = YAML_UNSAFE_OPS.filter((op) => op.startsWith("!"));
|
|
13903
13904
|
var QUOTED_SCALAR_RE = /^"((?:\\.|[^"\\])*)"$/;
|
|
13904
13905
|
function emitUnquotedOperators(yaml) {
|
|
13905
13906
|
const eol = detectNewline(yaml);
|
|
@@ -13936,14 +13937,14 @@ function unescapeQuotedScalar(value) {
|
|
|
13936
13937
|
}
|
|
13937
13938
|
return match[1].replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
13938
13939
|
}
|
|
13939
|
-
function
|
|
13940
|
+
function canEmitUnquotedOperatorValue(value) {
|
|
13940
13941
|
if (/^["']/.test(value)) {
|
|
13941
13942
|
return false;
|
|
13942
13943
|
}
|
|
13943
|
-
if (
|
|
13944
|
+
if (EMIT_FUZZY_PERCENT_OP_RE.test(value) || TIME_TILDE_OP_RE.test(value)) {
|
|
13944
13945
|
return true;
|
|
13945
13946
|
}
|
|
13946
|
-
for (const op of
|
|
13947
|
+
for (const op of EMIT_UNQUOTE_OPS) {
|
|
13947
13948
|
if (value === op || value.startsWith(op + " ")) {
|
|
13948
13949
|
return true;
|
|
13949
13950
|
}
|
|
@@ -13954,10 +13955,10 @@ function canEmitUnquotedExactOperator(value) {
|
|
|
13954
13955
|
if (/^["']/.test(value)) {
|
|
13955
13956
|
return false;
|
|
13956
13957
|
}
|
|
13957
|
-
if (
|
|
13958
|
+
if (EXACT_EMIT_FUZZY_PERCENT_OP_RE.test(value) || EXACT_TIME_TILDE_OP_RE.test(value)) {
|
|
13958
13959
|
return true;
|
|
13959
13960
|
}
|
|
13960
|
-
return
|
|
13961
|
+
return EMIT_UNQUOTE_OPS.some((op) => op === value);
|
|
13961
13962
|
}
|
|
13962
13963
|
function unquoteExpectLineIfNeeded(line) {
|
|
13963
13964
|
const trimmed = line.trimStart();
|
|
@@ -13966,7 +13967,7 @@ function unquoteExpectLineIfNeeded(line) {
|
|
|
13966
13967
|
if (mapMatch) {
|
|
13967
13968
|
const [, prefix, value] = mapMatch;
|
|
13968
13969
|
const inner = unescapeQuotedScalar(value.trim());
|
|
13969
|
-
if (inner !== void 0 &&
|
|
13970
|
+
if (inner !== void 0 && canEmitUnquotedOperatorValue(inner)) {
|
|
13970
13971
|
return leadingWS + prefix + inner;
|
|
13971
13972
|
}
|
|
13972
13973
|
return line;
|
|
@@ -13975,7 +13976,7 @@ function unquoteExpectLineIfNeeded(line) {
|
|
|
13975
13976
|
if (arrayMatch) {
|
|
13976
13977
|
const [, prefix, value] = arrayMatch;
|
|
13977
13978
|
const inner = unescapeQuotedScalar(value.trim());
|
|
13978
|
-
if (inner !== void 0 &&
|
|
13979
|
+
if (inner !== void 0 && canEmitUnquotedOperatorValue(inner)) {
|
|
13979
13980
|
return leadingWS + prefix + inner;
|
|
13980
13981
|
}
|
|
13981
13982
|
}
|
|
@@ -14034,6 +14035,7 @@ function needsOperatorQuoting(value) {
|
|
|
14034
14035
|
return false;
|
|
14035
14036
|
}
|
|
14036
14037
|
var EXACT_FUZZY_PERCENT_OP_RE = /^[>](?:0|[1-9][0-9]?|100)%$/;
|
|
14038
|
+
var EXACT_EMIT_FUZZY_PERCENT_OP_RE = /^[<>](?:0|[1-9][0-9]?|100)%$/;
|
|
14037
14039
|
function needsExactOperatorQuoting(value) {
|
|
14038
14040
|
if (/^["']/.test(value)) {
|
|
14039
14041
|
return false;
|
|
@@ -26656,7 +26658,18 @@ ${helperFactorySource}
|
|
|
26656
26658
|
const __mmt_exampleLabel = ${exampleLiteral};
|
|
26657
26659
|
` + helperDestructure + "\n" + (opts.apiFunctionSource ? `${indentMultiline(opts.apiFunctionSource, " ")}
|
|
26658
26660
|
|
|
26659
|
-
` : "") +
|
|
26661
|
+
` : "") + // Direct API runs only (this wrapper). Report wire request/response for
|
|
26662
|
+
// History; imported call: from tests does not use this wrap.
|
|
26663
|
+
` const __mmt_reportNetwork = (scope, request, response) => {
|
|
26664
|
+
if (typeof __reporter !== 'function') { return; }
|
|
26665
|
+
try {
|
|
26666
|
+
const payload = { scope: scope, request: request || {} };
|
|
26667
|
+
if (response !== undefined) { payload.response = response; }
|
|
26668
|
+
__reporter(payload);
|
|
26669
|
+
} catch (_e) {}
|
|
26670
|
+
};
|
|
26671
|
+
const __mmt_originalSend = send_;
|
|
26672
|
+
const __mmt_originalSendGrpc = typeof sendGrpc_ === 'function' ? sendGrpc_ : null;
|
|
26660
26673
|
send_ = async function(req) {
|
|
26661
26674
|
await checkAbort_();
|
|
26662
26675
|
const __req = req || {};
|
|
@@ -26687,6 +26700,7 @@ ${helperFactorySource}
|
|
|
26687
26700
|
body: __mmt_formatBodyValue(__req.body)
|
|
26688
26701
|
};
|
|
26689
26702
|
console.debug(__mmt_formatSection('Request:', __reqLog));
|
|
26703
|
+
__mmt_reportNetwork('network-request', __req);
|
|
26690
26704
|
try {
|
|
26691
26705
|
const __res = await __mmt_originalSend(req);
|
|
26692
26706
|
// Stop before Response logging when the user cancelled mid-request.
|
|
@@ -26708,6 +26722,9 @@ ${helperFactorySource}
|
|
|
26708
26722
|
if (__warning) {
|
|
26709
26723
|
console.warn(__warning);
|
|
26710
26724
|
}
|
|
26725
|
+
__mmt_reportNetwork(
|
|
26726
|
+
(typeof __status === 'number' && __status < 0) ? 'network-error' : 'network-response',
|
|
26727
|
+
__req, __res);
|
|
26711
26728
|
// Return network failures to the API function so outputs (and the
|
|
26712
26729
|
// tester Response panel) still receive the response; the wrapper
|
|
26713
26730
|
// marks the run failed after outputs are built.
|
|
@@ -26736,6 +26753,8 @@ ${helperFactorySource}
|
|
|
26736
26753
|
};
|
|
26737
26754
|
console.log(__mmt_formatSection('Response:', __resLog));
|
|
26738
26755
|
console.warn(__warning);
|
|
26756
|
+
__mmt_reportNetwork(
|
|
26757
|
+
__res.status < 0 ? 'network-error' : 'network-response', __req, __res);
|
|
26739
26758
|
return __res;
|
|
26740
26759
|
}
|
|
26741
26760
|
const __errorLog = {
|
|
@@ -26750,9 +26769,41 @@ ${helperFactorySource}
|
|
|
26750
26769
|
}
|
|
26751
26770
|
}
|
|
26752
26771
|
console.error(__mmt_formatSection('Response:', __errorLog));
|
|
26772
|
+
__mmt_reportNetwork('network-error', __req, {
|
|
26773
|
+
status: err && typeof err.status === 'number' ? err.status : -1,
|
|
26774
|
+
statusText: err && err.message ? String(err.message) : String(err),
|
|
26775
|
+
body: err && err.body,
|
|
26776
|
+
headers: err && err.headers || {},
|
|
26777
|
+
duration: err && typeof err.duration === 'number' ? err.duration : -1
|
|
26778
|
+
});
|
|
26753
26779
|
throw err;
|
|
26754
26780
|
}
|
|
26755
26781
|
};
|
|
26782
|
+
if (__mmt_originalSendGrpc) {
|
|
26783
|
+
sendGrpc_ = async function(req) {
|
|
26784
|
+
await checkAbort_();
|
|
26785
|
+
const __req = req || {};
|
|
26786
|
+
__mmt_reportNetwork('network-request', __req);
|
|
26787
|
+
try {
|
|
26788
|
+
const __res = await __mmt_originalSendGrpc(req);
|
|
26789
|
+
await checkAbort_();
|
|
26790
|
+
__mmt_reportNetwork('network-response', __req, __res);
|
|
26791
|
+
return __res;
|
|
26792
|
+
} catch (err) {
|
|
26793
|
+
if (err && (err.kind === 'test-abort' || (typeof isTestAbortError === 'function' && isTestAbortError(err)))) {
|
|
26794
|
+
throw err;
|
|
26795
|
+
}
|
|
26796
|
+
__mmt_reportNetwork('network-error', __req, {
|
|
26797
|
+
status: err && typeof err.status === 'number' ? err.status : -1,
|
|
26798
|
+
statusText: err && err.message ? String(err.message) : String(err),
|
|
26799
|
+
body: err && err.body,
|
|
26800
|
+
headers: err && err.headers || {},
|
|
26801
|
+
duration: err && typeof err.duration === 'number' ? err.duration : -1
|
|
26802
|
+
});
|
|
26803
|
+
throw err;
|
|
26804
|
+
}
|
|
26805
|
+
};
|
|
26806
|
+
}
|
|
26756
26807
|
|
|
26757
26808
|
try {
|
|
26758
26809
|
if (__mmt_exampleLabel) {
|
|
@@ -26814,6 +26865,7 @@ ${helperFactorySource}
|
|
|
26814
26865
|
return result;
|
|
26815
26866
|
} finally {
|
|
26816
26867
|
send_ = __mmt_originalSend;
|
|
26868
|
+
if (__mmt_originalSendGrpc) { sendGrpc_ = __mmt_originalSendGrpc; }
|
|
26817
26869
|
}
|
|
26818
26870
|
})();`;
|
|
26819
26871
|
}
|
|
@@ -26866,10 +26918,15 @@ async function executeApi(prepared, options, preLogs) {
|
|
|
26866
26918
|
exampleOutputs,
|
|
26867
26919
|
checkTitle: fileDisplayName
|
|
26868
26920
|
});
|
|
26869
|
-
const
|
|
26870
|
-
|
|
26871
|
-
|
|
26921
|
+
const apiReporter = typeof options.reporter === "function" ? (event) => {
|
|
26922
|
+
const isSuiteChild = options.__mmtIsSuiteBundleChildRun === true;
|
|
26923
|
+
if (isSuiteChild && event && event.scope !== "setenv") {
|
|
26924
|
+
return;
|
|
26872
26925
|
}
|
|
26926
|
+
options.reporter({
|
|
26927
|
+
...event,
|
|
26928
|
+
id: event.id || options.id
|
|
26929
|
+
});
|
|
26873
26930
|
} : void 0;
|
|
26874
26931
|
const result = await runGeneratedJs(
|
|
26875
26932
|
"run-api",
|
|
@@ -26880,7 +26937,7 @@ async function executeApi(prepared, options, preLogs) {
|
|
|
26880
26937
|
void 0,
|
|
26881
26938
|
options.id,
|
|
26882
26939
|
fileLoader,
|
|
26883
|
-
|
|
26940
|
+
apiReporter,
|
|
26884
26941
|
options.abortSignal,
|
|
26885
26942
|
void 0,
|
|
26886
26943
|
prepared.filePath ? prepared.filePath.split(/[/\\]/).slice(0, -1).join("/") : void 0,
|
package/dist/server.js
CHANGED
|
@@ -13865,7 +13865,9 @@ function formatHtmlBody(html) {
|
|
|
13865
13865
|
|
|
13866
13866
|
// ../core/src/expectOperatorYaml.ts
|
|
13867
13867
|
var YAML_UNSAFE_OPS = opsList.filter((op) => op.startsWith("!") || op.startsWith(">")).sort((a, b) => b.length - a.length);
|
|
13868
|
+
var EMIT_UNQUOTE_OPS = [...opsList].sort((a, b) => b.length - a.length);
|
|
13868
13869
|
var FUZZY_PERCENT_OP_RE = /^[>](?:0|[1-9][0-9]?|100)%(?:\s|$)/;
|
|
13870
|
+
var EMIT_FUZZY_PERCENT_OP_RE = /^[<>](?:0|[1-9][0-9]?|100)%(?:\s|$)/;
|
|
13869
13871
|
var TIME_TILDE_OP_RE = new RegExp(`^${TIME_OPERATOR_PATTERN}(?:\\s|$)`);
|
|
13870
13872
|
var EXACT_TIME_TILDE_OP_RE = new RegExp(`^${TIME_OPERATOR_PATTERN}$`);
|
|
13871
13873
|
var MAP_ENTRY_RE = /^([^:]+?:\s+)(.+)$/;
|
|
@@ -13899,7 +13901,6 @@ function quoteExpectOperators(yaml) {
|
|
|
13899
13901
|
}
|
|
13900
13902
|
return joinLines(lines, eol);
|
|
13901
13903
|
}
|
|
13902
|
-
var YAML_BANG_UNSAFE_OPS = YAML_UNSAFE_OPS.filter((op) => op.startsWith("!"));
|
|
13903
13904
|
var QUOTED_SCALAR_RE = /^"((?:\\.|[^"\\])*)"$/;
|
|
13904
13905
|
function emitUnquotedOperators(yaml) {
|
|
13905
13906
|
const eol = detectNewline(yaml);
|
|
@@ -13936,14 +13937,14 @@ function unescapeQuotedScalar(value) {
|
|
|
13936
13937
|
}
|
|
13937
13938
|
return match[1].replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
13938
13939
|
}
|
|
13939
|
-
function
|
|
13940
|
+
function canEmitUnquotedOperatorValue(value) {
|
|
13940
13941
|
if (/^["']/.test(value)) {
|
|
13941
13942
|
return false;
|
|
13942
13943
|
}
|
|
13943
|
-
if (
|
|
13944
|
+
if (EMIT_FUZZY_PERCENT_OP_RE.test(value) || TIME_TILDE_OP_RE.test(value)) {
|
|
13944
13945
|
return true;
|
|
13945
13946
|
}
|
|
13946
|
-
for (const op of
|
|
13947
|
+
for (const op of EMIT_UNQUOTE_OPS) {
|
|
13947
13948
|
if (value === op || value.startsWith(op + " ")) {
|
|
13948
13949
|
return true;
|
|
13949
13950
|
}
|
|
@@ -13954,10 +13955,10 @@ function canEmitUnquotedExactOperator(value) {
|
|
|
13954
13955
|
if (/^["']/.test(value)) {
|
|
13955
13956
|
return false;
|
|
13956
13957
|
}
|
|
13957
|
-
if (
|
|
13958
|
+
if (EXACT_EMIT_FUZZY_PERCENT_OP_RE.test(value) || EXACT_TIME_TILDE_OP_RE.test(value)) {
|
|
13958
13959
|
return true;
|
|
13959
13960
|
}
|
|
13960
|
-
return
|
|
13961
|
+
return EMIT_UNQUOTE_OPS.some((op) => op === value);
|
|
13961
13962
|
}
|
|
13962
13963
|
function unquoteExpectLineIfNeeded(line) {
|
|
13963
13964
|
const trimmed = line.trimStart();
|
|
@@ -13966,7 +13967,7 @@ function unquoteExpectLineIfNeeded(line) {
|
|
|
13966
13967
|
if (mapMatch) {
|
|
13967
13968
|
const [, prefix, value] = mapMatch;
|
|
13968
13969
|
const inner = unescapeQuotedScalar(value.trim());
|
|
13969
|
-
if (inner !== void 0 &&
|
|
13970
|
+
if (inner !== void 0 && canEmitUnquotedOperatorValue(inner)) {
|
|
13970
13971
|
return leadingWS + prefix + inner;
|
|
13971
13972
|
}
|
|
13972
13973
|
return line;
|
|
@@ -13975,7 +13976,7 @@ function unquoteExpectLineIfNeeded(line) {
|
|
|
13975
13976
|
if (arrayMatch) {
|
|
13976
13977
|
const [, prefix, value] = arrayMatch;
|
|
13977
13978
|
const inner = unescapeQuotedScalar(value.trim());
|
|
13978
|
-
if (inner !== void 0 &&
|
|
13979
|
+
if (inner !== void 0 && canEmitUnquotedOperatorValue(inner)) {
|
|
13979
13980
|
return leadingWS + prefix + inner;
|
|
13980
13981
|
}
|
|
13981
13982
|
}
|
|
@@ -14034,6 +14035,7 @@ function needsOperatorQuoting(value) {
|
|
|
14034
14035
|
return false;
|
|
14035
14036
|
}
|
|
14036
14037
|
var EXACT_FUZZY_PERCENT_OP_RE = /^[>](?:0|[1-9][0-9]?|100)%$/;
|
|
14038
|
+
var EXACT_EMIT_FUZZY_PERCENT_OP_RE = /^[<>](?:0|[1-9][0-9]?|100)%$/;
|
|
14037
14039
|
function needsExactOperatorQuoting(value) {
|
|
14038
14040
|
if (/^["']/.test(value)) {
|
|
14039
14041
|
return false;
|
|
@@ -26656,7 +26658,18 @@ ${helperFactorySource}
|
|
|
26656
26658
|
const __mmt_exampleLabel = ${exampleLiteral};
|
|
26657
26659
|
` + helperDestructure + "\n" + (opts.apiFunctionSource ? `${indentMultiline(opts.apiFunctionSource, " ")}
|
|
26658
26660
|
|
|
26659
|
-
` : "") +
|
|
26661
|
+
` : "") + // Direct API runs only (this wrapper). Report wire request/response for
|
|
26662
|
+
// History; imported call: from tests does not use this wrap.
|
|
26663
|
+
` const __mmt_reportNetwork = (scope, request, response) => {
|
|
26664
|
+
if (typeof __reporter !== 'function') { return; }
|
|
26665
|
+
try {
|
|
26666
|
+
const payload = { scope: scope, request: request || {} };
|
|
26667
|
+
if (response !== undefined) { payload.response = response; }
|
|
26668
|
+
__reporter(payload);
|
|
26669
|
+
} catch (_e) {}
|
|
26670
|
+
};
|
|
26671
|
+
const __mmt_originalSend = send_;
|
|
26672
|
+
const __mmt_originalSendGrpc = typeof sendGrpc_ === 'function' ? sendGrpc_ : null;
|
|
26660
26673
|
send_ = async function(req) {
|
|
26661
26674
|
await checkAbort_();
|
|
26662
26675
|
const __req = req || {};
|
|
@@ -26687,6 +26700,7 @@ ${helperFactorySource}
|
|
|
26687
26700
|
body: __mmt_formatBodyValue(__req.body)
|
|
26688
26701
|
};
|
|
26689
26702
|
console.debug(__mmt_formatSection('Request:', __reqLog));
|
|
26703
|
+
__mmt_reportNetwork('network-request', __req);
|
|
26690
26704
|
try {
|
|
26691
26705
|
const __res = await __mmt_originalSend(req);
|
|
26692
26706
|
// Stop before Response logging when the user cancelled mid-request.
|
|
@@ -26708,6 +26722,9 @@ ${helperFactorySource}
|
|
|
26708
26722
|
if (__warning) {
|
|
26709
26723
|
console.warn(__warning);
|
|
26710
26724
|
}
|
|
26725
|
+
__mmt_reportNetwork(
|
|
26726
|
+
(typeof __status === 'number' && __status < 0) ? 'network-error' : 'network-response',
|
|
26727
|
+
__req, __res);
|
|
26711
26728
|
// Return network failures to the API function so outputs (and the
|
|
26712
26729
|
// tester Response panel) still receive the response; the wrapper
|
|
26713
26730
|
// marks the run failed after outputs are built.
|
|
@@ -26736,6 +26753,8 @@ ${helperFactorySource}
|
|
|
26736
26753
|
};
|
|
26737
26754
|
console.log(__mmt_formatSection('Response:', __resLog));
|
|
26738
26755
|
console.warn(__warning);
|
|
26756
|
+
__mmt_reportNetwork(
|
|
26757
|
+
__res.status < 0 ? 'network-error' : 'network-response', __req, __res);
|
|
26739
26758
|
return __res;
|
|
26740
26759
|
}
|
|
26741
26760
|
const __errorLog = {
|
|
@@ -26750,9 +26769,41 @@ ${helperFactorySource}
|
|
|
26750
26769
|
}
|
|
26751
26770
|
}
|
|
26752
26771
|
console.error(__mmt_formatSection('Response:', __errorLog));
|
|
26772
|
+
__mmt_reportNetwork('network-error', __req, {
|
|
26773
|
+
status: err && typeof err.status === 'number' ? err.status : -1,
|
|
26774
|
+
statusText: err && err.message ? String(err.message) : String(err),
|
|
26775
|
+
body: err && err.body,
|
|
26776
|
+
headers: err && err.headers || {},
|
|
26777
|
+
duration: err && typeof err.duration === 'number' ? err.duration : -1
|
|
26778
|
+
});
|
|
26753
26779
|
throw err;
|
|
26754
26780
|
}
|
|
26755
26781
|
};
|
|
26782
|
+
if (__mmt_originalSendGrpc) {
|
|
26783
|
+
sendGrpc_ = async function(req) {
|
|
26784
|
+
await checkAbort_();
|
|
26785
|
+
const __req = req || {};
|
|
26786
|
+
__mmt_reportNetwork('network-request', __req);
|
|
26787
|
+
try {
|
|
26788
|
+
const __res = await __mmt_originalSendGrpc(req);
|
|
26789
|
+
await checkAbort_();
|
|
26790
|
+
__mmt_reportNetwork('network-response', __req, __res);
|
|
26791
|
+
return __res;
|
|
26792
|
+
} catch (err) {
|
|
26793
|
+
if (err && (err.kind === 'test-abort' || (typeof isTestAbortError === 'function' && isTestAbortError(err)))) {
|
|
26794
|
+
throw err;
|
|
26795
|
+
}
|
|
26796
|
+
__mmt_reportNetwork('network-error', __req, {
|
|
26797
|
+
status: err && typeof err.status === 'number' ? err.status : -1,
|
|
26798
|
+
statusText: err && err.message ? String(err.message) : String(err),
|
|
26799
|
+
body: err && err.body,
|
|
26800
|
+
headers: err && err.headers || {},
|
|
26801
|
+
duration: err && typeof err.duration === 'number' ? err.duration : -1
|
|
26802
|
+
});
|
|
26803
|
+
throw err;
|
|
26804
|
+
}
|
|
26805
|
+
};
|
|
26806
|
+
}
|
|
26756
26807
|
|
|
26757
26808
|
try {
|
|
26758
26809
|
if (__mmt_exampleLabel) {
|
|
@@ -26814,6 +26865,7 @@ ${helperFactorySource}
|
|
|
26814
26865
|
return result;
|
|
26815
26866
|
} finally {
|
|
26816
26867
|
send_ = __mmt_originalSend;
|
|
26868
|
+
if (__mmt_originalSendGrpc) { sendGrpc_ = __mmt_originalSendGrpc; }
|
|
26817
26869
|
}
|
|
26818
26870
|
})();`;
|
|
26819
26871
|
}
|
|
@@ -26866,10 +26918,15 @@ async function executeApi(prepared, options, preLogs) {
|
|
|
26866
26918
|
exampleOutputs,
|
|
26867
26919
|
checkTitle: fileDisplayName
|
|
26868
26920
|
});
|
|
26869
|
-
const
|
|
26870
|
-
|
|
26871
|
-
|
|
26921
|
+
const apiReporter = typeof options.reporter === "function" ? (event) => {
|
|
26922
|
+
const isSuiteChild = options.__mmtIsSuiteBundleChildRun === true;
|
|
26923
|
+
if (isSuiteChild && event && event.scope !== "setenv") {
|
|
26924
|
+
return;
|
|
26872
26925
|
}
|
|
26926
|
+
options.reporter({
|
|
26927
|
+
...event,
|
|
26928
|
+
id: event.id || options.id
|
|
26929
|
+
});
|
|
26873
26930
|
} : void 0;
|
|
26874
26931
|
const result = await runGeneratedJs(
|
|
26875
26932
|
"run-api",
|
|
@@ -26880,7 +26937,7 @@ async function executeApi(prepared, options, preLogs) {
|
|
|
26880
26937
|
void 0,
|
|
26881
26938
|
options.id,
|
|
26882
26939
|
fileLoader,
|
|
26883
|
-
|
|
26940
|
+
apiReporter,
|
|
26884
26941
|
options.abortSignal,
|
|
26885
26942
|
void 0,
|
|
26886
26943
|
prepared.filePath ? prepared.filePath.split(/[/\\]/).slice(0, -1).join("/") : void 0,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mmt-mcp",
|
|
3
|
-
"version": "1.45.
|
|
3
|
+
"version": "1.45.2-pre",
|
|
4
4
|
"description": "Multimeter MCP server for Cursor, Copilot, and Claude. Scaffold, validate, format, and run YAML .mmt API tests. Do not invent .mmt syntax.",
|
|
5
5
|
"mcpName": "io.github.mshobeyri/multimeter",
|
|
6
6
|
"type": "module",
|