norn-cli 1.9.0 → 1.10.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.
Files changed (2) hide show
  1. package/dist/cli.js +209 -2
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -109375,6 +109375,9 @@ init_quotedString();
109375
109375
  var fs8 = __toESM(require("fs"));
109376
109376
  var path6 = __toESM(require("path"));
109377
109377
 
109378
+ // src/sqlBuiltInAdapters.ts
109379
+ var import_child_process2 = require("child_process");
109380
+
109378
109381
  // node_modules/pg/esm/index.mjs
109379
109382
  var import_lib = __toESM(require_lib2(), 1);
109380
109383
  var Client = import_lib.default.Client;
@@ -109405,6 +109408,13 @@ var BUILT_IN_SQL_ADAPTERS = [
109405
109408
  description: "Built-in SQL Server adapter using a connection string.",
109406
109409
  connectionSetupSummary: "connectionString",
109407
109410
  optionalConnectionKeys: []
109411
+ },
109412
+ {
109413
+ id: "sqlserver-integrated",
109414
+ label: "SQL Server (Integrated Auth)",
109415
+ description: "Built-in SQL Server adapter using PowerShell for Windows/Trusted authentication.",
109416
+ connectionSetupSummary: "connectionString",
109417
+ optionalConnectionKeys: []
109408
109418
  }
109409
109419
  ];
109410
109420
  var BUILT_IN_SQL_ADAPTER_MAP = new Map(
@@ -109429,6 +109439,180 @@ function getConnectionString(values) {
109429
109439
  function buildMissingConnectionError(adapterLabel, profile) {
109430
109440
  return `Missing required ${adapterLabel} connection string. Expected 'connectionString ${profile} = ...' in .nornenv.`;
109431
109441
  }
109442
+ var pwshAvailable2 = null;
109443
+ function isPwshAvailable2() {
109444
+ if (pwshAvailable2 !== null) {
109445
+ return pwshAvailable2;
109446
+ }
109447
+ try {
109448
+ const result = (0, import_child_process2.spawnSync)("pwsh", ["--version"], {
109449
+ timeout: 5e3,
109450
+ stdio: "pipe"
109451
+ });
109452
+ pwshAvailable2 = result.status === 0;
109453
+ } catch (error) {
109454
+ pwshAvailable2 = false;
109455
+ }
109456
+ return pwshAvailable2;
109457
+ }
109458
+ function getPowerShellCommand() {
109459
+ return isPwshAvailable2() ? "pwsh" : "powershell";
109460
+ }
109461
+ function encodePowerShellCommand(script) {
109462
+ return Buffer.from(script, "utf16le").toString("base64");
109463
+ }
109464
+ async function runSqlServerIntegratedViaPowerShell(request) {
109465
+ const script = `
109466
+ $ErrorActionPreference = 'Stop'
109467
+ [Console]::InputEncoding = [System.Text.Encoding]::UTF8
109468
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
109469
+
109470
+ $raw = [Console]::In.ReadToEnd()
109471
+ if ([string]::IsNullOrWhiteSpace($raw)) {
109472
+ throw 'Missing SQL adapter payload.'
109473
+ }
109474
+
109475
+ $payload = $raw | ConvertFrom-Json -Depth 100
109476
+ $connectionString = [string]$payload.connection.values.connectionString
109477
+ if ([string]::IsNullOrWhiteSpace($connectionString)) {
109478
+ throw 'Missing SQL Server Integrated Auth connection string.'
109479
+ }
109480
+
109481
+ $sqlText = [string]$payload.operation.sql
109482
+ $mode = [string]$payload.mode
109483
+ $paramsObject = $payload.params
109484
+
109485
+ $connection = $null
109486
+ try {
109487
+ $connection = New-Object System.Data.SqlClient.SqlConnection $connectionString
109488
+ $command = $connection.CreateCommand()
109489
+ $command.CommandText = $sqlText
109490
+
109491
+ if ($null -ne $paramsObject) {
109492
+ foreach ($property in $paramsObject.PSObject.Properties) {
109493
+ $value = $property.Value
109494
+ if ($null -eq $value) {
109495
+ $value = [DBNull]::Value
109496
+ } elseif ($value -is [datetime]) {
109497
+ $value = $value.ToUniversalTime()
109498
+ } elseif ($value -is [System.Collections.IEnumerable] -and -not ($value -is [string]) -and -not ($value -is [byte[]])) {
109499
+ $value = ($value | ConvertTo-Json -Depth 100 -Compress)
109500
+ } elseif ($value -is [pscustomobject]) {
109501
+ $value = ($value | ConvertTo-Json -Depth 100 -Compress)
109502
+ }
109503
+ [void]$command.Parameters.AddWithValue("@$($property.Name)", $value)
109504
+ }
109505
+ }
109506
+
109507
+ $connection.Open()
109508
+
109509
+ if ($mode -eq 'query') {
109510
+ $reader = $command.ExecuteReader()
109511
+ $rows = @()
109512
+
109513
+ try {
109514
+ while ($reader.Read()) {
109515
+ $row = [ordered]@{}
109516
+ for ($i = 0; $i -lt $reader.FieldCount; $i++) {
109517
+ $value = $reader.GetValue($i)
109518
+ if ($value -is [DBNull]) {
109519
+ $value = $null
109520
+ } elseif ($value -is [datetime]) {
109521
+ $value = $value.ToString('o')
109522
+ } elseif ($value -is [byte[]]) {
109523
+ $value = [Convert]::ToBase64String($value)
109524
+ }
109525
+ $row[$reader.GetName($i)] = $value
109526
+ }
109527
+ $rows += [pscustomobject]$row
109528
+ }
109529
+ } finally {
109530
+ $reader.Close()
109531
+ }
109532
+
109533
+ $response = [pscustomobject]@{
109534
+ success = $true
109535
+ result = [pscustomobject]@{
109536
+ kind = 'rows'
109537
+ rowCount = @($rows).Count
109538
+ rows = @($rows)
109539
+ }
109540
+ }
109541
+ } else {
109542
+ $affectedRows = $command.ExecuteNonQuery()
109543
+ if ($affectedRows -lt 0) {
109544
+ $affectedRows = 0
109545
+ }
109546
+ $response = [pscustomobject]@{
109547
+ success = $true
109548
+ result = [pscustomobject]@{
109549
+ kind = 'exec'
109550
+ affectedRows = $affectedRows
109551
+ }
109552
+ }
109553
+ }
109554
+
109555
+ $response | ConvertTo-Json -Depth 100 -Compress
109556
+ }
109557
+ catch {
109558
+ $details = @()
109559
+ if ($_.Exception -and $_.Exception.GetType()) {
109560
+ $details += "type: $($_.Exception.GetType().FullName)"
109561
+ }
109562
+ if ($_.InvocationInfo -and $_.InvocationInfo.ScriptLineNumber) {
109563
+ $details += "line: $($_.InvocationInfo.ScriptLineNumber)"
109564
+ }
109565
+ if ($_.FullyQualifiedErrorId) {
109566
+ $details += "id: $($_.FullyQualifiedErrorId)"
109567
+ }
109568
+ $suffix = if ($details.Count -gt 0) { " ($($details -join ', '))" } else { '' }
109569
+ [Console]::Error.WriteLine("$($_.Exception.Message)$suffix")
109570
+ exit 1
109571
+ }
109572
+ finally {
109573
+ if ($null -ne $connection) {
109574
+ $connection.Dispose()
109575
+ }
109576
+ }
109577
+ `.trim();
109578
+ const payload = JSON.stringify(request);
109579
+ const command = getPowerShellCommand();
109580
+ const commandArgs = ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-OutputFormat", "Text", "-EncodedCommand", encodePowerShellCommand(script)];
109581
+ return new Promise((resolve11, reject) => {
109582
+ const child = (0, import_child_process2.spawn)(command, commandArgs, {
109583
+ cwd: request.context?.workingDir || process.cwd(),
109584
+ shell: false,
109585
+ env: {
109586
+ ...process.env
109587
+ }
109588
+ });
109589
+ let stdout = "";
109590
+ let stderr = "";
109591
+ child.stdout.on("data", (data) => {
109592
+ stdout += data.toString();
109593
+ });
109594
+ child.stderr.on("data", (data) => {
109595
+ stderr += data.toString();
109596
+ });
109597
+ child.on("error", (error) => {
109598
+ reject(new Error(`Failed to start PowerShell for SQL Server Integrated Auth: ${error.message}`));
109599
+ });
109600
+ child.on("close", (code) => {
109601
+ if (code !== 0) {
109602
+ reject(new Error((stderr || stdout || `PowerShell exited with code ${code}`).trim()));
109603
+ return;
109604
+ }
109605
+ try {
109606
+ const parsed = JSON.parse(stdout.trim());
109607
+ resolve11(parsed);
109608
+ } catch (error) {
109609
+ reject(new Error(`Invalid PowerShell SQL adapter response: ${error instanceof Error ? error.message : String(error)}`));
109610
+ }
109611
+ });
109612
+ child.stdin.write(payload);
109613
+ child.stdin.end();
109614
+ });
109615
+ }
109432
109616
  function shouldPassThroughError(error) {
109433
109617
  if (!(error instanceof Error)) {
109434
109618
  return false;
@@ -109573,6 +109757,27 @@ async function runBuiltInSqlServerAdapter(request) {
109573
109757
  await pool.close().catch(() => void 0);
109574
109758
  }
109575
109759
  }
109760
+ async function runBuiltInSqlServerIntegratedAdapter(request) {
109761
+ const values = request.connection.values;
109762
+ const connectionString = getConnectionString(values);
109763
+ if (!connectionString) {
109764
+ fail(buildMissingConnectionError("SQL Server Integrated Auth", request.connection.profile));
109765
+ }
109766
+ const compiled = compileSqlServerSql(request.operation.sql, request.params || {});
109767
+ const compiledRequest = {
109768
+ ...request,
109769
+ operation: {
109770
+ ...request.operation,
109771
+ sql: compiled.text
109772
+ },
109773
+ params: Object.fromEntries(compiled.names.map((name) => [name, request.params?.[name] ?? null]))
109774
+ };
109775
+ try {
109776
+ return await runSqlServerIntegratedViaPowerShell(compiledRequest);
109777
+ } catch (error) {
109778
+ throw formatBuiltInDriverError("SQL Server Integrated Auth", error);
109779
+ }
109780
+ }
109576
109781
  function isBuiltInSqlAdapter(adapterId) {
109577
109782
  return BUILT_IN_SQL_ADAPTER_MAP.has(adapterId.toLowerCase());
109578
109783
  }
@@ -109582,6 +109787,8 @@ async function runBuiltInSqlAdapter(adapterId, request) {
109582
109787
  return runBuiltInPostgresAdapter(request);
109583
109788
  case "sqlserver":
109584
109789
  return runBuiltInSqlServerAdapter(request);
109790
+ case "sqlserver-integrated":
109791
+ return runBuiltInSqlServerIntegratedAdapter(request);
109585
109792
  default:
109586
109793
  fail(`Built-in SQL adapter '${adapterId}' is not supported`);
109587
109794
  }
@@ -109759,7 +109966,7 @@ function resolveSqlAdapterTarget(startPath, adapterId) {
109759
109966
  }
109760
109967
 
109761
109968
  // src/sqlAdapterRunner.ts
109762
- var import_child_process2 = require("child_process");
109969
+ var import_child_process3 = require("child_process");
109763
109970
  function isRowsResult(value) {
109764
109971
  if (!value || typeof value !== "object" || Array.isArray(value)) {
109765
109972
  return false;
@@ -109799,7 +110006,7 @@ async function runExternalSqlAdapter(command, request, workingDir) {
109799
110006
  throw new Error("SQL adapter command is empty");
109800
110007
  }
109801
110008
  return new Promise((resolve11, reject) => {
109802
- const child = (0, import_child_process2.spawn)(command[0], command.slice(1), {
110009
+ const child = (0, import_child_process3.spawn)(command[0], command.slice(1), {
109803
110010
  cwd: workingDir,
109804
110011
  env: process.env,
109805
110012
  shell: false
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.9.0",
5
+ "version": "1.10.0",
6
6
  "publisher": "Norn-PeterKrustanov",
7
7
  "author": {
8
8
  "name": "Peter Krastanov"