@noormdev/sdk 1.4.1 → 1.4.2

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.
@@ -1,11 +1,12 @@
1
1
  import { createRequire } from 'module';
2
- export { eta, isTemplate, processFile, processFiles, renderTemplate } from './chunk-G4B7EHL7.js';
2
+ export { eta, isTemplate, processFile, processFiles, renderTemplate } from './chunk-CDTFXLXU.js';
3
3
  import './chunk-UOFJT5PY.js';
4
- import './chunk-LY2F7ZFI.js';
4
+ import './chunk-A2OYZAVT.js';
5
+ import './chunk-TXDGFA44.js';
5
6
  import './chunk-TBRUDUBQ.js';
6
7
  import './chunk-YJBKNUTP.js';
7
8
  import './chunk-D2XW2UOP.js';
8
9
 
9
10
  createRequire(import.meta.url);
10
- //# sourceMappingURL=engine-MZQ364EH.js.map
11
- //# sourceMappingURL=engine-MZQ364EH.js.map
11
+ //# sourceMappingURL=engine-6ALQ5YTN.js.map
12
+ //# sourceMappingURL=engine-6ALQ5YTN.js.map
package/dist/index.d.ts CHANGED
@@ -2650,6 +2650,8 @@ export interface ProcedureSummary {
2650
2650
  name: string;
2651
2651
  schema?: string;
2652
2652
  parameterCount: number;
2653
+ /** Argument list that tells PostgreSQL overloads apart, e.g. `v integer, w text`. */
2654
+ signature?: string;
2653
2655
  }
2654
2656
  /**
2655
2657
  * Function summary for list display.
@@ -2659,6 +2661,8 @@ export interface FunctionSummary {
2659
2661
  schema?: string;
2660
2662
  parameterCount: number;
2661
2663
  returnType: string;
2664
+ /** Argument list that tells PostgreSQL overloads apart, e.g. `v integer, w text`. */
2665
+ signature?: string;
2662
2666
  }
2663
2667
  /**
2664
2668
  * Type/Enum summary for list display.
@@ -4688,7 +4692,11 @@ export interface NoormEvents extends SettingsEvents, UpdateEvents, VaultEvents,
4688
4692
  };
4689
4693
  "connection:error": {
4690
4694
  configName: string;
4695
+ /** Worded for the user. */
4691
4696
  error: string;
4697
+ /** What the server or driver reported, for the log: its code(s) and message(s). */
4698
+ serverCode?: string;
4699
+ serverMessage?: string;
4692
4700
  };
4693
4701
  "app:starting": {
4694
4702
  mode: AppMode;
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import { createRequire } from 'module';
2
- import { processFile, es_default, DtReader, isTemplate, FORMAT_VERSION, DT_EXTENSIONS, encryptWithPassphrase, ENCODED_TYPES } from './chunk-G4B7EHL7.js';
2
+ import { processFile, es_default, DtReader, isTemplate, FORMAT_VERSION, DT_EXTENSIONS, encryptWithPassphrase, ENCODED_TYPES } from './chunk-CDTFXLXU.js';
3
3
  import './chunk-UOFJT5PY.js';
4
- import { resolveLegacyAccess, checkConfigPolicy, initializeVault, getVaultStatus, setVaultSecret, getVaultSecret, getAllVaultSecrets, listVaultSecretKeys, deleteVaultSecret, vaultSecretExists, getVaultKey, noormDb, getNoormTables, encryptVaultKey, assertVaultPolicy, assertPolicy, detectAgentHarness, guarded } from './chunk-FSVO6NAJ.js';
5
- import { makeNestedConfig, gigabytes, attempt, observer, attemptSync, getEnvConfigName, clone, merge, equals, retry, runWithTimeout, isTimeoutError, ObserverRelay, isDebug, wait } from './chunk-LY2F7ZFI.js';
6
- export { observer as noormObserver } from './chunk-LY2F7ZFI.js';
4
+ import { resolveLegacyAccess, checkConfigPolicy, initializeVault, getVaultStatus, setVaultSecret, getVaultSecret, getAllVaultSecrets, listVaultSecretKeys, deleteVaultSecret, vaultSecretExists, getVaultKey, noormDb, getNoormTables, encryptVaultKey, assertVaultPolicy, assertPolicy, detectAgentHarness, guarded } from './chunk-OMY6CKR4.js';
5
+ import { observer, getEnvConfigName, ObserverRelay, isDebug } from './chunk-A2OYZAVT.js';
6
+ export { observer as noormObserver } from './chunk-A2OYZAVT.js';
7
+ import { explainConnectionError, DatabaseConnectionError } from './chunk-OXTXFKWJ.js';
8
+ import { makeNestedConfig, gigabytes, attempt, attemptSync, clone, merge, equals, retry, runWithTimeout, isTimeoutError, wait } from './chunk-TXDGFA44.js';
7
9
  import { external_exports, PortSchema, connectTimeoutFor, DEFAULT_PORTS } from './chunk-WE2JLJMT.js';
8
10
  import { dist_default } from './chunk-TBRUDUBQ.js';
9
11
  import { require_dist } from './chunk-YJBKNUTP.js';
@@ -2926,7 +2928,7 @@ async function getDialectFactory(dialect) {
2926
2928
  case "mysql":
2927
2929
  return (await import('./mysql-32B4SXWA.js')).createMysqlConnection;
2928
2930
  case "mssql":
2929
- return (await import('./mssql-3BQB6ACD.js')).createMssqlConnection;
2931
+ return (await import('./mssql-II62FO2B.js')).createMssqlConnection;
2930
2932
  default:
2931
2933
  throw new Error(`Unsupported dialect: ${dialect}`);
2932
2934
  }
@@ -2997,6 +2999,9 @@ async function openConnection(config, configName, retryOptions, signal) {
2997
2999
  backoff,
2998
3000
  jitterFactor: 0.1,
2999
3001
  signal,
3002
+ // Otherwise running out of retries reads "Max retries
3003
+ // reached", and the server's own error is lost.
3004
+ throwLastError: true,
3000
3005
  shouldRetry: (err2) => {
3001
3006
  if (err2 instanceof OperationAbortedError) return false;
3002
3007
  const msg = err2.message.toLowerCase();
@@ -3014,8 +3019,10 @@ async function openConnection(config, configName, retryOptions, signal) {
3014
3019
  )
3015
3020
  );
3016
3021
  if (err) {
3017
- observer.emit("connection:error", { configName, error: err.message });
3018
- throw err;
3022
+ const explained = explainConnectionError(err, config);
3023
+ const server = explained instanceof DatabaseConnectionError ? { serverCode: explained.serverCode, serverMessage: explained.serverMessage } : {};
3024
+ observer.emit("connection:error", { configName, error: explained.message, ...server });
3025
+ throw explained;
3019
3026
  }
3020
3027
  const manager = getConnectionManager();
3021
3028
  const trackId = manager.track(conn, configName);
@@ -3055,15 +3062,21 @@ var SYSTEM_DATABASES = {
3055
3062
  // SQLite creates the file on connect
3056
3063
  mssql: "master"
3057
3064
  };
3058
- async function testConnection(config, options = {}) {
3059
- let testConfig = config;
3060
- if (options.testServerOnly && config.dialect !== "sqlite") {
3061
- const systemDb = SYSTEM_DATABASES[config.dialect];
3062
- testConfig = {
3063
- ...config,
3064
- database: systemDb ?? config.database
3065
- };
3065
+ async function probeConnection(config, signal) {
3066
+ const [conn, err] = await attempt(
3067
+ () => createConnection(config, "__test__", {}, signal)
3068
+ );
3069
+ if (err) {
3070
+ if (err instanceof OperationAbortedError) {
3071
+ return { ok: false, error: err.message, aborted: true };
3072
+ }
3073
+ return { ok: false, error: err.message };
3066
3074
  }
3075
+ await conn.destroy();
3076
+ return { ok: true };
3077
+ }
3078
+ async function testConnection(config, options = {}) {
3079
+ const systemDb = SYSTEM_DATABASES[config.dialect];
3067
3080
  if (options.testServerOnly && config.dialect === "sqlite") {
3068
3081
  const filename = config.filename ?? config.database;
3069
3082
  if (filename !== ":memory:" && !existsSync(filename)) {
@@ -3074,17 +3087,12 @@ async function testConnection(config, options = {}) {
3074
3087
  return { ok: true };
3075
3088
  }
3076
3089
  }
3077
- const [conn, err] = await attempt(
3078
- () => createConnection(testConfig, "__test__", {}, options.signal)
3079
- );
3080
- if (err) {
3081
- if (err instanceof OperationAbortedError) {
3082
- return { ok: false, error: err.message, aborted: true };
3083
- }
3084
- return { ok: false, error: err.message };
3090
+ const result = await probeConnection(config, options.signal);
3091
+ const targetMissing = !result.ok && !result.aborted && !!result.error?.includes("does not exist");
3092
+ if (options.testServerOnly && systemDb && targetMissing) {
3093
+ return probeConnection({ ...config, database: systemDb }, options.signal);
3085
3094
  }
3086
- await conn.destroy();
3087
- return { ok: true };
3095
+ return result;
3088
3096
  }
3089
3097
  function addIdColumn(builder, dialect) {
3090
3098
  if (dialect === "postgres") {
@@ -7546,7 +7554,7 @@ async function resolveVaultKey(db, dialect) {
7546
7554
  async function buildSecretsContext(stateManager, configName, db, vaultKey, dialect) {
7547
7555
  const secrets = {};
7548
7556
  if (db && vaultKey) {
7549
- const { getAllVaultSecrets: getAllVaultSecrets2 } = await import('./storage-V5I67ANZ.js');
7557
+ const { getAllVaultSecrets: getAllVaultSecrets2 } = await import('./storage-V6BHWNS3.js');
7550
7558
  const vaultSecrets = await getAllVaultSecrets2(db, vaultKey, dialect ?? "postgres");
7551
7559
  for (const [key, secret] of Object.entries(vaultSecrets)) {
7552
7560
  secrets[key] = secret.value;
@@ -9227,7 +9235,8 @@ var postgresExploreOperations = {
9227
9235
  SELECT
9228
9236
  p.proname,
9229
9237
  n.nspname,
9230
- p.pronargs::text as param_count
9238
+ p.pronargs::text as param_count,
9239
+ pg_get_function_identity_arguments(p.oid) as identity_args
9231
9240
  FROM pg_proc p
9232
9241
  JOIN pg_namespace n ON p.pronamespace = n.oid
9233
9242
  WHERE n.nspname ${schemaFilter(schema)}
@@ -9242,7 +9251,8 @@ var postgresExploreOperations = {
9242
9251
  return result.rows.map((row) => ({
9243
9252
  name: row.proname,
9244
9253
  schema: row.nspname,
9245
- parameterCount: parseInt(row.param_count, 10)
9254
+ parameterCount: parseInt(row.param_count, 10),
9255
+ signature: row.identity_args
9246
9256
  }));
9247
9257
  },
9248
9258
  async listFunctions(db, schema) {
@@ -9251,7 +9261,8 @@ var postgresExploreOperations = {
9251
9261
  p.proname,
9252
9262
  n.nspname,
9253
9263
  p.pronargs::text as param_count,
9254
- pg_get_function_result(p.oid) as return_type
9264
+ pg_get_function_result(p.oid) as return_type,
9265
+ pg_get_function_identity_arguments(p.oid) as identity_args
9255
9266
  FROM pg_proc p
9256
9267
  JOIN pg_namespace n ON p.pronamespace = n.oid
9257
9268
  WHERE n.nspname ${schemaFilter(schema)}
@@ -9267,7 +9278,8 @@ var postgresExploreOperations = {
9267
9278
  name: row.proname,
9268
9279
  schema: row.nspname,
9269
9280
  parameterCount: parseInt(row.param_count, 10),
9270
- returnType: row.return_type
9281
+ returnType: row.return_type,
9282
+ signature: row.identity_args
9271
9283
  }));
9272
9284
  },
9273
9285
  async listTypes(db, schema) {
@@ -1,4 +1,6 @@
1
1
  import { createRequire } from 'module';
2
+ import { explainMssqlLoginFailure } from './chunk-OXTXFKWJ.js';
3
+ import { attempt } from './chunk-TXDGFA44.js';
2
4
  import { DEFAULT_PORTS, connectTimeoutFor } from './chunk-WE2JLJMT.js';
3
5
  import './chunk-D2XW2UOP.js';
4
6
  import { isIP } from 'net';
@@ -73,7 +75,7 @@ function resolveTlsServerName(config) {
73
75
  }
74
76
  return UNVERIFIED_TLS_SERVER_NAME;
75
77
  }
76
- function buildTediousOptions(config, database) {
78
+ function buildTediousOptions(config) {
77
79
  return {
78
80
  server: config.host ?? "localhost",
79
81
  authentication: {
@@ -85,7 +87,7 @@ function buildTediousOptions(config, database) {
85
87
  },
86
88
  options: {
87
89
  port: config.port ?? DEFAULT_PORTS.mssql,
88
- database: database ?? config.database,
90
+ database: config.database,
89
91
  trustServerCertificate: !config.ssl,
90
92
  encrypt: true,
91
93
  serverName: resolveTlsServerName(config),
@@ -98,46 +100,19 @@ function buildTediousOptions(config, database) {
98
100
  }
99
101
  };
100
102
  }
101
- function buildTediousConfig(Tedious, config, database) {
102
- return new Tedious.Connection(buildTediousOptions(config, database));
103
- }
104
- async function verifyDatabaseExists(Tedious, Tarn, config) {
105
- const masterDb = new Kysely({
106
- dialect: new MssqlDialect({
107
- tarn: {
108
- ...Tarn,
109
- options: {
110
- min: 0,
111
- max: 1,
112
- propagateCreateError: true
113
- }
114
- },
115
- tedious: {
116
- ...Tedious,
117
- connectionFactory: () => buildTediousConfig(Tedious, config, "master")
118
- }
119
- }),
120
- plugins: [new MssqlLimitPlugin()]
121
- });
122
- try {
123
- const { rows } = await sql`
124
- SELECT name FROM sys.databases WHERE name = ${config.database}
125
- `.execute(masterDb);
126
- if (rows.length === 0) {
127
- throw new Error(
128
- `Database '${config.database}' does not exist on ${config.host ?? "localhost"}:${config.port ?? DEFAULT_PORTS.mssql}`
129
- );
130
- }
131
- } finally {
132
- await masterDb.destroy();
133
- }
103
+ function buildTediousConnection(Tedious, config, loginErrors) {
104
+ const connection = new Tedious.Connection(buildTediousOptions(config));
105
+ const record = (token) => loginErrors.push({ number: token.number, message: token.message });
106
+ connection.on("errorMessage", record);
107
+ connection.once("connect", () => connection.removeListener("errorMessage", record));
108
+ return connection;
134
109
  }
135
110
  async function createMssqlConnection(config) {
136
111
  const TediousImport = await import('tedious');
137
112
  const TarnImport = await import('tarn');
138
113
  const Tedious = TediousImport.default ?? TediousImport;
139
114
  const Tarn = TarnImport.default ?? TarnImport;
140
- await verifyDatabaseExists(Tedious, Tarn, config);
115
+ let loginErrors = [];
141
116
  const db = new Kysely({
142
117
  dialect: new MssqlDialect({
143
118
  tarn: {
@@ -150,11 +125,19 @@ async function createMssqlConnection(config) {
150
125
  },
151
126
  tedious: {
152
127
  ...Tedious,
153
- connectionFactory: () => buildTediousConfig(Tedious, config)
128
+ connectionFactory: () => {
129
+ loginErrors = [];
130
+ return buildTediousConnection(Tedious, config, loginErrors);
131
+ }
154
132
  }
155
133
  }),
156
134
  plugins: [new MssqlLimitPlugin()]
157
135
  });
136
+ const [, connectErr] = await attempt(() => sql`SELECT 1`.execute(db));
137
+ if (connectErr) {
138
+ await db.destroy();
139
+ throw explainMssqlLoginFailure(loginErrors, connectErr, config);
140
+ }
158
141
  return {
159
142
  db,
160
143
  dialect: "mssql",
@@ -163,5 +146,5 @@ async function createMssqlConnection(config) {
163
146
  }
164
147
 
165
148
  export { MssqlTlsServerNameError, UNVERIFIED_TLS_SERVER_NAME, buildTediousOptions, createMssqlConnection, resolveTlsServerName };
166
- //# sourceMappingURL=mssql-3BQB6ACD.js.map
167
- //# sourceMappingURL=mssql-3BQB6ACD.js.map
149
+ //# sourceMappingURL=mssql-II62FO2B.js.map
150
+ //# sourceMappingURL=mssql-II62FO2B.js.map
@@ -1,8 +1,9 @@
1
1
  import { createRequire } from 'module';
2
- export { deleteVaultSecret, deleteVaultSecretChecked, getAllVaultSecrets, getVaultKey, getVaultKeyChecked, getVaultSecret, getVaultStatus, initializeVault, initializeVaultChecked, listVaultSecretKeys, listVaultSecretKeysChecked, setVaultSecret, setVaultSecretChecked, vaultSecretExists } from './chunk-FSVO6NAJ.js';
3
- import './chunk-LY2F7ZFI.js';
2
+ export { deleteVaultSecret, deleteVaultSecretChecked, getAllVaultSecrets, getVaultKey, getVaultKeyChecked, getVaultSecret, getVaultStatus, initializeVault, initializeVaultChecked, listVaultSecretKeys, listVaultSecretKeysChecked, setVaultSecret, setVaultSecretChecked, vaultSecretExists } from './chunk-OMY6CKR4.js';
3
+ import './chunk-A2OYZAVT.js';
4
+ import './chunk-TXDGFA44.js';
4
5
  import './chunk-D2XW2UOP.js';
5
6
 
6
7
  createRequire(import.meta.url);
7
- //# sourceMappingURL=storage-V5I67ANZ.js.map
8
- //# sourceMappingURL=storage-V5I67ANZ.js.map
8
+ //# sourceMappingURL=storage-V6BHWNS3.js.map
9
+ //# sourceMappingURL=storage-V6BHWNS3.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noormdev/sdk",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Database schema & changeset manager SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",