@piyushdoorwar/yamlet 1.14.0 → 1.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/yamlet.js +325 -89
- package/package.json +1 -1
package/dist/yamlet.js
CHANGED
|
@@ -17654,8 +17654,8 @@ var require_lodash = __commonJS({
|
|
|
17654
17654
|
}
|
|
17655
17655
|
value = toNumber(value);
|
|
17656
17656
|
if (value === INFINITY || value === -INFINITY) {
|
|
17657
|
-
var
|
|
17658
|
-
return
|
|
17657
|
+
var sign2 = value < 0 ? -1 : 1;
|
|
17658
|
+
return sign2 * MAX_INTEGER;
|
|
17659
17659
|
}
|
|
17660
17660
|
return value === value ? value : 0;
|
|
17661
17661
|
}
|
|
@@ -19851,8 +19851,8 @@ var require_moment = __commonJS({
|
|
|
19851
19851
|
return units;
|
|
19852
19852
|
}
|
|
19853
19853
|
function zeroFill(number, targetLength, forceSign) {
|
|
19854
|
-
var absNumber = "" + Math.abs(number), zerosToFill = targetLength - absNumber.length,
|
|
19855
|
-
return (
|
|
19854
|
+
var absNumber = "" + Math.abs(number), zerosToFill = targetLength - absNumber.length, sign3 = number >= 0;
|
|
19855
|
+
return (sign3 ? forceSign ? "+" : "" : "-") + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
|
|
19856
19856
|
}
|
|
19857
19857
|
var formattingTokens = /(\[[^\[]*\])|(\\e)|(\\)?(eHHmm|[Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, formatFunctions = {}, formatTokenFunctions = {};
|
|
19858
19858
|
function addFormatToken(token2, padded, ordinal3, callback) {
|
|
@@ -21955,12 +21955,12 @@ var require_moment = __commonJS({
|
|
|
21955
21955
|
}
|
|
21956
21956
|
function offset(token2, separator) {
|
|
21957
21957
|
addFormatToken(token2, 0, 0, function() {
|
|
21958
|
-
var offset2 = this.utcOffset(),
|
|
21958
|
+
var offset2 = this.utcOffset(), sign3 = "+";
|
|
21959
21959
|
if (offset2 < 0) {
|
|
21960
21960
|
offset2 = -offset2;
|
|
21961
|
-
|
|
21961
|
+
sign3 = "-";
|
|
21962
21962
|
}
|
|
21963
|
-
return
|
|
21963
|
+
return sign3 + zeroFill(~~(offset2 / 60), 2) + separator + zeroFill(~~offset2 % 60, 2);
|
|
21964
21964
|
});
|
|
21965
21965
|
}
|
|
21966
21966
|
offset("Z", ":");
|
|
@@ -22120,7 +22120,7 @@ var require_moment = __commonJS({
|
|
|
22120
22120
|
}
|
|
22121
22121
|
var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/, isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
|
|
22122
22122
|
function createDuration(input, key) {
|
|
22123
|
-
var duration = input, match = null,
|
|
22123
|
+
var duration = input, match = null, sign3, ret, diffRes;
|
|
22124
22124
|
if (isDuration(input)) {
|
|
22125
22125
|
duration = {
|
|
22126
22126
|
ms: input._milliseconds,
|
|
@@ -22135,26 +22135,26 @@ var require_moment = __commonJS({
|
|
|
22135
22135
|
duration.milliseconds = +input;
|
|
22136
22136
|
}
|
|
22137
22137
|
} else if (match = aspNetRegex.exec(input)) {
|
|
22138
|
-
|
|
22138
|
+
sign3 = match[1] === "-" ? -1 : 1;
|
|
22139
22139
|
duration = {
|
|
22140
22140
|
y: 0,
|
|
22141
|
-
d: toInt(match[DATE]) *
|
|
22142
|
-
h: toInt(match[HOUR]) *
|
|
22143
|
-
m: toInt(match[MINUTE]) *
|
|
22144
|
-
s: toInt(match[SECOND]) *
|
|
22145
|
-
ms: toInt(absRound(match[MILLISECOND] * 1e3)) *
|
|
22141
|
+
d: toInt(match[DATE]) * sign3,
|
|
22142
|
+
h: toInt(match[HOUR]) * sign3,
|
|
22143
|
+
m: toInt(match[MINUTE]) * sign3,
|
|
22144
|
+
s: toInt(match[SECOND]) * sign3,
|
|
22145
|
+
ms: toInt(absRound(match[MILLISECOND] * 1e3)) * sign3
|
|
22146
22146
|
// the millisecond decimal point is included in the match
|
|
22147
22147
|
};
|
|
22148
22148
|
} else if (match = isoRegex.exec(input)) {
|
|
22149
|
-
|
|
22149
|
+
sign3 = match[1] === "-" ? -1 : 1;
|
|
22150
22150
|
duration = {
|
|
22151
|
-
y: parseIso(match[2],
|
|
22152
|
-
M: parseIso(match[3],
|
|
22153
|
-
w: parseIso(match[4],
|
|
22154
|
-
d: parseIso(match[5],
|
|
22155
|
-
h: parseIso(match[6],
|
|
22156
|
-
m: parseIso(match[7],
|
|
22157
|
-
s: parseIso(match[8],
|
|
22151
|
+
y: parseIso(match[2], sign3),
|
|
22152
|
+
M: parseIso(match[3], sign3),
|
|
22153
|
+
w: parseIso(match[4], sign3),
|
|
22154
|
+
d: parseIso(match[5], sign3),
|
|
22155
|
+
h: parseIso(match[6], sign3),
|
|
22156
|
+
m: parseIso(match[7], sign3),
|
|
22157
|
+
s: parseIso(match[8], sign3)
|
|
22158
22158
|
};
|
|
22159
22159
|
} else if (duration == null) {
|
|
22160
22160
|
duration = {};
|
|
@@ -22178,9 +22178,9 @@ var require_moment = __commonJS({
|
|
|
22178
22178
|
}
|
|
22179
22179
|
createDuration.fn = Duration.prototype;
|
|
22180
22180
|
createDuration.invalid = createInvalid;
|
|
22181
|
-
function parseIso(inp,
|
|
22181
|
+
function parseIso(inp, sign3) {
|
|
22182
22182
|
var res = inp && parseFloat(inp.replace(",", "."));
|
|
22183
|
-
return (isNaN(res) ? 0 : res) *
|
|
22183
|
+
return (isNaN(res) ? 0 : res) * sign3;
|
|
22184
22184
|
}
|
|
22185
22185
|
function positiveMomentsDifference(base2, other) {
|
|
22186
22186
|
var res = {};
|
|
@@ -23549,7 +23549,7 @@ var require_moment = __commonJS({
|
|
|
23549
23549
|
return locale2.postformat(output);
|
|
23550
23550
|
}
|
|
23551
23551
|
var abs = Math.abs;
|
|
23552
|
-
function
|
|
23552
|
+
function sign2(x) {
|
|
23553
23553
|
return (x > 0) - (x < 0) || +x;
|
|
23554
23554
|
}
|
|
23555
23555
|
function toISOString() {
|
|
@@ -23568,9 +23568,9 @@ var require_moment = __commonJS({
|
|
|
23568
23568
|
months2 %= 12;
|
|
23569
23569
|
s = seconds2 ? seconds2.toFixed(3).replace(/\.?0+$/, "") : "";
|
|
23570
23570
|
totalSign = total < 0 ? "-" : "";
|
|
23571
|
-
ymSign =
|
|
23572
|
-
daysSign =
|
|
23573
|
-
hmsSign =
|
|
23571
|
+
ymSign = sign2(this._months) !== sign2(total) ? "-" : "";
|
|
23572
|
+
daysSign = sign2(this._days) !== sign2(total) ? "-" : "";
|
|
23573
|
+
hmsSign = sign2(this._milliseconds) !== sign2(total) ? "-" : "";
|
|
23574
23574
|
return totalSign + "P" + (years2 ? ymSign + years2 + "Y" : "") + (months2 ? ymSign + months2 + "M" : "") + (days2 ? daysSign + days2 + "D" : "") + (hours2 || minutes2 || seconds2 ? "T" : "") + (hours2 ? hmsSign + hours2 + "H" : "") + (minutes2 ? hmsSign + minutes2 + "M" : "") + (seconds2 ? hmsSign + s + "S" : "");
|
|
23575
23575
|
}
|
|
23576
23576
|
var proto = Duration.prototype;
|
|
@@ -24166,8 +24166,9 @@ function digestAuthorization(c, opts) {
|
|
|
24166
24166
|
const nc = (opts.nc ?? 1).toString(16).padStart(8, "0");
|
|
24167
24167
|
let ha1 = H(`${opts.username}:${c.realm}:${opts.password}`);
|
|
24168
24168
|
if (alg.endsWith("-SESS")) ha1 = H(`${ha1}:${c.nonce}:${cnonce}`);
|
|
24169
|
-
const
|
|
24170
|
-
const qop =
|
|
24169
|
+
const offered = c.qop?.split(",").map((q2) => q2.trim().toLowerCase()) ?? [];
|
|
24170
|
+
const qop = offered.includes("auth") ? "auth" : offered.includes("auth-int") ? "auth-int" : void 0;
|
|
24171
|
+
const ha2 = qop === "auth-int" ? H(`${opts.method}:${opts.uri}:${createHash(hashName).update(opts.body ?? "").digest("hex")}`) : H(`${opts.method}:${opts.uri}`);
|
|
24171
24172
|
const response = qop ? H(`${ha1}:${c.nonce}:${nc}:${cnonce}:${qop}:${ha2}`) : H(`${ha1}:${c.nonce}:${ha2}`);
|
|
24172
24173
|
const q = (s) => `"${s.replace(/(["\\])/g, "\\$1")}"`;
|
|
24173
24174
|
const parts = [
|
|
@@ -24213,18 +24214,48 @@ function signAwsV4(opts) {
|
|
|
24213
24214
|
const canonicalHeaders = names.map((k) => `${k}:${signed.get(k)}
|
|
24214
24215
|
`).join("");
|
|
24215
24216
|
const signedHeaders = names.join(";");
|
|
24216
|
-
const
|
|
24217
|
-
const canonicalPath = service === "s3" ? path5 : path5.split("/").map((seg) => awsEncode(decodeSafe(seg))).map((seg) => awsEncode(seg)).join("/");
|
|
24218
|
-
const canonicalQuery = [...url2.searchParams.entries()].map(([k, v]) => [awsEncode(k), awsEncode(v)]).sort(([a, x], [b, y]) => a < b ? -1 : a > b ? 1 : x < y ? -1 : x > y ? 1 : 0).map(([k, v]) => `${k}=${v}`).join("&");
|
|
24219
|
-
const canonicalRequest = [opts.method.toUpperCase(), canonicalPath, canonicalQuery, canonicalHeaders, signedHeaders, payloadHash].join("\n");
|
|
24217
|
+
const canonicalRequest = [opts.method.toUpperCase(), canonicalPath(url2, service), canonicalQuery([...url2.searchParams.entries()]), canonicalHeaders, signedHeaders, payloadHash].join("\n");
|
|
24220
24218
|
const scope = `${date}/${region}/${service}/aws4_request`;
|
|
24221
|
-
const
|
|
24222
|
-
const kDate = hmac(`AWS4${opts.aws.secretKey}`, date);
|
|
24223
|
-
const kSigning = hmac(hmac(hmac(kDate, region), service), "aws4_request");
|
|
24224
|
-
const signature = createHmac("sha256", kSigning).update(stringToSign).digest("hex");
|
|
24219
|
+
const signature = sign(canonicalRequest, { amzDate, date, region, service, scope, secretKey: opts.aws.secretKey });
|
|
24225
24220
|
added.push({ key: "Authorization", value: `AWS4-HMAC-SHA256 Credential=${opts.aws.accessKey}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`, enabled: true });
|
|
24226
24221
|
return added;
|
|
24227
24222
|
}
|
|
24223
|
+
function canonicalPath(url2, service) {
|
|
24224
|
+
const once = (url2.pathname || "/").split("/").map((seg) => awsEncode(decodeSafe(seg)));
|
|
24225
|
+
return (service === "s3" ? once : once.map((seg) => awsEncode(seg))).join("/");
|
|
24226
|
+
}
|
|
24227
|
+
function canonicalQuery(entries) {
|
|
24228
|
+
return entries.map(([k, v]) => [awsEncode(k), awsEncode(v)]).sort(([a, x], [b, y]) => a < b ? -1 : a > b ? 1 : x < y ? -1 : x > y ? 1 : 0).map(([k, v]) => `${k}=${v}`).join("&");
|
|
24229
|
+
}
|
|
24230
|
+
function sign(canonicalRequest, s) {
|
|
24231
|
+
const stringToSign = ["AWS4-HMAC-SHA256", s.amzDate, s.scope, sha256(canonicalRequest)].join("\n");
|
|
24232
|
+
const kDate = hmac(`AWS4${s.secretKey}`, s.date);
|
|
24233
|
+
const kSigning = hmac(hmac(hmac(kDate, s.region), s.service), "aws4_request");
|
|
24234
|
+
return createHmac("sha256", kSigning).update(stringToSign).digest("hex");
|
|
24235
|
+
}
|
|
24236
|
+
function presignAwsV4(opts) {
|
|
24237
|
+
const url2 = new URL(opts.url);
|
|
24238
|
+
const guessed = awsScopeFromHost(url2.hostname);
|
|
24239
|
+
const region = opts.aws.region.trim() || guessed.region || "us-east-1";
|
|
24240
|
+
const service = opts.aws.service.trim() || guessed.service || "execute-api";
|
|
24241
|
+
const amzDate = (opts.now ?? /* @__PURE__ */ new Date()).toISOString().replace(/[:-]|\.\d{3}/g, "");
|
|
24242
|
+
const date = amzDate.slice(0, 8);
|
|
24243
|
+
const scope = `${date}/${region}/${service}/aws4_request`;
|
|
24244
|
+
const entries = [
|
|
24245
|
+
...[...url2.searchParams.entries()].filter(([k]) => !k.toLowerCase().startsWith("x-amz-")),
|
|
24246
|
+
["X-Amz-Algorithm", "AWS4-HMAC-SHA256"],
|
|
24247
|
+
["X-Amz-Credential", `${opts.aws.accessKey}/${scope}`],
|
|
24248
|
+
["X-Amz-Date", amzDate],
|
|
24249
|
+
["X-Amz-Expires", String(opts.expiresSeconds ?? 3600)],
|
|
24250
|
+
["X-Amz-SignedHeaders", "host"]
|
|
24251
|
+
];
|
|
24252
|
+
if (opts.aws.sessionToken.trim()) entries.push(["X-Amz-Security-Token", opts.aws.sessionToken.trim()]);
|
|
24253
|
+
const query = canonicalQuery(entries);
|
|
24254
|
+
const canonicalRequest = [opts.method.toUpperCase(), canonicalPath(url2, service), query, `host:${url2.host}
|
|
24255
|
+
`, "host", service === "s3" ? "UNSIGNED-PAYLOAD" : sha256(opts.body ?? "")].join("\n");
|
|
24256
|
+
const signature = sign(canonicalRequest, { amzDate, date, region, service, scope, secretKey: opts.aws.secretKey });
|
|
24257
|
+
return `${url2.origin}${url2.pathname}?${query}&X-Amz-Signature=${signature}${url2.hash}`;
|
|
24258
|
+
}
|
|
24228
24259
|
function decodeSafe(s) {
|
|
24229
24260
|
try {
|
|
24230
24261
|
return decodeURIComponent(s);
|
|
@@ -24329,7 +24360,10 @@ function parseTokenBody(text3, contentType) {
|
|
|
24329
24360
|
const result = { accessToken, raw };
|
|
24330
24361
|
if (typeof o.refresh_token === "string" && o.refresh_token) result.refreshToken = o.refresh_token;
|
|
24331
24362
|
if (typeof o.token_type === "string" && o.token_type) result.tokenType = o.token_type;
|
|
24332
|
-
if (Number.isFinite(expires) && expires > 0)
|
|
24363
|
+
if (Number.isFinite(expires) && expires > 0) {
|
|
24364
|
+
result.expiresIn = expires;
|
|
24365
|
+
result.expiresAt = Date.now() + expires * 1e3;
|
|
24366
|
+
}
|
|
24333
24367
|
return result;
|
|
24334
24368
|
}
|
|
24335
24369
|
async function requestToken(cfg, resolve2, form, opts = {}) {
|
|
@@ -24388,7 +24422,8 @@ async function refreshAccessToken(cfg, resolve2, opts) {
|
|
|
24388
24422
|
const form = { grant_type: "refresh_token", refresh_token: refreshToken };
|
|
24389
24423
|
const scope = resolve2(cfg.scope).trim();
|
|
24390
24424
|
if (scope) form.scope = scope;
|
|
24391
|
-
const
|
|
24425
|
+
const refreshUrl = resolve2(cfg.refreshTokenUrl ?? "").trim();
|
|
24426
|
+
const result = await requestToken(refreshUrl ? { ...cfg, accessTokenUrl: cfg.refreshTokenUrl } : cfg, resolve2, form, opts);
|
|
24392
24427
|
if (!result.refreshToken) result.refreshToken = refreshToken;
|
|
24393
24428
|
return result;
|
|
24394
24429
|
}
|
|
@@ -24396,7 +24431,13 @@ var cache = /* @__PURE__ */ new Map();
|
|
|
24396
24431
|
var EXPIRY_MARGIN_MS = 3e4;
|
|
24397
24432
|
var DEFAULT_LIFETIME_S = 3600;
|
|
24398
24433
|
function cacheKey(cfg, resolve2) {
|
|
24399
|
-
return [cfg.grantType, resolve2(cfg.accessTokenUrl), resolve2(cfg.clientId), resolve2(cfg.scope), resolve2(cfg.username), cfg.clientAuthentication, resolve2(cfg.audience ?? ""), resolve2(cfg.resource ?? "")].join("|");
|
|
24434
|
+
return [cfg.grantType, resolve2(cfg.accessTokenUrl), resolve2(cfg.clientId), resolve2(cfg.clientSecret), resolve2(cfg.scope), resolve2(cfg.username), resolve2(cfg.password), cfg.clientAuthentication, resolve2(cfg.audience ?? ""), resolve2(cfg.resource ?? "")].join("|");
|
|
24435
|
+
}
|
|
24436
|
+
function forgetCachedToken(cfg, resolve2) {
|
|
24437
|
+
cache.delete(cacheKey(cfg, resolve2));
|
|
24438
|
+
}
|
|
24439
|
+
function isExpired(expiresAt) {
|
|
24440
|
+
return !!expiresAt && expiresAt - EXPIRY_MARGIN_MS < Date.now();
|
|
24400
24441
|
}
|
|
24401
24442
|
function canFetchAutomatically(cfg, resolve2) {
|
|
24402
24443
|
if (cfg.grantType !== "client_credentials" && cfg.grantType !== "password") return false;
|
|
@@ -29433,24 +29474,24 @@ function parse(formula) {
|
|
|
29433
29474
|
}
|
|
29434
29475
|
let idx = 0;
|
|
29435
29476
|
let a = 0;
|
|
29436
|
-
let
|
|
29477
|
+
let sign2 = readSign();
|
|
29437
29478
|
let number = readNumber();
|
|
29438
29479
|
if (idx < formula.length && formula.charAt(idx) === "n") {
|
|
29439
29480
|
idx++;
|
|
29440
|
-
a =
|
|
29481
|
+
a = sign2 * (number !== null && number !== void 0 ? number : 1);
|
|
29441
29482
|
skipWhitespace();
|
|
29442
29483
|
if (idx < formula.length) {
|
|
29443
|
-
|
|
29484
|
+
sign2 = readSign();
|
|
29444
29485
|
skipWhitespace();
|
|
29445
29486
|
number = readNumber();
|
|
29446
29487
|
} else {
|
|
29447
|
-
|
|
29488
|
+
sign2 = number = 0;
|
|
29448
29489
|
}
|
|
29449
29490
|
}
|
|
29450
29491
|
if (number === null || idx < formula.length) {
|
|
29451
29492
|
throw new Error(`n-th rule couldn't be parsed ('${formula}')`);
|
|
29452
29493
|
}
|
|
29453
|
-
return [a,
|
|
29494
|
+
return [a, sign2 * number];
|
|
29454
29495
|
function readSign() {
|
|
29455
29496
|
if (formula.charAt(idx) === "-") {
|
|
29456
29497
|
idx++;
|
|
@@ -32458,8 +32499,9 @@ async function exchange(opts) {
|
|
|
32458
32499
|
await res.body.dump();
|
|
32459
32500
|
redirects.push({ statusCode: res.statusCode, url: url2 });
|
|
32460
32501
|
const next2 = new URL(location, url2);
|
|
32461
|
-
if (next2.
|
|
32462
|
-
|
|
32502
|
+
if (next2.origin !== new URL(url2).origin && !opts.keepAuth) {
|
|
32503
|
+
const drop = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "x-amz-security-token", "x-amz-date", "x-amz-content-sha256", ...(opts.credentialHeaders ?? []).map((h) => h.toLowerCase())]);
|
|
32504
|
+
headers = headers.filter((h) => !drop.has(h.key.toLowerCase()));
|
|
32463
32505
|
explicitCookie = void 0;
|
|
32464
32506
|
}
|
|
32465
32507
|
if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && method === "POST" && !opts.keepMethod) {
|
|
@@ -32678,7 +32720,7 @@ async function execute(input) {
|
|
|
32678
32720
|
if (req.preRequestScript?.trim()) {
|
|
32679
32721
|
const before2 = tests.length;
|
|
32680
32722
|
try {
|
|
32681
|
-
await runScript({ ...scriptBase, script: req.preRequestScript, phase: "pre"
|
|
32723
|
+
await runScript({ ...scriptBase, script: req.preRequestScript, phase: "pre" });
|
|
32682
32724
|
requestTests += tests.length - before2;
|
|
32683
32725
|
} catch (e) {
|
|
32684
32726
|
return finish(errorResponse(emptyResponse(req.method, req.url), `Pre-request script error: ${errMessage2(e)}`));
|
|
@@ -32691,14 +32733,35 @@ async function execute(input) {
|
|
|
32691
32733
|
const resolve2 = (s) => resolveVariables(s ?? "", ctx);
|
|
32692
32734
|
const auth = effectiveAuth(req, collection, folders);
|
|
32693
32735
|
let oauthToken;
|
|
32694
|
-
|
|
32695
|
-
|
|
32696
|
-
|
|
32697
|
-
|
|
32698
|
-
|
|
32736
|
+
const remember = (t) => {
|
|
32737
|
+
const source = req.auth.type === "inherit" ? folders.some((f) => f.auth === auth) ? "folder" : "collection" : "request";
|
|
32738
|
+
oauthRefreshed = { accessToken: t.accessToken, refreshToken: t.refreshToken, expiresAt: t.expiresAt, source };
|
|
32739
|
+
if (source === "folder") oauthRefreshed.folderId = [...folders].reverse().find((f) => f.auth === auth)?.id;
|
|
32740
|
+
};
|
|
32741
|
+
if (auth.type === "oauth2") {
|
|
32742
|
+
const cfg = auth.oauth2;
|
|
32743
|
+
const known = refreshedTokenFor(cfg, resolve2);
|
|
32744
|
+
if (known) oauthToken = known.accessToken;
|
|
32745
|
+
const current = known?.accessToken ?? resolve2(cfg.accessToken).trim();
|
|
32746
|
+
let usable = !!current && !isExpired(known ? known.expiresAt : cfg.expiresAt);
|
|
32747
|
+
if (!usable && current && resolve2(cfg.refreshToken).trim()) {
|
|
32748
|
+
try {
|
|
32749
|
+
const t = await refreshAndRemember(cfg, resolve2, { dispatcher, signal: input.signal });
|
|
32750
|
+
oauthToken = t.accessToken;
|
|
32751
|
+
remember(t);
|
|
32752
|
+
usable = true;
|
|
32753
|
+
logs.push("OAuth 2.0: the access token had expired; got a new one with the refresh token.");
|
|
32754
|
+
} catch (e) {
|
|
32755
|
+
logs.push(`[warn] OAuth 2.0: refreshing the expired token failed: ${errMessage2(e)}`);
|
|
32756
|
+
}
|
|
32757
|
+
}
|
|
32758
|
+
if (!usable && canFetchAutomatically(cfg, resolve2)) {
|
|
32759
|
+
try {
|
|
32760
|
+
oauthToken = (await getCachedToken(cfg, resolve2, { dispatcher, signal: input.signal })).accessToken;
|
|
32761
|
+
} catch (e) {
|
|
32762
|
+
return finish(errorResponse(emptyResponse(req.method, resolve2(req.url)), `OAuth 2.0 token request failed: ${errMessage2(e)}`));
|
|
32763
|
+
}
|
|
32699
32764
|
}
|
|
32700
|
-
} else if (auth.type === "oauth2") {
|
|
32701
|
-
oauthToken = refreshedTokenFor(auth.oauth2, resolve2)?.accessToken;
|
|
32702
32765
|
}
|
|
32703
32766
|
let built;
|
|
32704
32767
|
try {
|
|
@@ -32720,7 +32783,12 @@ async function execute(input) {
|
|
|
32720
32783
|
let incomplete;
|
|
32721
32784
|
const withBodyType = (list) => prepared.contentType ? [...list.filter((h) => h.key.toLowerCase() !== "content-type"), { key: "Content-Type", value: prepared.contentType, enabled: true }] : list;
|
|
32722
32785
|
let headers = withBodyType(built.headers);
|
|
32723
|
-
if (auth.type === "awsv4") {
|
|
32786
|
+
if (auth.type === "awsv4" && auth.aws.addToQuery) {
|
|
32787
|
+
const a = auth.aws;
|
|
32788
|
+
const aws = { accessKey: resolve2(a.accessKey), secretKey: resolve2(a.secretKey), sessionToken: resolve2(a.sessionToken), region: resolve2(a.region), service: resolve2(a.service) };
|
|
32789
|
+
built = { ...built, url: presignAwsV4({ method: built.method, url: built.url, aws, body: prepared.body }) };
|
|
32790
|
+
headers = headers.filter((h) => h.key.toLowerCase() !== "authorization");
|
|
32791
|
+
} else if (auth.type === "awsv4") {
|
|
32724
32792
|
const a = auth.aws;
|
|
32725
32793
|
headers = [
|
|
32726
32794
|
...headers.filter((h) => h.key.toLowerCase() !== "authorization"),
|
|
@@ -32736,7 +32804,8 @@ async function execute(input) {
|
|
|
32736
32804
|
const send = (extra = [], live = true) => exchange({
|
|
32737
32805
|
url: built.url,
|
|
32738
32806
|
method: built.method,
|
|
32739
|
-
|
|
32807
|
+
// Headers computed at send time (Digest) replace ones of the same name.
|
|
32808
|
+
headers: [...headers.filter((h) => !extra.some((x) => x.key.toLowerCase() === h.key.toLowerCase())), ...extra],
|
|
32740
32809
|
body: prepared.body,
|
|
32741
32810
|
dispatcher,
|
|
32742
32811
|
signal,
|
|
@@ -32744,6 +32813,7 @@ async function execute(input) {
|
|
|
32744
32813
|
maxRedirects: settings.maxRedirects,
|
|
32745
32814
|
keepMethod: settings.followOriginalMethod,
|
|
32746
32815
|
keepAuth: settings.followAuthorizationHeader,
|
|
32816
|
+
credentialHeaders: auth.type === "apikey" && auth.apiKeyIn !== "query" && resolve2(auth.apiKeyName).trim() ? [resolve2(auth.apiKeyName).trim()] : void 0,
|
|
32747
32817
|
jar: settings.disableCookieJar ? void 0 : input.cookieJar,
|
|
32748
32818
|
onHead: input.onHead && live ? (status, headers2, firstByteMs) => input.onHead({ statusCode: status, reasonPhrase: STATUS_CODES[status] ?? "", headers: toHeaderList(headers2), contentType: headerValue(headers2, "content-type") ?? "", firstByteMs: Math.round(firstByteMs) }) : void 0,
|
|
32749
32819
|
onChunk: live ? input.onChunk : void 0,
|
|
@@ -32755,21 +32825,30 @@ async function execute(input) {
|
|
|
32755
32825
|
const challenge = probe.status === 401 ? parseDigestChallenge(headerValue(probe.headers, "www-authenticate")) : void 0;
|
|
32756
32826
|
if (challenge) {
|
|
32757
32827
|
const u = new URL(built.url);
|
|
32758
|
-
const authorization = digestAuthorization(challenge, { username: resolve2(auth.username), password: resolve2(auth.password), method: built.method, uri: u.pathname + u.search });
|
|
32828
|
+
const authorization = digestAuthorization(challenge, { username: resolve2(auth.username), password: resolve2(auth.password), method: built.method, uri: u.pathname + u.search, body: prepared.body });
|
|
32759
32829
|
ex = await send([{ key: "Authorization", value: authorization, enabled: true }]);
|
|
32760
32830
|
} else ex = probe;
|
|
32761
32831
|
} else ex = await send();
|
|
32762
|
-
if (ex.status === 401 && auth.type === "oauth2"
|
|
32832
|
+
if (ex.status === 401 && auth.type === "oauth2") {
|
|
32833
|
+
const cfg = auth.oauth2;
|
|
32834
|
+
let token;
|
|
32763
32835
|
try {
|
|
32764
|
-
|
|
32836
|
+
if (!oauthRefreshed && resolve2(cfg.refreshToken).trim()) {
|
|
32837
|
+
token = await refreshAndRemember(cfg, resolve2, { dispatcher, signal });
|
|
32838
|
+
logs.push("OAuth 2.0: the access token was rejected; got a new one with the refresh token and sent again.");
|
|
32839
|
+
} else if (canFetchAutomatically(cfg, resolve2)) {
|
|
32840
|
+
forgetCachedToken(cfg, resolve2);
|
|
32841
|
+
token = await getCachedToken(cfg, resolve2, { dispatcher, signal });
|
|
32842
|
+
logs.push("OAuth 2.0: the access token was rejected; fetched a new one and sent again.");
|
|
32843
|
+
}
|
|
32844
|
+
} catch (e) {
|
|
32845
|
+
logs.push(`[warn] OAuth 2.0: getting a new token failed: ${errMessage2(e)}`);
|
|
32846
|
+
}
|
|
32847
|
+
if (token) {
|
|
32765
32848
|
built = buildRequest(req, { ctx, collection, folders, oauthToken: token.accessToken });
|
|
32766
32849
|
headers = withBodyType(built.headers);
|
|
32767
|
-
|
|
32768
|
-
if (oauthRefreshed.source === "folder") oauthRefreshed.folderId = [...folders].reverse().find((f) => f.auth === auth)?.id;
|
|
32769
|
-
logs.push("OAuth 2.0: the access token was rejected; got a new one with the refresh token and sent again.");
|
|
32850
|
+
remember(token);
|
|
32770
32851
|
ex = await send();
|
|
32771
|
-
} catch (e) {
|
|
32772
|
-
logs.push(`[warn] OAuth 2.0: refreshing the token failed: ${errMessage2(e)}`);
|
|
32773
32852
|
}
|
|
32774
32853
|
}
|
|
32775
32854
|
if (ex.truncated) {
|
|
@@ -32809,7 +32888,7 @@ async function execute(input) {
|
|
|
32809
32888
|
if (req.postResponseScript?.trim()) {
|
|
32810
32889
|
const before2 = tests.length;
|
|
32811
32890
|
try {
|
|
32812
|
-
await runScript({ ...scriptBase, script: req.postResponseScript, phase: "post", response
|
|
32891
|
+
await runScript({ ...scriptBase, script: req.postResponseScript, phase: "post", response });
|
|
32813
32892
|
} catch (e) {
|
|
32814
32893
|
const message = errMessage2(e);
|
|
32815
32894
|
const last2 = tests.at(-1);
|
|
@@ -33073,6 +33152,7 @@ function parseDataFile(text3, filename) {
|
|
|
33073
33152
|
}
|
|
33074
33153
|
|
|
33075
33154
|
// core/src/workspaceStore.ts
|
|
33155
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
33076
33156
|
import { existsSync as existsSync3, promises as fs2, statSync as statSync2 } from "node:fs";
|
|
33077
33157
|
import path4 from "node:path";
|
|
33078
33158
|
|
|
@@ -33080,6 +33160,7 @@ import path4 from "node:path";
|
|
|
33080
33160
|
var environmentScope = (id) => `environment:${id}`;
|
|
33081
33161
|
var collectionScope = (id) => `collection:${id}`;
|
|
33082
33162
|
var GLOBALS_SCOPE = "globals";
|
|
33163
|
+
var TOKENS_SCOPE = "oauth-tokens";
|
|
33083
33164
|
var currentScope = (scope) => `current:${scope}`;
|
|
33084
33165
|
|
|
33085
33166
|
// core/src/pathNaming.ts
|
|
@@ -33368,6 +33449,7 @@ function readOAuth2(o) {
|
|
|
33368
33449
|
refreshToken: get2("refreshToken", "refresh_token") ?? "",
|
|
33369
33450
|
headerPrefix: get2("headerPrefix", "tokenType")?.trim() || d.headerPrefix,
|
|
33370
33451
|
accessTokenUrl: get2("accessTokenUrl", "tokenUrl", "access_token_url") ?? "",
|
|
33452
|
+
...get2("refreshTokenUrl", "refresh_token_url") ? { refreshTokenUrl: get2("refreshTokenUrl", "refresh_token_url") } : {},
|
|
33371
33453
|
authUrl: get2("authUrl", "authorizationUrl", "auth_url") ?? "",
|
|
33372
33454
|
clientId: get2("clientId", "client_id") ?? "",
|
|
33373
33455
|
clientSecret: get2("clientSecret", "client_secret") ?? "",
|
|
@@ -33399,7 +33481,8 @@ function readAuth(raw, fallback = "none") {
|
|
|
33399
33481
|
secretKey: aws("secretKey"),
|
|
33400
33482
|
sessionToken: aws("sessionToken"),
|
|
33401
33483
|
region: aws("region") || a.aws.region,
|
|
33402
|
-
service: aws("service")
|
|
33484
|
+
service: aws("service"),
|
|
33485
|
+
...["true", "1"].includes((aws("addAuthDataToQuery") || aws("addToQuery")).toLowerCase()) ? { addToQuery: true } : {}
|
|
33403
33486
|
};
|
|
33404
33487
|
a.apiKeyName = credential(raw.apikey, "key") ?? (type === "apikey" ? credential(raw.credentials, "key") : void 0) ?? str(raw.key);
|
|
33405
33488
|
a.apiKeyValue = credential(raw.apikey, "value") ?? (type === "apikey" ? credential(raw.credentials, "value") : void 0) ?? str(raw.value);
|
|
@@ -33417,6 +33500,7 @@ function writeOAuth2(o) {
|
|
|
33417
33500
|
if (v) out[k] = v;
|
|
33418
33501
|
};
|
|
33419
33502
|
put2("accessTokenUrl", o.accessTokenUrl);
|
|
33503
|
+
put2("refreshTokenUrl", o.refreshTokenUrl);
|
|
33420
33504
|
put2("authUrl", o.authUrl);
|
|
33421
33505
|
put2("clientId", o.clientId);
|
|
33422
33506
|
put2("clientSecret", o.clientSecret);
|
|
@@ -33424,8 +33508,6 @@ function writeOAuth2(o) {
|
|
|
33424
33508
|
put2("redirect_uri", o.redirectUri);
|
|
33425
33509
|
put2("username", o.username);
|
|
33426
33510
|
put2("password", o.password);
|
|
33427
|
-
put2("accessToken", o.accessToken);
|
|
33428
|
-
put2("refreshToken", o.refreshToken);
|
|
33429
33511
|
if (o.headerPrefix && o.headerPrefix !== "Bearer") out.tokenType = o.headerPrefix;
|
|
33430
33512
|
out.addTokenTo = o.addTokenTo === "query" ? "queryParams" : "header";
|
|
33431
33513
|
out.client_authentication = o.clientAuthentication === "body" ? "body" : "header";
|
|
@@ -33454,6 +33536,8 @@ var MODELED_CREDENTIALS = new Set(
|
|
|
33454
33536
|
"accessTokenUrl",
|
|
33455
33537
|
"tokenUrl",
|
|
33456
33538
|
"access_token_url",
|
|
33539
|
+
"refreshTokenUrl",
|
|
33540
|
+
"refresh_token_url",
|
|
33457
33541
|
"authUrl",
|
|
33458
33542
|
"authorizationUrl",
|
|
33459
33543
|
"auth_url",
|
|
@@ -33476,10 +33560,19 @@ var MODELED_CREDENTIALS = new Set(
|
|
|
33476
33560
|
"secretKey",
|
|
33477
33561
|
"sessionToken",
|
|
33478
33562
|
"region",
|
|
33479
|
-
"service"
|
|
33563
|
+
"service",
|
|
33564
|
+
"addAuthDataToQuery",
|
|
33565
|
+
"addToQuery"
|
|
33480
33566
|
].map((k) => k.toLowerCase())
|
|
33481
33567
|
);
|
|
33482
|
-
var
|
|
33568
|
+
var TOKEN_KEYS = /* @__PURE__ */ new Set(["accesstoken", "access_token", "refreshtoken", "refresh_token"]);
|
|
33569
|
+
function hasTokenIn(v) {
|
|
33570
|
+
if (Array.isArray(v)) return v.some(hasTokenIn);
|
|
33571
|
+
if (!isObj(v)) return false;
|
|
33572
|
+
if (typeof v.key === "string" && TOKEN_KEYS.has(v.key.toLowerCase()) && v.value) return true;
|
|
33573
|
+
return Object.entries(v).some(([k, val2]) => TOKEN_KEYS.has(k.toLowerCase()) && !!val2 || hasTokenIn(val2));
|
|
33574
|
+
}
|
|
33575
|
+
var normalizedAuth = (v) => ({ ...writeAuth(readAuth(v, "none")), ...hasTokenIn(v) ? { token: true } : {} });
|
|
33483
33576
|
function mergeAuth(ours, original) {
|
|
33484
33577
|
if (!isObj(original) || str(original.type).toLowerCase() !== str(ours.type).toLowerCase() || !isObj(original.credentials)) return ours;
|
|
33485
33578
|
const extra = Object.entries(original.credentials).filter(([k]) => !MODELED_CREDENTIALS.has(k.toLowerCase()));
|
|
@@ -33507,6 +33600,7 @@ function writeAuth(a) {
|
|
|
33507
33600
|
put2("sessionToken", a.aws.sessionToken);
|
|
33508
33601
|
put2("region", a.aws.region);
|
|
33509
33602
|
put2("service", a.aws.service);
|
|
33603
|
+
if (a.aws.addToQuery) creds.addAuthDataToQuery = true;
|
|
33510
33604
|
break;
|
|
33511
33605
|
case "apikey":
|
|
33512
33606
|
put2("key", a.apiKeyName);
|
|
@@ -33705,6 +33799,10 @@ function readExamples(raw) {
|
|
|
33705
33799
|
};
|
|
33706
33800
|
if (o.contentType) e.contentType = str(o.contentType);
|
|
33707
33801
|
if (o.savedAt) e.savedAt = str(o.savedAt);
|
|
33802
|
+
if (isObj(o.request) && (o.request.method || o.request.url)) {
|
|
33803
|
+
e.request = { method: str(o.request.method) || "GET", url: str(o.request.url) };
|
|
33804
|
+
if (o.request.body) e.request.body = str(o.request.body);
|
|
33805
|
+
}
|
|
33708
33806
|
return e;
|
|
33709
33807
|
});
|
|
33710
33808
|
}
|
|
@@ -33717,6 +33815,7 @@ function writeExamples(list) {
|
|
|
33717
33815
|
if (e.contentType) o.contentType = e.contentType;
|
|
33718
33816
|
if (e.body) o.body = e.body;
|
|
33719
33817
|
if (e.savedAt) o.savedAt = e.savedAt;
|
|
33818
|
+
if (e.request) o.request = { method: e.request.method, url: e.request.url, ...e.request.body ? { body: e.request.body } : {} };
|
|
33720
33819
|
return o;
|
|
33721
33820
|
});
|
|
33722
33821
|
}
|
|
@@ -34202,8 +34301,12 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34202
34301
|
async deleteCollection(id) {
|
|
34203
34302
|
return this.enqueue(async () => {
|
|
34204
34303
|
const c = this.requireCollection(id);
|
|
34205
|
-
if (c.directoryPath)
|
|
34304
|
+
if (c.directoryPath) {
|
|
34305
|
+
await fs2.rm(c.directoryPath, { recursive: true, force: true });
|
|
34306
|
+
this.forget(c.directoryPath);
|
|
34307
|
+
}
|
|
34206
34308
|
await this.dropLocal(collectionScope(c.id));
|
|
34309
|
+
await this.dropTokens(c);
|
|
34207
34310
|
this.workspace.collections = this.workspace.collections.filter((x) => x !== c);
|
|
34208
34311
|
return c;
|
|
34209
34312
|
});
|
|
@@ -34214,6 +34317,7 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34214
34317
|
if (!src.directoryPath) throw new Error("Collection has no directory");
|
|
34215
34318
|
const name = copyName(src.name);
|
|
34216
34319
|
const dir = uniqueDirectoryPath(this.workspace.collectionsPath, fileSafeName(name, "Collection"));
|
|
34320
|
+
this.forget(dir);
|
|
34217
34321
|
await fs2.cp(src.directoryPath, dir, { recursive: true });
|
|
34218
34322
|
const c = structuredClone(src);
|
|
34219
34323
|
repathTree(c, src.directoryPath, dir);
|
|
@@ -34221,7 +34325,7 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34221
34325
|
c.name = name;
|
|
34222
34326
|
c.filePath = path4.join(dir, DEFINITION_FILE);
|
|
34223
34327
|
c.order = nextOrder(this.workspace.collections);
|
|
34224
|
-
await this.
|
|
34328
|
+
await this.writeCopy(c, dir);
|
|
34225
34329
|
this.workspace.collections.push(c);
|
|
34226
34330
|
return c;
|
|
34227
34331
|
});
|
|
@@ -34242,19 +34346,24 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34242
34346
|
for (const [i, r] of node.requests.entries()) {
|
|
34243
34347
|
r.order = (i + 1) * ORDER_STEP;
|
|
34244
34348
|
r.sourceFilePath = uniqueFilePath(nodeDir, fileSafeName(r.name, "New Request"), REQUEST_SUFFIX);
|
|
34245
|
-
|
|
34349
|
+
const text3 = requestToYaml(r, void 0, r.sourceFilePath);
|
|
34350
|
+
await this.writeFile(r.sourceFilePath, text3);
|
|
34351
|
+
r.baseHash = textHash(text3);
|
|
34352
|
+
await this.saveToken(r.id, r.auth);
|
|
34246
34353
|
}
|
|
34247
34354
|
for (const [i, f] of node.folders.entries()) {
|
|
34248
34355
|
f.order = (i + 1) * ORDER_STEP;
|
|
34249
34356
|
f.directoryPath = uniqueDirectoryPath(nodeDir, fileSafeName(f.name, "New Folder"));
|
|
34250
34357
|
await fs2.mkdir(f.directoryPath, { recursive: true });
|
|
34251
34358
|
await this.writeFile(path4.join(f.directoryPath, DEFINITION_FILE), folderToYaml(f, void 0, path4.basename(f.directoryPath)));
|
|
34359
|
+
await this.saveToken(f.id, f.auth);
|
|
34252
34360
|
await placeAndWrite(f, f.directoryPath);
|
|
34253
34361
|
}
|
|
34254
34362
|
};
|
|
34255
34363
|
await placeAndWrite(c, dir);
|
|
34256
34364
|
await this.saveLocal(collectionScope(c.id), c.variables);
|
|
34257
34365
|
await this.writeFile(c.filePath, collectionToYaml(c));
|
|
34366
|
+
await this.saveToken(c.id, c.auth);
|
|
34258
34367
|
ws.collections.push(c);
|
|
34259
34368
|
return c;
|
|
34260
34369
|
});
|
|
@@ -34290,7 +34399,11 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34290
34399
|
return this.enqueue(async () => {
|
|
34291
34400
|
const hit = this.locateFolder(id);
|
|
34292
34401
|
if (!hit) throw new Error(`Folder not found: ${id}`);
|
|
34293
|
-
if (hit.folder.directoryPath)
|
|
34402
|
+
if (hit.folder.directoryPath) {
|
|
34403
|
+
await fs2.rm(hit.folder.directoryPath, { recursive: true, force: true });
|
|
34404
|
+
this.forget(hit.folder.directoryPath);
|
|
34405
|
+
}
|
|
34406
|
+
await this.dropTokens(hit.folder);
|
|
34294
34407
|
hit.list.splice(hit.list.indexOf(hit.folder), 1);
|
|
34295
34408
|
return hit.folder;
|
|
34296
34409
|
});
|
|
@@ -34303,12 +34416,13 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34303
34416
|
const srcDir = src.directoryPath;
|
|
34304
34417
|
const name = copyName(src.name);
|
|
34305
34418
|
const dir = uniqueDirectoryPath(path4.dirname(srcDir), fileSafeName(name, "Folder"));
|
|
34419
|
+
this.forget(dir);
|
|
34306
34420
|
await fs2.cp(srcDir, dir, { recursive: true });
|
|
34307
34421
|
const f = structuredClone(src);
|
|
34308
34422
|
repathTree(f, srcDir, dir);
|
|
34309
34423
|
freshIds(f);
|
|
34310
34424
|
f.name = name;
|
|
34311
|
-
await this.
|
|
34425
|
+
await this.writeCopy(f, dir);
|
|
34312
34426
|
hit.list.splice(hit.list.indexOf(src) + 1, 0, f);
|
|
34313
34427
|
await this.saveContainerOrder(hit.collection, hit.folders.at(-1) ?? null);
|
|
34314
34428
|
return f;
|
|
@@ -34323,7 +34437,10 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34323
34437
|
const id = init?.id && !this.idInUse(init.id) ? init.id : newId();
|
|
34324
34438
|
const r = newRequest({ ...init, id, name, sourceFilePath: file, order: nextOrder(node.requests) });
|
|
34325
34439
|
r.method = (r.method || "GET").toUpperCase();
|
|
34326
|
-
|
|
34440
|
+
const text3 = requestToYaml(r, void 0, file);
|
|
34441
|
+
await this.writeFile(file, text3);
|
|
34442
|
+
r.baseHash = textHash(text3);
|
|
34443
|
+
await this.saveToken(r.id, r.auth);
|
|
34327
34444
|
node.requests.push(r);
|
|
34328
34445
|
return r;
|
|
34329
34446
|
});
|
|
@@ -34345,7 +34462,15 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34345
34462
|
};
|
|
34346
34463
|
if (!existing.sourceFilePath) throw new Error("Request has no file path");
|
|
34347
34464
|
if (!updated.name.trim()) updated.name = existing.name;
|
|
34348
|
-
|
|
34465
|
+
let force = opts.force === true;
|
|
34466
|
+
if (!force && request3.baseHash) {
|
|
34467
|
+
const now = await readIfExists(existing.sourceFilePath);
|
|
34468
|
+
if (now !== void 0 && textHash(now) !== request3.baseHash) {
|
|
34469
|
+
throw conflict(`${this.relPath(existing.sourceFilePath)} changed on disk since this request was opened (a git pull or another editor?). Overwrite it, or use the disk version.`, "changed");
|
|
34470
|
+
}
|
|
34471
|
+
force = now !== void 0 && !this.track.broken.has(existing.sourceFilePath);
|
|
34472
|
+
}
|
|
34473
|
+
await this.writeRequest(updated, force);
|
|
34349
34474
|
hit.list[hit.list.indexOf(existing)] = updated;
|
|
34350
34475
|
return updated;
|
|
34351
34476
|
});
|
|
@@ -34354,7 +34479,11 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34354
34479
|
return this.enqueue(async () => {
|
|
34355
34480
|
const hit = this.locateRequest(id);
|
|
34356
34481
|
if (!hit) throw new Error(`Request not found: ${id}`);
|
|
34357
|
-
if (hit.request.sourceFilePath)
|
|
34482
|
+
if (hit.request.sourceFilePath) {
|
|
34483
|
+
await fs2.rm(hit.request.sourceFilePath, { force: true });
|
|
34484
|
+
this.forget(hit.request.sourceFilePath);
|
|
34485
|
+
}
|
|
34486
|
+
await this.dropTokens(hit.request);
|
|
34358
34487
|
hit.list.splice(hit.list.indexOf(hit.request), 1);
|
|
34359
34488
|
return hit.request;
|
|
34360
34489
|
});
|
|
@@ -34369,7 +34498,10 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34369
34498
|
for (const e of r.examples ?? []) e.id = newId();
|
|
34370
34499
|
r.name = copyName(src.name);
|
|
34371
34500
|
r.sourceFilePath = uniqueFilePath(path4.dirname(src.sourceFilePath), fileSafeName(r.name, "New Request"), REQUEST_SUFFIX);
|
|
34372
|
-
|
|
34501
|
+
const text3 = requestToYaml(r, await readIfExists(src.sourceFilePath), r.sourceFilePath);
|
|
34502
|
+
await this.writeFile(r.sourceFilePath, text3);
|
|
34503
|
+
r.baseHash = textHash(text3);
|
|
34504
|
+
await this.saveToken(r.id, r.auth);
|
|
34373
34505
|
hit.list.splice(hit.list.indexOf(src) + 1, 0, r);
|
|
34374
34506
|
await this.saveContainerOrder(hit.collection, hit.folders.at(-1) ?? null);
|
|
34375
34507
|
return r;
|
|
@@ -34435,7 +34567,8 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34435
34567
|
const fresh = await this.changedOnDisk(file);
|
|
34436
34568
|
if (fresh !== void 0) {
|
|
34437
34569
|
try {
|
|
34438
|
-
r = { ...requestFromDto(loadYaml(fresh), file), id: r.id };
|
|
34570
|
+
r = { ...requestFromDto(loadYaml(fresh), file), id: r.id, baseHash: textHash(fresh) };
|
|
34571
|
+
r.auth = withTokensOf(r0.auth, r.auth);
|
|
34439
34572
|
node.requests[i] = r;
|
|
34440
34573
|
} catch (e) {
|
|
34441
34574
|
this.track.broken.set(file, parseMessage(e));
|
|
@@ -34453,7 +34586,9 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34453
34586
|
const fresh = await this.changedOnDisk(file);
|
|
34454
34587
|
if (fresh !== void 0) {
|
|
34455
34588
|
try {
|
|
34589
|
+
const before2 = f.auth;
|
|
34456
34590
|
applyFolderMetadata(f, loadYaml(fresh));
|
|
34591
|
+
f.auth = withTokensOf(before2, f.auth);
|
|
34457
34592
|
} catch (e) {
|
|
34458
34593
|
this.track.broken.set(file, parseMessage(e));
|
|
34459
34594
|
continue;
|
|
@@ -34513,7 +34648,10 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34513
34648
|
const list = this.workspace.environments;
|
|
34514
34649
|
const env = list.find((e) => e.id === id);
|
|
34515
34650
|
if (!env) throw new Error(`Environment not found: ${id}`);
|
|
34516
|
-
if (env.filePath)
|
|
34651
|
+
if (env.filePath) {
|
|
34652
|
+
await fs2.rm(env.filePath, { force: true });
|
|
34653
|
+
this.forget(env.filePath);
|
|
34654
|
+
}
|
|
34517
34655
|
await this.dropLocal(environmentScope(env.id));
|
|
34518
34656
|
list.splice(list.indexOf(env), 1);
|
|
34519
34657
|
return env;
|
|
@@ -34536,13 +34674,28 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34536
34674
|
return this.enqueue(async () => {
|
|
34537
34675
|
const file = path4.join(this.workspace.globalsPath, GLOBALS_FILE);
|
|
34538
34676
|
const legacy = path4.join(this.workspace.globalsPath, LEGACY_GLOBALS_FILE);
|
|
34677
|
+
await this.assertWritable(legacy);
|
|
34539
34678
|
await this.saveLocal(GLOBALS_SCOPE, vars);
|
|
34540
34679
|
await this.writeFile(file, globalsToYaml(vars, await readIfExists(file) ?? await readIfExists(legacy)));
|
|
34541
34680
|
await fs2.rm(legacy, { force: true });
|
|
34681
|
+
this.track.seen.set(legacy, ABSENT);
|
|
34542
34682
|
this.workspace.globals = structuredClone(vars);
|
|
34543
34683
|
return this.workspace.globals;
|
|
34544
34684
|
});
|
|
34545
34685
|
}
|
|
34686
|
+
/**
|
|
34687
|
+
* A new OAuth 2.0 token for a collection or folder: kept in memory and the data folder
|
|
34688
|
+
* only, so the YAML (which never holds tokens) isn't rewritten.
|
|
34689
|
+
*/
|
|
34690
|
+
async setToken(id, t) {
|
|
34691
|
+
return this.enqueue(async () => {
|
|
34692
|
+
const node = this.findCollection(id) ?? this.locateFolder(id)?.folder;
|
|
34693
|
+
const auth = node?.auth;
|
|
34694
|
+
if (!node || auth?.type !== "oauth2") return;
|
|
34695
|
+
node.auth = { ...auth, oauth2: { ...auth.oauth2, accessToken: t.accessToken, refreshToken: t.refreshToken || auth.oauth2.refreshToken, expiresAt: t.expiresAt } };
|
|
34696
|
+
await this.saveToken(id, node.auth);
|
|
34697
|
+
});
|
|
34698
|
+
}
|
|
34546
34699
|
// ---- Internals -----------------------------------------------------------
|
|
34547
34700
|
enqueue(fn) {
|
|
34548
34701
|
const run2 = this.queue.then(fn, fn);
|
|
@@ -34603,6 +34756,10 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34603
34756
|
}
|
|
34604
34757
|
}
|
|
34605
34758
|
async writeFile(file, content, force = false) {
|
|
34759
|
+
if (!this.track.broken.has(file) && await readIfExists(file) === content) {
|
|
34760
|
+
this.track.seen.set(file, content);
|
|
34761
|
+
return;
|
|
34762
|
+
}
|
|
34606
34763
|
await this.assertWritable(file, force);
|
|
34607
34764
|
await writeFileAtomic(file, content);
|
|
34608
34765
|
this.track.seen.set(file, content);
|
|
@@ -34623,6 +34780,28 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34623
34780
|
}
|
|
34624
34781
|
}
|
|
34625
34782
|
}
|
|
34783
|
+
/** Forgets what was read under a path that was deleted or is about to be filled by a copy. */
|
|
34784
|
+
forget(target) {
|
|
34785
|
+
for (const map2 of [this.track.seen, this.track.broken]) {
|
|
34786
|
+
for (const file of [...map2.keys()]) if (file === target || file.startsWith(target + path4.sep)) map2.delete(file);
|
|
34787
|
+
}
|
|
34788
|
+
}
|
|
34789
|
+
/** Removes the stored tokens of a deleted item and everything under it. */
|
|
34790
|
+
async dropTokens(node) {
|
|
34791
|
+
if (!this.local) return;
|
|
34792
|
+
const ids = [];
|
|
34793
|
+
const walk2 = (n) => {
|
|
34794
|
+
ids.push(n.id);
|
|
34795
|
+
for (const r of n.requests) ids.push(r.id);
|
|
34796
|
+
for (const f of n.folders) walk2(f);
|
|
34797
|
+
};
|
|
34798
|
+
if ("folders" in node) walk2(node);
|
|
34799
|
+
else ids.push(node.id);
|
|
34800
|
+
const tokens = { ...this.local.get(TOKENS_SCOPE) };
|
|
34801
|
+
if (!ids.some((id) => id in tokens)) return;
|
|
34802
|
+
for (const id of ids) delete tokens[id];
|
|
34803
|
+
await this.local.set(TOKENS_SCOPE, tokens);
|
|
34804
|
+
}
|
|
34626
34805
|
/** The file's text if it changed on disk since Yamlet read it (it is then taken as read). */
|
|
34627
34806
|
async changedOnDisk(file) {
|
|
34628
34807
|
const known = this.track.seen.get(file);
|
|
@@ -34636,34 +34815,49 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34636
34815
|
async writeRequest(r, force = false) {
|
|
34637
34816
|
const file = r.sourceFilePath;
|
|
34638
34817
|
if (!file) return;
|
|
34639
|
-
await this.assertWritable(file, force);
|
|
34640
34818
|
const original = await readIfExists(file);
|
|
34641
34819
|
const target = uniqueFilePath(path4.dirname(file), fileSafeName(r.name, "New Request"), REQUEST_SUFFIX, file);
|
|
34642
34820
|
if (target !== file && existsSync3(file)) {
|
|
34821
|
+
await this.assertWritable(file, force);
|
|
34643
34822
|
await fs2.rename(file, target);
|
|
34644
34823
|
this.moved(file, target);
|
|
34645
34824
|
}
|
|
34646
34825
|
r.sourceFilePath = target;
|
|
34647
|
-
|
|
34826
|
+
const text3 = requestToYaml(r, original, target);
|
|
34827
|
+
await this.writeFile(target, text3, force);
|
|
34828
|
+
r.baseHash = textHash(text3);
|
|
34829
|
+
await this.saveToken(r.id, r.auth);
|
|
34830
|
+
}
|
|
34831
|
+
/** Keeps an item's OAuth 2.0 token (and expiry) in the data folder; the YAML never has it. */
|
|
34832
|
+
async saveToken(id, auth) {
|
|
34833
|
+
if (!this.local) return;
|
|
34834
|
+
const tokens = { ...this.local.get(TOKENS_SCOPE) };
|
|
34835
|
+
const o = auth?.type === "oauth2" ? auth.oauth2 : void 0;
|
|
34836
|
+
const entry = o && (o.accessToken || o.refreshToken) ? JSON.stringify({ accessToken: o.accessToken, refreshToken: o.refreshToken, ...o.expiresAt ? { expiresAt: o.expiresAt } : {} }) : void 0;
|
|
34837
|
+
if (tokens[id] === entry) return;
|
|
34838
|
+
if (entry) tokens[id] = entry;
|
|
34839
|
+
else delete tokens[id];
|
|
34840
|
+
await this.local.set(TOKENS_SCOPE, tokens);
|
|
34648
34841
|
}
|
|
34649
34842
|
/** Writes `.resources/definition.yaml` (renaming the directory to match the name) and drops a legacy collection.yaml. */
|
|
34650
34843
|
async writeCollection(c) {
|
|
34651
34844
|
if (!c.directoryPath) throw new Error("Collection has no directory");
|
|
34652
|
-
await this.assertWritable(path4.join(c.directoryPath, DEFINITION_FILE));
|
|
34845
|
+
if (path4.basename(c.directoryPath) !== fileSafeName(c.name, "New Collection")) await this.assertWritable(path4.join(c.directoryPath, DEFINITION_FILE));
|
|
34653
34846
|
await this.renameNodeDir(c, this.workspace.collectionsPath, fileSafeName(c.name, "New Collection"));
|
|
34654
34847
|
const file = path4.join(c.directoryPath, DEFINITION_FILE);
|
|
34655
34848
|
const legacy = path4.join(c.directoryPath, LEGACY_COLLECTION_FILE);
|
|
34656
|
-
await this.assertWritable(file);
|
|
34657
34849
|
await this.assertWritable(legacy);
|
|
34658
34850
|
const original = await readIfExists(file) ?? await readIfExists(legacy);
|
|
34659
34851
|
c.filePath = file;
|
|
34660
34852
|
await this.saveLocal(collectionScope(c.id), c.variables);
|
|
34661
34853
|
await this.writeFile(file, collectionToYaml(c, original));
|
|
34854
|
+
await this.saveToken(c.id, c.auth);
|
|
34662
34855
|
await fs2.rm(legacy, { force: true });
|
|
34856
|
+
this.forget(legacy);
|
|
34663
34857
|
}
|
|
34664
34858
|
async writeFolder(f) {
|
|
34665
34859
|
if (!f.directoryPath) return;
|
|
34666
|
-
await this.assertWritable(path4.join(f.directoryPath, DEFINITION_FILE));
|
|
34860
|
+
if (path4.basename(f.directoryPath) !== fileSafeName(f.name, "New Folder")) await this.assertWritable(path4.join(f.directoryPath, DEFINITION_FILE));
|
|
34667
34861
|
await this.assertWritable(path4.join(f.directoryPath, LEGACY_FOLDER_FILE));
|
|
34668
34862
|
await this.renameNodeDir(f, path4.dirname(f.directoryPath), fileSafeName(f.name, "New Folder"));
|
|
34669
34863
|
const dir = f.directoryPath;
|
|
@@ -34671,7 +34865,19 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34671
34865
|
const legacy = path4.join(dir, LEGACY_FOLDER_FILE);
|
|
34672
34866
|
const original = await readIfExists(file) ?? await readIfExists(legacy);
|
|
34673
34867
|
await this.writeFile(file, folderToYaml(f, original, path4.basename(dir)));
|
|
34868
|
+
await this.saveToken(f.id, f.auth);
|
|
34674
34869
|
await fs2.rm(legacy, { force: true });
|
|
34870
|
+
this.forget(legacy);
|
|
34871
|
+
}
|
|
34872
|
+
/** Writes a freshly copied tree; if that fails, the copy is removed rather than left behind. */
|
|
34873
|
+
async writeCopy(node, dir) {
|
|
34874
|
+
try {
|
|
34875
|
+
await this.writeTree(node);
|
|
34876
|
+
} catch (e) {
|
|
34877
|
+
await fs2.rm(dir, { recursive: true, force: true }).catch(() => void 0);
|
|
34878
|
+
this.forget(dir);
|
|
34879
|
+
throw e;
|
|
34880
|
+
}
|
|
34675
34881
|
}
|
|
34676
34882
|
/** Rewrites every metadata and request file under a node (used after copying a directory). */
|
|
34677
34883
|
async writeTree(node) {
|
|
@@ -34681,6 +34887,13 @@ var WorkspaceStore = class _WorkspaceStore {
|
|
|
34681
34887
|
for (const f of node.folders) await this.writeTree(f);
|
|
34682
34888
|
}
|
|
34683
34889
|
};
|
|
34890
|
+
function withTokensOf(prev2, next2) {
|
|
34891
|
+
if (prev2?.type !== "oauth2" || next2?.type !== "oauth2") return next2;
|
|
34892
|
+
const { accessToken, refreshToken, expiresAt } = prev2.oauth2;
|
|
34893
|
+
return { ...next2, oauth2: { ...next2.oauth2, accessToken, refreshToken, ...expiresAt ? { expiresAt } : {} } };
|
|
34894
|
+
}
|
|
34895
|
+
var ABSENT = "\0absent";
|
|
34896
|
+
var textHash = (text3) => createHash2("sha256").update(text3).digest("hex").slice(0, 32);
|
|
34684
34897
|
function conflict(message, reason) {
|
|
34685
34898
|
return Object.assign(new Error(message), { statusCode: 409, reason });
|
|
34686
34899
|
}
|
|
@@ -34726,6 +34939,10 @@ async function loadWorkspace(root2, track) {
|
|
|
34726
34939
|
const current = await readIfExists(globalsFile);
|
|
34727
34940
|
const globalsText = current ?? await readIfExists(legacyGlobals);
|
|
34728
34941
|
const globalsPath = current !== void 0 ? globalsFile : legacyGlobals;
|
|
34942
|
+
if (current === void 0) track.seen.set(globalsFile, ABSENT);
|
|
34943
|
+
if (globalsText === void 0 || current !== void 0) {
|
|
34944
|
+
if (!await readIfExists(legacyGlobals)) track.seen.set(legacyGlobals, ABSENT);
|
|
34945
|
+
}
|
|
34729
34946
|
if (globalsText) {
|
|
34730
34947
|
try {
|
|
34731
34948
|
ws.globals = globalsFromYaml(globalsText);
|
|
@@ -34749,6 +34966,7 @@ async function loadCollection(dir, rel, track) {
|
|
|
34749
34966
|
});
|
|
34750
34967
|
const read = async (file, apply) => {
|
|
34751
34968
|
const text3 = await readIfExists(file);
|
|
34969
|
+
if (text3 === void 0) track.seen.set(file, ABSENT);
|
|
34752
34970
|
if (!text3) return;
|
|
34753
34971
|
try {
|
|
34754
34972
|
apply(loadYaml(text3));
|
|
@@ -34771,6 +34989,7 @@ async function loadFolders(parentDir, rel, track) {
|
|
|
34771
34989
|
const f = newFolder({ id: stableId("f", rel(dir)), name: entry.name, directoryPath: dir });
|
|
34772
34990
|
for (const file of [DEFINITION_FILE, LEGACY_FOLDER_FILE]) {
|
|
34773
34991
|
const meta = await readIfExists(path4.join(dir, file));
|
|
34992
|
+
if (meta === void 0) track.seen.set(path4.join(dir, file), ABSENT);
|
|
34774
34993
|
if (!meta) continue;
|
|
34775
34994
|
try {
|
|
34776
34995
|
applyFolderMetadata(f, loadYaml(meta));
|
|
@@ -34799,6 +35018,7 @@ async function loadRequests(dir, rel, track) {
|
|
|
34799
35018
|
if (raw.$kind !== void 0 && String(raw.$kind) !== REQUEST_KIND) continue;
|
|
34800
35019
|
const r = requestFromDto(raw, file);
|
|
34801
35020
|
if (!String(raw.id ?? "").trim()) r.id = stableId("r", rel(file));
|
|
35021
|
+
r.baseHash = textHash(text3);
|
|
34802
35022
|
requests.push(r);
|
|
34803
35023
|
track.seen.set(file, text3);
|
|
34804
35024
|
} catch (e) {
|
|
@@ -34845,6 +35065,22 @@ function applyLocalValues(ws, local) {
|
|
|
34845
35065
|
for (const e of ws.environments) overlay(e.variables, environmentScope(e.id));
|
|
34846
35066
|
for (const c of ws.collections) overlay(c.variables, collectionScope(c.id));
|
|
34847
35067
|
overlay(ws.globals, GLOBALS_SCOPE);
|
|
35068
|
+
const tokens = local.get(TOKENS_SCOPE);
|
|
35069
|
+
if (!tokens) return;
|
|
35070
|
+
const withToken = (id, auth) => {
|
|
35071
|
+
if (auth?.type !== "oauth2" || !tokens[id]) return;
|
|
35072
|
+
try {
|
|
35073
|
+
const t = JSON.parse(tokens[id]);
|
|
35074
|
+
auth.oauth2 = { ...auth.oauth2, accessToken: t.accessToken ?? "", refreshToken: t.refreshToken ?? "", ...t.expiresAt ? { expiresAt: t.expiresAt } : {} };
|
|
35075
|
+
} catch {
|
|
35076
|
+
}
|
|
35077
|
+
};
|
|
35078
|
+
const walk2 = (node) => {
|
|
35079
|
+
withToken(node.id, node.auth);
|
|
35080
|
+
for (const r of node.requests) withToken(r.id, r.auth);
|
|
35081
|
+
for (const f of node.folders) walk2(f);
|
|
35082
|
+
};
|
|
35083
|
+
ws.collections.forEach(walk2);
|
|
34848
35084
|
}
|
|
34849
35085
|
|
|
34850
35086
|
// core/src/runReports.ts
|
|
@@ -34880,7 +35116,7 @@ function formatJson(summary) {
|
|
|
34880
35116
|
}
|
|
34881
35117
|
|
|
34882
35118
|
// cli/src/index.ts
|
|
34883
|
-
var VERSION = true ? "1.
|
|
35119
|
+
var VERSION = true ? "1.15.0" : "0.0.0-dev";
|
|
34884
35120
|
setYamletVersion(VERSION);
|
|
34885
35121
|
var CliError = class extends Error {
|
|
34886
35122
|
};
|