norn-cli 1.5.2 → 1.5.4
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/.norn-cache/secret-keys.json +9 -0
- package/.norn-cache/swagger-body-intellisense.json +1 -1
- package/.norn-cache/validation-results.json +14 -0
- package/CHANGELOG.md +32 -0
- package/README.md +54 -14
- package/dist/cli.js +1179 -322
- package/package.json +43 -1
package/dist/cli.js
CHANGED
|
@@ -8881,11 +8881,11 @@ var require_mime_types = __commonJS({
|
|
|
8881
8881
|
}
|
|
8882
8882
|
return exts[0];
|
|
8883
8883
|
}
|
|
8884
|
-
function lookup(
|
|
8885
|
-
if (!
|
|
8884
|
+
function lookup(path10) {
|
|
8885
|
+
if (!path10 || typeof path10 !== "string") {
|
|
8886
8886
|
return false;
|
|
8887
8887
|
}
|
|
8888
|
-
var extension2 = extname2("x." +
|
|
8888
|
+
var extension2 = extname2("x." + path10).toLowerCase().substr(1);
|
|
8889
8889
|
if (!extension2) {
|
|
8890
8890
|
return false;
|
|
8891
8891
|
}
|
|
@@ -8978,7 +8978,7 @@ var require_iterate = __commonJS({
|
|
|
8978
8978
|
module2.exports = iterate;
|
|
8979
8979
|
function iterate(list, iterator2, state, callback) {
|
|
8980
8980
|
var key = state["keyedList"] ? state["keyedList"][state.index] : state.index;
|
|
8981
|
-
state.jobs[key] = runJob(iterator2, key, list[key], function(error,
|
|
8981
|
+
state.jobs[key] = runJob(iterator2, key, list[key], function(error, output2) {
|
|
8982
8982
|
if (!(key in state.jobs)) {
|
|
8983
8983
|
return;
|
|
8984
8984
|
}
|
|
@@ -8986,7 +8986,7 @@ var require_iterate = __commonJS({
|
|
|
8986
8986
|
if (error) {
|
|
8987
8987
|
abort(state);
|
|
8988
8988
|
} else {
|
|
8989
|
-
state.results[key] =
|
|
8989
|
+
state.results[key] = output2;
|
|
8990
8990
|
}
|
|
8991
8991
|
callback(error, state.results);
|
|
8992
8992
|
});
|
|
@@ -9990,13 +9990,13 @@ var require_form_data = __commonJS({
|
|
|
9990
9990
|
"use strict";
|
|
9991
9991
|
var CombinedStream = require_combined_stream();
|
|
9992
9992
|
var util3 = require("util");
|
|
9993
|
-
var
|
|
9993
|
+
var path10 = require("path");
|
|
9994
9994
|
var http3 = require("http");
|
|
9995
|
-
var
|
|
9995
|
+
var https3 = require("https");
|
|
9996
9996
|
var parseUrl = require("url").parse;
|
|
9997
|
-
var
|
|
9997
|
+
var fs11 = require("fs");
|
|
9998
9998
|
var Stream = require("stream").Stream;
|
|
9999
|
-
var
|
|
9999
|
+
var crypto3 = require("crypto");
|
|
10000
10000
|
var mime = require_mime_types();
|
|
10001
10001
|
var asynckit = require_asynckit();
|
|
10002
10002
|
var setToStringTag = require_es_set_tostringtag();
|
|
@@ -10061,7 +10061,7 @@ var require_form_data = __commonJS({
|
|
|
10061
10061
|
if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
|
|
10062
10062
|
callback(null, value.end + 1 - (value.start ? value.start : 0));
|
|
10063
10063
|
} else {
|
|
10064
|
-
|
|
10064
|
+
fs11.stat(value.path, function(err, stat) {
|
|
10065
10065
|
if (err) {
|
|
10066
10066
|
callback(err);
|
|
10067
10067
|
return;
|
|
@@ -10118,11 +10118,11 @@ var require_form_data = __commonJS({
|
|
|
10118
10118
|
FormData3.prototype._getContentDisposition = function(value, options) {
|
|
10119
10119
|
var filename;
|
|
10120
10120
|
if (typeof options.filepath === "string") {
|
|
10121
|
-
filename =
|
|
10121
|
+
filename = path10.normalize(options.filepath).replace(/\\/g, "/");
|
|
10122
10122
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
10123
|
-
filename =
|
|
10123
|
+
filename = path10.basename(options.filename || value && (value.name || value.path));
|
|
10124
10124
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
10125
|
-
filename =
|
|
10125
|
+
filename = path10.basename(value.client._httpMessage.path || "");
|
|
10126
10126
|
}
|
|
10127
10127
|
if (filename) {
|
|
10128
10128
|
return 'filename="' + filename + '"';
|
|
@@ -10202,7 +10202,7 @@ var require_form_data = __commonJS({
|
|
|
10202
10202
|
return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]);
|
|
10203
10203
|
};
|
|
10204
10204
|
FormData3.prototype._generateBoundary = function() {
|
|
10205
|
-
this._boundary = "--------------------------" +
|
|
10205
|
+
this._boundary = "--------------------------" + crypto3.randomBytes(12).toString("hex");
|
|
10206
10206
|
};
|
|
10207
10207
|
FormData3.prototype.getLengthSync = function() {
|
|
10208
10208
|
var knownLength = this._overheadLength + this._valueLength;
|
|
@@ -10261,7 +10261,7 @@ var require_form_data = __commonJS({
|
|
|
10261
10261
|
}
|
|
10262
10262
|
options.headers = this.getHeaders(params.headers);
|
|
10263
10263
|
if (options.protocol === "https:") {
|
|
10264
|
-
request =
|
|
10264
|
+
request = https3.request(options);
|
|
10265
10265
|
} else {
|
|
10266
10266
|
request = http3.request(options);
|
|
10267
10267
|
}
|
|
@@ -11196,7 +11196,7 @@ var require_follow_redirects = __commonJS({
|
|
|
11196
11196
|
var url2 = require("url");
|
|
11197
11197
|
var URL2 = url2.URL;
|
|
11198
11198
|
var http3 = require("http");
|
|
11199
|
-
var
|
|
11199
|
+
var https3 = require("https");
|
|
11200
11200
|
var Writable = require("stream").Writable;
|
|
11201
11201
|
var assert = require("assert");
|
|
11202
11202
|
var debug = require_debug();
|
|
@@ -11547,15 +11547,15 @@ var require_follow_redirects = __commonJS({
|
|
|
11547
11547
|
var protocol = scheme + ":";
|
|
11548
11548
|
var nativeProtocol = nativeProtocols[protocol] = protocols[scheme];
|
|
11549
11549
|
var wrappedProtocol = exports3[scheme] = Object.create(nativeProtocol);
|
|
11550
|
-
function request(
|
|
11551
|
-
if (isURL(
|
|
11552
|
-
|
|
11553
|
-
} else if (isString3(
|
|
11554
|
-
|
|
11550
|
+
function request(input2, options, callback) {
|
|
11551
|
+
if (isURL(input2)) {
|
|
11552
|
+
input2 = spreadUrlObject(input2);
|
|
11553
|
+
} else if (isString3(input2)) {
|
|
11554
|
+
input2 = spreadUrlObject(parseUrl(input2));
|
|
11555
11555
|
} else {
|
|
11556
11556
|
callback = options;
|
|
11557
|
-
options = validateUrl(
|
|
11558
|
-
|
|
11557
|
+
options = validateUrl(input2);
|
|
11558
|
+
input2 = { protocol };
|
|
11559
11559
|
}
|
|
11560
11560
|
if (isFunction3(options)) {
|
|
11561
11561
|
callback = options;
|
|
@@ -11564,7 +11564,7 @@ var require_follow_redirects = __commonJS({
|
|
|
11564
11564
|
options = Object.assign({
|
|
11565
11565
|
maxRedirects: exports3.maxRedirects,
|
|
11566
11566
|
maxBodyLength: exports3.maxBodyLength
|
|
11567
|
-
},
|
|
11567
|
+
}, input2, options);
|
|
11568
11568
|
options.nativeProtocols = nativeProtocols;
|
|
11569
11569
|
if (!isString3(options.host) && !isString3(options.hostname)) {
|
|
11570
11570
|
options.hostname = "::1";
|
|
@@ -11573,8 +11573,8 @@ var require_follow_redirects = __commonJS({
|
|
|
11573
11573
|
debug("options", options);
|
|
11574
11574
|
return new RedirectableRequest(options, callback);
|
|
11575
11575
|
}
|
|
11576
|
-
function get(
|
|
11577
|
-
var wrappedRequest = wrappedProtocol.request(
|
|
11576
|
+
function get(input2, options, callback) {
|
|
11577
|
+
var wrappedRequest = wrappedProtocol.request(input2, options, callback);
|
|
11578
11578
|
wrappedRequest.end();
|
|
11579
11579
|
return wrappedRequest;
|
|
11580
11580
|
}
|
|
@@ -11587,29 +11587,29 @@ var require_follow_redirects = __commonJS({
|
|
|
11587
11587
|
}
|
|
11588
11588
|
function noop2() {
|
|
11589
11589
|
}
|
|
11590
|
-
function parseUrl(
|
|
11590
|
+
function parseUrl(input2) {
|
|
11591
11591
|
var parsed;
|
|
11592
11592
|
if (useNativeURL) {
|
|
11593
|
-
parsed = new URL2(
|
|
11593
|
+
parsed = new URL2(input2);
|
|
11594
11594
|
} else {
|
|
11595
|
-
parsed = validateUrl(url2.parse(
|
|
11595
|
+
parsed = validateUrl(url2.parse(input2));
|
|
11596
11596
|
if (!isString3(parsed.protocol)) {
|
|
11597
|
-
throw new InvalidUrlError({ input });
|
|
11597
|
+
throw new InvalidUrlError({ input: input2 });
|
|
11598
11598
|
}
|
|
11599
11599
|
}
|
|
11600
11600
|
return parsed;
|
|
11601
11601
|
}
|
|
11602
|
-
function resolveUrl(
|
|
11603
|
-
return useNativeURL ? new URL2(
|
|
11602
|
+
function resolveUrl(relative4, base) {
|
|
11603
|
+
return useNativeURL ? new URL2(relative4, base) : parseUrl(url2.resolve(base, relative4));
|
|
11604
11604
|
}
|
|
11605
|
-
function validateUrl(
|
|
11606
|
-
if (/^\[/.test(
|
|
11607
|
-
throw new InvalidUrlError({ input:
|
|
11605
|
+
function validateUrl(input2) {
|
|
11606
|
+
if (/^\[/.test(input2.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input2.hostname)) {
|
|
11607
|
+
throw new InvalidUrlError({ input: input2.href || input2 });
|
|
11608
11608
|
}
|
|
11609
|
-
if (/^\[/.test(
|
|
11610
|
-
throw new InvalidUrlError({ input:
|
|
11609
|
+
if (/^\[/.test(input2.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input2.host)) {
|
|
11610
|
+
throw new InvalidUrlError({ input: input2.href || input2 });
|
|
11611
11611
|
}
|
|
11612
|
-
return
|
|
11612
|
+
return input2;
|
|
11613
11613
|
}
|
|
11614
11614
|
function spreadUrlObject(urlObject, target) {
|
|
11615
11615
|
var spread3 = target || {};
|
|
@@ -11681,7 +11681,7 @@ var require_follow_redirects = __commonJS({
|
|
|
11681
11681
|
function isURL(value) {
|
|
11682
11682
|
return URL2 && value instanceof URL2;
|
|
11683
11683
|
}
|
|
11684
|
-
module2.exports = wrap({ http: http3, https:
|
|
11684
|
+
module2.exports = wrap({ http: http3, https: https3 });
|
|
11685
11685
|
module2.exports.wrap = wrap;
|
|
11686
11686
|
}
|
|
11687
11687
|
});
|
|
@@ -15089,7 +15089,7 @@ var require_compile = __commonJS({
|
|
|
15089
15089
|
const schOrFunc = root.refs[ref];
|
|
15090
15090
|
if (schOrFunc)
|
|
15091
15091
|
return schOrFunc;
|
|
15092
|
-
let _sch =
|
|
15092
|
+
let _sch = resolve9.call(this, root, ref);
|
|
15093
15093
|
if (_sch === void 0) {
|
|
15094
15094
|
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
|
|
15095
15095
|
const { schemaId } = this.opts;
|
|
@@ -15116,7 +15116,7 @@ var require_compile = __commonJS({
|
|
|
15116
15116
|
function sameSchemaEnv(s1, s2) {
|
|
15117
15117
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
15118
15118
|
}
|
|
15119
|
-
function
|
|
15119
|
+
function resolve9(root, ref) {
|
|
15120
15120
|
let sch;
|
|
15121
15121
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
15122
15122
|
ref = sch;
|
|
@@ -15214,27 +15214,27 @@ var require_utils = __commonJS({
|
|
|
15214
15214
|
"use strict";
|
|
15215
15215
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
15216
15216
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
15217
|
-
function stringArrayToHexStripped(
|
|
15217
|
+
function stringArrayToHexStripped(input2) {
|
|
15218
15218
|
let acc = "";
|
|
15219
15219
|
let code = 0;
|
|
15220
15220
|
let i = 0;
|
|
15221
|
-
for (i = 0; i <
|
|
15222
|
-
code =
|
|
15221
|
+
for (i = 0; i < input2.length; i++) {
|
|
15222
|
+
code = input2[i].charCodeAt(0);
|
|
15223
15223
|
if (code === 48) {
|
|
15224
15224
|
continue;
|
|
15225
15225
|
}
|
|
15226
15226
|
if (!(code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102)) {
|
|
15227
15227
|
return "";
|
|
15228
15228
|
}
|
|
15229
|
-
acc +=
|
|
15229
|
+
acc += input2[i];
|
|
15230
15230
|
break;
|
|
15231
15231
|
}
|
|
15232
|
-
for (i += 1; i <
|
|
15233
|
-
code =
|
|
15232
|
+
for (i += 1; i < input2.length; i++) {
|
|
15233
|
+
code = input2[i].charCodeAt(0);
|
|
15234
15234
|
if (!(code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102)) {
|
|
15235
15235
|
return "";
|
|
15236
15236
|
}
|
|
15237
|
-
acc +=
|
|
15237
|
+
acc += input2[i];
|
|
15238
15238
|
}
|
|
15239
15239
|
return acc;
|
|
15240
15240
|
}
|
|
@@ -15243,29 +15243,29 @@ var require_utils = __commonJS({
|
|
|
15243
15243
|
buffer.length = 0;
|
|
15244
15244
|
return true;
|
|
15245
15245
|
}
|
|
15246
|
-
function consumeHextets(buffer, address,
|
|
15246
|
+
function consumeHextets(buffer, address, output2) {
|
|
15247
15247
|
if (buffer.length) {
|
|
15248
15248
|
const hex = stringArrayToHexStripped(buffer);
|
|
15249
15249
|
if (hex !== "") {
|
|
15250
15250
|
address.push(hex);
|
|
15251
15251
|
} else {
|
|
15252
|
-
|
|
15252
|
+
output2.error = true;
|
|
15253
15253
|
return false;
|
|
15254
15254
|
}
|
|
15255
15255
|
buffer.length = 0;
|
|
15256
15256
|
}
|
|
15257
15257
|
return true;
|
|
15258
15258
|
}
|
|
15259
|
-
function getIPV6(
|
|
15259
|
+
function getIPV6(input2) {
|
|
15260
15260
|
let tokenCount = 0;
|
|
15261
|
-
const
|
|
15261
|
+
const output2 = { error: false, address: "", zone: "" };
|
|
15262
15262
|
const address = [];
|
|
15263
15263
|
const buffer = [];
|
|
15264
15264
|
let endipv6Encountered = false;
|
|
15265
15265
|
let endIpv6 = false;
|
|
15266
15266
|
let consume = consumeHextets;
|
|
15267
|
-
for (let i = 0; i <
|
|
15268
|
-
const cursor =
|
|
15267
|
+
for (let i = 0; i < input2.length; i++) {
|
|
15268
|
+
const cursor = input2[i];
|
|
15269
15269
|
if (cursor === "[" || cursor === "]") {
|
|
15270
15270
|
continue;
|
|
15271
15271
|
}
|
|
@@ -15273,20 +15273,20 @@ var require_utils = __commonJS({
|
|
|
15273
15273
|
if (endipv6Encountered === true) {
|
|
15274
15274
|
endIpv6 = true;
|
|
15275
15275
|
}
|
|
15276
|
-
if (!consume(buffer, address,
|
|
15276
|
+
if (!consume(buffer, address, output2)) {
|
|
15277
15277
|
break;
|
|
15278
15278
|
}
|
|
15279
15279
|
if (++tokenCount > 7) {
|
|
15280
|
-
|
|
15280
|
+
output2.error = true;
|
|
15281
15281
|
break;
|
|
15282
15282
|
}
|
|
15283
|
-
if (i > 0 &&
|
|
15283
|
+
if (i > 0 && input2[i - 1] === ":") {
|
|
15284
15284
|
endipv6Encountered = true;
|
|
15285
15285
|
}
|
|
15286
15286
|
address.push(":");
|
|
15287
15287
|
continue;
|
|
15288
15288
|
} else if (cursor === "%") {
|
|
15289
|
-
if (!consume(buffer, address,
|
|
15289
|
+
if (!consume(buffer, address, output2)) {
|
|
15290
15290
|
break;
|
|
15291
15291
|
}
|
|
15292
15292
|
consume = consumeIsZone;
|
|
@@ -15297,15 +15297,15 @@ var require_utils = __commonJS({
|
|
|
15297
15297
|
}
|
|
15298
15298
|
if (buffer.length) {
|
|
15299
15299
|
if (consume === consumeIsZone) {
|
|
15300
|
-
|
|
15300
|
+
output2.zone = buffer.join("");
|
|
15301
15301
|
} else if (endIpv6) {
|
|
15302
15302
|
address.push(buffer.join(""));
|
|
15303
15303
|
} else {
|
|
15304
15304
|
address.push(stringArrayToHexStripped(buffer));
|
|
15305
15305
|
}
|
|
15306
15306
|
}
|
|
15307
|
-
|
|
15308
|
-
return
|
|
15307
|
+
output2.address = address.join("");
|
|
15308
|
+
return output2;
|
|
15309
15309
|
}
|
|
15310
15310
|
function normalizeIPv6(host) {
|
|
15311
15311
|
if (findToken(host, ":") < 2) {
|
|
@@ -15331,80 +15331,80 @@ var require_utils = __commonJS({
|
|
|
15331
15331
|
}
|
|
15332
15332
|
return ind;
|
|
15333
15333
|
}
|
|
15334
|
-
function removeDotSegments(
|
|
15335
|
-
let
|
|
15336
|
-
const
|
|
15334
|
+
function removeDotSegments(path10) {
|
|
15335
|
+
let input2 = path10;
|
|
15336
|
+
const output2 = [];
|
|
15337
15337
|
let nextSlash = -1;
|
|
15338
15338
|
let len = 0;
|
|
15339
|
-
while (len =
|
|
15339
|
+
while (len = input2.length) {
|
|
15340
15340
|
if (len === 1) {
|
|
15341
|
-
if (
|
|
15341
|
+
if (input2 === ".") {
|
|
15342
15342
|
break;
|
|
15343
|
-
} else if (
|
|
15344
|
-
|
|
15343
|
+
} else if (input2 === "/") {
|
|
15344
|
+
output2.push("/");
|
|
15345
15345
|
break;
|
|
15346
15346
|
} else {
|
|
15347
|
-
|
|
15347
|
+
output2.push(input2);
|
|
15348
15348
|
break;
|
|
15349
15349
|
}
|
|
15350
15350
|
} else if (len === 2) {
|
|
15351
|
-
if (
|
|
15352
|
-
if (
|
|
15351
|
+
if (input2[0] === ".") {
|
|
15352
|
+
if (input2[1] === ".") {
|
|
15353
15353
|
break;
|
|
15354
|
-
} else if (
|
|
15355
|
-
|
|
15354
|
+
} else if (input2[1] === "/") {
|
|
15355
|
+
input2 = input2.slice(2);
|
|
15356
15356
|
continue;
|
|
15357
15357
|
}
|
|
15358
|
-
} else if (
|
|
15359
|
-
if (
|
|
15360
|
-
|
|
15358
|
+
} else if (input2[0] === "/") {
|
|
15359
|
+
if (input2[1] === "." || input2[1] === "/") {
|
|
15360
|
+
output2.push("/");
|
|
15361
15361
|
break;
|
|
15362
15362
|
}
|
|
15363
15363
|
}
|
|
15364
15364
|
} else if (len === 3) {
|
|
15365
|
-
if (
|
|
15366
|
-
if (
|
|
15367
|
-
|
|
15365
|
+
if (input2 === "/..") {
|
|
15366
|
+
if (output2.length !== 0) {
|
|
15367
|
+
output2.pop();
|
|
15368
15368
|
}
|
|
15369
|
-
|
|
15369
|
+
output2.push("/");
|
|
15370
15370
|
break;
|
|
15371
15371
|
}
|
|
15372
15372
|
}
|
|
15373
|
-
if (
|
|
15374
|
-
if (
|
|
15375
|
-
if (
|
|
15376
|
-
|
|
15373
|
+
if (input2[0] === ".") {
|
|
15374
|
+
if (input2[1] === ".") {
|
|
15375
|
+
if (input2[2] === "/") {
|
|
15376
|
+
input2 = input2.slice(3);
|
|
15377
15377
|
continue;
|
|
15378
15378
|
}
|
|
15379
|
-
} else if (
|
|
15380
|
-
|
|
15379
|
+
} else if (input2[1] === "/") {
|
|
15380
|
+
input2 = input2.slice(2);
|
|
15381
15381
|
continue;
|
|
15382
15382
|
}
|
|
15383
|
-
} else if (
|
|
15384
|
-
if (
|
|
15385
|
-
if (
|
|
15386
|
-
|
|
15383
|
+
} else if (input2[0] === "/") {
|
|
15384
|
+
if (input2[1] === ".") {
|
|
15385
|
+
if (input2[2] === "/") {
|
|
15386
|
+
input2 = input2.slice(2);
|
|
15387
15387
|
continue;
|
|
15388
|
-
} else if (
|
|
15389
|
-
if (
|
|
15390
|
-
|
|
15391
|
-
if (
|
|
15392
|
-
|
|
15388
|
+
} else if (input2[2] === ".") {
|
|
15389
|
+
if (input2[3] === "/") {
|
|
15390
|
+
input2 = input2.slice(3);
|
|
15391
|
+
if (output2.length !== 0) {
|
|
15392
|
+
output2.pop();
|
|
15393
15393
|
}
|
|
15394
15394
|
continue;
|
|
15395
15395
|
}
|
|
15396
15396
|
}
|
|
15397
15397
|
}
|
|
15398
15398
|
}
|
|
15399
|
-
if ((nextSlash =
|
|
15400
|
-
|
|
15399
|
+
if ((nextSlash = input2.indexOf("/", 1)) === -1) {
|
|
15400
|
+
output2.push(input2);
|
|
15401
15401
|
break;
|
|
15402
15402
|
} else {
|
|
15403
|
-
|
|
15404
|
-
|
|
15403
|
+
output2.push(input2.slice(0, nextSlash));
|
|
15404
|
+
input2 = input2.slice(nextSlash);
|
|
15405
15405
|
}
|
|
15406
15406
|
}
|
|
15407
|
-
return
|
|
15407
|
+
return output2.join("");
|
|
15408
15408
|
}
|
|
15409
15409
|
function normalizeComponentEncoding(component, esc) {
|
|
15410
15410
|
const func = esc !== true ? escape : unescape;
|
|
@@ -15531,8 +15531,8 @@ var require_schemes = __commonJS({
|
|
|
15531
15531
|
wsComponent.secure = void 0;
|
|
15532
15532
|
}
|
|
15533
15533
|
if (wsComponent.resourceName) {
|
|
15534
|
-
const [
|
|
15535
|
-
wsComponent.path =
|
|
15534
|
+
const [path10, query] = wsComponent.resourceName.split("?");
|
|
15535
|
+
wsComponent.path = path10 && path10 !== "/" ? path10 : void 0;
|
|
15536
15536
|
wsComponent.query = query;
|
|
15537
15537
|
wsComponent.resourceName = void 0;
|
|
15538
15538
|
}
|
|
@@ -15600,7 +15600,7 @@ var require_schemes = __commonJS({
|
|
|
15600
15600
|
serialize: httpSerialize
|
|
15601
15601
|
}
|
|
15602
15602
|
);
|
|
15603
|
-
var
|
|
15603
|
+
var https3 = (
|
|
15604
15604
|
/** @type {SchemeHandler} */
|
|
15605
15605
|
{
|
|
15606
15606
|
scheme: "https",
|
|
@@ -15649,7 +15649,7 @@ var require_schemes = __commonJS({
|
|
|
15649
15649
|
/** @type {Record<SchemeName, SchemeHandler>} */
|
|
15650
15650
|
{
|
|
15651
15651
|
http: http3,
|
|
15652
|
-
https:
|
|
15652
|
+
https: https3,
|
|
15653
15653
|
ws,
|
|
15654
15654
|
wss,
|
|
15655
15655
|
urn,
|
|
@@ -15691,55 +15691,55 @@ var require_fast_uri = __commonJS({
|
|
|
15691
15691
|
}
|
|
15692
15692
|
return uri;
|
|
15693
15693
|
}
|
|
15694
|
-
function
|
|
15694
|
+
function resolve9(baseURI, relativeURI, options) {
|
|
15695
15695
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
15696
15696
|
const resolved = resolveComponent(parse2(baseURI, schemelessOptions), parse2(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
15697
15697
|
schemelessOptions.skipEscape = true;
|
|
15698
15698
|
return serialize(resolved, schemelessOptions);
|
|
15699
15699
|
}
|
|
15700
|
-
function resolveComponent(base,
|
|
15700
|
+
function resolveComponent(base, relative4, options, skipNormalization) {
|
|
15701
15701
|
const target = {};
|
|
15702
15702
|
if (!skipNormalization) {
|
|
15703
15703
|
base = parse2(serialize(base, options), options);
|
|
15704
|
-
|
|
15704
|
+
relative4 = parse2(serialize(relative4, options), options);
|
|
15705
15705
|
}
|
|
15706
15706
|
options = options || {};
|
|
15707
|
-
if (!options.tolerant &&
|
|
15708
|
-
target.scheme =
|
|
15709
|
-
target.userinfo =
|
|
15710
|
-
target.host =
|
|
15711
|
-
target.port =
|
|
15712
|
-
target.path = removeDotSegments(
|
|
15713
|
-
target.query =
|
|
15707
|
+
if (!options.tolerant && relative4.scheme) {
|
|
15708
|
+
target.scheme = relative4.scheme;
|
|
15709
|
+
target.userinfo = relative4.userinfo;
|
|
15710
|
+
target.host = relative4.host;
|
|
15711
|
+
target.port = relative4.port;
|
|
15712
|
+
target.path = removeDotSegments(relative4.path || "");
|
|
15713
|
+
target.query = relative4.query;
|
|
15714
15714
|
} else {
|
|
15715
|
-
if (
|
|
15716
|
-
target.userinfo =
|
|
15717
|
-
target.host =
|
|
15718
|
-
target.port =
|
|
15719
|
-
target.path = removeDotSegments(
|
|
15720
|
-
target.query =
|
|
15715
|
+
if (relative4.userinfo !== void 0 || relative4.host !== void 0 || relative4.port !== void 0) {
|
|
15716
|
+
target.userinfo = relative4.userinfo;
|
|
15717
|
+
target.host = relative4.host;
|
|
15718
|
+
target.port = relative4.port;
|
|
15719
|
+
target.path = removeDotSegments(relative4.path || "");
|
|
15720
|
+
target.query = relative4.query;
|
|
15721
15721
|
} else {
|
|
15722
|
-
if (!
|
|
15722
|
+
if (!relative4.path) {
|
|
15723
15723
|
target.path = base.path;
|
|
15724
|
-
if (
|
|
15725
|
-
target.query =
|
|
15724
|
+
if (relative4.query !== void 0) {
|
|
15725
|
+
target.query = relative4.query;
|
|
15726
15726
|
} else {
|
|
15727
15727
|
target.query = base.query;
|
|
15728
15728
|
}
|
|
15729
15729
|
} else {
|
|
15730
|
-
if (
|
|
15731
|
-
target.path = removeDotSegments(
|
|
15730
|
+
if (relative4.path[0] === "/") {
|
|
15731
|
+
target.path = removeDotSegments(relative4.path);
|
|
15732
15732
|
} else {
|
|
15733
15733
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
15734
|
-
target.path = "/" +
|
|
15734
|
+
target.path = "/" + relative4.path;
|
|
15735
15735
|
} else if (!base.path) {
|
|
15736
|
-
target.path =
|
|
15736
|
+
target.path = relative4.path;
|
|
15737
15737
|
} else {
|
|
15738
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
15738
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative4.path;
|
|
15739
15739
|
}
|
|
15740
15740
|
target.path = removeDotSegments(target.path);
|
|
15741
15741
|
}
|
|
15742
|
-
target.query =
|
|
15742
|
+
target.query = relative4.query;
|
|
15743
15743
|
}
|
|
15744
15744
|
target.userinfo = base.userinfo;
|
|
15745
15745
|
target.host = base.host;
|
|
@@ -15747,7 +15747,7 @@ var require_fast_uri = __commonJS({
|
|
|
15747
15747
|
}
|
|
15748
15748
|
target.scheme = base.scheme;
|
|
15749
15749
|
}
|
|
15750
|
-
target.fragment =
|
|
15750
|
+
target.fragment = relative4.fragment;
|
|
15751
15751
|
return target;
|
|
15752
15752
|
}
|
|
15753
15753
|
function equal(uriA, uriB, options) {
|
|
@@ -15918,7 +15918,7 @@ var require_fast_uri = __commonJS({
|
|
|
15918
15918
|
var fastUri = {
|
|
15919
15919
|
SCHEMES,
|
|
15920
15920
|
normalize,
|
|
15921
|
-
resolve:
|
|
15921
|
+
resolve: resolve9,
|
|
15922
15922
|
resolveComponent,
|
|
15923
15923
|
equal,
|
|
15924
15924
|
serialize,
|
|
@@ -18738,8 +18738,8 @@ function validateAgainstSchemaDetailed(value, schemaPath, basePath, workspaceRoo
|
|
|
18738
18738
|
if (!valid && validate2.errors) {
|
|
18739
18739
|
const errors = validate2.errors.map((err) => convertAjvError(err, value));
|
|
18740
18740
|
const errorStrings = validate2.errors.map((err) => {
|
|
18741
|
-
const
|
|
18742
|
-
return `${
|
|
18741
|
+
const path10 = err.instancePath || "(root)";
|
|
18742
|
+
return `${path10}: ${err.message}`;
|
|
18743
18743
|
});
|
|
18744
18744
|
return {
|
|
18745
18745
|
valid: false,
|
|
@@ -18868,7 +18868,7 @@ function resolveValue(expr, responses, variables, getValueByPath2, responseIndex
|
|
|
18868
18868
|
if (refMatch) {
|
|
18869
18869
|
const responseIdx = parseInt(refMatch[1], 10);
|
|
18870
18870
|
const responseIndex = responseIdx - 1;
|
|
18871
|
-
const
|
|
18871
|
+
const path10 = refMatch[2];
|
|
18872
18872
|
if (responseIndex < 0 || responseIndex >= responses.length) {
|
|
18873
18873
|
return {
|
|
18874
18874
|
value: void 0,
|
|
@@ -18876,12 +18876,12 @@ function resolveValue(expr, responses, variables, getValueByPath2, responseIndex
|
|
|
18876
18876
|
};
|
|
18877
18877
|
}
|
|
18878
18878
|
const response = responses[responseIndex];
|
|
18879
|
-
const value = getValueByPath2(response,
|
|
18879
|
+
const value = getValueByPath2(response, path10);
|
|
18880
18880
|
return {
|
|
18881
18881
|
value,
|
|
18882
18882
|
responseIndex: responseIdx,
|
|
18883
18883
|
response,
|
|
18884
|
-
jsonPath:
|
|
18884
|
+
jsonPath: path10,
|
|
18885
18885
|
variableName: responseIndexToVariable?.get(responseIdx)
|
|
18886
18886
|
};
|
|
18887
18887
|
}
|
|
@@ -18898,22 +18898,22 @@ function resolveValue(expr, responses, variables, getValueByPath2, responseIndex
|
|
|
18898
18898
|
if (varName in variables) {
|
|
18899
18899
|
const varValue = variables[varName];
|
|
18900
18900
|
if (typeof varValue === "object" && varValue !== null) {
|
|
18901
|
-
const
|
|
18902
|
-
const value = getNestedValue2(varValue,
|
|
18901
|
+
const path10 = pathPart.replace(/^\./, "");
|
|
18902
|
+
const value = getNestedValue2(varValue, path10);
|
|
18903
18903
|
const isHttpResponse = "status" in varValue && "body" in varValue;
|
|
18904
18904
|
return {
|
|
18905
18905
|
value,
|
|
18906
18906
|
variableName: varName,
|
|
18907
|
-
jsonPath:
|
|
18907
|
+
jsonPath: path10,
|
|
18908
18908
|
response: isHttpResponse ? varValue : void 0
|
|
18909
18909
|
};
|
|
18910
18910
|
}
|
|
18911
18911
|
if (typeof varValue === "string") {
|
|
18912
18912
|
try {
|
|
18913
18913
|
const parsed = JSON.parse(varValue);
|
|
18914
|
-
const
|
|
18915
|
-
const value = getNestedValue2(parsed,
|
|
18916
|
-
return { value, variableName: varName, jsonPath:
|
|
18914
|
+
const path10 = pathPart.replace(/^\./, "");
|
|
18915
|
+
const value = getNestedValue2(parsed, path10);
|
|
18916
|
+
return { value, variableName: varName, jsonPath: path10 };
|
|
18917
18917
|
} catch {
|
|
18918
18918
|
return { value: void 0, error: `Cannot access path on non-object variable: ${varName}` };
|
|
18919
18919
|
}
|
|
@@ -18969,11 +18969,11 @@ function resolveValue(expr, responses, variables, getValueByPath2, responseIndex
|
|
|
18969
18969
|
}
|
|
18970
18970
|
return { value: void 0, error: `Cannot resolve expression: ${trimmed}` };
|
|
18971
18971
|
}
|
|
18972
|
-
function getNestedValue2(obj,
|
|
18973
|
-
if (!
|
|
18972
|
+
function getNestedValue2(obj, path10) {
|
|
18973
|
+
if (!path10 || obj === null || obj === void 0) {
|
|
18974
18974
|
return obj;
|
|
18975
18975
|
}
|
|
18976
|
-
const parts =
|
|
18976
|
+
const parts = path10.replace(/\[(\d+)\]/g, ".$1").split(".").filter((p) => p !== "");
|
|
18977
18977
|
let current = obj;
|
|
18978
18978
|
for (const part of parts) {
|
|
18979
18979
|
if (current === null || current === void 0) {
|
|
@@ -19769,16 +19769,16 @@ var init_source = __esm({
|
|
|
19769
19769
|
});
|
|
19770
19770
|
|
|
19771
19771
|
// src/cli.ts
|
|
19772
|
-
var
|
|
19772
|
+
var fs10 = __toESM(require("fs"));
|
|
19773
19773
|
var fsPromises = __toESM(require("fs/promises"));
|
|
19774
|
-
var
|
|
19774
|
+
var path9 = __toESM(require("path"));
|
|
19775
19775
|
|
|
19776
19776
|
// src/nornapiParser.ts
|
|
19777
|
-
function extractPathParameters(
|
|
19777
|
+
function extractPathParameters(path10) {
|
|
19778
19778
|
const params = [];
|
|
19779
19779
|
const regex = /(?<!\{)\{([a-zA-Z_][a-zA-Z0-9_]*)\}(?!\})/g;
|
|
19780
19780
|
let match;
|
|
19781
|
-
while ((match = regex.exec(
|
|
19781
|
+
while ((match = regex.exec(path10)) !== null) {
|
|
19782
19782
|
params.push(match[1]);
|
|
19783
19783
|
}
|
|
19784
19784
|
return params;
|
|
@@ -19828,12 +19828,12 @@ function parseNornApiFile(content) {
|
|
|
19828
19828
|
if (inEndpointsBlock) {
|
|
19829
19829
|
const endpointMatch = trimmed.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+(.+)$/i);
|
|
19830
19830
|
if (endpointMatch) {
|
|
19831
|
-
const
|
|
19831
|
+
const path10 = endpointMatch[3].trim();
|
|
19832
19832
|
endpoints.push({
|
|
19833
19833
|
name: endpointMatch[1],
|
|
19834
19834
|
method: endpointMatch[2].toUpperCase(),
|
|
19835
|
-
path:
|
|
19836
|
-
parameters: extractPathParameters(
|
|
19835
|
+
path: path10,
|
|
19836
|
+
parameters: extractPathParameters(path10)
|
|
19837
19837
|
});
|
|
19838
19838
|
}
|
|
19839
19839
|
continue;
|
|
@@ -20123,11 +20123,11 @@ function extractFileLevelVariables(text) {
|
|
|
20123
20123
|
}
|
|
20124
20124
|
return variables;
|
|
20125
20125
|
}
|
|
20126
|
-
function getNestedValue(obj,
|
|
20127
|
-
if (!
|
|
20126
|
+
function getNestedValue(obj, path10) {
|
|
20127
|
+
if (!path10 || obj === null || obj === void 0) {
|
|
20128
20128
|
return obj;
|
|
20129
20129
|
}
|
|
20130
|
-
const parts =
|
|
20130
|
+
const parts = path10.replace(/\[(\d+)\]/g, ".$1").split(".").filter((p) => p !== "");
|
|
20131
20131
|
let current = obj;
|
|
20132
20132
|
for (const part of parts) {
|
|
20133
20133
|
if (current === null || current === void 0) {
|
|
@@ -20159,8 +20159,8 @@ function substituteVariables(text, variables) {
|
|
|
20159
20159
|
const value = variables[varName];
|
|
20160
20160
|
if (typeof value === "object" && value !== null) {
|
|
20161
20161
|
if (pathPart) {
|
|
20162
|
-
const
|
|
20163
|
-
const nestedValue = getNestedValue(value,
|
|
20162
|
+
const path10 = pathPart.replace(/^\./, "");
|
|
20163
|
+
const nestedValue = getNestedValue(value, path10);
|
|
20164
20164
|
return valueToString(nestedValue);
|
|
20165
20165
|
}
|
|
20166
20166
|
return valueToString(value);
|
|
@@ -20168,8 +20168,8 @@ function substituteVariables(text, variables) {
|
|
|
20168
20168
|
if (pathPart && typeof value === "string") {
|
|
20169
20169
|
try {
|
|
20170
20170
|
const parsed = JSON.parse(value);
|
|
20171
|
-
const
|
|
20172
|
-
const nestedValue = getNestedValue(parsed,
|
|
20171
|
+
const path10 = pathPart.replace(/^\./, "");
|
|
20172
|
+
const nestedValue = getNestedValue(parsed, path10);
|
|
20173
20173
|
return valueToString(nestedValue);
|
|
20174
20174
|
} catch {
|
|
20175
20175
|
return value;
|
|
@@ -20285,8 +20285,8 @@ async function resolveImports(text, baseDir, readFile2, alreadyImported = /* @__
|
|
|
20285
20285
|
const namedRequestSources = /* @__PURE__ */ new Map();
|
|
20286
20286
|
const sequenceSources = /* @__PURE__ */ new Map();
|
|
20287
20287
|
for (const imp of imports) {
|
|
20288
|
-
const
|
|
20289
|
-
const absolutePath =
|
|
20288
|
+
const path10 = await import("path");
|
|
20289
|
+
const absolutePath = path10.resolve(baseDir, imp.path);
|
|
20290
20290
|
if (importStack.has(absolutePath)) {
|
|
20291
20291
|
errors.push({
|
|
20292
20292
|
path: imp.path,
|
|
@@ -20333,7 +20333,7 @@ async function resolveImports(text, baseDir, readFile2, alreadyImported = /* @__
|
|
|
20333
20333
|
}
|
|
20334
20334
|
continue;
|
|
20335
20335
|
}
|
|
20336
|
-
const importDir =
|
|
20336
|
+
const importDir = path10.dirname(absolutePath);
|
|
20337
20337
|
const nestedResult = await resolveImports(content, importDir, readFile2, alreadyImported, importStack);
|
|
20338
20338
|
errors.push(...nestedResult.errors);
|
|
20339
20339
|
resolvedPaths.push(...nestedResult.resolvedPaths);
|
|
@@ -20932,9 +20932,9 @@ function isVisitable(thing) {
|
|
|
20932
20932
|
function removeBrackets(key) {
|
|
20933
20933
|
return utils_default.endsWith(key, "[]") ? key.slice(0, -2) : key;
|
|
20934
20934
|
}
|
|
20935
|
-
function renderKey(
|
|
20936
|
-
if (!
|
|
20937
|
-
return
|
|
20935
|
+
function renderKey(path10, key, dots) {
|
|
20936
|
+
if (!path10) return key;
|
|
20937
|
+
return path10.concat(key).map(function each(token, i) {
|
|
20938
20938
|
token = removeBrackets(token);
|
|
20939
20939
|
return !dots && i ? "[" + token + "]" : token;
|
|
20940
20940
|
}).join(dots ? "." : "");
|
|
@@ -20982,9 +20982,9 @@ function toFormData(obj, formData, options) {
|
|
|
20982
20982
|
}
|
|
20983
20983
|
return value;
|
|
20984
20984
|
}
|
|
20985
|
-
function defaultVisitor(value, key,
|
|
20985
|
+
function defaultVisitor(value, key, path10) {
|
|
20986
20986
|
let arr = value;
|
|
20987
|
-
if (value && !
|
|
20987
|
+
if (value && !path10 && typeof value === "object") {
|
|
20988
20988
|
if (utils_default.endsWith(key, "{}")) {
|
|
20989
20989
|
key = metaTokens ? key : key.slice(0, -2);
|
|
20990
20990
|
value = JSON.stringify(value);
|
|
@@ -21003,7 +21003,7 @@ function toFormData(obj, formData, options) {
|
|
|
21003
21003
|
if (isVisitable(value)) {
|
|
21004
21004
|
return true;
|
|
21005
21005
|
}
|
|
21006
|
-
formData.append(renderKey(
|
|
21006
|
+
formData.append(renderKey(path10, key, dots), convertValue(value));
|
|
21007
21007
|
return false;
|
|
21008
21008
|
}
|
|
21009
21009
|
const stack = [];
|
|
@@ -21012,10 +21012,10 @@ function toFormData(obj, formData, options) {
|
|
|
21012
21012
|
convertValue,
|
|
21013
21013
|
isVisitable
|
|
21014
21014
|
});
|
|
21015
|
-
function build(value,
|
|
21015
|
+
function build(value, path10) {
|
|
21016
21016
|
if (utils_default.isUndefined(value)) return;
|
|
21017
21017
|
if (stack.indexOf(value) !== -1) {
|
|
21018
|
-
throw Error("Circular reference detected in " +
|
|
21018
|
+
throw Error("Circular reference detected in " + path10.join("."));
|
|
21019
21019
|
}
|
|
21020
21020
|
stack.push(value);
|
|
21021
21021
|
utils_default.forEach(value, function each(el, key) {
|
|
@@ -21023,11 +21023,11 @@ function toFormData(obj, formData, options) {
|
|
|
21023
21023
|
formData,
|
|
21024
21024
|
el,
|
|
21025
21025
|
utils_default.isString(key) ? key.trim() : key,
|
|
21026
|
-
|
|
21026
|
+
path10,
|
|
21027
21027
|
exposedHelpers
|
|
21028
21028
|
);
|
|
21029
21029
|
if (result === true) {
|
|
21030
|
-
build(el,
|
|
21030
|
+
build(el, path10 ? path10.concat(key) : [key]);
|
|
21031
21031
|
}
|
|
21032
21032
|
});
|
|
21033
21033
|
stack.pop();
|
|
@@ -21239,7 +21239,7 @@ var platform_default = {
|
|
|
21239
21239
|
// node_modules/axios/lib/helpers/toURLEncodedForm.js
|
|
21240
21240
|
function toURLEncodedForm(data, options) {
|
|
21241
21241
|
return toFormData_default(data, new platform_default.classes.URLSearchParams(), {
|
|
21242
|
-
visitor: function(value, key,
|
|
21242
|
+
visitor: function(value, key, path10, helpers) {
|
|
21243
21243
|
if (platform_default.isNode && utils_default.isBuffer(value)) {
|
|
21244
21244
|
this.append(key, value.toString("base64"));
|
|
21245
21245
|
return false;
|
|
@@ -21269,11 +21269,11 @@ function arrayToObject(arr) {
|
|
|
21269
21269
|
return obj;
|
|
21270
21270
|
}
|
|
21271
21271
|
function formDataToJSON(formData) {
|
|
21272
|
-
function buildPath(
|
|
21273
|
-
let name =
|
|
21272
|
+
function buildPath(path10, value, target, index) {
|
|
21273
|
+
let name = path10[index++];
|
|
21274
21274
|
if (name === "__proto__") return true;
|
|
21275
21275
|
const isNumericKey = Number.isFinite(+name);
|
|
21276
|
-
const isLast = index >=
|
|
21276
|
+
const isLast = index >= path10.length;
|
|
21277
21277
|
name = !name && utils_default.isArray(target) ? target.length : name;
|
|
21278
21278
|
if (isLast) {
|
|
21279
21279
|
if (utils_default.hasOwnProp(target, name)) {
|
|
@@ -21286,7 +21286,7 @@ function formDataToJSON(formData) {
|
|
|
21286
21286
|
if (!target[name] || !utils_default.isObject(target[name])) {
|
|
21287
21287
|
target[name] = [];
|
|
21288
21288
|
}
|
|
21289
|
-
const result = buildPath(
|
|
21289
|
+
const result = buildPath(path10, value, target[name], index);
|
|
21290
21290
|
if (result && utils_default.isArray(target[name])) {
|
|
21291
21291
|
target[name] = arrayToObject(target[name]);
|
|
21292
21292
|
}
|
|
@@ -21715,10 +21715,10 @@ utils_default.inherits(CanceledError, AxiosError_default, {
|
|
|
21715
21715
|
var CanceledError_default = CanceledError;
|
|
21716
21716
|
|
|
21717
21717
|
// node_modules/axios/lib/core/settle.js
|
|
21718
|
-
function settle(
|
|
21718
|
+
function settle(resolve9, reject, response) {
|
|
21719
21719
|
const validateStatus2 = response.config.validateStatus;
|
|
21720
21720
|
if (!response.status || !validateStatus2 || validateStatus2(response.status)) {
|
|
21721
|
-
|
|
21721
|
+
resolve9(response);
|
|
21722
21722
|
} else {
|
|
21723
21723
|
reject(new AxiosError_default(
|
|
21724
21724
|
"Request failed with status code " + response.status,
|
|
@@ -22341,7 +22341,7 @@ function setProxy(options, configProxy, location) {
|
|
|
22341
22341
|
}
|
|
22342
22342
|
var isHttpAdapterSupported = typeof process !== "undefined" && utils_default.kindOf(process) === "process";
|
|
22343
22343
|
var wrapAsync = (asyncExecutor) => {
|
|
22344
|
-
return new Promise((
|
|
22344
|
+
return new Promise((resolve9, reject) => {
|
|
22345
22345
|
let onDone;
|
|
22346
22346
|
let isDone;
|
|
22347
22347
|
const done = (value, isRejected) => {
|
|
@@ -22351,7 +22351,7 @@ var wrapAsync = (asyncExecutor) => {
|
|
|
22351
22351
|
};
|
|
22352
22352
|
const _resolve = (value) => {
|
|
22353
22353
|
done(value);
|
|
22354
|
-
|
|
22354
|
+
resolve9(value);
|
|
22355
22355
|
};
|
|
22356
22356
|
const _reject = (reason) => {
|
|
22357
22357
|
done(reason, true);
|
|
@@ -22403,7 +22403,7 @@ var http2Transport = {
|
|
|
22403
22403
|
}
|
|
22404
22404
|
};
|
|
22405
22405
|
var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
22406
|
-
return wrapAsync(async function dispatchHttpRequest(
|
|
22406
|
+
return wrapAsync(async function dispatchHttpRequest(resolve9, reject, onDone) {
|
|
22407
22407
|
let { data, lookup, family, httpVersion = 1, http2Options } = config;
|
|
22408
22408
|
const { responseType, responseEncoding } = config;
|
|
22409
22409
|
const method = config.method.toUpperCase();
|
|
@@ -22488,7 +22488,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
22488
22488
|
}
|
|
22489
22489
|
let convertedData;
|
|
22490
22490
|
if (method !== "GET") {
|
|
22491
|
-
return settle(
|
|
22491
|
+
return settle(resolve9, reject, {
|
|
22492
22492
|
status: 405,
|
|
22493
22493
|
statusText: "method not allowed",
|
|
22494
22494
|
headers: {},
|
|
@@ -22510,7 +22510,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
22510
22510
|
} else if (responseType === "stream") {
|
|
22511
22511
|
convertedData = import_stream4.default.Readable.from(convertedData);
|
|
22512
22512
|
}
|
|
22513
|
-
return settle(
|
|
22513
|
+
return settle(resolve9, reject, {
|
|
22514
22514
|
data: convertedData,
|
|
22515
22515
|
status: 200,
|
|
22516
22516
|
statusText: "OK",
|
|
@@ -22608,9 +22608,9 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
22608
22608
|
auth = urlUsername + ":" + urlPassword;
|
|
22609
22609
|
}
|
|
22610
22610
|
auth && headers.delete("authorization");
|
|
22611
|
-
let
|
|
22611
|
+
let path10;
|
|
22612
22612
|
try {
|
|
22613
|
-
|
|
22613
|
+
path10 = buildURL(
|
|
22614
22614
|
parsed.pathname + parsed.search,
|
|
22615
22615
|
config.params,
|
|
22616
22616
|
config.paramsSerializer
|
|
@@ -22628,7 +22628,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
22628
22628
|
false
|
|
22629
22629
|
);
|
|
22630
22630
|
const options = {
|
|
22631
|
-
path:
|
|
22631
|
+
path: path10,
|
|
22632
22632
|
method,
|
|
22633
22633
|
headers: headers.toJSON(),
|
|
22634
22634
|
agents: { http: config.httpAgent, https: config.httpsAgent },
|
|
@@ -22729,7 +22729,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
22729
22729
|
};
|
|
22730
22730
|
if (responseType === "stream") {
|
|
22731
22731
|
response.data = responseStream;
|
|
22732
|
-
settle(
|
|
22732
|
+
settle(resolve9, reject, response);
|
|
22733
22733
|
} else {
|
|
22734
22734
|
const responseBuffer = [];
|
|
22735
22735
|
let totalResponseBytes = 0;
|
|
@@ -22777,7 +22777,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
22777
22777
|
} catch (err) {
|
|
22778
22778
|
return reject(AxiosError_default.from(err, null, config, response.request, response));
|
|
22779
22779
|
}
|
|
22780
|
-
settle(
|
|
22780
|
+
settle(resolve9, reject, response);
|
|
22781
22781
|
});
|
|
22782
22782
|
}
|
|
22783
22783
|
abortEmitter.once("abort", (err) => {
|
|
@@ -22864,14 +22864,14 @@ var isURLSameOrigin_default = platform_default.hasStandardBrowserEnv ? /* @__PUR
|
|
|
22864
22864
|
var cookies_default = platform_default.hasStandardBrowserEnv ? (
|
|
22865
22865
|
// Standard browser envs support document.cookie
|
|
22866
22866
|
{
|
|
22867
|
-
write(name, value, expires,
|
|
22867
|
+
write(name, value, expires, path10, domain, secure, sameSite) {
|
|
22868
22868
|
if (typeof document === "undefined") return;
|
|
22869
22869
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
22870
22870
|
if (utils_default.isNumber(expires)) {
|
|
22871
22871
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
22872
22872
|
}
|
|
22873
|
-
if (utils_default.isString(
|
|
22874
|
-
cookie.push(`path=${
|
|
22873
|
+
if (utils_default.isString(path10)) {
|
|
22874
|
+
cookie.push(`path=${path10}`);
|
|
22875
22875
|
}
|
|
22876
22876
|
if (utils_default.isString(domain)) {
|
|
22877
22877
|
cookie.push(`domain=${domain}`);
|
|
@@ -23026,7 +23026,7 @@ var resolveConfig_default = (config) => {
|
|
|
23026
23026
|
// node_modules/axios/lib/adapters/xhr.js
|
|
23027
23027
|
var isXHRAdapterSupported = typeof XMLHttpRequest !== "undefined";
|
|
23028
23028
|
var xhr_default = isXHRAdapterSupported && function(config) {
|
|
23029
|
-
return new Promise(function dispatchXhrRequest(
|
|
23029
|
+
return new Promise(function dispatchXhrRequest(resolve9, reject) {
|
|
23030
23030
|
const _config = resolveConfig_default(config);
|
|
23031
23031
|
let requestData = _config.data;
|
|
23032
23032
|
const requestHeaders = AxiosHeaders_default.from(_config.headers).normalize();
|
|
@@ -23060,7 +23060,7 @@ var xhr_default = isXHRAdapterSupported && function(config) {
|
|
|
23060
23060
|
request
|
|
23061
23061
|
};
|
|
23062
23062
|
settle(function _resolve(value) {
|
|
23063
|
-
|
|
23063
|
+
resolve9(value);
|
|
23064
23064
|
done();
|
|
23065
23065
|
}, function _reject(err) {
|
|
23066
23066
|
reject(err);
|
|
@@ -23431,8 +23431,8 @@ var factory = (env3) => {
|
|
|
23431
23431
|
responseType = responseType || "text";
|
|
23432
23432
|
let responseData = await resolvers[utils_default.findKey(resolvers, responseType) || "text"](response, config);
|
|
23433
23433
|
!isStreamResponse && unsubscribe && unsubscribe();
|
|
23434
|
-
return await new Promise((
|
|
23435
|
-
settle(
|
|
23434
|
+
return await new Promise((resolve9, reject) => {
|
|
23435
|
+
settle(resolve9, reject, {
|
|
23436
23436
|
data: responseData,
|
|
23437
23437
|
headers: AxiosHeaders_default.from(response.headers),
|
|
23438
23438
|
status: response.status,
|
|
@@ -23828,8 +23828,8 @@ var CancelToken = class _CancelToken {
|
|
|
23828
23828
|
throw new TypeError("executor must be a function.");
|
|
23829
23829
|
}
|
|
23830
23830
|
let resolvePromise;
|
|
23831
|
-
this.promise = new Promise(function promiseExecutor(
|
|
23832
|
-
resolvePromise =
|
|
23831
|
+
this.promise = new Promise(function promiseExecutor(resolve9) {
|
|
23832
|
+
resolvePromise = resolve9;
|
|
23833
23833
|
});
|
|
23834
23834
|
const token = this;
|
|
23835
23835
|
this.promise.then((cancel) => {
|
|
@@ -23842,9 +23842,9 @@ var CancelToken = class _CancelToken {
|
|
|
23842
23842
|
});
|
|
23843
23843
|
this.promise.then = (onfulfilled) => {
|
|
23844
23844
|
let _resolve;
|
|
23845
|
-
const promise = new Promise((
|
|
23846
|
-
token.subscribe(
|
|
23847
|
-
_resolve =
|
|
23845
|
+
const promise = new Promise((resolve9) => {
|
|
23846
|
+
token.subscribe(resolve9);
|
|
23847
|
+
_resolve = resolve9;
|
|
23848
23848
|
}).then(onfulfilled);
|
|
23849
23849
|
promise.cancel = function reject() {
|
|
23850
23850
|
token.unsubscribe(_resolve);
|
|
@@ -24061,6 +24061,9 @@ var {
|
|
|
24061
24061
|
mergeConfig: mergeConfig2
|
|
24062
24062
|
} = axios_default;
|
|
24063
24063
|
|
|
24064
|
+
// src/httpClient.ts
|
|
24065
|
+
var https2 = __toESM(require("https"));
|
|
24066
|
+
|
|
24064
24067
|
// node_modules/tough-cookie/dist/index.js
|
|
24065
24068
|
var import_tldts = __toESM(require_cjs(), 1);
|
|
24066
24069
|
function pathMatch(reqPath, cookiePath) {
|
|
@@ -24215,10 +24218,10 @@ var safeToStringImpl = (val, seenArrays = /* @__PURE__ */ new WeakSet()) => {
|
|
|
24215
24218
|
var safeToString = (val) => safeToStringImpl(val);
|
|
24216
24219
|
function createPromiseCallback(cb) {
|
|
24217
24220
|
let callback;
|
|
24218
|
-
let
|
|
24221
|
+
let resolve9;
|
|
24219
24222
|
let reject;
|
|
24220
24223
|
const promise = new Promise((_resolve, _reject) => {
|
|
24221
|
-
|
|
24224
|
+
resolve9 = _resolve;
|
|
24222
24225
|
reject = _reject;
|
|
24223
24226
|
});
|
|
24224
24227
|
if (typeof cb === "function") {
|
|
@@ -24234,7 +24237,7 @@ function createPromiseCallback(cb) {
|
|
|
24234
24237
|
callback = (err, result) => {
|
|
24235
24238
|
try {
|
|
24236
24239
|
if (err) reject(err);
|
|
24237
|
-
else
|
|
24240
|
+
else resolve9(result);
|
|
24238
24241
|
} catch (e) {
|
|
24239
24242
|
reject(e instanceof Error ? e : new Error());
|
|
24240
24243
|
}
|
|
@@ -24268,18 +24271,18 @@ var MemoryCookieStore = class extends Store {
|
|
|
24268
24271
|
/**
|
|
24269
24272
|
* @internal No doc because this is an overload that supports the implementation
|
|
24270
24273
|
*/
|
|
24271
|
-
findCookie(domain,
|
|
24274
|
+
findCookie(domain, path10, key, callback) {
|
|
24272
24275
|
const promiseCallback = createPromiseCallback(callback);
|
|
24273
|
-
if (domain == null ||
|
|
24276
|
+
if (domain == null || path10 == null || key == null) {
|
|
24274
24277
|
return promiseCallback.resolve(void 0);
|
|
24275
24278
|
}
|
|
24276
|
-
const result = this.idx[domain]?.[
|
|
24279
|
+
const result = this.idx[domain]?.[path10]?.[key];
|
|
24277
24280
|
return promiseCallback.resolve(result);
|
|
24278
24281
|
}
|
|
24279
24282
|
/**
|
|
24280
24283
|
* @internal No doc because this is an overload that supports the implementation
|
|
24281
24284
|
*/
|
|
24282
|
-
findCookies(domain,
|
|
24285
|
+
findCookies(domain, path10, allowSpecialUseDomain = false, callback) {
|
|
24283
24286
|
if (typeof allowSpecialUseDomain === "function") {
|
|
24284
24287
|
callback = allowSpecialUseDomain;
|
|
24285
24288
|
allowSpecialUseDomain = true;
|
|
@@ -24290,7 +24293,7 @@ var MemoryCookieStore = class extends Store {
|
|
|
24290
24293
|
return promiseCallback.resolve([]);
|
|
24291
24294
|
}
|
|
24292
24295
|
let pathMatcher;
|
|
24293
|
-
if (!
|
|
24296
|
+
if (!path10) {
|
|
24294
24297
|
pathMatcher = function matchAll2(domainIndex) {
|
|
24295
24298
|
for (const curPath in domainIndex) {
|
|
24296
24299
|
const pathIndex = domainIndex[curPath];
|
|
@@ -24305,7 +24308,7 @@ var MemoryCookieStore = class extends Store {
|
|
|
24305
24308
|
} else {
|
|
24306
24309
|
pathMatcher = function matchRFC(domainIndex) {
|
|
24307
24310
|
for (const cookiePath in domainIndex) {
|
|
24308
|
-
if (pathMatch(
|
|
24311
|
+
if (pathMatch(path10, cookiePath)) {
|
|
24309
24312
|
const pathIndex = domainIndex[cookiePath];
|
|
24310
24313
|
for (const key in pathIndex) {
|
|
24311
24314
|
const value = pathIndex[key];
|
|
@@ -24333,14 +24336,14 @@ var MemoryCookieStore = class extends Store {
|
|
|
24333
24336
|
*/
|
|
24334
24337
|
putCookie(cookie, callback) {
|
|
24335
24338
|
const promiseCallback = createPromiseCallback(callback);
|
|
24336
|
-
const { domain, path:
|
|
24337
|
-
if (domain == null ||
|
|
24339
|
+
const { domain, path: path10, key } = cookie;
|
|
24340
|
+
if (domain == null || path10 == null || key == null) {
|
|
24338
24341
|
return promiseCallback.resolve(void 0);
|
|
24339
24342
|
}
|
|
24340
24343
|
const domainEntry = this.idx[domain] ?? /* @__PURE__ */ Object.create(null);
|
|
24341
24344
|
this.idx[domain] = domainEntry;
|
|
24342
|
-
const pathEntry = domainEntry[
|
|
24343
|
-
domainEntry[
|
|
24345
|
+
const pathEntry = domainEntry[path10] ?? /* @__PURE__ */ Object.create(null);
|
|
24346
|
+
domainEntry[path10] = pathEntry;
|
|
24344
24347
|
pathEntry[key] = cookie;
|
|
24345
24348
|
return promiseCallback.resolve(void 0);
|
|
24346
24349
|
}
|
|
@@ -24354,20 +24357,20 @@ var MemoryCookieStore = class extends Store {
|
|
|
24354
24357
|
/**
|
|
24355
24358
|
* @internal No doc because this is an overload that supports the implementation
|
|
24356
24359
|
*/
|
|
24357
|
-
removeCookie(domain,
|
|
24360
|
+
removeCookie(domain, path10, key, callback) {
|
|
24358
24361
|
const promiseCallback = createPromiseCallback(callback);
|
|
24359
|
-
delete this.idx[domain]?.[
|
|
24362
|
+
delete this.idx[domain]?.[path10]?.[key];
|
|
24360
24363
|
return promiseCallback.resolve(void 0);
|
|
24361
24364
|
}
|
|
24362
24365
|
/**
|
|
24363
24366
|
* @internal No doc because this is an overload that supports the implementation
|
|
24364
24367
|
*/
|
|
24365
|
-
removeCookies(domain,
|
|
24368
|
+
removeCookies(domain, path10, callback) {
|
|
24366
24369
|
const promiseCallback = createPromiseCallback(callback);
|
|
24367
24370
|
const domainEntry = this.idx[domain];
|
|
24368
24371
|
if (domainEntry) {
|
|
24369
|
-
if (
|
|
24370
|
-
delete domainEntry[
|
|
24372
|
+
if (path10) {
|
|
24373
|
+
delete domainEntry[path10];
|
|
24371
24374
|
} else {
|
|
24372
24375
|
delete this.idx[domain];
|
|
24373
24376
|
}
|
|
@@ -24393,8 +24396,8 @@ var MemoryCookieStore = class extends Store {
|
|
|
24393
24396
|
domains.forEach((domain) => {
|
|
24394
24397
|
const domainEntry = idx[domain] ?? {};
|
|
24395
24398
|
const paths = Object.keys(domainEntry);
|
|
24396
|
-
paths.forEach((
|
|
24397
|
-
const pathEntry = domainEntry[
|
|
24399
|
+
paths.forEach((path10) => {
|
|
24400
|
+
const pathEntry = domainEntry[path10] ?? {};
|
|
24398
24401
|
const keys = Object.keys(pathEntry);
|
|
24399
24402
|
keys.forEach((key) => {
|
|
24400
24403
|
const keyEntry = pathEntry[key];
|
|
@@ -25278,18 +25281,18 @@ function cookieCompare(a, b) {
|
|
|
25278
25281
|
cmp = (a.creationIndex || 0) - (b.creationIndex || 0);
|
|
25279
25282
|
return cmp;
|
|
25280
25283
|
}
|
|
25281
|
-
function defaultPath(
|
|
25282
|
-
if (!
|
|
25284
|
+
function defaultPath(path10) {
|
|
25285
|
+
if (!path10 || path10.slice(0, 1) !== "/") {
|
|
25283
25286
|
return "/";
|
|
25284
25287
|
}
|
|
25285
|
-
if (
|
|
25286
|
-
return
|
|
25288
|
+
if (path10 === "/") {
|
|
25289
|
+
return path10;
|
|
25287
25290
|
}
|
|
25288
|
-
const rightSlash =
|
|
25291
|
+
const rightSlash = path10.lastIndexOf("/");
|
|
25289
25292
|
if (rightSlash === 0) {
|
|
25290
25293
|
return "/";
|
|
25291
25294
|
}
|
|
25292
|
-
return
|
|
25295
|
+
return path10.slice(0, rightSlash);
|
|
25293
25296
|
}
|
|
25294
25297
|
var IP_REGEX_LOWERCASE = /(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-f\d]{1,4}:){7}(?:[a-f\d]{1,4}|:)|(?:[a-f\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-f\d]{1,4}|:)|(?:[a-f\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,2}|:)|(?:[a-f\d]{1,4}:){4}(?:(?::[a-f\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,3}|:)|(?:[a-f\d]{1,4}:){3}(?:(?::[a-f\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,4}|:)|(?:[a-f\d]{1,4}:){2}(?:(?::[a-f\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,5}|:)|(?:[a-f\d]{1,4}:){1}(?:(?::[a-f\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,6}|:)|(?::(?:(?::[a-f\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,7}|:)))$)/;
|
|
25295
25298
|
function domainMatch(domain, cookieDomain, canonicalize) {
|
|
@@ -25691,7 +25694,7 @@ var CookieJar = class _CookieJar {
|
|
|
25691
25694
|
return promiseCallback.reject(parameterError);
|
|
25692
25695
|
}
|
|
25693
25696
|
const host = canonicalDomain(context.hostname);
|
|
25694
|
-
const
|
|
25697
|
+
const path10 = context.pathname || "/";
|
|
25695
25698
|
const potentiallyTrustworthy = isPotentiallyTrustworthy(
|
|
25696
25699
|
url2,
|
|
25697
25700
|
this.allowSecureOnLocal
|
|
@@ -25722,7 +25725,7 @@ var CookieJar = class _CookieJar {
|
|
|
25722
25725
|
return false;
|
|
25723
25726
|
}
|
|
25724
25727
|
}
|
|
25725
|
-
if (!allPaths && typeof c.path === "string" && !pathMatch(
|
|
25728
|
+
if (!allPaths && typeof c.path === "string" && !pathMatch(path10, c.path)) {
|
|
25726
25729
|
return false;
|
|
25727
25730
|
}
|
|
25728
25731
|
if (c.secure && !potentiallyTrustworthy) {
|
|
@@ -25754,7 +25757,7 @@ var CookieJar = class _CookieJar {
|
|
|
25754
25757
|
}
|
|
25755
25758
|
store.findCookies(
|
|
25756
25759
|
host,
|
|
25757
|
-
allPaths ? null :
|
|
25760
|
+
allPaths ? null : path10,
|
|
25758
25761
|
this.allowSpecialUseDomain,
|
|
25759
25762
|
(err, cookies) => {
|
|
25760
25763
|
if (err) {
|
|
@@ -26231,8 +26234,21 @@ function isNornError(error) {
|
|
|
26231
26234
|
return error instanceof NornError;
|
|
26232
26235
|
}
|
|
26233
26236
|
|
|
26237
|
+
// src/httpRuntimeOptions.ts
|
|
26238
|
+
var verifyTlsCertificates = true;
|
|
26239
|
+
function setVerifyTlsCertificates(enabled) {
|
|
26240
|
+
verifyTlsCertificates = enabled;
|
|
26241
|
+
}
|
|
26242
|
+
function getVerifyTlsCertificates() {
|
|
26243
|
+
return verifyTlsCertificates;
|
|
26244
|
+
}
|
|
26245
|
+
|
|
26234
26246
|
// src/httpClient.ts
|
|
26235
26247
|
var sharedCookieJar = new CookieJar();
|
|
26248
|
+
var insecureHttpsAgent = new https2.Agent({ rejectUnauthorized: false });
|
|
26249
|
+
function getHttpsAgent() {
|
|
26250
|
+
return getVerifyTlsCertificates() ? void 0 : insecureHttpsAgent;
|
|
26251
|
+
}
|
|
26236
26252
|
function createCookieJar() {
|
|
26237
26253
|
return new CookieJar();
|
|
26238
26254
|
}
|
|
@@ -26253,7 +26269,7 @@ async function sendRequest(request, retryOptions) {
|
|
|
26253
26269
|
return sendRequestWithJar(request, sharedCookieJar, retryOptions);
|
|
26254
26270
|
}
|
|
26255
26271
|
function sleep(ms) {
|
|
26256
|
-
return new Promise((
|
|
26272
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
26257
26273
|
}
|
|
26258
26274
|
function shouldRetry(response, error) {
|
|
26259
26275
|
if (error) return true;
|
|
@@ -26328,11 +26344,13 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
26328
26344
|
const response = await axios_default({
|
|
26329
26345
|
method: currentMethod,
|
|
26330
26346
|
url: currentUrl,
|
|
26347
|
+
adapter: "http",
|
|
26331
26348
|
headers,
|
|
26332
26349
|
data,
|
|
26333
26350
|
timeout: 3e4,
|
|
26334
26351
|
maxRedirects: 0,
|
|
26335
|
-
validateStatus: () => true
|
|
26352
|
+
validateStatus: () => true,
|
|
26353
|
+
httpsAgent: getHttpsAgent()
|
|
26336
26354
|
});
|
|
26337
26355
|
const setCookieHeader = response.headers["set-cookie"];
|
|
26338
26356
|
if (setCookieHeader) {
|
|
@@ -26448,8 +26466,8 @@ var pwshAvailable = null;
|
|
|
26448
26466
|
function stripAnsiCodes(str) {
|
|
26449
26467
|
return str.replace(/\x1B(?:\[[0-9;]*[a-zA-Z]|\][^\x07]*(?:\x07|\x1B\\)|[a-zA-Z])/g, "");
|
|
26450
26468
|
}
|
|
26451
|
-
function tryParsePowerShellOutput(
|
|
26452
|
-
const lines =
|
|
26469
|
+
function tryParsePowerShellOutput(output2) {
|
|
26470
|
+
const lines = output2.split("\n").map((l) => l.trimEnd());
|
|
26453
26471
|
const nonEmptyLines = lines.filter((l) => l.trim() !== "");
|
|
26454
26472
|
if (nonEmptyLines.length === 0) {
|
|
26455
26473
|
return null;
|
|
@@ -26543,8 +26561,8 @@ function parseValue(str) {
|
|
|
26543
26561
|
}
|
|
26544
26562
|
return str;
|
|
26545
26563
|
}
|
|
26546
|
-
function cleanScriptOutput(
|
|
26547
|
-
let cleaned = stripAnsiCodes(
|
|
26564
|
+
function cleanScriptOutput(output2) {
|
|
26565
|
+
let cleaned = stripAnsiCodes(output2).trim();
|
|
26548
26566
|
if (cleaned.startsWith("{") && cleaned.endsWith("}") || cleaned.startsWith("[") && cleaned.endsWith("]")) {
|
|
26549
26567
|
try {
|
|
26550
26568
|
const parsed = JSON.parse(cleaned);
|
|
@@ -26664,7 +26682,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
26664
26682
|
captureVar
|
|
26665
26683
|
};
|
|
26666
26684
|
}
|
|
26667
|
-
return new Promise((
|
|
26685
|
+
return new Promise((resolve9) => {
|
|
26668
26686
|
const env3 = {
|
|
26669
26687
|
...process.env,
|
|
26670
26688
|
// Pass variables as environment variables with NORN_ prefix
|
|
@@ -26688,7 +26706,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
26688
26706
|
stderr += data.toString();
|
|
26689
26707
|
});
|
|
26690
26708
|
child.on("error", (err) => {
|
|
26691
|
-
|
|
26709
|
+
resolve9({
|
|
26692
26710
|
success: false,
|
|
26693
26711
|
output: cleanScriptOutput(stdout),
|
|
26694
26712
|
error: `Failed to execute script: ${err.message}`,
|
|
@@ -26702,7 +26720,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
26702
26720
|
child.on("close", (code) => {
|
|
26703
26721
|
const exitCode = code ?? 0;
|
|
26704
26722
|
const cleanedOutput = cleanScriptOutput(stdout);
|
|
26705
|
-
|
|
26723
|
+
resolve9({
|
|
26706
26724
|
success: exitCode === 0,
|
|
26707
26725
|
output: cleanedOutput,
|
|
26708
26726
|
error: stderr.trim(),
|
|
@@ -26767,11 +26785,11 @@ function readJsonFile(filePath, workingDir) {
|
|
|
26767
26785
|
};
|
|
26768
26786
|
}
|
|
26769
26787
|
}
|
|
26770
|
-
function setNestedValue(obj,
|
|
26771
|
-
if (!
|
|
26788
|
+
function setNestedValue(obj, path10, value) {
|
|
26789
|
+
if (!path10 || obj === null || obj === void 0 || typeof obj !== "object") {
|
|
26772
26790
|
return false;
|
|
26773
26791
|
}
|
|
26774
|
-
const parts =
|
|
26792
|
+
const parts = path10.replace(/\[(\d+)\]/g, ".$1").split(".").filter((p) => p !== "");
|
|
26775
26793
|
if (parts.length === 0) {
|
|
26776
26794
|
return false;
|
|
26777
26795
|
}
|
|
@@ -27273,8 +27291,8 @@ function bindSequenceArguments(params, args, runtimeVariables) {
|
|
|
27273
27291
|
}
|
|
27274
27292
|
return { variables: result };
|
|
27275
27293
|
}
|
|
27276
|
-
function getVariableValueByPath(
|
|
27277
|
-
const parts =
|
|
27294
|
+
function getVariableValueByPath(path10, variables) {
|
|
27295
|
+
const parts = path10.split(".");
|
|
27278
27296
|
let current = variables;
|
|
27279
27297
|
for (const part of parts) {
|
|
27280
27298
|
if (current === null || current === void 0) {
|
|
@@ -27639,8 +27657,8 @@ function evaluateValueExpression(expr, runtimeVariables) {
|
|
|
27639
27657
|
} else {
|
|
27640
27658
|
return { value: String(varValue), error: `Cannot access path on non-object value` };
|
|
27641
27659
|
}
|
|
27642
|
-
const
|
|
27643
|
-
const parts =
|
|
27660
|
+
const path10 = pathPart.replace(/^\./, "").replace(/\[(\d+)\]/g, ".$1");
|
|
27661
|
+
const parts = path10.split(".").filter((p) => p !== "");
|
|
27644
27662
|
let current = dataToNavigate;
|
|
27645
27663
|
for (const part of parts) {
|
|
27646
27664
|
if (current === null || current === void 0) {
|
|
@@ -27719,8 +27737,8 @@ function resolveBareVariables(text, variables) {
|
|
|
27719
27737
|
if (varName in variables) {
|
|
27720
27738
|
const value = variables[varName];
|
|
27721
27739
|
if (pathPart) {
|
|
27722
|
-
const
|
|
27723
|
-
const nestedValue = getNestedValueFromObject(value,
|
|
27740
|
+
const path10 = pathPart.replace(/^\./, "");
|
|
27741
|
+
const nestedValue = getNestedValueFromObject(value, path10);
|
|
27724
27742
|
return valueToString2(nestedValue);
|
|
27725
27743
|
}
|
|
27726
27744
|
return valueToString2(value);
|
|
@@ -27740,8 +27758,8 @@ function resolveBareVariables(text, variables) {
|
|
|
27740
27758
|
if (varName in variables) {
|
|
27741
27759
|
const value = variables[varName];
|
|
27742
27760
|
if (pathPart) {
|
|
27743
|
-
const
|
|
27744
|
-
return valueToString2(getNestedValueFromObject(value,
|
|
27761
|
+
const path10 = pathPart.replace(/^\./, "");
|
|
27762
|
+
return valueToString2(getNestedValueFromObject(value, path10));
|
|
27745
27763
|
}
|
|
27746
27764
|
return valueToString2(value);
|
|
27747
27765
|
}
|
|
@@ -27778,11 +27796,11 @@ function splitExpressionParts(expr) {
|
|
|
27778
27796
|
}
|
|
27779
27797
|
return parts;
|
|
27780
27798
|
}
|
|
27781
|
-
function getNestedValueFromObject(obj,
|
|
27782
|
-
if (!
|
|
27799
|
+
function getNestedValueFromObject(obj, path10) {
|
|
27800
|
+
if (!path10) {
|
|
27783
27801
|
return obj;
|
|
27784
27802
|
}
|
|
27785
|
-
const parts =
|
|
27803
|
+
const parts = path10.split(/\.|\[(\d+)\]/).filter((p) => p !== "" && p !== void 0);
|
|
27786
27804
|
let current = obj;
|
|
27787
27805
|
for (const part of parts) {
|
|
27788
27806
|
if (current === null || current === void 0) {
|
|
@@ -27805,7 +27823,7 @@ function valueToString2(value) {
|
|
|
27805
27823
|
return String(value);
|
|
27806
27824
|
}
|
|
27807
27825
|
function sleep2(ms) {
|
|
27808
|
-
return new Promise((
|
|
27826
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
27809
27827
|
}
|
|
27810
27828
|
function isIfCommand(line2) {
|
|
27811
27829
|
return /^if\s+.+$/i.test(line2.trim());
|
|
@@ -28127,24 +28145,24 @@ function extractCaptureDirectives(content) {
|
|
|
28127
28145
|
for (const line2 of content.split("\n")) {
|
|
28128
28146
|
const match = line2.trim().match(captureRegex);
|
|
28129
28147
|
if (match) {
|
|
28130
|
-
let
|
|
28131
|
-
if (
|
|
28132
|
-
|
|
28148
|
+
let path10 = match[3] || "";
|
|
28149
|
+
if (path10.startsWith(".")) {
|
|
28150
|
+
path10 = path10.substring(1);
|
|
28133
28151
|
}
|
|
28134
28152
|
captures.push({
|
|
28135
28153
|
varName: match[1],
|
|
28136
28154
|
afterRequest: parseInt(match[2], 10),
|
|
28137
|
-
path:
|
|
28155
|
+
path: path10
|
|
28138
28156
|
});
|
|
28139
28157
|
}
|
|
28140
28158
|
}
|
|
28141
28159
|
return captures;
|
|
28142
28160
|
}
|
|
28143
|
-
function getValueByPath(response,
|
|
28144
|
-
if (!
|
|
28161
|
+
function getValueByPath(response, path10) {
|
|
28162
|
+
if (!path10) {
|
|
28145
28163
|
return void 0;
|
|
28146
28164
|
}
|
|
28147
|
-
const parts =
|
|
28165
|
+
const parts = path10.replace(/\[(\d+)\]/g, ".$1").split(".").filter((p) => p !== "");
|
|
28148
28166
|
if (parts.length === 0) {
|
|
28149
28167
|
return void 0;
|
|
28150
28168
|
}
|
|
@@ -28448,8 +28466,8 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
28448
28466
|
}
|
|
28449
28467
|
}
|
|
28450
28468
|
if (pathPart) {
|
|
28451
|
-
const
|
|
28452
|
-
newValue = getNestedValueFromObject(value,
|
|
28469
|
+
const path10 = pathPart.replace(/^\./, "");
|
|
28470
|
+
newValue = getNestedValueFromObject(value, path10);
|
|
28453
28471
|
} else {
|
|
28454
28472
|
newValue = value;
|
|
28455
28473
|
}
|
|
@@ -28811,8 +28829,8 @@ ${indentMultiline(userMessage)}`;
|
|
|
28811
28829
|
if (sequenceSources) {
|
|
28812
28830
|
const sourceFile = sequenceSources.get(targetName.toLowerCase());
|
|
28813
28831
|
if (sourceFile) {
|
|
28814
|
-
const
|
|
28815
|
-
subWorkingDir =
|
|
28832
|
+
const path10 = await import("path");
|
|
28833
|
+
subWorkingDir = path10.dirname(sourceFile);
|
|
28816
28834
|
}
|
|
28817
28835
|
}
|
|
28818
28836
|
const subResult = await runSequenceWithJar(
|
|
@@ -29073,12 +29091,14 @@ ${indentMultiline(userMessage)}`;
|
|
|
29073
29091
|
} : void 0;
|
|
29074
29092
|
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts) : await sendRequest(requestParsed, retryOpts);
|
|
29075
29093
|
addResponse(response);
|
|
29094
|
+
responseIndexToVariable.set(responses.length, varName);
|
|
29076
29095
|
const stepResult = {
|
|
29077
29096
|
type: "request",
|
|
29078
29097
|
stepIndex: stepIdx,
|
|
29079
29098
|
response,
|
|
29080
29099
|
requestMethod: requestParsed.method,
|
|
29081
|
-
requestUrl: requestParsed.url
|
|
29100
|
+
requestUrl: requestParsed.url,
|
|
29101
|
+
variableName: varName
|
|
29082
29102
|
};
|
|
29083
29103
|
orderedSteps.push(stepResult);
|
|
29084
29104
|
reportProgress(stepIdx, "namedRequest", `var ${varName} = run ${sequenceName} \u2192 ${requestParsed.method} ${requestParsed.url}`, stepResult);
|
|
@@ -29165,8 +29185,8 @@ ${indentMultiline(userMessage)}`;
|
|
|
29165
29185
|
if (sequenceSources) {
|
|
29166
29186
|
const sourceFile = sequenceSources.get(sequenceName.toLowerCase());
|
|
29167
29187
|
if (sourceFile) {
|
|
29168
|
-
const
|
|
29169
|
-
subWorkingDir =
|
|
29188
|
+
const path10 = await import("path");
|
|
29189
|
+
subWorkingDir = path10.dirname(sourceFile);
|
|
29170
29190
|
}
|
|
29171
29191
|
}
|
|
29172
29192
|
const subResult = await runSequenceWithJar(
|
|
@@ -30571,14 +30591,238 @@ function generateHtmlReportFromResponse(response, testName, options) {
|
|
|
30571
30591
|
}
|
|
30572
30592
|
|
|
30573
30593
|
// src/environmentParser.ts
|
|
30594
|
+
var fs7 = __toESM(require("fs"));
|
|
30595
|
+
var path6 = __toESM(require("path"));
|
|
30596
|
+
|
|
30597
|
+
// src/secrets/crypto.ts
|
|
30598
|
+
var crypto2 = __toESM(require("crypto"));
|
|
30599
|
+
var ENCRYPTED_SECRET_PREFIX = "ENC[";
|
|
30600
|
+
var ENCRYPTED_SECRET_SUFFIX = "]";
|
|
30601
|
+
var ENCRYPTED_SECRET_VERSION = "NORN_AGE_V1";
|
|
30602
|
+
var encryptedSecretRegex = /^ENC\[([A-Z0-9_]+):kid=([a-zA-Z0-9._-]+):([A-Za-z0-9_-]+)\]$/;
|
|
30603
|
+
function deriveEncryptionKey(sharedKey) {
|
|
30604
|
+
return crypto2.createHash("sha256").update(sharedKey, "utf8").digest();
|
|
30605
|
+
}
|
|
30606
|
+
function generateSharedSecretKey() {
|
|
30607
|
+
return crypto2.randomBytes(32).toString("base64url");
|
|
30608
|
+
}
|
|
30609
|
+
function isEncryptedSecretValue(value) {
|
|
30610
|
+
return value.trim().startsWith(ENCRYPTED_SECRET_PREFIX) && value.trim().endsWith(ENCRYPTED_SECRET_SUFFIX);
|
|
30611
|
+
}
|
|
30612
|
+
function parseEncryptedSecretValue(value) {
|
|
30613
|
+
const trimmed = value.trim();
|
|
30614
|
+
const match = trimmed.match(encryptedSecretRegex);
|
|
30615
|
+
if (!match) {
|
|
30616
|
+
return {
|
|
30617
|
+
ok: false,
|
|
30618
|
+
error: `Invalid encrypted secret format. Expected: ENC[${ENCRYPTED_SECRET_VERSION}:kid=<id>:<payload>]`
|
|
30619
|
+
};
|
|
30620
|
+
}
|
|
30621
|
+
return {
|
|
30622
|
+
ok: true,
|
|
30623
|
+
parsed: {
|
|
30624
|
+
version: match[1],
|
|
30625
|
+
kid: match[2],
|
|
30626
|
+
payload: match[3]
|
|
30627
|
+
}
|
|
30628
|
+
};
|
|
30629
|
+
}
|
|
30630
|
+
function encryptSecretValue(plaintext, sharedKey, kid) {
|
|
30631
|
+
const key = deriveEncryptionKey(sharedKey);
|
|
30632
|
+
const iv = crypto2.randomBytes(12);
|
|
30633
|
+
const cipher = crypto2.createCipheriv("aes-256-gcm", key, iv);
|
|
30634
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
30635
|
+
const authTag = cipher.getAuthTag();
|
|
30636
|
+
const payload = Buffer.concat([iv, authTag, ciphertext]).toString("base64url");
|
|
30637
|
+
return `ENC[${ENCRYPTED_SECRET_VERSION}:kid=${kid}:${payload}]`;
|
|
30638
|
+
}
|
|
30639
|
+
function decryptSecretValue(encryptedValue, sharedKey) {
|
|
30640
|
+
const parsedResult = parseEncryptedSecretValue(encryptedValue);
|
|
30641
|
+
if (!parsedResult.ok) {
|
|
30642
|
+
throw new Error(parsedResult.error);
|
|
30643
|
+
}
|
|
30644
|
+
const { version: version2, payload } = parsedResult.parsed;
|
|
30645
|
+
if (version2 !== ENCRYPTED_SECRET_VERSION) {
|
|
30646
|
+
throw new Error(`Unsupported encrypted secret version '${version2}'. Expected '${ENCRYPTED_SECRET_VERSION}'.`);
|
|
30647
|
+
}
|
|
30648
|
+
const raw = Buffer.from(payload, "base64url");
|
|
30649
|
+
if (raw.length < 28) {
|
|
30650
|
+
throw new Error("Encrypted payload is too short.");
|
|
30651
|
+
}
|
|
30652
|
+
const iv = raw.subarray(0, 12);
|
|
30653
|
+
const authTag = raw.subarray(12, 28);
|
|
30654
|
+
const ciphertext = raw.subarray(28);
|
|
30655
|
+
const key = deriveEncryptionKey(sharedKey);
|
|
30656
|
+
const decipher = crypto2.createDecipheriv("aes-256-gcm", key, iv);
|
|
30657
|
+
decipher.setAuthTag(authTag);
|
|
30658
|
+
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
30659
|
+
return decrypted.toString("utf8");
|
|
30660
|
+
}
|
|
30661
|
+
|
|
30662
|
+
// src/secrets/keyStore.ts
|
|
30663
|
+
var fs6 = __toESM(require("fs"));
|
|
30664
|
+
var path5 = __toESM(require("path"));
|
|
30665
|
+
|
|
30666
|
+
// src/cacheDir.ts
|
|
30574
30667
|
var fs5 = __toESM(require("fs"));
|
|
30575
30668
|
var path4 = __toESM(require("path"));
|
|
30669
|
+
var NORN_CACHE_DIR = ".norn-cache";
|
|
30670
|
+
var CACHE_GITIGNORE_FILE = ".gitignore";
|
|
30671
|
+
var CACHE_GITIGNORE_CONTENT = "*\n";
|
|
30672
|
+
function ensureNornCacheGitignore(cacheDir) {
|
|
30673
|
+
const gitignorePath = path4.join(cacheDir, CACHE_GITIGNORE_FILE);
|
|
30674
|
+
try {
|
|
30675
|
+
const hasDesiredContent = fs5.existsSync(gitignorePath) && fs5.readFileSync(gitignorePath, "utf8") === CACHE_GITIGNORE_CONTENT;
|
|
30676
|
+
if (hasDesiredContent) {
|
|
30677
|
+
return;
|
|
30678
|
+
}
|
|
30679
|
+
fs5.writeFileSync(gitignorePath, CACHE_GITIGNORE_CONTENT, "utf8");
|
|
30680
|
+
} catch {
|
|
30681
|
+
}
|
|
30682
|
+
}
|
|
30683
|
+
|
|
30684
|
+
// src/secrets/keyStore.ts
|
|
30685
|
+
var CACHE_FILE = "secret-keys.json";
|
|
30686
|
+
var CACHE_VERSION = 1;
|
|
30687
|
+
var sessionKeys = /* @__PURE__ */ new Map();
|
|
30688
|
+
function getSearchStartDirectory(targetPath) {
|
|
30689
|
+
const resolvedPath = path5.resolve(targetPath);
|
|
30690
|
+
try {
|
|
30691
|
+
const stats = fs6.statSync(resolvedPath);
|
|
30692
|
+
return stats.isDirectory() ? resolvedPath : path5.dirname(resolvedPath);
|
|
30693
|
+
} catch {
|
|
30694
|
+
return path5.dirname(resolvedPath);
|
|
30695
|
+
}
|
|
30696
|
+
}
|
|
30697
|
+
function findExistingCacheDir(targetPath) {
|
|
30698
|
+
let dir = getSearchStartDirectory(targetPath);
|
|
30699
|
+
while (true) {
|
|
30700
|
+
const cacheDir = path5.join(dir, NORN_CACHE_DIR);
|
|
30701
|
+
if (fs6.existsSync(cacheDir) && fs6.statSync(cacheDir).isDirectory()) {
|
|
30702
|
+
return cacheDir;
|
|
30703
|
+
}
|
|
30704
|
+
const parent = path5.dirname(dir);
|
|
30705
|
+
if (parent === dir) {
|
|
30706
|
+
return void 0;
|
|
30707
|
+
}
|
|
30708
|
+
dir = parent;
|
|
30709
|
+
}
|
|
30710
|
+
}
|
|
30711
|
+
function ensureCacheDir(targetPath) {
|
|
30712
|
+
const existing = findExistingCacheDir(targetPath);
|
|
30713
|
+
const cacheDir = existing ?? path5.join(getSearchStartDirectory(targetPath), NORN_CACHE_DIR);
|
|
30714
|
+
if (!fs6.existsSync(cacheDir)) {
|
|
30715
|
+
fs6.mkdirSync(cacheDir, { recursive: true });
|
|
30716
|
+
}
|
|
30717
|
+
ensureNornCacheGitignore(cacheDir);
|
|
30718
|
+
return cacheDir;
|
|
30719
|
+
}
|
|
30720
|
+
function getCachePath(targetPath) {
|
|
30721
|
+
const cacheDir = ensureCacheDir(targetPath);
|
|
30722
|
+
return path5.join(cacheDir, CACHE_FILE);
|
|
30723
|
+
}
|
|
30724
|
+
function readCache(targetPath) {
|
|
30725
|
+
const cachePath = getCachePath(targetPath);
|
|
30726
|
+
if (!fs6.existsSync(cachePath)) {
|
|
30727
|
+
return { version: CACHE_VERSION, keys: {} };
|
|
30728
|
+
}
|
|
30729
|
+
try {
|
|
30730
|
+
const parsed = JSON.parse(fs6.readFileSync(cachePath, "utf8"));
|
|
30731
|
+
if (parsed.version !== CACHE_VERSION || typeof parsed.keys !== "object" || parsed.keys === null) {
|
|
30732
|
+
return { version: CACHE_VERSION, keys: {} };
|
|
30733
|
+
}
|
|
30734
|
+
return parsed;
|
|
30735
|
+
} catch {
|
|
30736
|
+
return { version: CACHE_VERSION, keys: {} };
|
|
30737
|
+
}
|
|
30738
|
+
}
|
|
30739
|
+
function writeCache(targetPath, cache) {
|
|
30740
|
+
const cachePath = getCachePath(targetPath);
|
|
30741
|
+
fs6.writeFileSync(cachePath, JSON.stringify(cache, null, 2), { encoding: "utf8", mode: 384 });
|
|
30742
|
+
try {
|
|
30743
|
+
fs6.chmodSync(cachePath, 384);
|
|
30744
|
+
} catch {
|
|
30745
|
+
}
|
|
30746
|
+
}
|
|
30747
|
+
function kidToEnvVarSuffix(kid) {
|
|
30748
|
+
return kid.replace(/[^a-zA-Z0-9]/g, "_").toUpperCase();
|
|
30749
|
+
}
|
|
30750
|
+
function getEnvMappedKeys() {
|
|
30751
|
+
const raw = process.env.NORN_SECRET_KEYS;
|
|
30752
|
+
if (!raw) {
|
|
30753
|
+
return {};
|
|
30754
|
+
}
|
|
30755
|
+
try {
|
|
30756
|
+
const parsed = JSON.parse(raw);
|
|
30757
|
+
const mapped = {};
|
|
30758
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
30759
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
30760
|
+
mapped[key] = value;
|
|
30761
|
+
}
|
|
30762
|
+
}
|
|
30763
|
+
return mapped;
|
|
30764
|
+
} catch {
|
|
30765
|
+
return {};
|
|
30766
|
+
}
|
|
30767
|
+
}
|
|
30768
|
+
function resolveSecretKey(kid, targetPath) {
|
|
30769
|
+
const sessionValue = sessionKeys.get(kid);
|
|
30770
|
+
if (sessionValue) {
|
|
30771
|
+
return sessionValue;
|
|
30772
|
+
}
|
|
30773
|
+
const mapped = getEnvMappedKeys();
|
|
30774
|
+
if (mapped[kid]) {
|
|
30775
|
+
return mapped[kid];
|
|
30776
|
+
}
|
|
30777
|
+
const specific = process.env[`NORN_SECRET_KEY_${kidToEnvVarSuffix(kid)}`];
|
|
30778
|
+
if (specific && specific.trim() !== "") {
|
|
30779
|
+
return specific;
|
|
30780
|
+
}
|
|
30781
|
+
const cache = readCache(targetPath);
|
|
30782
|
+
const cached = cache.keys[kid]?.value;
|
|
30783
|
+
if (cached && cached.trim() !== "") {
|
|
30784
|
+
return cached;
|
|
30785
|
+
}
|
|
30786
|
+
const fallback = process.env.NORN_SECRET_KEY;
|
|
30787
|
+
if (fallback && fallback.trim() !== "") {
|
|
30788
|
+
return fallback;
|
|
30789
|
+
}
|
|
30790
|
+
return void 0;
|
|
30791
|
+
}
|
|
30792
|
+
function setSessionSecretKey(kid, key) {
|
|
30793
|
+
sessionKeys.set(kid, key);
|
|
30794
|
+
}
|
|
30795
|
+
function saveSecretKeyToCache(kid, key, targetPath) {
|
|
30796
|
+
const cache = readCache(targetPath);
|
|
30797
|
+
cache.keys[kid] = {
|
|
30798
|
+
value: key,
|
|
30799
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
30800
|
+
};
|
|
30801
|
+
writeCache(targetPath, cache);
|
|
30802
|
+
setSessionSecretKey(kid, key);
|
|
30803
|
+
}
|
|
30804
|
+
function removeSecretKeyFromCache(kid, targetPath) {
|
|
30805
|
+
const cache = readCache(targetPath);
|
|
30806
|
+
if (!cache.keys[kid]) {
|
|
30807
|
+
return false;
|
|
30808
|
+
}
|
|
30809
|
+
delete cache.keys[kid];
|
|
30810
|
+
writeCache(targetPath, cache);
|
|
30811
|
+
sessionKeys.delete(kid);
|
|
30812
|
+
return true;
|
|
30813
|
+
}
|
|
30814
|
+
function listCachedSecretKeyIds(targetPath) {
|
|
30815
|
+
const cache = readCache(targetPath);
|
|
30816
|
+
return Object.keys(cache.keys).sort();
|
|
30817
|
+
}
|
|
30818
|
+
|
|
30819
|
+
// src/environmentParser.ts
|
|
30576
30820
|
var ENV_FILENAME = ".nornenv";
|
|
30577
30821
|
var importRegex = /^import\s+["']?(.+?)["']?\s*$/;
|
|
30578
30822
|
var envRegex = /^\[env:([a-zA-Z_][a-zA-Z0-9_-]*)\]$/;
|
|
30579
30823
|
var varRegex = /^var\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
|
|
30580
30824
|
var secretRegex = /^secret\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
|
|
30581
|
-
function parseEnvFile(content) {
|
|
30825
|
+
function parseEnvFile(content, sourceFilePath) {
|
|
30582
30826
|
const lines = content.split("\n");
|
|
30583
30827
|
const config = {
|
|
30584
30828
|
common: {},
|
|
@@ -30586,7 +30830,8 @@ function parseEnvFile(content) {
|
|
|
30586
30830
|
secretNames: /* @__PURE__ */ new Set(),
|
|
30587
30831
|
secretValues: /* @__PURE__ */ new Map(),
|
|
30588
30832
|
imports: [],
|
|
30589
|
-
misplacedImports: []
|
|
30833
|
+
misplacedImports: [],
|
|
30834
|
+
secretDeclarations: []
|
|
30590
30835
|
};
|
|
30591
30836
|
let currentEnv = null;
|
|
30592
30837
|
let seenContent = false;
|
|
@@ -30621,6 +30866,13 @@ function parseEnvFile(content) {
|
|
|
30621
30866
|
if (secretMatch) {
|
|
30622
30867
|
const varName = secretMatch[1];
|
|
30623
30868
|
const varValue = secretMatch[2].trim();
|
|
30869
|
+
config.secretDeclarations.push({
|
|
30870
|
+
name: varName,
|
|
30871
|
+
value: varValue,
|
|
30872
|
+
envName: currentEnv?.name,
|
|
30873
|
+
lineNumber: i,
|
|
30874
|
+
filePath: sourceFilePath
|
|
30875
|
+
});
|
|
30624
30876
|
config.secretNames.add(varName);
|
|
30625
30877
|
config.secretValues.set(varName, varValue);
|
|
30626
30878
|
if (currentEnv) {
|
|
@@ -30644,22 +30896,22 @@ function parseEnvFile(content) {
|
|
|
30644
30896
|
return config;
|
|
30645
30897
|
}
|
|
30646
30898
|
function getEnvSearchStartDirectory(targetPath) {
|
|
30647
|
-
const resolvedPath =
|
|
30899
|
+
const resolvedPath = path6.resolve(targetPath);
|
|
30648
30900
|
try {
|
|
30649
|
-
const stats =
|
|
30650
|
-
return stats.isDirectory() ? resolvedPath :
|
|
30901
|
+
const stats = fs7.statSync(resolvedPath);
|
|
30902
|
+
return stats.isDirectory() ? resolvedPath : path6.dirname(resolvedPath);
|
|
30651
30903
|
} catch {
|
|
30652
|
-
return
|
|
30904
|
+
return path6.dirname(resolvedPath);
|
|
30653
30905
|
}
|
|
30654
30906
|
}
|
|
30655
30907
|
function findEnvFileFromPath(filePath) {
|
|
30656
30908
|
let dir = getEnvSearchStartDirectory(filePath);
|
|
30657
30909
|
while (true) {
|
|
30658
|
-
const envPath =
|
|
30659
|
-
if (
|
|
30910
|
+
const envPath = path6.join(dir, ENV_FILENAME);
|
|
30911
|
+
if (fs7.existsSync(envPath)) {
|
|
30660
30912
|
return envPath;
|
|
30661
30913
|
}
|
|
30662
|
-
const parentDir =
|
|
30914
|
+
const parentDir = path6.dirname(dir);
|
|
30663
30915
|
if (parentDir === dir) {
|
|
30664
30916
|
break;
|
|
30665
30917
|
}
|
|
@@ -30669,6 +30921,7 @@ function findEnvFileFromPath(filePath) {
|
|
|
30669
30921
|
}
|
|
30670
30922
|
function resolveNornenvImports(config, baseDir, entryFilePath, readFile2, importStack, alreadyImported) {
|
|
30671
30923
|
const errors = [];
|
|
30924
|
+
const secretErrors = [];
|
|
30672
30925
|
const resolvedPaths = [];
|
|
30673
30926
|
const stack = importStack ?? [entryFilePath];
|
|
30674
30927
|
const visited = alreadyImported ?? /* @__PURE__ */ new Set([entryFilePath]);
|
|
@@ -30683,7 +30936,7 @@ function resolveNornenvImports(config, baseDir, entryFilePath, readFile2, import
|
|
|
30683
30936
|
}
|
|
30684
30937
|
for (const imp of config.imports) {
|
|
30685
30938
|
const resolvedImportPath = resolveImportPath(imp.path, baseDir);
|
|
30686
|
-
if (!resolvedImportPath || !
|
|
30939
|
+
if (!resolvedImportPath || !fs7.existsSync(resolvedImportPath)) {
|
|
30687
30940
|
errors.push({
|
|
30688
30941
|
message: `Imported file not found: '${imp.path}'`,
|
|
30689
30942
|
filePath: entryFilePath,
|
|
@@ -30699,10 +30952,10 @@ function resolveNornenvImports(config, baseDir, entryFilePath, readFile2, import
|
|
|
30699
30952
|
});
|
|
30700
30953
|
continue;
|
|
30701
30954
|
}
|
|
30702
|
-
const normalizedPath =
|
|
30955
|
+
const normalizedPath = path6.resolve(resolvedImportPath);
|
|
30703
30956
|
if (stack.includes(normalizedPath)) {
|
|
30704
|
-
const entryDir =
|
|
30705
|
-
const cycle = [...stack, normalizedPath].map((p) =>
|
|
30957
|
+
const entryDir = path6.dirname(stack[0]);
|
|
30958
|
+
const cycle = [...stack, normalizedPath].map((p) => path6.relative(entryDir, p) || path6.basename(p)).join(" \u2192 ");
|
|
30706
30959
|
errors.push({
|
|
30707
30960
|
message: `Circular import detected: ${cycle}`,
|
|
30708
30961
|
filePath: entryFilePath,
|
|
@@ -30726,29 +30979,30 @@ function resolveNornenvImports(config, baseDir, entryFilePath, readFile2, import
|
|
|
30726
30979
|
});
|
|
30727
30980
|
continue;
|
|
30728
30981
|
}
|
|
30729
|
-
const importedConfig = parseEnvFile(importedContent);
|
|
30982
|
+
const importedConfig = parseEnvFile(importedContent, normalizedPath);
|
|
30730
30983
|
resolvedPaths.push(normalizedPath);
|
|
30731
30984
|
if (importedConfig.imports.length > 0) {
|
|
30732
30985
|
const childResult = resolveNornenvImports(
|
|
30733
30986
|
importedConfig,
|
|
30734
|
-
|
|
30987
|
+
path6.dirname(normalizedPath),
|
|
30735
30988
|
normalizedPath,
|
|
30736
30989
|
readFile2,
|
|
30737
30990
|
[...stack, normalizedPath],
|
|
30738
30991
|
visited
|
|
30739
30992
|
);
|
|
30740
30993
|
errors.push(...childResult.errors);
|
|
30994
|
+
secretErrors.push(...childResult.secretErrors);
|
|
30741
30995
|
resolvedPaths.push(...childResult.resolvedPaths);
|
|
30742
30996
|
mergeConfigs(config, childResult.config, entryFilePath, normalizedPath, variableOrigins, errors);
|
|
30743
30997
|
} else {
|
|
30744
30998
|
mergeConfigs(config, importedConfig, entryFilePath, normalizedPath, variableOrigins, errors);
|
|
30745
30999
|
}
|
|
30746
31000
|
}
|
|
30747
|
-
return { config, errors, resolvedPaths };
|
|
31001
|
+
return { config, errors, secretErrors, resolvedPaths };
|
|
30748
31002
|
}
|
|
30749
31003
|
function resolveImportPath(importPath, baseDir) {
|
|
30750
31004
|
const cleaned = importPath.replace(/^["']|["']$/g, "");
|
|
30751
|
-
return
|
|
31005
|
+
return path6.resolve(baseDir, cleaned);
|
|
30752
31006
|
}
|
|
30753
31007
|
function registerVariableOrigins(config, filePath, origins) {
|
|
30754
31008
|
for (const varName of Object.keys(config.common)) {
|
|
@@ -30807,31 +31061,578 @@ function mergeConfigs(target, source, targetFilePath, sourceFilePath, variableOr
|
|
|
30807
31061
|
for (const [name, value] of source.secretValues) {
|
|
30808
31062
|
target.secretValues.set(name, value);
|
|
30809
31063
|
}
|
|
31064
|
+
for (const declaration of source.secretDeclarations) {
|
|
31065
|
+
target.secretDeclarations.push({ ...declaration, filePath: declaration.filePath ?? sourceFilePath });
|
|
31066
|
+
}
|
|
30810
31067
|
}
|
|
30811
31068
|
function toDisplayPath(filePath, entryFilePath) {
|
|
30812
|
-
const entryDir =
|
|
30813
|
-
const
|
|
30814
|
-
return
|
|
31069
|
+
const entryDir = path6.dirname(entryFilePath);
|
|
31070
|
+
const relative4 = path6.relative(entryDir, filePath);
|
|
31071
|
+
return relative4 && relative4 !== "" ? relative4 : path6.basename(filePath);
|
|
30815
31072
|
}
|
|
30816
31073
|
function loadAndResolveEnvFile(filePath) {
|
|
30817
|
-
const content =
|
|
30818
|
-
const config = parseEnvFile(content);
|
|
31074
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
31075
|
+
const config = parseEnvFile(content, filePath);
|
|
30819
31076
|
if (config.imports.length === 0) {
|
|
30820
|
-
|
|
31077
|
+
const secretErrors = resolveEncryptedSecretValues(config, filePath);
|
|
31078
|
+
return { config, errors: [], secretErrors, resolvedPaths: [] };
|
|
30821
31079
|
}
|
|
30822
|
-
|
|
31080
|
+
const result = resolveNornenvImports(
|
|
30823
31081
|
config,
|
|
30824
|
-
|
|
31082
|
+
path6.dirname(filePath),
|
|
30825
31083
|
filePath,
|
|
30826
|
-
(p) =>
|
|
31084
|
+
(p) => fs7.readFileSync(p, "utf-8")
|
|
30827
31085
|
);
|
|
31086
|
+
result.secretErrors.push(...resolveEncryptedSecretValues(result.config, filePath));
|
|
31087
|
+
return result;
|
|
31088
|
+
}
|
|
31089
|
+
function resolveEncryptedSecretValues(config, entryFilePath) {
|
|
31090
|
+
const errors = [];
|
|
31091
|
+
for (const declaration of config.secretDeclarations) {
|
|
31092
|
+
if (!isEncryptedSecretValue(declaration.value)) {
|
|
31093
|
+
continue;
|
|
31094
|
+
}
|
|
31095
|
+
const parsed = parseEncryptedSecretValue(declaration.value);
|
|
31096
|
+
const filePath = declaration.filePath ?? entryFilePath;
|
|
31097
|
+
if (!parsed.ok) {
|
|
31098
|
+
errors.push({
|
|
31099
|
+
code: "invalid-format",
|
|
31100
|
+
message: parsed.error,
|
|
31101
|
+
filePath,
|
|
31102
|
+
line: declaration.lineNumber,
|
|
31103
|
+
variableName: declaration.name
|
|
31104
|
+
});
|
|
31105
|
+
continue;
|
|
31106
|
+
}
|
|
31107
|
+
const { kid } = parsed.parsed;
|
|
31108
|
+
const key = resolveSecretKey(kid, filePath);
|
|
31109
|
+
if (!key) {
|
|
31110
|
+
errors.push({
|
|
31111
|
+
code: "missing-key",
|
|
31112
|
+
message: `Missing secret key for kid '${kid}'.`,
|
|
31113
|
+
filePath,
|
|
31114
|
+
line: declaration.lineNumber,
|
|
31115
|
+
variableName: declaration.name,
|
|
31116
|
+
kid
|
|
31117
|
+
});
|
|
31118
|
+
continue;
|
|
31119
|
+
}
|
|
31120
|
+
let plaintext;
|
|
31121
|
+
try {
|
|
31122
|
+
plaintext = decryptSecretValue(declaration.value, key);
|
|
31123
|
+
} catch (error) {
|
|
31124
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
31125
|
+
errors.push({
|
|
31126
|
+
code: "decrypt-failed",
|
|
31127
|
+
message: `Failed to decrypt secret '${declaration.name}' with kid '${kid}': ${message}`,
|
|
31128
|
+
filePath,
|
|
31129
|
+
line: declaration.lineNumber,
|
|
31130
|
+
variableName: declaration.name,
|
|
31131
|
+
kid
|
|
31132
|
+
});
|
|
31133
|
+
continue;
|
|
31134
|
+
}
|
|
31135
|
+
declaration.value = plaintext;
|
|
31136
|
+
if (declaration.envName) {
|
|
31137
|
+
const env3 = config.environments.find((e) => e.name === declaration.envName);
|
|
31138
|
+
if (env3) {
|
|
31139
|
+
env3.variables[declaration.name] = plaintext;
|
|
31140
|
+
}
|
|
31141
|
+
} else {
|
|
31142
|
+
config.common[declaration.name] = plaintext;
|
|
31143
|
+
}
|
|
31144
|
+
config.secretValues.set(declaration.name, plaintext);
|
|
31145
|
+
}
|
|
31146
|
+
return errors;
|
|
31147
|
+
}
|
|
31148
|
+
|
|
31149
|
+
// src/secrets/cliSecrets.ts
|
|
31150
|
+
var fs9 = __toESM(require("fs"));
|
|
31151
|
+
var path8 = __toESM(require("path"));
|
|
31152
|
+
var readline = __toESM(require("readline"));
|
|
31153
|
+
var import_process = require("process");
|
|
31154
|
+
|
|
31155
|
+
// src/secrets/envFileSecrets.ts
|
|
31156
|
+
var fs8 = __toESM(require("fs"));
|
|
31157
|
+
var path7 = __toESM(require("path"));
|
|
31158
|
+
var envRegex2 = /^\s*\[env:([a-zA-Z_][a-zA-Z0-9_-]*)\]\s*$/;
|
|
31159
|
+
var secretRegex2 = /^(\s*secret\s+)([a-zA-Z_][a-zA-Z0-9_]*)(\s*=\s*)(.+)$/;
|
|
31160
|
+
function extractSecretLines(content, filePath) {
|
|
31161
|
+
const lines = content.split("\n");
|
|
31162
|
+
const secrets = [];
|
|
31163
|
+
let currentEnv;
|
|
31164
|
+
for (let i = 0; i < lines.length; i++) {
|
|
31165
|
+
const line2 = lines[i];
|
|
31166
|
+
const trimmed = line2.trim();
|
|
31167
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
31168
|
+
continue;
|
|
31169
|
+
}
|
|
31170
|
+
const envMatch = trimmed.match(envRegex2);
|
|
31171
|
+
if (envMatch) {
|
|
31172
|
+
currentEnv = envMatch[1];
|
|
31173
|
+
continue;
|
|
31174
|
+
}
|
|
31175
|
+
const secretMatch = line2.match(secretRegex2);
|
|
31176
|
+
if (!secretMatch) {
|
|
31177
|
+
continue;
|
|
31178
|
+
}
|
|
31179
|
+
const value = secretMatch[4].trim();
|
|
31180
|
+
const encrypted = isEncryptedSecretValue(value);
|
|
31181
|
+
let kid;
|
|
31182
|
+
if (encrypted) {
|
|
31183
|
+
const parsed = parseEncryptedSecretValue(value);
|
|
31184
|
+
if (parsed.ok) {
|
|
31185
|
+
kid = parsed.parsed.kid;
|
|
31186
|
+
}
|
|
31187
|
+
}
|
|
31188
|
+
secrets.push({
|
|
31189
|
+
filePath,
|
|
31190
|
+
lineNumber: i,
|
|
31191
|
+
envName: currentEnv,
|
|
31192
|
+
name: secretMatch[2],
|
|
31193
|
+
value,
|
|
31194
|
+
encrypted,
|
|
31195
|
+
kid
|
|
31196
|
+
});
|
|
31197
|
+
}
|
|
31198
|
+
return secrets;
|
|
31199
|
+
}
|
|
31200
|
+
function updateSecretLineValue(content, lineNumber, newValue) {
|
|
31201
|
+
const lines = content.split("\n");
|
|
31202
|
+
if (lineNumber < 0 || lineNumber >= lines.length) {
|
|
31203
|
+
throw new Error(`Line ${lineNumber + 1} is out of range.`);
|
|
31204
|
+
}
|
|
31205
|
+
const line2 = lines[lineNumber];
|
|
31206
|
+
const secretMatch = line2.match(secretRegex2);
|
|
31207
|
+
if (!secretMatch) {
|
|
31208
|
+
throw new Error(`Line ${lineNumber + 1} is not a secret declaration.`);
|
|
31209
|
+
}
|
|
31210
|
+
lines[lineNumber] = `${secretMatch[1]}${secretMatch[2]}${secretMatch[3]}${newValue}`;
|
|
31211
|
+
return lines.join("\n");
|
|
31212
|
+
}
|
|
31213
|
+
function findSecretLine(content, variableName, envName) {
|
|
31214
|
+
const secretLines = extractSecretLines(content);
|
|
31215
|
+
if (envName !== void 0) {
|
|
31216
|
+
return secretLines.find((secret) => secret.name === variableName && secret.envName === envName);
|
|
31217
|
+
}
|
|
31218
|
+
const commonMatch = secretLines.find((secret) => secret.name === variableName && secret.envName === void 0);
|
|
31219
|
+
if (commonMatch) {
|
|
31220
|
+
return commonMatch;
|
|
31221
|
+
}
|
|
31222
|
+
return secretLines.find((secret) => secret.name === variableName);
|
|
31223
|
+
}
|
|
31224
|
+
function loadSecretLine(filePath, variableName, envName) {
|
|
31225
|
+
const content = fs8.readFileSync(filePath, "utf8");
|
|
31226
|
+
const secret = findSecretLine(content, variableName, envName);
|
|
31227
|
+
if (!secret) {
|
|
31228
|
+
const envLabel = envName ? ` in [env:${envName}]` : "";
|
|
31229
|
+
throw new Error(`Secret '${variableName}' not found${envLabel} in ${filePath}`);
|
|
31230
|
+
}
|
|
31231
|
+
return { content, secret };
|
|
31232
|
+
}
|
|
31233
|
+
function writeSecretLine(filePath, content) {
|
|
31234
|
+
fs8.writeFileSync(filePath, content, "utf8");
|
|
31235
|
+
}
|
|
31236
|
+
function discoverNornenvFiles(targetPath) {
|
|
31237
|
+
const resolved = path7.resolve(targetPath);
|
|
31238
|
+
if (!fs8.existsSync(resolved)) {
|
|
31239
|
+
return [];
|
|
31240
|
+
}
|
|
31241
|
+
const stats = fs8.statSync(resolved);
|
|
31242
|
+
if (stats.isFile()) {
|
|
31243
|
+
return path7.basename(resolved) === ".nornenv" ? [resolved] : [];
|
|
31244
|
+
}
|
|
31245
|
+
const results = [];
|
|
31246
|
+
const walk = (dir) => {
|
|
31247
|
+
const entries = fs8.readdirSync(dir, { withFileTypes: true });
|
|
31248
|
+
for (const entry of entries) {
|
|
31249
|
+
const fullPath = path7.join(dir, entry.name);
|
|
31250
|
+
if (entry.isDirectory()) {
|
|
31251
|
+
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist" || entry.name === "out") {
|
|
31252
|
+
continue;
|
|
31253
|
+
}
|
|
31254
|
+
walk(fullPath);
|
|
31255
|
+
continue;
|
|
31256
|
+
}
|
|
31257
|
+
if (entry.isFile() && entry.name === ".nornenv") {
|
|
31258
|
+
results.push(fullPath);
|
|
31259
|
+
}
|
|
31260
|
+
}
|
|
31261
|
+
};
|
|
31262
|
+
walk(resolved);
|
|
31263
|
+
return results.sort();
|
|
31264
|
+
}
|
|
31265
|
+
|
|
31266
|
+
// src/secrets/cliSecrets.ts
|
|
31267
|
+
function getFlagValue(args, flag, shortFlag) {
|
|
31268
|
+
const longIndex = args.indexOf(flag);
|
|
31269
|
+
if (longIndex >= 0 && longIndex + 1 < args.length) {
|
|
31270
|
+
return args[longIndex + 1];
|
|
31271
|
+
}
|
|
31272
|
+
if (shortFlag) {
|
|
31273
|
+
const shortIndex = args.indexOf(shortFlag);
|
|
31274
|
+
if (shortIndex >= 0 && shortIndex + 1 < args.length) {
|
|
31275
|
+
return args[shortIndex + 1];
|
|
31276
|
+
}
|
|
31277
|
+
}
|
|
31278
|
+
return void 0;
|
|
31279
|
+
}
|
|
31280
|
+
async function promptLine(question) {
|
|
31281
|
+
if (!process.stdin.isTTY) {
|
|
31282
|
+
return void 0;
|
|
31283
|
+
}
|
|
31284
|
+
const rl = readline.createInterface({ input: import_process.stdin, output: import_process.stdout });
|
|
31285
|
+
try {
|
|
31286
|
+
const answer = await new Promise((resolve9) => {
|
|
31287
|
+
rl.question(question, resolve9);
|
|
31288
|
+
});
|
|
31289
|
+
const trimmed = answer.trim();
|
|
31290
|
+
return trimmed === "" ? void 0 : trimmed;
|
|
31291
|
+
} finally {
|
|
31292
|
+
rl.close();
|
|
31293
|
+
}
|
|
31294
|
+
}
|
|
31295
|
+
function uniqueUnlockableKids(errors) {
|
|
31296
|
+
const kids = /* @__PURE__ */ new Set();
|
|
31297
|
+
for (const err of errors) {
|
|
31298
|
+
if ((err.code === "missing-key" || err.code === "decrypt-failed") && err.kid) {
|
|
31299
|
+
kids.add(err.kid);
|
|
31300
|
+
}
|
|
31301
|
+
}
|
|
31302
|
+
return Array.from(kids).sort();
|
|
31303
|
+
}
|
|
31304
|
+
function formatSecretError(err, envFilePath) {
|
|
31305
|
+
if (!envFilePath) {
|
|
31306
|
+
return `${err.message}`;
|
|
31307
|
+
}
|
|
31308
|
+
const relative4 = path8.relative(path8.dirname(envFilePath), err.filePath);
|
|
31309
|
+
const fileLabel = relative4 && relative4 !== "" ? relative4 : path8.basename(err.filePath);
|
|
31310
|
+
const lineLabel = err.line >= 0 ? `${fileLabel}:${err.line + 1}` : fileLabel;
|
|
31311
|
+
return `${lineLabel} - ${err.message}`;
|
|
31312
|
+
}
|
|
31313
|
+
async function ensureKeyForKid(kid, contextPath) {
|
|
31314
|
+
const existing = resolveSecretKey(kid, contextPath);
|
|
31315
|
+
if (existing) {
|
|
31316
|
+
return existing;
|
|
31317
|
+
}
|
|
31318
|
+
const entered = await promptLine(`Enter shared key for kid '${kid}': `);
|
|
31319
|
+
if (!entered) {
|
|
31320
|
+
return void 0;
|
|
31321
|
+
}
|
|
31322
|
+
saveSecretKeyToCache(kid, entered, contextPath);
|
|
31323
|
+
return entered;
|
|
31324
|
+
}
|
|
31325
|
+
async function ensureCliSecretsUnlocked(targetPath) {
|
|
31326
|
+
const envFilePath = findEnvFileFromPath(targetPath);
|
|
31327
|
+
if (!envFilePath) {
|
|
31328
|
+
return { ok: true, errors: [] };
|
|
31329
|
+
}
|
|
31330
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
31331
|
+
const result = loadAndResolveEnvFile(envFilePath);
|
|
31332
|
+
const unlockableKids = uniqueUnlockableKids(result.secretErrors);
|
|
31333
|
+
if (unlockableKids.length === 0) {
|
|
31334
|
+
return { ok: result.secretErrors.length === 0, envFilePath, errors: result.secretErrors };
|
|
31335
|
+
}
|
|
31336
|
+
for (const kid of unlockableKids) {
|
|
31337
|
+
const key = await ensureKeyForKid(kid, envFilePath);
|
|
31338
|
+
if (!key) {
|
|
31339
|
+
return { ok: false, envFilePath, errors: result.secretErrors };
|
|
31340
|
+
}
|
|
31341
|
+
}
|
|
31342
|
+
}
|
|
31343
|
+
const finalResult = loadAndResolveEnvFile(envFilePath);
|
|
31344
|
+
return { ok: finalResult.secretErrors.length === 0, envFilePath, errors: finalResult.secretErrors };
|
|
31345
|
+
}
|
|
31346
|
+
function printSecretsHelp() {
|
|
31347
|
+
console.log(`
|
|
31348
|
+
Norn Secrets Commands
|
|
31349
|
+
|
|
31350
|
+
Usage:
|
|
31351
|
+
norn secrets keygen --name <kid>
|
|
31352
|
+
norn secrets import-key --kid <kid> [--key <value>]
|
|
31353
|
+
norn secrets encrypt --file <.nornenv> --var <name> [--env <env>] [--kid <kid>]
|
|
31354
|
+
norn secrets rotate --file <.nornenv> --var <name> [--env <env>] [--kid <kid>] [--value <plaintext>]
|
|
31355
|
+
norn secrets rekey [path] [--kid <newKid>]
|
|
31356
|
+
norn secrets audit [path]
|
|
31357
|
+
norn secrets keys
|
|
31358
|
+
norn secrets forget --kid <kid>
|
|
31359
|
+
|
|
31360
|
+
Notes:
|
|
31361
|
+
- Secrets are stored as ENC[NORN_AGE_V1:kid=<id>:<payload>] in .nornenv.
|
|
31362
|
+
- Keys are cached locally in .norn-cache/secret-keys.json (gitignored).
|
|
31363
|
+
- norn run auto-prompts once for missing kids when interactive.
|
|
31364
|
+
`);
|
|
31365
|
+
}
|
|
31366
|
+
async function handleKeygen(args) {
|
|
31367
|
+
const kid = getFlagValue(args, "--name", "-n");
|
|
31368
|
+
if (!kid) {
|
|
31369
|
+
console.error(`Error: Missing --name for keygen.`);
|
|
31370
|
+
return 1;
|
|
31371
|
+
}
|
|
31372
|
+
const key = generateSharedSecretKey();
|
|
31373
|
+
saveSecretKeyToCache(kid, key, process.cwd());
|
|
31374
|
+
console.log(`Generated shared key for kid '${kid}'.`);
|
|
31375
|
+
console.log(`Store this key in your team vault now:`);
|
|
31376
|
+
console.log(key);
|
|
31377
|
+
console.log(`Saved to local cache for current workspace.`);
|
|
31378
|
+
return 0;
|
|
31379
|
+
}
|
|
31380
|
+
async function handleImportKey(args) {
|
|
31381
|
+
const kid = getFlagValue(args, "--kid", "-k");
|
|
31382
|
+
if (!kid) {
|
|
31383
|
+
console.error(`Error: Missing --kid for import-key.`);
|
|
31384
|
+
return 1;
|
|
31385
|
+
}
|
|
31386
|
+
const directKey = getFlagValue(args, "--key");
|
|
31387
|
+
const key = directKey ?? await promptLine(`Enter shared key for kid '${kid}': `);
|
|
31388
|
+
if (!key) {
|
|
31389
|
+
console.error(`Error: No key provided.`);
|
|
31390
|
+
return 1;
|
|
31391
|
+
}
|
|
31392
|
+
saveSecretKeyToCache(kid, key, process.cwd());
|
|
31393
|
+
console.log(`Saved key for kid '${kid}' to local cache.`);
|
|
31394
|
+
return 0;
|
|
31395
|
+
}
|
|
31396
|
+
async function handleEncrypt(args) {
|
|
31397
|
+
const filePath = getFlagValue(args, "--file", "-f");
|
|
31398
|
+
const variableName = getFlagValue(args, "--var");
|
|
31399
|
+
const envName = getFlagValue(args, "--env");
|
|
31400
|
+
const explicitKid = getFlagValue(args, "--kid");
|
|
31401
|
+
if (!filePath || !variableName) {
|
|
31402
|
+
console.error(`Error: encrypt requires --file and --var.`);
|
|
31403
|
+
return 1;
|
|
31404
|
+
}
|
|
31405
|
+
const absoluteFilePath = path8.resolve(filePath);
|
|
31406
|
+
const { content, secret } = loadSecretLine(absoluteFilePath, variableName, envName);
|
|
31407
|
+
if (secret.encrypted) {
|
|
31408
|
+
console.error(`Error: Secret '${variableName}' is already encrypted. Use rotate instead.`);
|
|
31409
|
+
return 1;
|
|
31410
|
+
}
|
|
31411
|
+
const kid = explicitKid;
|
|
31412
|
+
if (!kid) {
|
|
31413
|
+
console.error(`Error: --kid is required when encrypting plaintext secret '${variableName}'.`);
|
|
31414
|
+
return 1;
|
|
31415
|
+
}
|
|
31416
|
+
const key = await ensureKeyForKid(kid, absoluteFilePath);
|
|
31417
|
+
if (!key) {
|
|
31418
|
+
console.error(`Error: Missing key for kid '${kid}'.`);
|
|
31419
|
+
return 1;
|
|
31420
|
+
}
|
|
31421
|
+
const encryptedValue = encryptSecretValue(secret.value, key, kid);
|
|
31422
|
+
const updatedContent = updateSecretLineValue(content, secret.lineNumber, encryptedValue);
|
|
31423
|
+
writeSecretLine(absoluteFilePath, updatedContent);
|
|
31424
|
+
console.log(`Encrypted secret '${variableName}' in ${absoluteFilePath}:${secret.lineNumber + 1}`);
|
|
31425
|
+
return 0;
|
|
31426
|
+
}
|
|
31427
|
+
async function handleRotate(args) {
|
|
31428
|
+
const filePath = getFlagValue(args, "--file", "-f");
|
|
31429
|
+
const variableName = getFlagValue(args, "--var");
|
|
31430
|
+
const envName = getFlagValue(args, "--env");
|
|
31431
|
+
const explicitKid = getFlagValue(args, "--kid");
|
|
31432
|
+
const explicitValue = getFlagValue(args, "--value");
|
|
31433
|
+
if (!filePath || !variableName) {
|
|
31434
|
+
console.error(`Error: rotate requires --file and --var.`);
|
|
31435
|
+
return 1;
|
|
31436
|
+
}
|
|
31437
|
+
const absoluteFilePath = path8.resolve(filePath);
|
|
31438
|
+
const { content, secret } = loadSecretLine(absoluteFilePath, variableName, envName);
|
|
31439
|
+
let kid = explicitKid;
|
|
31440
|
+
if (!kid && secret.encrypted) {
|
|
31441
|
+
const parsed = parseEncryptedSecretValue(secret.value);
|
|
31442
|
+
if (parsed.ok) {
|
|
31443
|
+
kid = parsed.parsed.kid;
|
|
31444
|
+
}
|
|
31445
|
+
}
|
|
31446
|
+
if (!kid) {
|
|
31447
|
+
console.error(`Error: Could not determine kid for '${variableName}'. Pass --kid.`);
|
|
31448
|
+
return 1;
|
|
31449
|
+
}
|
|
31450
|
+
const nextPlaintext = explicitValue ?? await promptLine(`Enter new plaintext value for '${variableName}': `);
|
|
31451
|
+
if (nextPlaintext === void 0) {
|
|
31452
|
+
console.error(`Error: No replacement value provided.`);
|
|
31453
|
+
return 1;
|
|
31454
|
+
}
|
|
31455
|
+
const key = await ensureKeyForKid(kid, absoluteFilePath);
|
|
31456
|
+
if (!key) {
|
|
31457
|
+
console.error(`Error: Missing key for kid '${kid}'.`);
|
|
31458
|
+
return 1;
|
|
31459
|
+
}
|
|
31460
|
+
const encryptedValue = encryptSecretValue(nextPlaintext, key, kid);
|
|
31461
|
+
const updatedContent = updateSecretLineValue(content, secret.lineNumber, encryptedValue);
|
|
31462
|
+
writeSecretLine(absoluteFilePath, updatedContent);
|
|
31463
|
+
console.log(`Rotated secret '${variableName}' in ${absoluteFilePath}:${secret.lineNumber + 1}`);
|
|
31464
|
+
return 0;
|
|
31465
|
+
}
|
|
31466
|
+
async function handleRekey(args) {
|
|
31467
|
+
const positional = args.filter((arg) => !arg.startsWith("-"));
|
|
31468
|
+
const targetPath = positional[0] ? path8.resolve(positional[0]) : process.cwd();
|
|
31469
|
+
const targetKid = getFlagValue(args, "--kid");
|
|
31470
|
+
const files = discoverNornenvFiles(targetPath);
|
|
31471
|
+
if (files.length === 0) {
|
|
31472
|
+
console.log(`No .nornenv files found under ${targetPath}`);
|
|
31473
|
+
return 0;
|
|
31474
|
+
}
|
|
31475
|
+
let updatedFiles = 0;
|
|
31476
|
+
let updatedSecrets = 0;
|
|
31477
|
+
for (const filePath of files) {
|
|
31478
|
+
const original = fs9.readFileSync(filePath, "utf8");
|
|
31479
|
+
const secretLines = extractSecretLines(original, filePath);
|
|
31480
|
+
if (secretLines.length === 0) {
|
|
31481
|
+
continue;
|
|
31482
|
+
}
|
|
31483
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
31484
|
+
for (const secret of secretLines) {
|
|
31485
|
+
if (!secret.encrypted) {
|
|
31486
|
+
continue;
|
|
31487
|
+
}
|
|
31488
|
+
const parsed = parseEncryptedSecretValue(secret.value);
|
|
31489
|
+
if (!parsed.ok) {
|
|
31490
|
+
console.error(`Skipping malformed secret at ${filePath}:${secret.lineNumber + 1}: ${parsed.error}`);
|
|
31491
|
+
continue;
|
|
31492
|
+
}
|
|
31493
|
+
const sourceKid = parsed.parsed.kid;
|
|
31494
|
+
const decryptKey = await ensureKeyForKid(sourceKid, filePath);
|
|
31495
|
+
if (!decryptKey) {
|
|
31496
|
+
console.error(`Missing key for source kid '${sourceKid}' (${filePath}:${secret.lineNumber + 1})`);
|
|
31497
|
+
return 1;
|
|
31498
|
+
}
|
|
31499
|
+
let plaintext;
|
|
31500
|
+
try {
|
|
31501
|
+
plaintext = decryptSecretValue(secret.value, decryptKey);
|
|
31502
|
+
} catch (error) {
|
|
31503
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
31504
|
+
console.error(`Failed to decrypt ${filePath}:${secret.lineNumber + 1} (${sourceKid}): ${message}`);
|
|
31505
|
+
return 1;
|
|
31506
|
+
}
|
|
31507
|
+
const destinationKid = targetKid ?? sourceKid;
|
|
31508
|
+
const encryptKey = destinationKid === sourceKid ? decryptKey : await ensureKeyForKid(destinationKid, filePath);
|
|
31509
|
+
if (!encryptKey) {
|
|
31510
|
+
console.error(`Missing key for destination kid '${destinationKid}'`);
|
|
31511
|
+
return 1;
|
|
31512
|
+
}
|
|
31513
|
+
replacements.set(secret.lineNumber, encryptSecretValue(plaintext, encryptKey, destinationKid));
|
|
31514
|
+
}
|
|
31515
|
+
if (replacements.size === 0) {
|
|
31516
|
+
continue;
|
|
31517
|
+
}
|
|
31518
|
+
let updated = original;
|
|
31519
|
+
const orderedLines = Array.from(replacements.keys()).sort((a, b) => a - b);
|
|
31520
|
+
for (const lineNumber of orderedLines) {
|
|
31521
|
+
const value = replacements.get(lineNumber);
|
|
31522
|
+
if (!value) {
|
|
31523
|
+
continue;
|
|
31524
|
+
}
|
|
31525
|
+
updated = updateSecretLineValue(updated, lineNumber, value);
|
|
31526
|
+
updatedSecrets += 1;
|
|
31527
|
+
}
|
|
31528
|
+
if (updated !== original) {
|
|
31529
|
+
fs9.writeFileSync(filePath, updated, "utf8");
|
|
31530
|
+
updatedFiles += 1;
|
|
31531
|
+
}
|
|
31532
|
+
}
|
|
31533
|
+
console.log(`Rekey complete. Updated ${updatedSecrets} secrets across ${updatedFiles} file(s).`);
|
|
31534
|
+
return 0;
|
|
31535
|
+
}
|
|
31536
|
+
async function handleAudit(args) {
|
|
31537
|
+
const positional = args.filter((arg) => !arg.startsWith("-"));
|
|
31538
|
+
const targetPath = positional[0] ? path8.resolve(positional[0]) : process.cwd();
|
|
31539
|
+
const files = discoverNornenvFiles(targetPath);
|
|
31540
|
+
if (files.length === 0) {
|
|
31541
|
+
console.log(`No .nornenv files found under ${targetPath}`);
|
|
31542
|
+
return 0;
|
|
31543
|
+
}
|
|
31544
|
+
const issues = [];
|
|
31545
|
+
for (const filePath of files) {
|
|
31546
|
+
const content = fs9.readFileSync(filePath, "utf8");
|
|
31547
|
+
const secrets = extractSecretLines(content, filePath);
|
|
31548
|
+
for (const secret of secrets) {
|
|
31549
|
+
if (!secret.encrypted) {
|
|
31550
|
+
issues.push(`${filePath}:${secret.lineNumber + 1} secret '${secret.name}' is plaintext.`);
|
|
31551
|
+
continue;
|
|
31552
|
+
}
|
|
31553
|
+
const parsed = parseEncryptedSecretValue(secret.value);
|
|
31554
|
+
if (!parsed.ok) {
|
|
31555
|
+
issues.push(`${filePath}:${secret.lineNumber + 1} malformed encrypted value (${parsed.error}).`);
|
|
31556
|
+
}
|
|
31557
|
+
}
|
|
31558
|
+
}
|
|
31559
|
+
if (issues.length === 0) {
|
|
31560
|
+
console.log(`Audit passed. All secret declarations are encrypted.`);
|
|
31561
|
+
return 0;
|
|
31562
|
+
}
|
|
31563
|
+
console.error(`Audit failed with ${issues.length} issue(s):`);
|
|
31564
|
+
for (const issue of issues) {
|
|
31565
|
+
console.error(` - ${issue}`);
|
|
31566
|
+
}
|
|
31567
|
+
return 1;
|
|
31568
|
+
}
|
|
31569
|
+
async function handleKeys() {
|
|
31570
|
+
const keys = listCachedSecretKeyIds(process.cwd());
|
|
31571
|
+
if (keys.length === 0) {
|
|
31572
|
+
console.log("No cached keys found for this workspace.");
|
|
31573
|
+
return 0;
|
|
31574
|
+
}
|
|
31575
|
+
console.log("Cached key ids:");
|
|
31576
|
+
for (const kid of keys) {
|
|
31577
|
+
console.log(` - ${kid}`);
|
|
31578
|
+
}
|
|
31579
|
+
return 0;
|
|
31580
|
+
}
|
|
31581
|
+
async function handleForget(args) {
|
|
31582
|
+
const kid = getFlagValue(args, "--kid", "-k");
|
|
31583
|
+
if (!kid) {
|
|
31584
|
+
console.error(`Error: forget requires --kid.`);
|
|
31585
|
+
return 1;
|
|
31586
|
+
}
|
|
31587
|
+
const removed = removeSecretKeyFromCache(kid, process.cwd());
|
|
31588
|
+
if (!removed) {
|
|
31589
|
+
console.log(`No cached key found for '${kid}'.`);
|
|
31590
|
+
return 0;
|
|
31591
|
+
}
|
|
31592
|
+
console.log(`Removed cached key '${kid}'.`);
|
|
31593
|
+
return 0;
|
|
31594
|
+
}
|
|
31595
|
+
async function handleSecretsCommand(args) {
|
|
31596
|
+
const [subcommand, ...rest] = args;
|
|
31597
|
+
switch (subcommand) {
|
|
31598
|
+
case "keygen":
|
|
31599
|
+
return handleKeygen(rest);
|
|
31600
|
+
case "import-key":
|
|
31601
|
+
return handleImportKey(rest);
|
|
31602
|
+
case "encrypt":
|
|
31603
|
+
return handleEncrypt(rest);
|
|
31604
|
+
case "rotate":
|
|
31605
|
+
return handleRotate(rest);
|
|
31606
|
+
case "rekey":
|
|
31607
|
+
return handleRekey(rest);
|
|
31608
|
+
case "audit":
|
|
31609
|
+
return handleAudit(rest);
|
|
31610
|
+
case "keys":
|
|
31611
|
+
return handleKeys();
|
|
31612
|
+
case "forget":
|
|
31613
|
+
return handleForget(rest);
|
|
31614
|
+
case "--help":
|
|
31615
|
+
case "-h":
|
|
31616
|
+
case void 0:
|
|
31617
|
+
printSecretsHelp();
|
|
31618
|
+
return 0;
|
|
31619
|
+
default:
|
|
31620
|
+
console.error(`Unknown secrets command: ${subcommand}`);
|
|
31621
|
+
printSecretsHelp();
|
|
31622
|
+
return 1;
|
|
31623
|
+
}
|
|
31624
|
+
}
|
|
31625
|
+
function printSecretResolutionErrors(errors, envFilePath) {
|
|
31626
|
+
for (const err of errors) {
|
|
31627
|
+
console.error(`Error: ${formatSecretError(err, envFilePath)}`);
|
|
31628
|
+
}
|
|
30828
31629
|
}
|
|
30829
31630
|
|
|
30830
31631
|
// src/cli.ts
|
|
30831
31632
|
function formatNornenvErrorLocation(rootEnvFilePath, errorFilePath, line2) {
|
|
30832
|
-
const baseDir =
|
|
30833
|
-
const relativePath =
|
|
30834
|
-
const fileLabel = relativePath && relativePath !== "" ? relativePath :
|
|
31633
|
+
const baseDir = path9.dirname(rootEnvFilePath);
|
|
31634
|
+
const relativePath = path9.relative(baseDir, errorFilePath);
|
|
31635
|
+
const fileLabel = relativePath && relativePath !== "" ? relativePath : path9.basename(errorFilePath);
|
|
30835
31636
|
return line2 >= 0 ? `${fileLabel}:${line2 + 1}` : fileLabel;
|
|
30836
31637
|
}
|
|
30837
31638
|
function resolveEnvironmentForPath(targetPath, selectedEnv) {
|
|
@@ -30841,10 +31642,11 @@ function resolveEnvironmentForPath(targetPath, selectedEnv) {
|
|
|
30841
31642
|
variables: {},
|
|
30842
31643
|
secretNames: /* @__PURE__ */ new Set(),
|
|
30843
31644
|
secretValues: /* @__PURE__ */ new Map(),
|
|
31645
|
+
secretErrors: [],
|
|
30844
31646
|
availableEnvironments: []
|
|
30845
31647
|
};
|
|
30846
31648
|
}
|
|
30847
|
-
const { config: envConfig, errors: importErrors } = loadAndResolveEnvFile(envFilePath);
|
|
31649
|
+
const { config: envConfig, errors: importErrors, secretErrors } = loadAndResolveEnvFile(envFilePath);
|
|
30848
31650
|
for (const err of importErrors) {
|
|
30849
31651
|
const location = formatNornenvErrorLocation(envFilePath, err.filePath, err.line);
|
|
30850
31652
|
console.error(`Error in ${location}: ${err.message}`);
|
|
@@ -30865,6 +31667,7 @@ function resolveEnvironmentForPath(targetPath, selectedEnv) {
|
|
|
30865
31667
|
variables,
|
|
30866
31668
|
secretNames,
|
|
30867
31669
|
secretValues,
|
|
31670
|
+
secretErrors: secretErrors.map((e) => e.message),
|
|
30868
31671
|
availableEnvironments,
|
|
30869
31672
|
envNotFound: selectedEnv
|
|
30870
31673
|
};
|
|
@@ -30881,6 +31684,7 @@ function resolveEnvironmentForPath(targetPath, selectedEnv) {
|
|
|
30881
31684
|
variables,
|
|
30882
31685
|
secretNames,
|
|
30883
31686
|
secretValues,
|
|
31687
|
+
secretErrors: secretErrors.map((e) => e.message),
|
|
30884
31688
|
availableEnvironments
|
|
30885
31689
|
};
|
|
30886
31690
|
}
|
|
@@ -30910,10 +31714,10 @@ function generateTimestamp() {
|
|
|
30910
31714
|
return `${year}-${month}-${day}-${hours}${minutes}${seconds}`;
|
|
30911
31715
|
}
|
|
30912
31716
|
function generateReportPaths(outputDir, inputFile, timestamp) {
|
|
30913
|
-
const baseName =
|
|
31717
|
+
const baseName = path9.basename(inputFile, path9.extname(inputFile));
|
|
30914
31718
|
return {
|
|
30915
|
-
junitPath:
|
|
30916
|
-
htmlPath:
|
|
31719
|
+
junitPath: path9.join(outputDir, `${baseName}-${timestamp}-results.xml`),
|
|
31720
|
+
htmlPath: path9.join(outputDir, `${baseName}-${timestamp}-report.html`)
|
|
30917
31721
|
};
|
|
30918
31722
|
}
|
|
30919
31723
|
function parseArgs(args) {
|
|
@@ -30924,7 +31728,8 @@ function parseArgs(args) {
|
|
|
30924
31728
|
failOnError: true,
|
|
30925
31729
|
noRedact: false,
|
|
30926
31730
|
tagFilters: [],
|
|
30927
|
-
tagsFilter: []
|
|
31731
|
+
tagsFilter: [],
|
|
31732
|
+
insecure: false
|
|
30928
31733
|
};
|
|
30929
31734
|
for (let i = 0; i < args.length; i++) {
|
|
30930
31735
|
const arg = args[i];
|
|
@@ -30940,6 +31745,8 @@ function parseArgs(args) {
|
|
|
30940
31745
|
options.env = args[++i];
|
|
30941
31746
|
} else if (arg === "--timeout" || arg === "-t") {
|
|
30942
31747
|
options.timeout = parseInt(args[++i], 10) * 1e3;
|
|
31748
|
+
} else if (arg === "--insecure") {
|
|
31749
|
+
options.insecure = true;
|
|
30943
31750
|
} else if (arg === "--no-fail") {
|
|
30944
31751
|
options.failOnError = false;
|
|
30945
31752
|
} else if (arg === "--no-redact") {
|
|
@@ -30975,6 +31782,7 @@ function printHelp() {
|
|
|
30975
31782
|
Norn CLI - Run HTTP requests and test sequences from .norn files
|
|
30976
31783
|
|
|
30977
31784
|
Usage: norn <file.norn|directory> [options]
|
|
31785
|
+
norn secrets <command> [options]
|
|
30978
31786
|
|
|
30979
31787
|
When given a directory, recursively discovers and runs all test sequences
|
|
30980
31788
|
from .norn files within that directory and subdirectories.
|
|
@@ -30984,6 +31792,7 @@ Options:
|
|
|
30984
31792
|
-r, --request <name> Run a specific named request (single file only)
|
|
30985
31793
|
-e, --env <name> Use environment from .nornenv (e.g., dev, prod)
|
|
30986
31794
|
-t, --timeout <sec> Request timeout in seconds (default: no timeout)
|
|
31795
|
+
--insecure Disable TLS certificate verification (dev/self-signed only)
|
|
30987
31796
|
-j, --json Output results as JSON (for CI/CD)
|
|
30988
31797
|
-v, --verbose Show detailed output (headers, request/response bodies)
|
|
30989
31798
|
--no-fail Don't exit with error code on failed requests
|
|
@@ -31034,7 +31843,11 @@ Examples:
|
|
|
31034
31843
|
norn tests/ -o ./reports # Generate reports for all tests
|
|
31035
31844
|
norn api-tests.norn --junit results.xml # Generate JUnit report (explicit)
|
|
31036
31845
|
norn api-tests.norn --html report.html # Generate HTML report (explicit)
|
|
31846
|
+
norn api-tests.norn --insecure # Allow self-signed/local TLS certs
|
|
31037
31847
|
norn api-tests.norn --no-redact # Show all data (no redaction)
|
|
31848
|
+
norn secrets keygen --name team-main # Generate shared key and cache locally
|
|
31849
|
+
norn secrets import-key --kid team-main # Save shared key from your vault
|
|
31850
|
+
norn secrets audit . # Fail if plaintext secrets are committed
|
|
31038
31851
|
`);
|
|
31039
31852
|
}
|
|
31040
31853
|
async function runSingleRequest(fileContent, variables, cookieJar, apiDefinitions, filePath, envContext) {
|
|
@@ -31172,9 +31985,9 @@ async function runSingleRequest(fileContent, variables, cookieJar, apiDefinition
|
|
|
31172
31985
|
function discoverNornFiles(dirPath) {
|
|
31173
31986
|
const files = [];
|
|
31174
31987
|
function walkDir(currentPath) {
|
|
31175
|
-
const entries =
|
|
31988
|
+
const entries = fs10.readdirSync(currentPath, { withFileTypes: true });
|
|
31176
31989
|
for (const entry of entries) {
|
|
31177
|
-
const fullPath =
|
|
31990
|
+
const fullPath = path9.join(currentPath, entry.name);
|
|
31178
31991
|
if (entry.isDirectory()) {
|
|
31179
31992
|
if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
31180
31993
|
walkDir(fullPath);
|
|
@@ -31194,7 +32007,7 @@ function countTestSequences(fileContent, tagFilterOptions) {
|
|
|
31194
32007
|
return { total: testSequences.length, filtered };
|
|
31195
32008
|
}
|
|
31196
32009
|
async function loadTheoryFile(theoryPath, workingDir) {
|
|
31197
|
-
const absolutePath =
|
|
32010
|
+
const absolutePath = path9.resolve(workingDir, theoryPath);
|
|
31198
32011
|
const content = await fsPromises.readFile(absolutePath, "utf-8");
|
|
31199
32012
|
return JSON.parse(content);
|
|
31200
32013
|
}
|
|
@@ -31288,23 +32101,37 @@ async function runAllSequences(fileContent, variables, cookieJar, workingDir, ap
|
|
|
31288
32101
|
return results;
|
|
31289
32102
|
}
|
|
31290
32103
|
async function main() {
|
|
31291
|
-
const
|
|
32104
|
+
const rawArgs = process.argv.slice(2);
|
|
32105
|
+
if (rawArgs[0] === "secrets") {
|
|
32106
|
+
const exitCode = await handleSecretsCommand(rawArgs.slice(1));
|
|
32107
|
+
process.exit(exitCode);
|
|
32108
|
+
}
|
|
32109
|
+
const args = rawArgs[0] === "run" ? rawArgs.slice(1) : rawArgs;
|
|
31292
32110
|
if (args.length === 0) {
|
|
31293
32111
|
printHelp();
|
|
31294
32112
|
process.exit(1);
|
|
31295
32113
|
}
|
|
31296
32114
|
const options = parseArgs(args);
|
|
32115
|
+
setVerifyTlsCertificates(!options.insecure);
|
|
32116
|
+
if (options.insecure) {
|
|
32117
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
32118
|
+
} else {
|
|
32119
|
+
delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
|
32120
|
+
}
|
|
31297
32121
|
if (!options.file) {
|
|
31298
32122
|
console.error("Error: No input file or directory specified");
|
|
31299
32123
|
process.exit(1);
|
|
31300
32124
|
}
|
|
31301
32125
|
const colors = await initColors();
|
|
31302
|
-
|
|
31303
|
-
|
|
32126
|
+
if (options.insecure) {
|
|
32127
|
+
console.error(colors.warning("Warning: TLS certificate verification is disabled (--insecure). Use this only for local development."));
|
|
32128
|
+
}
|
|
32129
|
+
const inputPath = path9.resolve(options.file);
|
|
32130
|
+
if (!fs10.existsSync(inputPath)) {
|
|
31304
32131
|
console.error(`Error: Path not found: ${inputPath}`);
|
|
31305
32132
|
process.exit(1);
|
|
31306
32133
|
}
|
|
31307
|
-
const isDirectory =
|
|
32134
|
+
const isDirectory = fs10.statSync(inputPath).isDirectory();
|
|
31308
32135
|
let filesToRun;
|
|
31309
32136
|
if (isDirectory) {
|
|
31310
32137
|
filesToRun = discoverNornFiles(inputPath);
|
|
@@ -31342,6 +32169,15 @@ async function main() {
|
|
|
31342
32169
|
}
|
|
31343
32170
|
if (options.sequence || options.request) {
|
|
31344
32171
|
const filePath = filesToRun[0];
|
|
32172
|
+
const secretUnlockResult = await ensureCliSecretsUnlocked(filePath);
|
|
32173
|
+
if (!secretUnlockResult.ok) {
|
|
32174
|
+
if (secretUnlockResult.errors.length > 0) {
|
|
32175
|
+
printSecretResolutionErrors(secretUnlockResult.errors, secretUnlockResult.envFilePath);
|
|
32176
|
+
} else {
|
|
32177
|
+
console.error("Unable to unlock encrypted secrets.");
|
|
32178
|
+
}
|
|
32179
|
+
process.exit(1);
|
|
32180
|
+
}
|
|
31345
32181
|
const resolvedEnv = resolveEnvironmentForPath(filePath, options.env);
|
|
31346
32182
|
const envValidationContext = buildCliEnvironmentValidationContext(resolvedEnv, options.env);
|
|
31347
32183
|
if (resolvedEnv.envNotFound) {
|
|
@@ -31349,6 +32185,12 @@ async function main() {
|
|
|
31349
32185
|
console.error(`Available environments: ${resolvedEnv.availableEnvironments.join(", ") || "none"}`);
|
|
31350
32186
|
process.exit(1);
|
|
31351
32187
|
}
|
|
32188
|
+
if (resolvedEnv.secretErrors.length > 0) {
|
|
32189
|
+
for (const error of resolvedEnv.secretErrors) {
|
|
32190
|
+
console.error(`Error: ${error}`);
|
|
32191
|
+
}
|
|
32192
|
+
process.exit(1);
|
|
32193
|
+
}
|
|
31352
32194
|
if (!resolvedEnv.envFilePath && options.env) {
|
|
31353
32195
|
console.error(colors.warning(`Warning: --env specified but no .nornenv file found`));
|
|
31354
32196
|
} else if (resolvedEnv.envFilePath && options.env && options.verbose) {
|
|
@@ -31356,11 +32198,11 @@ async function main() {
|
|
|
31356
32198
|
}
|
|
31357
32199
|
mergeSecrets(combinedSecretNames, combinedSecretValues, resolvedEnv.secretNames, resolvedEnv.secretValues);
|
|
31358
32200
|
const redaction2 = createRedactionOptions(combinedSecretNames, combinedSecretValues, !options.noRedact);
|
|
31359
|
-
const fileContent =
|
|
32201
|
+
const fileContent = fs10.readFileSync(filePath, "utf-8");
|
|
31360
32202
|
const fileVariables = extractFileLevelVariables(fileContent);
|
|
31361
32203
|
const variables = { ...resolvedEnv.variables, ...fileVariables };
|
|
31362
32204
|
const cookieJar = createCookieJar();
|
|
31363
|
-
const workingDir =
|
|
32205
|
+
const workingDir = path9.dirname(filePath);
|
|
31364
32206
|
const importResult = await resolveImports(
|
|
31365
32207
|
fileContent,
|
|
31366
32208
|
workingDir,
|
|
@@ -31461,7 +32303,7 @@ ${fileContent}` : fileContent;
|
|
|
31461
32303
|
let totalTestCount = 0;
|
|
31462
32304
|
let filteredTestCount = 0;
|
|
31463
32305
|
for (const filePath of filesToRun) {
|
|
31464
|
-
const fileContent =
|
|
32306
|
+
const fileContent = fs10.readFileSync(filePath, "utf-8");
|
|
31465
32307
|
const counts = countTestSequences(fileContent, tagFilterOptions);
|
|
31466
32308
|
totalTestCount += counts.total;
|
|
31467
32309
|
filteredTestCount += counts.filtered;
|
|
@@ -31480,6 +32322,15 @@ ${fileContent}` : fileContent;
|
|
|
31480
32322
|
console.log("");
|
|
31481
32323
|
}
|
|
31482
32324
|
for (const filePath of filesToRun) {
|
|
32325
|
+
const secretUnlockResult = await ensureCliSecretsUnlocked(filePath);
|
|
32326
|
+
if (!secretUnlockResult.ok) {
|
|
32327
|
+
if (secretUnlockResult.errors.length > 0) {
|
|
32328
|
+
printSecretResolutionErrors(secretUnlockResult.errors, secretUnlockResult.envFilePath);
|
|
32329
|
+
} else {
|
|
32330
|
+
console.error("Unable to unlock encrypted secrets.");
|
|
32331
|
+
}
|
|
32332
|
+
process.exit(1);
|
|
32333
|
+
}
|
|
31483
32334
|
const resolvedEnv = resolveEnvironmentForPath(filePath, options.env);
|
|
31484
32335
|
const envValidationContext = buildCliEnvironmentValidationContext(resolvedEnv, options.env);
|
|
31485
32336
|
if (resolvedEnv.envNotFound) {
|
|
@@ -31487,17 +32338,23 @@ ${fileContent}` : fileContent;
|
|
|
31487
32338
|
console.error(`Available environments: ${resolvedEnv.availableEnvironments.join(", ") || "none"}`);
|
|
31488
32339
|
process.exit(1);
|
|
31489
32340
|
}
|
|
32341
|
+
if (resolvedEnv.secretErrors.length > 0) {
|
|
32342
|
+
for (const error of resolvedEnv.secretErrors) {
|
|
32343
|
+
console.error(`Error: ${error}`);
|
|
32344
|
+
}
|
|
32345
|
+
process.exit(1);
|
|
32346
|
+
}
|
|
31490
32347
|
if (!resolvedEnv.envFilePath && options.env) {
|
|
31491
|
-
const relPath = isDirectory ?
|
|
32348
|
+
const relPath = isDirectory ? path9.relative(inputPath, filePath) : path9.basename(filePath);
|
|
31492
32349
|
console.error(colors.warning(`Warning: --env specified but no .nornenv file found for ${relPath}`));
|
|
31493
32350
|
}
|
|
31494
32351
|
mergeSecrets(combinedSecretNames, combinedSecretValues, resolvedEnv.secretNames, resolvedEnv.secretValues);
|
|
31495
32352
|
const redaction2 = createRedactionOptions(combinedSecretNames, combinedSecretValues, !options.noRedact);
|
|
31496
|
-
const fileContent =
|
|
32353
|
+
const fileContent = fs10.readFileSync(filePath, "utf-8");
|
|
31497
32354
|
const fileVariables = extractFileLevelVariables(fileContent);
|
|
31498
32355
|
const variables = { ...resolvedEnv.variables, ...fileVariables };
|
|
31499
32356
|
const cookieJar = createCookieJar();
|
|
31500
|
-
const workingDir =
|
|
32357
|
+
const workingDir = path9.dirname(filePath);
|
|
31501
32358
|
const importResult = await resolveImports(
|
|
31502
32359
|
fileContent,
|
|
31503
32360
|
workingDir,
|
|
@@ -31529,7 +32386,7 @@ ${fileContent}` : fileContent;
|
|
|
31529
32386
|
continue;
|
|
31530
32387
|
}
|
|
31531
32388
|
if (isDirectory && options.output !== "json") {
|
|
31532
|
-
const relPath =
|
|
32389
|
+
const relPath = path9.relative(inputPath, filePath);
|
|
31533
32390
|
console.log(colors.info(`
|
|
31534
32391
|
\u2501\u2501\u2501 ${relPath} \u2501\u2501\u2501`));
|
|
31535
32392
|
}
|
|
@@ -31573,7 +32430,7 @@ ${fileContent}` : fileContent;
|
|
|
31573
32430
|
let htmlOutputPath = options.htmlOutput;
|
|
31574
32431
|
if (options.outputDir) {
|
|
31575
32432
|
const timestamp = generateTimestamp();
|
|
31576
|
-
const baseName = isDirectory ?
|
|
32433
|
+
const baseName = isDirectory ? path9.basename(inputPath) : path9.basename(inputPath, path9.extname(inputPath));
|
|
31577
32434
|
const generatedPaths = generateReportPaths(options.outputDir, baseName + ".norn", timestamp);
|
|
31578
32435
|
if (!junitOutputPath) {
|
|
31579
32436
|
junitOutputPath = generatedPaths.junitPath;
|
|
@@ -31581,12 +32438,12 @@ ${fileContent}` : fileContent;
|
|
|
31581
32438
|
if (!htmlOutputPath) {
|
|
31582
32439
|
htmlOutputPath = generatedPaths.htmlPath;
|
|
31583
32440
|
}
|
|
31584
|
-
if (!
|
|
31585
|
-
|
|
32441
|
+
if (!fs10.existsSync(options.outputDir)) {
|
|
32442
|
+
fs10.mkdirSync(options.outputDir, { recursive: true });
|
|
31586
32443
|
}
|
|
31587
32444
|
}
|
|
31588
32445
|
if (junitOutputPath) {
|
|
31589
|
-
const suiteName = isDirectory ?
|
|
32446
|
+
const suiteName = isDirectory ? path9.basename(inputPath) : path9.basename(inputPath, path9.extname(inputPath));
|
|
31590
32447
|
if (result.type === "request") {
|
|
31591
32448
|
generateJUnitReportFromResponse(
|
|
31592
32449
|
result.results[0],
|
|
@@ -31602,11 +32459,11 @@ ${fileContent}` : fileContent;
|
|
|
31602
32459
|
console.log(colors.info(`JUnit report written to: ${junitOutputPath}`));
|
|
31603
32460
|
}
|
|
31604
32461
|
if (htmlOutputPath) {
|
|
31605
|
-
const title = `Norn Test Report - ${
|
|
32462
|
+
const title = `Norn Test Report - ${path9.basename(inputPath)}`;
|
|
31606
32463
|
if (result.type === "request") {
|
|
31607
32464
|
generateHtmlReportFromResponse(
|
|
31608
32465
|
result.results[0],
|
|
31609
|
-
options.request ||
|
|
32466
|
+
options.request || path9.basename(inputPath),
|
|
31610
32467
|
{ outputPath: htmlOutputPath, redaction, title }
|
|
31611
32468
|
);
|
|
31612
32469
|
} else {
|