@requesto/cli 1.9.0 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +116 -32
- package/dist/sandbox-worker.js +193 -4
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -56,6 +56,9 @@ var require_variable_substitution = __commonJS({
|
|
|
56
56
|
"use strict";
|
|
57
57
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
58
|
exports.substituteVariables = substituteVariables;
|
|
59
|
+
exports.substituteJsonVariables = substituteJsonVariables;
|
|
60
|
+
exports.isNumericLiteral = isNumericLiteral2;
|
|
61
|
+
exports.inferType = inferType3;
|
|
59
62
|
exports.substituteInRequest = substituteInRequest2;
|
|
60
63
|
exports.substituteInAuth = substituteInAuth2;
|
|
61
64
|
function substituteVariables(text, environment) {
|
|
@@ -63,17 +66,44 @@ var require_variable_substitution = __commonJS({
|
|
|
63
66
|
return text;
|
|
64
67
|
const values = getResolvedValues(environment);
|
|
65
68
|
let result = text;
|
|
66
|
-
for (const [key,
|
|
69
|
+
for (const [key, entry] of values) {
|
|
67
70
|
const pattern = new RegExp(`{{\\s*${escapeRegex(key)}\\s*}}`, "g");
|
|
68
|
-
result = result.replace(pattern, value);
|
|
71
|
+
result = result.replace(pattern, entry.value);
|
|
69
72
|
}
|
|
70
73
|
return result;
|
|
71
74
|
}
|
|
75
|
+
function substituteJsonVariables(text, environment) {
|
|
76
|
+
if (!environment)
|
|
77
|
+
return text;
|
|
78
|
+
const values = getResolvedValues(environment);
|
|
79
|
+
let result = text;
|
|
80
|
+
for (const [key, entry] of values) {
|
|
81
|
+
const keyPattern = escapeRegex(key);
|
|
82
|
+
const quoted = new RegExp(`"{{\\s*${keyPattern}\\s*}}"`, "g");
|
|
83
|
+
const literal = typedJsonLiteral(entry.value, entry.type);
|
|
84
|
+
result = result.replace(quoted, literal ?? JSON.stringify(entry.value));
|
|
85
|
+
const plain = new RegExp(`{{\\s*${keyPattern}\\s*}}`, "g");
|
|
86
|
+
result = result.replace(plain, entry.value);
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
function typedJsonLiteral(value, type2) {
|
|
91
|
+
if (type2 === "boolean") {
|
|
92
|
+
return value === "true" || value === "false" ? value : null;
|
|
93
|
+
}
|
|
94
|
+
if (type2 === "number") {
|
|
95
|
+
return isNumericLiteral2(value) ? value : null;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
72
99
|
function getResolvedValues(environment) {
|
|
73
100
|
const raw = /* @__PURE__ */ new Map();
|
|
74
101
|
for (const variable of environment.variables) {
|
|
75
102
|
if (variable.enabled) {
|
|
76
|
-
raw.set(variable.key,
|
|
103
|
+
raw.set(variable.key, {
|
|
104
|
+
value: variable.currentValue ?? variable.value,
|
|
105
|
+
type: variable.type
|
|
106
|
+
});
|
|
77
107
|
}
|
|
78
108
|
}
|
|
79
109
|
const resolved = /* @__PURE__ */ new Map();
|
|
@@ -82,33 +112,55 @@ var require_variable_substitution = __commonJS({
|
|
|
82
112
|
const memo = resolved.get(key);
|
|
83
113
|
if (memo !== void 0)
|
|
84
114
|
return memo;
|
|
85
|
-
if (visiting.has(key))
|
|
86
|
-
|
|
115
|
+
if (visiting.has(key)) {
|
|
116
|
+
const entry2 = raw.get(key);
|
|
117
|
+
return { value: entry2?.value ?? "", type: entry2?.type };
|
|
118
|
+
}
|
|
87
119
|
visiting.add(key);
|
|
88
|
-
const
|
|
89
|
-
const value =
|
|
120
|
+
const entry = raw.get(key) ?? { value: "", type: void 0 };
|
|
121
|
+
const value = entry.value.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, (match, name) => {
|
|
90
122
|
const referenced = name.trim();
|
|
91
|
-
return raw.has(referenced) ? resolve3(referenced) : match;
|
|
123
|
+
return raw.has(referenced) ? resolve3(referenced).value : match;
|
|
92
124
|
});
|
|
93
125
|
visiting.delete(key);
|
|
94
|
-
|
|
95
|
-
|
|
126
|
+
const result = { value, type: entry.type };
|
|
127
|
+
resolved.set(key, result);
|
|
128
|
+
return result;
|
|
96
129
|
};
|
|
97
130
|
for (const key of raw.keys())
|
|
98
131
|
resolve3(key);
|
|
99
132
|
return resolved;
|
|
100
133
|
}
|
|
134
|
+
function isNumericLiteral2(value) {
|
|
135
|
+
return /^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?$/.test(value.trim());
|
|
136
|
+
}
|
|
137
|
+
function inferType3(value) {
|
|
138
|
+
if (typeof value === "number") {
|
|
139
|
+
return Number.isFinite(value) ? "number" : "string";
|
|
140
|
+
}
|
|
141
|
+
if (typeof value === "boolean")
|
|
142
|
+
return "boolean";
|
|
143
|
+
if (typeof value === "string") {
|
|
144
|
+
if (value === "true" || value === "false")
|
|
145
|
+
return "boolean";
|
|
146
|
+
if (isNumericLiteral2(value))
|
|
147
|
+
return "number";
|
|
148
|
+
}
|
|
149
|
+
return "string";
|
|
150
|
+
}
|
|
101
151
|
function escapeRegex(str2) {
|
|
102
152
|
return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
103
153
|
}
|
|
104
154
|
function substituteInRequest2(request, environment) {
|
|
155
|
+
const jsonMode = request.bodyType === "json" || !request.bodyType && !!request.body;
|
|
156
|
+
const bodySub = jsonMode ? substituteJsonVariables : substituteVariables;
|
|
105
157
|
return {
|
|
106
|
-
url:
|
|
158
|
+
url: substituteUrlVariables(request.url, environment),
|
|
107
159
|
headers: request.headers ? Object.fromEntries(Object.entries(request.headers).map(([key, value]) => [
|
|
108
160
|
key,
|
|
109
161
|
substituteVariables(value, environment)
|
|
110
162
|
])) : void 0,
|
|
111
|
-
body: request.body ?
|
|
163
|
+
body: request.body ? bodySub(request.body, environment) : void 0,
|
|
112
164
|
formDataEntries: request.formDataEntries ? request.formDataEntries.map((entry) => ({
|
|
113
165
|
...entry,
|
|
114
166
|
key: substituteVariables(entry.key, environment),
|
|
@@ -116,6 +168,21 @@ var require_variable_substitution = __commonJS({
|
|
|
116
168
|
})) : void 0
|
|
117
169
|
};
|
|
118
170
|
}
|
|
171
|
+
function substituteUrlVariables(url, environment) {
|
|
172
|
+
const substituted = substituteVariables(url, environment);
|
|
173
|
+
if (!environment || !substituted.includes("="))
|
|
174
|
+
return substituted;
|
|
175
|
+
try {
|
|
176
|
+
const parsed = new URL(substituted);
|
|
177
|
+
const variables = parsed.searchParams.get("variables");
|
|
178
|
+
if (variables && variables.includes("{{")) {
|
|
179
|
+
parsed.searchParams.set("variables", substituteJsonVariables(variables, environment));
|
|
180
|
+
return parsed.toString();
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
}
|
|
184
|
+
return substituted;
|
|
185
|
+
}
|
|
119
186
|
function substituteInAuth2(auth, environment) {
|
|
120
187
|
if (!auth)
|
|
121
188
|
return auth;
|
|
@@ -101351,7 +101418,7 @@ var require_proxy_service = __commonJS({
|
|
|
101351
101418
|
const { method, url, headers, body, bodyType, formDataEntries, auth, insecureTls } = req;
|
|
101352
101419
|
const hasEnvOverride = Object.prototype.hasOwnProperty.call(opts, "environment");
|
|
101353
101420
|
const effectiveEnv = hasEnvOverride ? opts.environment ?? null : this.environmentService.getActive();
|
|
101354
|
-
const substituted = (0, variable_substitution_1.substituteInRequest)({ url, headers, body, formDataEntries }, effectiveEnv);
|
|
101421
|
+
const substituted = (0, variable_substitution_1.substituteInRequest)({ url, headers, body, bodyType, formDataEntries }, effectiveEnv);
|
|
101355
101422
|
const substitutedAuth = (0, variable_substitution_1.substituteInAuth)(auth, effectiveEnv);
|
|
101356
101423
|
if (!isValidUrl(substituted.url)) {
|
|
101357
101424
|
throw new Error(`Invalid URL format: ${substituted.url}`);
|
|
@@ -101426,7 +101493,7 @@ var require_proxy_service = __commonJS({
|
|
|
101426
101493
|
if (!isValidUrl(url)) {
|
|
101427
101494
|
throw new Error("Invalid URL format");
|
|
101428
101495
|
}
|
|
101429
|
-
const substituted = this.environmentService.substituteInRequest({ url, headers, body, formDataEntries });
|
|
101496
|
+
const substituted = this.environmentService.substituteInRequest({ url, headers, body, bodyType, formDataEntries });
|
|
101430
101497
|
const substitutedAuth = this.environmentService.substituteInAuth(auth);
|
|
101431
101498
|
const authenticated = await (0, auth_1.applyAuthentication)(substitutedAuth, substituted.headers, substituted.url, this.oauthResolver);
|
|
101432
101499
|
const built = buildBodyAndHeaders({
|
|
@@ -116576,16 +116643,21 @@ function requireLoader() {
|
|
|
116576
116643
|
state.result += _result;
|
|
116577
116644
|
}
|
|
116578
116645
|
}
|
|
116646
|
+
function chargeMergeWork(state) {
|
|
116647
|
+
state.totalMergeKeys++;
|
|
116648
|
+
if (state.maxTotalMergeKeys !== -1 && state.totalMergeKeys > state.maxTotalMergeKeys) {
|
|
116649
|
+
throwError(state, "merge keys exceeded maxTotalMergeKeys (" + state.maxTotalMergeKeys + ")");
|
|
116650
|
+
}
|
|
116651
|
+
}
|
|
116579
116652
|
function mergeMappings(state, destination, source, overridableKeys) {
|
|
116580
116653
|
if (!common2.isObject(source)) {
|
|
116581
116654
|
throwError(state, "cannot merge mappings; the provided source object is unacceptable");
|
|
116582
116655
|
}
|
|
116656
|
+
chargeMergeWork(state);
|
|
116583
116657
|
const sourceKeys = Object.keys(source);
|
|
116584
116658
|
for (let index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
|
|
116585
116659
|
const key = sourceKeys[index];
|
|
116586
|
-
|
|
116587
|
-
throwError(state, "merge keys exceeded maxTotalMergeKeys (" + state.maxTotalMergeKeys + ")");
|
|
116588
|
-
}
|
|
116660
|
+
chargeMergeWork(state);
|
|
116589
116661
|
if (!_hasOwnProperty.call(destination, key)) {
|
|
116590
116662
|
setProperty(destination, key, source[key]);
|
|
116591
116663
|
overridableKeys[key] = true;
|
|
@@ -116613,6 +116685,9 @@ function requireLoader() {
|
|
|
116613
116685
|
}
|
|
116614
116686
|
if (keyTag === "tag:yaml.org,2002:merge") {
|
|
116615
116687
|
if (Array.isArray(valueNode)) {
|
|
116688
|
+
if (valueNode.length > 100) {
|
|
116689
|
+
throwError(state, "abnormal merge sequence size");
|
|
116690
|
+
}
|
|
116616
116691
|
for (let index = 0, quantity = valueNode.length; index < quantity; index += 1) {
|
|
116617
116692
|
mergeMappings(state, _result, valueNode[index], overridableKeys);
|
|
116618
116693
|
}
|
|
@@ -131271,12 +131346,13 @@ function isExcluded(collection, selectors) {
|
|
|
131271
131346
|
return lower2.includes(collection.name.toLowerCase()) || lower2.includes(collection.id.toLowerCase());
|
|
131272
131347
|
}
|
|
131273
131348
|
function applyEnvOverrides(env2, overrides) {
|
|
131274
|
-
|
|
131349
|
+
const { envOverrides, envTypes } = overrides;
|
|
131350
|
+
if (!env2 || Object.keys(envOverrides).length === 0)
|
|
131275
131351
|
return env2;
|
|
131276
|
-
const variables = env2.variables.map((v) => Object.prototype.hasOwnProperty.call(
|
|
131277
|
-
for (const [key, value] of Object.entries(
|
|
131352
|
+
const variables = env2.variables.map((v) => Object.prototype.hasOwnProperty.call(envOverrides, v.key) ? { ...v, currentValue: envOverrides[v.key], type: envTypes?.[v.key] ?? v.type } : v);
|
|
131353
|
+
for (const [key, value] of Object.entries(envOverrides)) {
|
|
131278
131354
|
if (!variables.some((v) => v.key === key)) {
|
|
131279
|
-
variables.push({ key, value, currentValue: value, enabled: true });
|
|
131355
|
+
variables.push({ key, value, currentValue: value, enabled: true, type: envTypes?.[key] ?? "string" });
|
|
131280
131356
|
}
|
|
131281
131357
|
}
|
|
131282
131358
|
return { ...env2, variables };
|
|
@@ -131335,6 +131411,7 @@ async function runCollections(opts) {
|
|
|
131335
131411
|
url: proxyReq.url,
|
|
131336
131412
|
headers: proxyReq.headers,
|
|
131337
131413
|
body: proxyReq.body,
|
|
131414
|
+
bodyType: proxyReq.bodyType,
|
|
131338
131415
|
formDataEntries: proxyReq.formDataEntries
|
|
131339
131416
|
}, liveEnv);
|
|
131340
131417
|
const auth = (0, import_variable_substitution.substituteInAuth)(proxyReq.auth, liveEnv);
|
|
@@ -131354,7 +131431,7 @@ async function runCollections(opts) {
|
|
|
131354
131431
|
duration: response.duration
|
|
131355
131432
|
}, { method: proxyReq.method, url: proxyReq.url, headers: proxyReq.headers, body: proxyReq.body }, envRecord(liveEnv));
|
|
131356
131433
|
testResults = outcome.testResults;
|
|
131357
|
-
liveEnv = applyEnvOverrides(liveEnv, outcome
|
|
131434
|
+
liveEnv = applyEnvOverrides(liveEnv, outcome);
|
|
131358
131435
|
}
|
|
131359
131436
|
const allPassed = testResults.every((t2) => t2.passed);
|
|
131360
131437
|
const status = allPassed ? "passed" : "failed";
|
|
@@ -131394,6 +131471,9 @@ async function runCollections(opts) {
|
|
|
131394
131471
|
};
|
|
131395
131472
|
}
|
|
131396
131473
|
|
|
131474
|
+
// ../../packages/engine/dist/scripts/sandbox-core.js
|
|
131475
|
+
var import_variable_substitution2 = __toESM(require_variable_substitution(), 1);
|
|
131476
|
+
|
|
131397
131477
|
// ../../packages/engine/dist/scripts/node-scripts.js
|
|
131398
131478
|
import { Worker } from "node:worker_threads";
|
|
131399
131479
|
import fs2 from "node:fs";
|
|
@@ -131435,7 +131515,7 @@ function runInWorker(message) {
|
|
|
131435
131515
|
}
|
|
131436
131516
|
async function runPreRequestScript(script, env2, request) {
|
|
131437
131517
|
if (!script.trim())
|
|
131438
|
-
return {};
|
|
131518
|
+
return { envOverrides: {}, envTypes: {} };
|
|
131439
131519
|
const result = await runInWorker({
|
|
131440
131520
|
type: "pre-request",
|
|
131441
131521
|
script,
|
|
@@ -131444,12 +131524,12 @@ async function runPreRequestScript(script, env2, request) {
|
|
|
131444
131524
|
if ("error" in result)
|
|
131445
131525
|
throw new Error(result.error);
|
|
131446
131526
|
if ("envOverrides" in result)
|
|
131447
|
-
return result.envOverrides;
|
|
131448
|
-
return {};
|
|
131527
|
+
return { envOverrides: result.envOverrides, envTypes: result.envTypes };
|
|
131528
|
+
return { envOverrides: {}, envTypes: {} };
|
|
131449
131529
|
}
|
|
131450
131530
|
async function runTestScript(script, response, request, env2) {
|
|
131451
131531
|
if (!script.trim())
|
|
131452
|
-
return { testResults: [], envOverrides: {} };
|
|
131532
|
+
return { testResults: [], envOverrides: {}, envTypes: {} };
|
|
131453
131533
|
const result = await runInWorker({
|
|
131454
131534
|
type: "test",
|
|
131455
131535
|
script,
|
|
@@ -131457,15 +131537,19 @@ async function runTestScript(script, response, request, env2) {
|
|
|
131457
131537
|
});
|
|
131458
131538
|
if ("error" in result)
|
|
131459
131539
|
throw new Error(result.error);
|
|
131460
|
-
if ("testResults" in result)
|
|
131461
|
-
return { testResults: result.testResults, envOverrides: result.envOverrides };
|
|
131462
|
-
|
|
131540
|
+
if ("testResults" in result) {
|
|
131541
|
+
return { testResults: result.testResults, envOverrides: result.envOverrides, envTypes: result.envTypes ?? {} };
|
|
131542
|
+
}
|
|
131543
|
+
return { testResults: [], envOverrides: {}, envTypes: {} };
|
|
131463
131544
|
}
|
|
131464
131545
|
var nodeScriptRunner = {
|
|
131465
131546
|
runPreRequest: (script, env2, request) => runPreRequestScript(script, env2, request),
|
|
131466
131547
|
runTest: (script, response, request, env2) => runTestScript(script, response, request, env2)
|
|
131467
131548
|
};
|
|
131468
131549
|
|
|
131550
|
+
// ../../packages/engine/dist/index.js
|
|
131551
|
+
var import_variable_substitution3 = __toESM(require_variable_substitution(), 1);
|
|
131552
|
+
|
|
131469
131553
|
// ../../packages/engine/dist/isolation/scratch-workspace.js
|
|
131470
131554
|
var IsolationHttpError = class extends Error {
|
|
131471
131555
|
status;
|
|
@@ -131678,18 +131762,18 @@ function applyVarOverrides(env2, overrides) {
|
|
|
131678
131762
|
const variables = base.variables.map((v) => {
|
|
131679
131763
|
if (overrides.has(v.key)) {
|
|
131680
131764
|
used.add(v.key);
|
|
131681
|
-
return { ...v, currentValue: overrides.get(v.key) };
|
|
131765
|
+
return { ...v, currentValue: overrides.get(v.key), type: (0, import_variable_substitution3.inferType)(overrides.get(v.key)) };
|
|
131682
131766
|
}
|
|
131683
131767
|
const normalisedMatch = [...normalised.entries()].find(([key]) => normalizeKey(v.key) === key);
|
|
131684
131768
|
if (normalisedMatch) {
|
|
131685
131769
|
used.add(normalisedMatch[0]);
|
|
131686
|
-
return { ...v, currentValue: normalisedMatch[1] };
|
|
131770
|
+
return { ...v, currentValue: normalisedMatch[1], type: (0, import_variable_substitution3.inferType)(normalisedMatch[1]) };
|
|
131687
131771
|
}
|
|
131688
131772
|
return v;
|
|
131689
131773
|
});
|
|
131690
131774
|
for (const [key, value] of overrides) {
|
|
131691
131775
|
if (used.has(key) || used.has(normalizeKey(key))) continue;
|
|
131692
|
-
variables.push({ key, value, currentValue: value, enabled: true });
|
|
131776
|
+
variables.push({ key, value, currentValue: value, enabled: true, type: (0, import_variable_substitution3.inferType)(value) });
|
|
131693
131777
|
}
|
|
131694
131778
|
return { ...base, variables };
|
|
131695
131779
|
}
|
package/dist/sandbox-worker.js
CHANGED
|
@@ -1,7 +1,193 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
try {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
} catch (e) {
|
|
11
|
+
throw mod = 0, e;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
28
|
+
mod
|
|
29
|
+
));
|
|
30
|
+
|
|
31
|
+
// ../backend/dist/utils/variable-substitution.js
|
|
32
|
+
var require_variable_substitution = __commonJS({
|
|
33
|
+
"../backend/dist/utils/variable-substitution.js"(exports) {
|
|
34
|
+
"use strict";
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.substituteVariables = substituteVariables;
|
|
37
|
+
exports.substituteJsonVariables = substituteJsonVariables;
|
|
38
|
+
exports.isNumericLiteral = isNumericLiteral;
|
|
39
|
+
exports.inferType = inferType2;
|
|
40
|
+
exports.substituteInRequest = substituteInRequest;
|
|
41
|
+
exports.substituteInAuth = substituteInAuth;
|
|
42
|
+
function substituteVariables(text, environment) {
|
|
43
|
+
if (!environment)
|
|
44
|
+
return text;
|
|
45
|
+
const values = getResolvedValues(environment);
|
|
46
|
+
let result = text;
|
|
47
|
+
for (const [key, entry] of values) {
|
|
48
|
+
const pattern = new RegExp(`{{\\s*${escapeRegex(key)}\\s*}}`, "g");
|
|
49
|
+
result = result.replace(pattern, entry.value);
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
function substituteJsonVariables(text, environment) {
|
|
54
|
+
if (!environment)
|
|
55
|
+
return text;
|
|
56
|
+
const values = getResolvedValues(environment);
|
|
57
|
+
let result = text;
|
|
58
|
+
for (const [key, entry] of values) {
|
|
59
|
+
const keyPattern = escapeRegex(key);
|
|
60
|
+
const quoted = new RegExp(`"{{\\s*${keyPattern}\\s*}}"`, "g");
|
|
61
|
+
const literal = typedJsonLiteral(entry.value, entry.type);
|
|
62
|
+
result = result.replace(quoted, literal ?? JSON.stringify(entry.value));
|
|
63
|
+
const plain = new RegExp(`{{\\s*${keyPattern}\\s*}}`, "g");
|
|
64
|
+
result = result.replace(plain, entry.value);
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
function typedJsonLiteral(value, type) {
|
|
69
|
+
if (type === "boolean") {
|
|
70
|
+
return value === "true" || value === "false" ? value : null;
|
|
71
|
+
}
|
|
72
|
+
if (type === "number") {
|
|
73
|
+
return isNumericLiteral(value) ? value : null;
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
function getResolvedValues(environment) {
|
|
78
|
+
const raw = /* @__PURE__ */ new Map();
|
|
79
|
+
for (const variable of environment.variables) {
|
|
80
|
+
if (variable.enabled) {
|
|
81
|
+
raw.set(variable.key, {
|
|
82
|
+
value: variable.currentValue ?? variable.value,
|
|
83
|
+
type: variable.type
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
88
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
89
|
+
const resolve = (key) => {
|
|
90
|
+
const memo = resolved.get(key);
|
|
91
|
+
if (memo !== void 0)
|
|
92
|
+
return memo;
|
|
93
|
+
if (visiting.has(key)) {
|
|
94
|
+
const entry2 = raw.get(key);
|
|
95
|
+
return { value: entry2?.value ?? "", type: entry2?.type };
|
|
96
|
+
}
|
|
97
|
+
visiting.add(key);
|
|
98
|
+
const entry = raw.get(key) ?? { value: "", type: void 0 };
|
|
99
|
+
const value = entry.value.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, (match, name) => {
|
|
100
|
+
const referenced = name.trim();
|
|
101
|
+
return raw.has(referenced) ? resolve(referenced).value : match;
|
|
102
|
+
});
|
|
103
|
+
visiting.delete(key);
|
|
104
|
+
const result = { value, type: entry.type };
|
|
105
|
+
resolved.set(key, result);
|
|
106
|
+
return result;
|
|
107
|
+
};
|
|
108
|
+
for (const key of raw.keys())
|
|
109
|
+
resolve(key);
|
|
110
|
+
return resolved;
|
|
111
|
+
}
|
|
112
|
+
function isNumericLiteral(value) {
|
|
113
|
+
return /^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?$/.test(value.trim());
|
|
114
|
+
}
|
|
115
|
+
function inferType2(value) {
|
|
116
|
+
if (typeof value === "number") {
|
|
117
|
+
return Number.isFinite(value) ? "number" : "string";
|
|
118
|
+
}
|
|
119
|
+
if (typeof value === "boolean")
|
|
120
|
+
return "boolean";
|
|
121
|
+
if (typeof value === "string") {
|
|
122
|
+
if (value === "true" || value === "false")
|
|
123
|
+
return "boolean";
|
|
124
|
+
if (isNumericLiteral(value))
|
|
125
|
+
return "number";
|
|
126
|
+
}
|
|
127
|
+
return "string";
|
|
128
|
+
}
|
|
129
|
+
function escapeRegex(str) {
|
|
130
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
131
|
+
}
|
|
132
|
+
function substituteInRequest(request, environment) {
|
|
133
|
+
const jsonMode = request.bodyType === "json" || !request.bodyType && !!request.body;
|
|
134
|
+
const bodySub = jsonMode ? substituteJsonVariables : substituteVariables;
|
|
135
|
+
return {
|
|
136
|
+
url: substituteUrlVariables(request.url, environment),
|
|
137
|
+
headers: request.headers ? Object.fromEntries(Object.entries(request.headers).map(([key, value]) => [
|
|
138
|
+
key,
|
|
139
|
+
substituteVariables(value, environment)
|
|
140
|
+
])) : void 0,
|
|
141
|
+
body: request.body ? bodySub(request.body, environment) : void 0,
|
|
142
|
+
formDataEntries: request.formDataEntries ? request.formDataEntries.map((entry) => ({
|
|
143
|
+
...entry,
|
|
144
|
+
key: substituteVariables(entry.key, environment),
|
|
145
|
+
value: entry.type === "text" ? substituteVariables(entry.value, environment) : entry.value
|
|
146
|
+
})) : void 0
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function substituteUrlVariables(url, environment) {
|
|
150
|
+
const substituted = substituteVariables(url, environment);
|
|
151
|
+
if (!environment || !substituted.includes("="))
|
|
152
|
+
return substituted;
|
|
153
|
+
try {
|
|
154
|
+
const parsed = new URL(substituted);
|
|
155
|
+
const variables = parsed.searchParams.get("variables");
|
|
156
|
+
if (variables && variables.includes("{{")) {
|
|
157
|
+
parsed.searchParams.set("variables", substituteJsonVariables(variables, environment));
|
|
158
|
+
return parsed.toString();
|
|
159
|
+
}
|
|
160
|
+
} catch {
|
|
161
|
+
}
|
|
162
|
+
return substituted;
|
|
163
|
+
}
|
|
164
|
+
function substituteInAuth(auth, environment) {
|
|
165
|
+
if (!auth)
|
|
166
|
+
return auth;
|
|
167
|
+
const sub = (v) => substituteVariables(v, environment);
|
|
168
|
+
switch (auth.type) {
|
|
169
|
+
case "basic":
|
|
170
|
+
return auth.basic ? { ...auth, basic: { username: sub(auth.basic.username), password: sub(auth.basic.password) } } : auth;
|
|
171
|
+
case "bearer":
|
|
172
|
+
return auth.bearer ? { ...auth, bearer: { token: sub(auth.bearer.token) } } : auth;
|
|
173
|
+
case "api-key":
|
|
174
|
+
return auth.apiKey ? { ...auth, apiKey: { ...auth.apiKey, key: sub(auth.apiKey.key), value: sub(auth.apiKey.value) } } : auth;
|
|
175
|
+
case "digest":
|
|
176
|
+
return auth.digest ? { ...auth, digest: { username: sub(auth.digest.username), password: sub(auth.digest.password) } } : auth;
|
|
177
|
+
case "oauth":
|
|
178
|
+
case "none":
|
|
179
|
+
default:
|
|
180
|
+
return auth;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
1
186
|
// ../../packages/engine/dist/scripts/sandbox-worker.js
|
|
2
187
|
import { parentPort } from "node:worker_threads";
|
|
3
188
|
|
|
4
189
|
// ../../packages/engine/dist/scripts/sandbox-core.js
|
|
190
|
+
var import_variable_substitution = __toESM(require_variable_substitution(), 1);
|
|
5
191
|
var SHADOWED_GLOBALS = `
|
|
6
192
|
"use strict";
|
|
7
193
|
const self = undefined;
|
|
@@ -58,28 +244,31 @@ function createExpect(actual, inverted = false) {
|
|
|
58
244
|
}
|
|
59
245
|
function createEnvironment(env) {
|
|
60
246
|
const envStore = { ...env };
|
|
247
|
+
const typeStore = {};
|
|
61
248
|
return {
|
|
62
249
|
store: envStore,
|
|
250
|
+
types: typeStore,
|
|
63
251
|
api: {
|
|
64
252
|
get: (key) => envStore[key] ?? "",
|
|
65
253
|
set: (key, value) => {
|
|
66
254
|
envStore[key] = String(value);
|
|
255
|
+
typeStore[key] = (0, import_variable_substitution.inferType)(value);
|
|
67
256
|
}
|
|
68
257
|
}
|
|
69
258
|
};
|
|
70
259
|
}
|
|
71
260
|
function executePreRequestScript(script, context) {
|
|
72
|
-
const { store, api } = createEnvironment(context.env);
|
|
261
|
+
const { store, types, api } = createEnvironment(context.env);
|
|
73
262
|
const request = { ...context.request };
|
|
74
263
|
const fn = new Function("environment", "request", `${SHADOWED_GLOBALS}
|
|
75
264
|
${script}`);
|
|
76
265
|
fn(api, request);
|
|
77
|
-
return { envOverrides: store };
|
|
266
|
+
return { envOverrides: store, envTypes: types };
|
|
78
267
|
}
|
|
79
268
|
function executeTestScript(script, context) {
|
|
80
269
|
const results = [];
|
|
81
270
|
const { response: responseCtx, request } = context;
|
|
82
|
-
const { store, api } = createEnvironment(context.env);
|
|
271
|
+
const { store, types, api } = createEnvironment(context.env);
|
|
83
272
|
const response = {
|
|
84
273
|
status: responseCtx.status,
|
|
85
274
|
statusText: responseCtx.statusText,
|
|
@@ -104,7 +293,7 @@ function executeTestScript(script, context) {
|
|
|
104
293
|
const fn = new Function("test", "expect", "response", "request", "environment", `${SHADOWED_GLOBALS}
|
|
105
294
|
${script}`);
|
|
106
295
|
fn(test, expect, response, request, api);
|
|
107
|
-
return { testResults: results, envOverrides: store };
|
|
296
|
+
return { testResults: results, envOverrides: store, envTypes: types };
|
|
108
297
|
}
|
|
109
298
|
|
|
110
299
|
// ../../packages/engine/dist/scripts/sandbox-worker.js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@requesto/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "Run your Requesto collections from the terminal and CI pipelines",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^26.4.1",
|
|
28
28
|
"esbuild": "^0.28.2",
|
|
29
|
-
"requesto-backend": "1.
|
|
30
|
-
"requesto-engine": "1.
|
|
29
|
+
"requesto-backend": "1.10.1",
|
|
30
|
+
"requesto-engine": "1.10.1",
|
|
31
31
|
"tsx": "^4.23.13",
|
|
32
32
|
"typescript": "^7.0.2",
|
|
33
33
|
"vitest": "^5.0.0"
|