@rogatio/cli 5.14.0 → 5.15.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/dist/node/index.js +213 -21
- package/package.json +1 -1
package/dist/node/index.js
CHANGED
|
@@ -11,6 +11,117 @@ import * as path from "node:path";
|
|
|
11
11
|
|
|
12
12
|
// packages/schema/dist/node/index.js
|
|
13
13
|
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
14
|
+
function skipBalancedGroup(source, start) {
|
|
15
|
+
let depth = 0;
|
|
16
|
+
let index = start;
|
|
17
|
+
while (index < source.length) {
|
|
18
|
+
const char = source[index];
|
|
19
|
+
if (char === "\\") {
|
|
20
|
+
index += 2;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (char === "(") depth += 1;
|
|
24
|
+
else if (char === ")") {
|
|
25
|
+
depth -= 1;
|
|
26
|
+
if (depth === 0) return index;
|
|
27
|
+
}
|
|
28
|
+
index += 1;
|
|
29
|
+
}
|
|
30
|
+
return source.length;
|
|
31
|
+
}
|
|
32
|
+
function countCapturingGroups(urlRegex) {
|
|
33
|
+
let count = 0;
|
|
34
|
+
let index = 0;
|
|
35
|
+
while (index < urlRegex.length) {
|
|
36
|
+
const char = urlRegex[index];
|
|
37
|
+
if (char === "\\") {
|
|
38
|
+
index += 2;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (char === "(") {
|
|
42
|
+
if (urlRegex[index + 1] === "?") {
|
|
43
|
+
index = skipBalancedGroup(urlRegex, index);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
count += 1;
|
|
47
|
+
}
|
|
48
|
+
index += 1;
|
|
49
|
+
}
|
|
50
|
+
return count;
|
|
51
|
+
}
|
|
52
|
+
function validateCaptureTemplate(template, urlRegex) {
|
|
53
|
+
const groups = countCapturingGroups(urlRegex);
|
|
54
|
+
const issues = [];
|
|
55
|
+
for (let index = 0; index < template.length; index += 1) {
|
|
56
|
+
if (template[index] !== "$") continue;
|
|
57
|
+
const next = template[index + 1];
|
|
58
|
+
if (next === "$") {
|
|
59
|
+
index += 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (next === void 0 || next < "0" || next > "9") {
|
|
63
|
+
issues.push({
|
|
64
|
+
code: "invalid-syntax",
|
|
65
|
+
message: "Capture references must use $1 through $9; use $$ for a literal $.",
|
|
66
|
+
offset: index,
|
|
67
|
+
groups
|
|
68
|
+
});
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const referenced = Number(next);
|
|
72
|
+
if (referenced === 0 || (template[index + 2] ?? "") >= "0" && (template[index + 2] ?? "") <= "9") {
|
|
73
|
+
issues.push({
|
|
74
|
+
code: "invalid-syntax",
|
|
75
|
+
message: "Capture references must use one digit: $1 through $9.",
|
|
76
|
+
offset: index,
|
|
77
|
+
referenced,
|
|
78
|
+
groups
|
|
79
|
+
});
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (referenced > groups) {
|
|
83
|
+
issues.push({
|
|
84
|
+
code: "out-of-range",
|
|
85
|
+
message: `Capture group $${referenced} is not defined by the URL pattern, which has ${groups} group${groups === 1 ? "" : "s"}.`,
|
|
86
|
+
offset: index,
|
|
87
|
+
referenced,
|
|
88
|
+
groups
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return issues;
|
|
93
|
+
}
|
|
94
|
+
function substituteUrlCaptures(template, captures) {
|
|
95
|
+
let output = "";
|
|
96
|
+
for (let index = 0; index < template.length; index += 1) {
|
|
97
|
+
const char = template[index];
|
|
98
|
+
if (char !== "$") {
|
|
99
|
+
output += char;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const next = template[index + 1];
|
|
103
|
+
if (next === "$") {
|
|
104
|
+
output += "$";
|
|
105
|
+
index += 1;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (next !== void 0 && next >= "1" && next <= "9") {
|
|
109
|
+
output += captures[Number(next) - 1] ?? "";
|
|
110
|
+
index += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
output += "$";
|
|
114
|
+
}
|
|
115
|
+
return output;
|
|
116
|
+
}
|
|
117
|
+
function matchUrlCaptures(urlRegex, url) {
|
|
118
|
+
try {
|
|
119
|
+
const match = new RegExp(urlRegex).exec(url);
|
|
120
|
+
return match === null ? null : match.slice(1);
|
|
121
|
+
} catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
14
125
|
function hasControl(value) {
|
|
15
126
|
for (let index = 0; index < value.length; index += 1) {
|
|
16
127
|
const code = value.charCodeAt(index);
|
|
@@ -741,17 +852,25 @@ function semanticIssues(project) {
|
|
|
741
852
|
params: {}
|
|
742
853
|
});
|
|
743
854
|
} else {
|
|
855
|
+
const destinationPath = `${rulePath}/redirect/destination`;
|
|
744
856
|
for (const issue of validateRedirectDestination(
|
|
745
857
|
destination,
|
|
746
858
|
rule.urlRegex
|
|
747
859
|
)) {
|
|
748
860
|
issues.push({
|
|
749
|
-
instancePath:
|
|
861
|
+
instancePath: destinationPath,
|
|
750
862
|
keyword: issue.code,
|
|
751
863
|
message: issue.message,
|
|
752
864
|
params: {}
|
|
753
865
|
});
|
|
754
866
|
}
|
|
867
|
+
issues.push(
|
|
868
|
+
...captureValidationIssues(
|
|
869
|
+
destination,
|
|
870
|
+
rule.urlRegex,
|
|
871
|
+
destinationPath
|
|
872
|
+
)
|
|
873
|
+
);
|
|
755
874
|
}
|
|
756
875
|
}
|
|
757
876
|
const effectiveOrigins = /* @__PURE__ */ new Set();
|
|
@@ -797,6 +916,14 @@ function semanticIssues(project) {
|
|
|
797
916
|
message: "query param value is required for set",
|
|
798
917
|
params: {}
|
|
799
918
|
});
|
|
919
|
+
} else {
|
|
920
|
+
issues.push(
|
|
921
|
+
...captureValidationIssues(
|
|
922
|
+
param.value,
|
|
923
|
+
rule.urlRegex,
|
|
924
|
+
`${rulePath}/action/params/${p}/value`
|
|
925
|
+
)
|
|
926
|
+
);
|
|
800
927
|
}
|
|
801
928
|
} else if (param.value !== void 0) {
|
|
802
929
|
issues.push({
|
|
@@ -821,6 +948,15 @@ function semanticIssues(project) {
|
|
|
821
948
|
}
|
|
822
949
|
});
|
|
823
950
|
}
|
|
951
|
+
if ((rule.headerOperation ?? "set") !== "remove" && typeof rule.headerValue === "string") {
|
|
952
|
+
issues.push(
|
|
953
|
+
...captureValidationIssues(
|
|
954
|
+
rule.headerValue,
|
|
955
|
+
rule.urlRegex,
|
|
956
|
+
`${rulePath}/headerValue`
|
|
957
|
+
)
|
|
958
|
+
);
|
|
959
|
+
}
|
|
824
960
|
}
|
|
825
961
|
if (rule.type === "response-body") {
|
|
826
962
|
const action2 = rule.responseBody;
|
|
@@ -854,6 +990,14 @@ function semanticIssues(project) {
|
|
|
854
990
|
message: "Replace body must not contain lone UTF-16 surrogates.",
|
|
855
991
|
params: {}
|
|
856
992
|
});
|
|
993
|
+
} else {
|
|
994
|
+
issues.push(
|
|
995
|
+
...captureValidationIssues(
|
|
996
|
+
action2.body,
|
|
997
|
+
rule.urlRegex,
|
|
998
|
+
`${actionPath}/body`
|
|
999
|
+
)
|
|
1000
|
+
);
|
|
857
1001
|
}
|
|
858
1002
|
} else if ("replacements" in action2 && Array.isArray(action2.replacements)) {
|
|
859
1003
|
if (action2.replacements.length === 0) {
|
|
@@ -927,6 +1071,14 @@ function semanticIssues(project) {
|
|
|
927
1071
|
message: "Replace body must not contain lone UTF-16 surrogates.",
|
|
928
1072
|
params: {}
|
|
929
1073
|
});
|
|
1074
|
+
} else {
|
|
1075
|
+
issues.push(
|
|
1076
|
+
...captureValidationIssues(
|
|
1077
|
+
action2.body,
|
|
1078
|
+
rule.urlRegex,
|
|
1079
|
+
`${actionPath}/body`
|
|
1080
|
+
)
|
|
1081
|
+
);
|
|
930
1082
|
}
|
|
931
1083
|
}
|
|
932
1084
|
if (action2.mode === "regex") {
|
|
@@ -1059,7 +1211,19 @@ function semanticIssues(project) {
|
|
|
1059
1211
|
}
|
|
1060
1212
|
return issues;
|
|
1061
1213
|
}
|
|
1062
|
-
function
|
|
1214
|
+
function captureValidationIssues(value, urlRegex, instancePath) {
|
|
1215
|
+
return validateCaptureTemplate(value, urlRegex).map((issue) => ({
|
|
1216
|
+
instancePath,
|
|
1217
|
+
keyword: `schema.capture-${issue.code}`,
|
|
1218
|
+
message: issue.message,
|
|
1219
|
+
params: {
|
|
1220
|
+
offset: issue.offset,
|
|
1221
|
+
groups: issue.groups,
|
|
1222
|
+
...issue.referenced === void 0 ? {} : { referenced: issue.referenced }
|
|
1223
|
+
}
|
|
1224
|
+
}));
|
|
1225
|
+
}
|
|
1226
|
+
function skipBalancedGroup2(source, start) {
|
|
1063
1227
|
let depth = 0;
|
|
1064
1228
|
let index = start;
|
|
1065
1229
|
const length = source.length;
|
|
@@ -1079,7 +1243,7 @@ function skipBalancedGroup(source, start) {
|
|
|
1079
1243
|
}
|
|
1080
1244
|
return length;
|
|
1081
1245
|
}
|
|
1082
|
-
function
|
|
1246
|
+
function countCapturingGroups2(urlRegex) {
|
|
1083
1247
|
let count = 0;
|
|
1084
1248
|
let index = 0;
|
|
1085
1249
|
const length = urlRegex.length;
|
|
@@ -1091,7 +1255,7 @@ function countCapturingGroups(urlRegex) {
|
|
|
1091
1255
|
}
|
|
1092
1256
|
if (char === "(") {
|
|
1093
1257
|
if (urlRegex[index + 1] === "?") {
|
|
1094
|
-
index =
|
|
1258
|
+
index = skipBalancedGroup2(urlRegex, index);
|
|
1095
1259
|
continue;
|
|
1096
1260
|
}
|
|
1097
1261
|
count += 1;
|
|
@@ -1147,7 +1311,7 @@ function validateRedirectDestination(destination, urlRegex) {
|
|
|
1147
1311
|
});
|
|
1148
1312
|
return issues;
|
|
1149
1313
|
}
|
|
1150
|
-
const groups =
|
|
1314
|
+
const groups = countCapturingGroups2(urlRegex);
|
|
1151
1315
|
const backreference = /\\([1-9])/g;
|
|
1152
1316
|
let match = backreference.exec(destination);
|
|
1153
1317
|
while (match !== null) {
|
|
@@ -20717,6 +20881,7 @@ function authorizeExact(preset, value) {
|
|
|
20717
20881
|
kind: grant.kind,
|
|
20718
20882
|
target: grant.target,
|
|
20719
20883
|
method: grant.method,
|
|
20884
|
+
urlRegex: matcher.matcher.urlRegex.source,
|
|
20720
20885
|
presetDigest: preset.digest
|
|
20721
20886
|
})
|
|
20722
20887
|
};
|
|
@@ -23383,14 +23548,14 @@ function normalizeOptions(raw) {
|
|
|
23383
23548
|
}
|
|
23384
23549
|
maxCases = maxCasesProperty.value;
|
|
23385
23550
|
}
|
|
23386
|
-
let
|
|
23551
|
+
let previewAction2;
|
|
23387
23552
|
if (previewProperty.present) {
|
|
23388
23553
|
if (previewProperty.value !== void 0 && typeof previewProperty.value !== "function") {
|
|
23389
23554
|
return { ok: false };
|
|
23390
23555
|
}
|
|
23391
|
-
|
|
23556
|
+
previewAction2 = previewProperty.value;
|
|
23392
23557
|
}
|
|
23393
|
-
return { ok: true, maxCases, previewAction };
|
|
23558
|
+
return { ok: true, maxCases, previewAction: previewAction2 };
|
|
23394
23559
|
}
|
|
23395
23560
|
function dryRunProject(operations, cases, options) {
|
|
23396
23561
|
const normalizedOptions = normalizeOptions(options);
|
|
@@ -25182,17 +25347,44 @@ function usageError(message) {
|
|
|
25182
25347
|
return `Error: ${message}
|
|
25183
25348
|
`;
|
|
25184
25349
|
}
|
|
25185
|
-
function
|
|
25186
|
-
|
|
25187
|
-
|
|
25188
|
-
|
|
25189
|
-
|
|
25190
|
-
|
|
25191
|
-
|
|
25192
|
-
|
|
25193
|
-
|
|
25194
|
-
|
|
25195
|
-
)
|
|
25350
|
+
function previewAction(operation, url) {
|
|
25351
|
+
const captures = matchUrlCaptures(operation.matcher.urlRegex.source, url);
|
|
25352
|
+
if (captures === null) return null;
|
|
25353
|
+
const expand = (value) => substituteUrlCaptures(value, captures);
|
|
25354
|
+
if (operation.kind === "redirect") {
|
|
25355
|
+
return {
|
|
25356
|
+
kind: "redirect",
|
|
25357
|
+
summary: expand(operation.redirect.destination)
|
|
25358
|
+
};
|
|
25359
|
+
}
|
|
25360
|
+
if (operation.kind === "query") {
|
|
25361
|
+
const values = operation.action.params.map(
|
|
25362
|
+
(param) => param.operation === "remove" ? `${param.name}=<removed>` : `${param.name}=${expand(param.value ?? "")}`
|
|
25363
|
+
).join(", ");
|
|
25364
|
+
return { kind: "query", summary: values };
|
|
25365
|
+
}
|
|
25366
|
+
if (operation.kind === "header") {
|
|
25367
|
+
if (operation.header.operation === "remove") {
|
|
25368
|
+
return { kind: "header", summary: `${operation.header.name}=<removed>` };
|
|
25369
|
+
}
|
|
25370
|
+
return {
|
|
25371
|
+
kind: "header",
|
|
25372
|
+
summary: `${operation.header.name}=${expand(operation.header.value ?? "")}`
|
|
25373
|
+
};
|
|
25374
|
+
}
|
|
25375
|
+
if (operation.kind === "request-body" && operation.requestBody.mode === "replace") {
|
|
25376
|
+
return {
|
|
25377
|
+
kind: operation.kind,
|
|
25378
|
+
summary: expand(operation.requestBody.body)
|
|
25379
|
+
};
|
|
25380
|
+
}
|
|
25381
|
+
if (operation.kind === "response-body" && "mode" in operation.responseBody && operation.responseBody.mode === "replace") {
|
|
25382
|
+
return {
|
|
25383
|
+
kind: operation.kind,
|
|
25384
|
+
summary: expand(operation.responseBody.body)
|
|
25385
|
+
};
|
|
25386
|
+
}
|
|
25387
|
+
return null;
|
|
25196
25388
|
}
|
|
25197
25389
|
function isUrl(value) {
|
|
25198
25390
|
return parseTestUrl(value).ok;
|
|
@@ -25248,7 +25440,7 @@ function addDefaults(cases, defaultMethod, defaultResourceType) {
|
|
|
25248
25440
|
);
|
|
25249
25441
|
}
|
|
25250
25442
|
function resultOptions(maxCases) {
|
|
25251
|
-
const options = {};
|
|
25443
|
+
const options = { previewAction };
|
|
25252
25444
|
if (maxCases !== void 0) options.maxCases = maxCases;
|
|
25253
25445
|
return options;
|
|
25254
25446
|
}
|
|
@@ -25444,7 +25636,7 @@ async function testCommandImpl(args, stdinInput, captureOutput, options = {}) {
|
|
|
25444
25636
|
defaultResourceType
|
|
25445
25637
|
);
|
|
25446
25638
|
const dryRunResult = dryRunProject(
|
|
25447
|
-
|
|
25639
|
+
compileResult.operations,
|
|
25448
25640
|
testCases,
|
|
25449
25641
|
resultOptions(maxCases)
|
|
25450
25642
|
);
|
package/package.json
CHANGED