norn-cli 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +183 -176
- package/package.json +7 -1
package/dist/cli.js
CHANGED
|
@@ -109395,16 +109395,16 @@ var BUILT_IN_SQL_ADAPTERS = [
|
|
|
109395
109395
|
{
|
|
109396
109396
|
id: "postgres",
|
|
109397
109397
|
label: "PostgreSQL",
|
|
109398
|
-
description: "Built-in PostgreSQL adapter using
|
|
109399
|
-
connectionSetupSummary: "connectionString
|
|
109400
|
-
optionalConnectionKeys: [
|
|
109398
|
+
description: "Built-in PostgreSQL adapter using a connection string.",
|
|
109399
|
+
connectionSetupSummary: "connectionString",
|
|
109400
|
+
optionalConnectionKeys: []
|
|
109401
109401
|
},
|
|
109402
109402
|
{
|
|
109403
109403
|
id: "sqlserver",
|
|
109404
109404
|
label: "SQL Server",
|
|
109405
|
-
description: "Built-in SQL Server adapter using
|
|
109406
|
-
connectionSetupSummary: "connectionString
|
|
109407
|
-
optionalConnectionKeys: [
|
|
109405
|
+
description: "Built-in SQL Server adapter using a connection string.",
|
|
109406
|
+
connectionSetupSummary: "connectionString",
|
|
109407
|
+
optionalConnectionKeys: []
|
|
109408
109408
|
}
|
|
109409
109409
|
];
|
|
109410
109410
|
var BUILT_IN_SQL_ADAPTER_MAP = new Map(
|
|
@@ -109426,31 +109426,48 @@ function getConnectionValue(values, ...keys) {
|
|
|
109426
109426
|
function getConnectionString(values) {
|
|
109427
109427
|
return getConnectionValue(values, "connectionString");
|
|
109428
109428
|
}
|
|
109429
|
-
function
|
|
109430
|
-
|
|
109431
|
-
|
|
109432
|
-
|
|
109433
|
-
|
|
109434
|
-
if (["true", "1", "yes", "on"].includes(normalized)) {
|
|
109435
|
-
return true;
|
|
109436
|
-
}
|
|
109437
|
-
if (["false", "0", "no", "off"].includes(normalized)) {
|
|
109429
|
+
function buildMissingConnectionError(adapterLabel, profile) {
|
|
109430
|
+
return `Missing required ${adapterLabel} connection string. Expected 'connectionString ${profile} = ...' in .nornenv.`;
|
|
109431
|
+
}
|
|
109432
|
+
function shouldPassThroughError(error) {
|
|
109433
|
+
if (!(error instanceof Error)) {
|
|
109438
109434
|
return false;
|
|
109439
109435
|
}
|
|
109440
|
-
return
|
|
109436
|
+
return /^(Missing required|Missing SQL parameter|Invalid )/.test(error.message);
|
|
109441
109437
|
}
|
|
109442
|
-
function
|
|
109443
|
-
if (
|
|
109444
|
-
return
|
|
109445
|
-
}
|
|
109446
|
-
const parsed = Number(value);
|
|
109447
|
-
if (!Number.isFinite(parsed)) {
|
|
109448
|
-
fail(`Invalid ${label} '${value}'`);
|
|
109438
|
+
function formatBuiltInDriverError(adapterLabel, error) {
|
|
109439
|
+
if (shouldPassThroughError(error)) {
|
|
109440
|
+
return error;
|
|
109449
109441
|
}
|
|
109450
|
-
|
|
109451
|
-
|
|
109452
|
-
|
|
109453
|
-
|
|
109442
|
+
const candidate = error;
|
|
109443
|
+
const baseMessage = error instanceof Error ? error.message : typeof error === "string" ? error : "Unknown database error";
|
|
109444
|
+
const details = [];
|
|
109445
|
+
const append2 = (label, value) => {
|
|
109446
|
+
if (value === void 0 || value === null || `${value}`.trim() === "") {
|
|
109447
|
+
return;
|
|
109448
|
+
}
|
|
109449
|
+
details.push(`${label}: ${value}`);
|
|
109450
|
+
};
|
|
109451
|
+
append2("code", candidate?.code);
|
|
109452
|
+
append2("number", candidate?.number);
|
|
109453
|
+
append2("state", candidate?.state);
|
|
109454
|
+
append2("severity", candidate?.severity ?? candidate?.class);
|
|
109455
|
+
append2("detail", candidate?.detail);
|
|
109456
|
+
append2("hint", candidate?.hint);
|
|
109457
|
+
append2("schema", candidate?.schema);
|
|
109458
|
+
append2("table", candidate?.table);
|
|
109459
|
+
append2("column", candidate?.column);
|
|
109460
|
+
append2("constraint", candidate?.constraint);
|
|
109461
|
+
append2("routine", candidate?.routine);
|
|
109462
|
+
append2("line", candidate?.lineNumber);
|
|
109463
|
+
append2("procedure", candidate?.procName);
|
|
109464
|
+
append2("server", candidate?.serverName);
|
|
109465
|
+
const precedingErrors = Array.isArray(candidate?.precedingErrors) ? (candidate?.precedingErrors).map((item) => item?.message).filter((message) => message !== void 0 && message !== null && `${message}`.trim() !== "") : [];
|
|
109466
|
+
if (precedingErrors.length > 0) {
|
|
109467
|
+
details.push(`precedingErrors: ${precedingErrors.join(" | ")}`);
|
|
109468
|
+
}
|
|
109469
|
+
const suffix = details.length > 0 ? ` (${details.join(", ")})` : "";
|
|
109470
|
+
return new Error(`${adapterLabel} driver error: ${baseMessage}${suffix}`);
|
|
109454
109471
|
}
|
|
109455
109472
|
function compilePostgresSql(sql, params) {
|
|
109456
109473
|
const values = [];
|
|
@@ -109485,31 +109502,12 @@ function compileSqlServerSql(sql, params) {
|
|
|
109485
109502
|
async function runBuiltInPostgresAdapter(request) {
|
|
109486
109503
|
const values = request.connection.values;
|
|
109487
109504
|
const connectionString = getConnectionString(values);
|
|
109488
|
-
|
|
109489
|
-
|
|
109490
|
-
|
|
109491
|
-
const
|
|
109492
|
-
const client = connectionString ? new Client(connectionString) : (() => {
|
|
109493
|
-
if (!host || !database || !user || !password) {
|
|
109494
|
-
fail(buildMissingConnectionError("Postgres"));
|
|
109495
|
-
}
|
|
109496
|
-
const port = parseOptionalNumber(values.port, "Postgres port") ?? 5432;
|
|
109497
|
-
return new Client({
|
|
109498
|
-
host,
|
|
109499
|
-
port,
|
|
109500
|
-
database,
|
|
109501
|
-
user,
|
|
109502
|
-
password,
|
|
109503
|
-
ssl: parseBoolean(values.ssl, false) ? { rejectUnauthorized: parseBoolean(values.rejectUnauthorized, false) } : false,
|
|
109504
|
-
application_name: values.applicationName || "norn-sql"
|
|
109505
|
-
});
|
|
109506
|
-
})();
|
|
109505
|
+
if (!connectionString) {
|
|
109506
|
+
fail(buildMissingConnectionError("Postgres", request.connection.profile));
|
|
109507
|
+
}
|
|
109508
|
+
const client = new Client(connectionString);
|
|
109507
109509
|
try {
|
|
109508
109510
|
await client.connect();
|
|
109509
|
-
if (values.schema) {
|
|
109510
|
-
const safeSchema = values.schema.replace(/"/g, '""');
|
|
109511
|
-
await client.query(`set search_path to "${safeSchema}"`);
|
|
109512
|
-
}
|
|
109513
109511
|
const compiled = compilePostgresSql(request.operation.sql, request.params || {});
|
|
109514
109512
|
const result = await client.query(compiled.text, compiled.values);
|
|
109515
109513
|
if (request.mode === "query") {
|
|
@@ -109529,6 +109527,8 @@ async function runBuiltInPostgresAdapter(request) {
|
|
|
109529
109527
|
affectedRows: result.rowCount ?? 0
|
|
109530
109528
|
}
|
|
109531
109529
|
};
|
|
109530
|
+
} catch (error) {
|
|
109531
|
+
throw formatBuiltInDriverError("Postgres", error);
|
|
109532
109532
|
} finally {
|
|
109533
109533
|
await client.end().catch(() => void 0);
|
|
109534
109534
|
}
|
|
@@ -109536,53 +109536,10 @@ async function runBuiltInPostgresAdapter(request) {
|
|
|
109536
109536
|
async function runBuiltInSqlServerAdapter(request) {
|
|
109537
109537
|
const values = request.connection.values;
|
|
109538
109538
|
const connectionString = getConnectionString(values);
|
|
109539
|
-
|
|
109540
|
-
|
|
109541
|
-
|
|
109542
|
-
|
|
109543
|
-
const password = getConnectionValue(values, "password");
|
|
109544
|
-
if (!server || !database || !user || !password) {
|
|
109545
|
-
fail(buildMissingConnectionError("SQL Server"));
|
|
109546
|
-
}
|
|
109547
|
-
const port = parseOptionalNumber(values.port, "SQL Server port");
|
|
109548
|
-
const connectionTimeout = parseOptionalNumber(values.connectionTimeout, "SQL Server connectionTimeout");
|
|
109549
|
-
const requestTimeout = parseOptionalNumber(values.requestTimeout, "SQL Server requestTimeout");
|
|
109550
|
-
const config = {
|
|
109551
|
-
server,
|
|
109552
|
-
database,
|
|
109553
|
-
user,
|
|
109554
|
-
password,
|
|
109555
|
-
options: {
|
|
109556
|
-
encrypt: parseBoolean(values.encrypt, false),
|
|
109557
|
-
trustServerCertificate: parseBoolean(values.trustServerCertificate, false)
|
|
109558
|
-
}
|
|
109559
|
-
};
|
|
109560
|
-
if (port !== void 0) {
|
|
109561
|
-
config.port = port;
|
|
109562
|
-
}
|
|
109563
|
-
if (values.instanceName) {
|
|
109564
|
-
config.options = {
|
|
109565
|
-
...config.options,
|
|
109566
|
-
instanceName: values.instanceName
|
|
109567
|
-
};
|
|
109568
|
-
}
|
|
109569
|
-
if (values.appName) {
|
|
109570
|
-
config.options = {
|
|
109571
|
-
...config.options,
|
|
109572
|
-
appName: values.appName
|
|
109573
|
-
};
|
|
109574
|
-
}
|
|
109575
|
-
if (values.domain) {
|
|
109576
|
-
config.domain = values.domain;
|
|
109577
|
-
}
|
|
109578
|
-
if (connectionTimeout !== void 0) {
|
|
109579
|
-
config.connectionTimeout = connectionTimeout;
|
|
109580
|
-
}
|
|
109581
|
-
if (requestTimeout !== void 0) {
|
|
109582
|
-
config.requestTimeout = requestTimeout;
|
|
109583
|
-
}
|
|
109584
|
-
return new mssql.ConnectionPool(config);
|
|
109585
|
-
})();
|
|
109539
|
+
if (!connectionString) {
|
|
109540
|
+
fail(buildMissingConnectionError("SQL Server", request.connection.profile));
|
|
109541
|
+
}
|
|
109542
|
+
const pool = new mssql.ConnectionPool(connectionString);
|
|
109586
109543
|
try {
|
|
109587
109544
|
await pool.connect();
|
|
109588
109545
|
const compiled = compileSqlServerSql(request.operation.sql, request.params || {});
|
|
@@ -109610,6 +109567,8 @@ async function runBuiltInSqlServerAdapter(request) {
|
|
|
109610
109567
|
affectedRows
|
|
109611
109568
|
}
|
|
109612
109569
|
};
|
|
109570
|
+
} catch (error) {
|
|
109571
|
+
throw formatBuiltInDriverError("SQL Server", error);
|
|
109613
109572
|
} finally {
|
|
109614
109573
|
await pool.close().catch(() => void 0);
|
|
109615
109574
|
}
|
|
@@ -110161,23 +110120,35 @@ function splitNamedArgumentList(argsStr) {
|
|
|
110161
110120
|
}
|
|
110162
110121
|
return parts;
|
|
110163
110122
|
}
|
|
110164
|
-
function
|
|
110123
|
+
function parseSqlArguments(argsStr) {
|
|
110165
110124
|
if (!argsStr.trim()) {
|
|
110166
110125
|
return { args: [] };
|
|
110167
110126
|
}
|
|
110168
110127
|
const parts = splitNamedArgumentList(argsStr);
|
|
110169
110128
|
const args = [];
|
|
110129
|
+
let sawNamedArgument = false;
|
|
110170
110130
|
for (const part of parts) {
|
|
110171
|
-
const
|
|
110172
|
-
if (!
|
|
110131
|
+
const trimmed = part.trim();
|
|
110132
|
+
if (!trimmed) {
|
|
110133
|
+
continue;
|
|
110134
|
+
}
|
|
110135
|
+
const match = trimmed.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*(.+)$/);
|
|
110136
|
+
if (match) {
|
|
110137
|
+
sawNamedArgument = true;
|
|
110138
|
+
args.push({
|
|
110139
|
+
name: match[1],
|
|
110140
|
+
valueExpression: match[2].trim()
|
|
110141
|
+
});
|
|
110142
|
+
continue;
|
|
110143
|
+
}
|
|
110144
|
+
if (sawNamedArgument) {
|
|
110173
110145
|
return {
|
|
110174
110146
|
args: [],
|
|
110175
|
-
error: "SQL arguments
|
|
110147
|
+
error: "Positional SQL arguments cannot follow named arguments."
|
|
110176
110148
|
};
|
|
110177
110149
|
}
|
|
110178
110150
|
args.push({
|
|
110179
|
-
|
|
110180
|
-
valueExpression: match[2].trim()
|
|
110151
|
+
valueExpression: trimmed
|
|
110181
110152
|
});
|
|
110182
110153
|
}
|
|
110183
110154
|
return { args };
|
|
@@ -110191,7 +110162,7 @@ function parseRunSqlCommand(line2) {
|
|
|
110191
110162
|
if (!match) {
|
|
110192
110163
|
return null;
|
|
110193
110164
|
}
|
|
110194
|
-
const parsedArgs =
|
|
110165
|
+
const parsedArgs = parseSqlArguments(match[3] || "");
|
|
110195
110166
|
if (parsedArgs.error) {
|
|
110196
110167
|
return {
|
|
110197
110168
|
variableName: match[1],
|
|
@@ -110206,6 +110177,52 @@ function parseRunSqlCommand(line2) {
|
|
|
110206
110177
|
args: parsedArgs.args
|
|
110207
110178
|
};
|
|
110208
110179
|
}
|
|
110180
|
+
function bindSqlArguments(parameterNames, args, runtimeVariables) {
|
|
110181
|
+
const resolvedParams = {};
|
|
110182
|
+
const boundParams = /* @__PURE__ */ new Set();
|
|
110183
|
+
let positionalIndex = 0;
|
|
110184
|
+
let sawNamedArgument = false;
|
|
110185
|
+
for (const arg of args) {
|
|
110186
|
+
if (arg.name) {
|
|
110187
|
+
sawNamedArgument = true;
|
|
110188
|
+
const declaredParam2 = parameterNames.find((param) => param.toLowerCase() === arg.name.toLowerCase());
|
|
110189
|
+
if (!declaredParam2) {
|
|
110190
|
+
return { error: `Unknown SQL parameter '${arg.name}'.` };
|
|
110191
|
+
}
|
|
110192
|
+
const declaredLower = declaredParam2.toLowerCase();
|
|
110193
|
+
if (boundParams.has(declaredLower)) {
|
|
110194
|
+
return { error: `Duplicate SQL parameter '${declaredParam2}' in run sql call.` };
|
|
110195
|
+
}
|
|
110196
|
+
const valueResult2 = evaluateSqlArgumentExpression(arg.valueExpression, runtimeVariables);
|
|
110197
|
+
if (valueResult2.error) {
|
|
110198
|
+
return { error: valueResult2.error };
|
|
110199
|
+
}
|
|
110200
|
+
resolvedParams[declaredParam2] = valueResult2.value;
|
|
110201
|
+
boundParams.add(declaredLower);
|
|
110202
|
+
continue;
|
|
110203
|
+
}
|
|
110204
|
+
if (sawNamedArgument) {
|
|
110205
|
+
return { error: "Positional SQL arguments cannot follow named arguments." };
|
|
110206
|
+
}
|
|
110207
|
+
if (positionalIndex >= parameterNames.length) {
|
|
110208
|
+
return { error: `Too many SQL arguments: expected ${parameterNames.length}.` };
|
|
110209
|
+
}
|
|
110210
|
+
const declaredParam = parameterNames[positionalIndex];
|
|
110211
|
+
const valueResult = evaluateSqlArgumentExpression(arg.valueExpression, runtimeVariables);
|
|
110212
|
+
if (valueResult.error) {
|
|
110213
|
+
return { error: valueResult.error };
|
|
110214
|
+
}
|
|
110215
|
+
resolvedParams[declaredParam] = valueResult.value;
|
|
110216
|
+
boundParams.add(declaredParam.toLowerCase());
|
|
110217
|
+
positionalIndex++;
|
|
110218
|
+
}
|
|
110219
|
+
for (const param of parameterNames) {
|
|
110220
|
+
if (!boundParams.has(param.toLowerCase())) {
|
|
110221
|
+
return { error: `Missing required SQL parameter '${param}'.` };
|
|
110222
|
+
}
|
|
110223
|
+
}
|
|
110224
|
+
return { params: resolvedParams };
|
|
110225
|
+
}
|
|
110209
110226
|
function isVarRunSequenceCommand(line2) {
|
|
110210
110227
|
const trimmed = line2.trim();
|
|
110211
110228
|
if (!/^var\s+[a-zA-Z_][a-zA-Z0-9_]*\s*=\s*run\s+[a-zA-Z_][a-zA-Z0-9_-]*(?:\s*\([^)]*\))?(?:\s+retry\s+\d+)?(?:\s+backoff\s+\d+(?:\.\d+)?\s*(?:s|ms|seconds?|milliseconds?)?)?\s*$/i.test(trimmed)) {
|
|
@@ -111719,78 +111736,25 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
111719
111736
|
duration: Date.now() - startTime
|
|
111720
111737
|
};
|
|
111721
111738
|
}
|
|
111722
|
-
const
|
|
111723
|
-
|
|
111724
|
-
|
|
111725
|
-
|
|
111726
|
-
|
|
111727
|
-
|
|
111728
|
-
|
|
111729
|
-
|
|
111730
|
-
|
|
111731
|
-
|
|
111732
|
-
|
|
111733
|
-
|
|
111734
|
-
|
|
111735
|
-
errors,
|
|
111736
|
-
duration: Date.now() - startTime
|
|
111737
|
-
};
|
|
111738
|
-
}
|
|
111739
|
-
if (!declaredParams.has(lowerName)) {
|
|
111740
|
-
errors.push(`Unknown SQL parameter '${arg.name}'.`);
|
|
111741
|
-
return {
|
|
111742
|
-
name: "",
|
|
111743
|
-
success: false,
|
|
111744
|
-
responses,
|
|
111745
|
-
scriptResults,
|
|
111746
|
-
assertionResults,
|
|
111747
|
-
steps: orderedSteps,
|
|
111748
|
-
errors,
|
|
111749
|
-
duration: Date.now() - startTime
|
|
111750
|
-
};
|
|
111751
|
-
}
|
|
111752
|
-
const valueResult = evaluateSqlArgumentExpression(arg.valueExpression, runtimeVariables);
|
|
111753
|
-
if (valueResult.error) {
|
|
111754
|
-
errors.push(`Step ${stepIdx + 1}: ${valueResult.error}`);
|
|
111755
|
-
return {
|
|
111756
|
-
name: "",
|
|
111757
|
-
success: false,
|
|
111758
|
-
responses,
|
|
111759
|
-
scriptResults,
|
|
111760
|
-
assertionResults,
|
|
111761
|
-
steps: orderedSteps,
|
|
111762
|
-
errors,
|
|
111763
|
-
duration: Date.now() - startTime
|
|
111764
|
-
};
|
|
111765
|
-
}
|
|
111766
|
-
providedArgs.set(lowerName, valueResult.value);
|
|
111767
|
-
}
|
|
111768
|
-
for (const param of operation.parameters) {
|
|
111769
|
-
if (!providedArgs.has(param.toLowerCase())) {
|
|
111770
|
-
errors.push(`Missing required SQL parameter '${param}'.`);
|
|
111771
|
-
return {
|
|
111772
|
-
name: "",
|
|
111773
|
-
success: false,
|
|
111774
|
-
responses,
|
|
111775
|
-
scriptResults,
|
|
111776
|
-
assertionResults,
|
|
111777
|
-
steps: orderedSteps,
|
|
111778
|
-
errors,
|
|
111779
|
-
duration: Date.now() - startTime
|
|
111780
|
-
};
|
|
111781
|
-
}
|
|
111739
|
+
const boundArgs = bindSqlArguments(operation.parameters, parsed.args, runtimeVariables);
|
|
111740
|
+
if ("error" in boundArgs) {
|
|
111741
|
+
errors.push(`Step ${stepIdx + 1}: ${boundArgs.error}`);
|
|
111742
|
+
return {
|
|
111743
|
+
name: "",
|
|
111744
|
+
success: false,
|
|
111745
|
+
responses,
|
|
111746
|
+
scriptResults,
|
|
111747
|
+
assertionResults,
|
|
111748
|
+
steps: orderedSteps,
|
|
111749
|
+
errors,
|
|
111750
|
+
duration: Date.now() - startTime
|
|
111751
|
+
};
|
|
111782
111752
|
}
|
|
111783
111753
|
const adapterWorkingDir = workingDir || process.cwd();
|
|
111784
111754
|
try {
|
|
111785
111755
|
const connection = resolveSqlConnection(executionContext?.filePath || adapterWorkingDir, operation.connectionName);
|
|
111786
111756
|
const adapterTarget = resolveSqlAdapterTarget(executionContext?.filePath || adapterWorkingDir, connection.adapter);
|
|
111787
111757
|
const connectionValues = getSqlConnectionValues(connection.profile, runtimeVariables);
|
|
111788
|
-
const paramPayload = Object.fromEntries(
|
|
111789
|
-
Array.from(providedArgs.entries()).map(([lowerName, value]) => {
|
|
111790
|
-
const declaredName = operation.parameters.find((param) => param.toLowerCase() === lowerName) || lowerName;
|
|
111791
|
-
return [declaredName, value];
|
|
111792
|
-
})
|
|
111793
|
-
);
|
|
111794
111758
|
const adapterResponse = await runSqlAdapter(
|
|
111795
111759
|
adapterTarget,
|
|
111796
111760
|
{
|
|
@@ -111804,7 +111768,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
111804
111768
|
connectionName: operation.connectionName,
|
|
111805
111769
|
sourcePath: operation.sourcePath
|
|
111806
111770
|
},
|
|
111807
|
-
params:
|
|
111771
|
+
params: boundArgs.params,
|
|
111808
111772
|
connection: {
|
|
111809
111773
|
name: connection.alias,
|
|
111810
111774
|
profile: connection.profile,
|
|
@@ -114326,7 +114290,9 @@ var ENV_FILENAME = ".nornenv";
|
|
|
114326
114290
|
var importRegex = /^import\s+["']?(.+?)["']?\s*$/;
|
|
114327
114291
|
var envRegex = /^\[env:([a-zA-Z_][a-zA-Z0-9_-]*)\]$/;
|
|
114328
114292
|
var varRegex = /^var\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
|
|
114293
|
+
var connectionStringRegex = /^connectionString\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
|
|
114329
114294
|
var secretRegex = /^secret\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
|
|
114295
|
+
var secretConnectionStringRegex = /^secret\s+connectionString\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
|
|
114330
114296
|
function parseEnvFile(content, sourceFilePath) {
|
|
114331
114297
|
const lines = content.split("\n");
|
|
114332
114298
|
const config = {
|
|
@@ -114367,6 +114333,27 @@ function parseEnvFile(content, sourceFilePath) {
|
|
|
114367
114333
|
config.environments.push(currentEnv);
|
|
114368
114334
|
continue;
|
|
114369
114335
|
}
|
|
114336
|
+
const secretConnectionStringMatch = trimmed.match(secretConnectionStringRegex);
|
|
114337
|
+
if (secretConnectionStringMatch) {
|
|
114338
|
+
const profileName = secretConnectionStringMatch[1];
|
|
114339
|
+
const varName = `${profileName}_connectionString`;
|
|
114340
|
+
const varValue = secretConnectionStringMatch[2].trim();
|
|
114341
|
+
config.secretDeclarations.push({
|
|
114342
|
+
name: varName,
|
|
114343
|
+
value: varValue,
|
|
114344
|
+
envName: currentEnv?.name,
|
|
114345
|
+
lineNumber: i,
|
|
114346
|
+
filePath: sourceFilePath
|
|
114347
|
+
});
|
|
114348
|
+
config.secretNames.add(varName);
|
|
114349
|
+
config.secretValues.set(varName, varValue);
|
|
114350
|
+
if (currentEnv) {
|
|
114351
|
+
currentEnv.variables[varName] = varValue;
|
|
114352
|
+
} else {
|
|
114353
|
+
config.common[varName] = varValue;
|
|
114354
|
+
}
|
|
114355
|
+
continue;
|
|
114356
|
+
}
|
|
114370
114357
|
const secretMatch = trimmed.match(secretRegex);
|
|
114371
114358
|
if (secretMatch) {
|
|
114372
114359
|
const varName = secretMatch[1];
|
|
@@ -114387,6 +114374,18 @@ function parseEnvFile(content, sourceFilePath) {
|
|
|
114387
114374
|
}
|
|
114388
114375
|
continue;
|
|
114389
114376
|
}
|
|
114377
|
+
const connectionStringMatch = trimmed.match(connectionStringRegex);
|
|
114378
|
+
if (connectionStringMatch) {
|
|
114379
|
+
const profileName = connectionStringMatch[1];
|
|
114380
|
+
const varName = `${profileName}_connectionString`;
|
|
114381
|
+
const varValue = connectionStringMatch[2].trim();
|
|
114382
|
+
if (currentEnv) {
|
|
114383
|
+
currentEnv.variables[varName] = varValue;
|
|
114384
|
+
} else {
|
|
114385
|
+
config.common[varName] = varValue;
|
|
114386
|
+
}
|
|
114387
|
+
continue;
|
|
114388
|
+
}
|
|
114390
114389
|
const varMatch = trimmed.match(varRegex);
|
|
114391
114390
|
if (varMatch) {
|
|
114392
114391
|
const varName = varMatch[1];
|
|
@@ -114661,6 +114660,7 @@ var import_process = require("process");
|
|
|
114661
114660
|
var fs14 = __toESM(require("fs"));
|
|
114662
114661
|
var path10 = __toESM(require("path"));
|
|
114663
114662
|
var envRegex2 = /^\s*\[env:([a-zA-Z_][a-zA-Z0-9_-]*)\]\s*$/;
|
|
114663
|
+
var secretConnectionStringRegex2 = /^(\s*secret\s+connectionString\s+)([a-zA-Z_][a-zA-Z0-9_]*)(\s*=\s*)(.+)$/;
|
|
114664
114664
|
var secretRegex2 = /^(\s*secret\s+)([a-zA-Z_][a-zA-Z0-9_]*)(\s*=\s*)(.+)$/;
|
|
114665
114665
|
function splitContentLines(content) {
|
|
114666
114666
|
return content.split(/\r?\n/);
|
|
@@ -114686,11 +114686,13 @@ function extractSecretLines(content, filePath) {
|
|
|
114686
114686
|
currentEnv = envMatch[1];
|
|
114687
114687
|
continue;
|
|
114688
114688
|
}
|
|
114689
|
+
const secretConnectionStringMatch = line2.match(secretConnectionStringRegex2);
|
|
114689
114690
|
const secretMatch = line2.match(secretRegex2);
|
|
114690
|
-
if (!secretMatch) {
|
|
114691
|
+
if (!secretConnectionStringMatch && !secretMatch) {
|
|
114691
114692
|
continue;
|
|
114692
114693
|
}
|
|
114693
|
-
const
|
|
114694
|
+
const secretName = secretConnectionStringMatch ? `${secretConnectionStringMatch[2]}_connectionString` : secretMatch[2];
|
|
114695
|
+
const value = (secretConnectionStringMatch?.[4] ?? secretMatch[4]).trim();
|
|
114694
114696
|
const encrypted = isEncryptedSecretValue(value);
|
|
114695
114697
|
let kid;
|
|
114696
114698
|
if (encrypted) {
|
|
@@ -114703,7 +114705,7 @@ function extractSecretLines(content, filePath) {
|
|
|
114703
114705
|
filePath,
|
|
114704
114706
|
lineNumber: i,
|
|
114705
114707
|
envName: currentEnv,
|
|
114706
|
-
name:
|
|
114708
|
+
name: secretName,
|
|
114707
114709
|
value,
|
|
114708
114710
|
encrypted,
|
|
114709
114711
|
kid
|
|
@@ -114717,11 +114719,16 @@ function updateSecretLineValue(content, lineNumber, newValue) {
|
|
|
114717
114719
|
throw new Error(`Line ${lineNumber + 1} is out of range.`);
|
|
114718
114720
|
}
|
|
114719
114721
|
const line2 = lines[lineNumber];
|
|
114722
|
+
const secretConnectionStringMatch = line2.match(secretConnectionStringRegex2);
|
|
114720
114723
|
const secretMatch = line2.match(secretRegex2);
|
|
114721
|
-
if (!secretMatch) {
|
|
114724
|
+
if (!secretConnectionStringMatch && !secretMatch) {
|
|
114722
114725
|
throw new Error(`Line ${lineNumber + 1} is not a secret declaration.`);
|
|
114723
114726
|
}
|
|
114724
|
-
|
|
114727
|
+
if (secretConnectionStringMatch) {
|
|
114728
|
+
lines[lineNumber] = `${secretConnectionStringMatch[1]}${secretConnectionStringMatch[2]}${secretConnectionStringMatch[3]}${newValue}`;
|
|
114729
|
+
} else {
|
|
114730
|
+
lines[lineNumber] = `${secretMatch[1]}${secretMatch[2]}${secretMatch[3]}${newValue}`;
|
|
114731
|
+
}
|
|
114725
114732
|
return lines.join(detectEol(content));
|
|
114726
114733
|
}
|
|
114727
114734
|
function findSecretLine(content, variableName, envName) {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "norn-cli",
|
|
3
3
|
"displayName": "Norn - REST Client",
|
|
4
4
|
"description": "A powerful REST client for making HTTP requests with sequences, variables, scripts, and cookie support",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.9.0",
|
|
6
6
|
"publisher": "Norn-PeterKrustanov",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Peter Krastanov"
|
|
@@ -362,6 +362,12 @@
|
|
|
362
362
|
"settings": {
|
|
363
363
|
"foreground": "#85EA2C"
|
|
364
364
|
}
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"scope": "support.type.connection.nornenv",
|
|
368
|
+
"settings": {
|
|
369
|
+
"foreground": "#d7ba7d"
|
|
370
|
+
}
|
|
365
371
|
}
|
|
366
372
|
]
|
|
367
373
|
}
|