pg-promise 12.4.0 → 12.6.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.
@@ -11,7 +11,8 @@ const {QueryFileError} = require('./query-file-error');
11
11
 
12
12
  const npm = {
13
13
  os: require('os'),
14
- utils: require('../utils')
14
+ utils: require('../utils'),
15
+ inspect: require('util').inspect
15
16
  };
16
17
 
17
18
  /**
@@ -56,40 +57,15 @@ class ParameterizedQueryError extends Error {
56
57
  }
57
58
  }
58
59
 
59
- /**
60
- * @method errors.ParameterizedQueryError#toString
61
- * @description
62
- * Creates a well-formatted multi-line string that represents the error.
63
- *
64
- * It is called automatically when writing the object into the console.
65
- *
66
- * @param {number} [level=0]
67
- * Nested output level, to provide visual offset.
68
- *
69
- * @returns {string}
70
- */
71
- ParameterizedQueryError.prototype.toString = function (level) {
72
- level = level > 0 ? parseInt(level) : 0;
73
- const gap0 = npm.utils.messageGap(level),
74
- gap1 = npm.utils.messageGap(level + 1),
75
- gap2 = npm.utils.messageGap(level + 2),
76
- lines = [
77
- 'ParameterizedQueryError {',
78
- gap1 + 'message: "' + this.message + '"',
79
- gap1 + 'result: {',
80
- gap2 + 'text: ' + npm.utils.toJson(this.result.text),
81
- gap2 + 'values: ' + npm.utils.toJson(this.result.values),
82
- gap1 + '}'
83
- ];
60
+ npm.utils.addInspection(ParameterizedQueryError, function () {
61
+ const obj = {
62
+ message: this.message,
63
+ result: this.result
64
+ };
84
65
  if (this.error) {
85
- lines.push(gap1 + 'error: ' + this.error.toString(level + 1));
66
+ obj.error = this.error;
86
67
  }
87
- lines.push(gap0 + '}');
88
- return lines.join(npm.os.EOL);
89
- };
90
-
91
- npm.utils.addInspection(ParameterizedQueryError, function () {
92
- return this.toString();
68
+ return 'ParameterizedQueryError ' + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
93
69
  });
94
70
 
95
71
  module.exports = {ParameterizedQueryError};
@@ -11,7 +11,8 @@ const {QueryFileError} = require('./query-file-error');
11
11
 
12
12
  const npm = {
13
13
  os: require('os'),
14
- utils: require('../utils')
14
+ utils: require('../utils'),
15
+ inspect: require('util').inspect
15
16
  };
16
17
 
17
18
  /**
@@ -56,41 +57,15 @@ class PreparedStatementError extends Error {
56
57
  }
57
58
  }
58
59
 
59
- /**
60
- * @method errors.PreparedStatementError#toString
61
- * @description
62
- * Creates a well-formatted multi-line string that represents the error.
63
- *
64
- * It is called automatically when writing the object into the console.
65
- *
66
- * @param {number} [level=0]
67
- * Nested output level, to provide visual offset.
68
- *
69
- * @returns {string}
70
- */
71
- PreparedStatementError.prototype.toString = function (level) {
72
- level = level > 0 ? parseInt(level) : 0;
73
- const gap0 = npm.utils.messageGap(level),
74
- gap1 = npm.utils.messageGap(level + 1),
75
- gap2 = npm.utils.messageGap(level + 2),
76
- lines = [
77
- 'PreparedStatementError {',
78
- gap1 + 'message: "' + this.message + '"',
79
- gap1 + 'result: {',
80
- gap2 + 'name: ' + npm.utils.toJson(this.result.name),
81
- gap2 + 'text: ' + npm.utils.toJson(this.result.text),
82
- gap2 + 'values: ' + npm.utils.toJson(this.result.values),
83
- gap1 + '}'
84
- ];
60
+ npm.utils.addInspection(PreparedStatementError, function () {
61
+ const obj = {
62
+ message: this.message,
63
+ result: this.result
64
+ };
85
65
  if (this.error) {
86
- lines.push(gap1 + 'error: ' + this.error.toString(level + 1));
66
+ obj.error = this.error;
87
67
  }
88
- lines.push(gap0 + '}');
89
- return lines.join(npm.os.EOL);
90
- };
91
-
92
- npm.utils.addInspection(PreparedStatementError, function () {
93
- return this.toString();
68
+ return 'PreparedStatementError ' + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
94
69
  });
95
70
 
96
71
  module.exports = {PreparedStatementError};
@@ -10,7 +10,8 @@
10
10
  const npm = {
11
11
  os: require('os'),
12
12
  utils: require('../utils'),
13
- minify: require('pg-minify')
13
+ minify: require('pg-minify'),
14
+ inspect: require('util').inspect
14
15
  };
15
16
 
16
17
  /**
@@ -59,37 +60,16 @@ class QueryFileError extends Error {
59
60
  }
60
61
  }
61
62
 
62
- /**
63
- * @method errors.QueryFileError#toString
64
- * @description
65
- * Creates a well-formatted multi-line string that represents the error.
66
- *
67
- * It is called automatically when writing the object into the console.
68
- *
69
- * @param {number} [level=0]
70
- * Nested output level, to provide visual offset.
71
- *
72
- * @returns {string}
73
- */
74
- QueryFileError.prototype.toString = function (level) {
75
- level = level > 0 ? parseInt(level) : 0;
76
- const gap0 = npm.utils.messageGap(level),
77
- gap1 = npm.utils.messageGap(level + 1),
78
- lines = [
79
- 'QueryFileError {',
80
- gap1 + 'message: "' + this.message + '"',
81
- gap1 + 'options: ' + npm.utils.toJson(this.options),
82
- gap1 + 'file: "' + this.file + '"'
83
- ];
63
+ npm.utils.addInspection(QueryFileError, function () {
64
+ const obj = {
65
+ message: this.message,
66
+ file: this.file,
67
+ options: this.options
68
+ };
84
69
  if (this.error) {
85
- lines.push(gap1 + 'error: ' + this.error.toString(level + 1));
70
+ obj.error = this.error;
86
71
  }
87
- lines.push(gap0 + '}');
88
- return lines.join(npm.os.EOL);
89
- };
90
-
91
- npm.utils.addInspection(QueryFileError, function () {
92
- return this.toString();
72
+ return 'QueryFileError ' + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
93
73
  });
94
74
 
95
75
  module.exports = {QueryFileError};
@@ -10,7 +10,8 @@
10
10
  const npm = {
11
11
  os: require('os'),
12
12
  utils: require('../utils'),
13
- text: require('../text')
13
+ text: require('../text'),
14
+ inspect: require('util').inspect
14
15
  };
15
16
 
16
17
  /**
@@ -102,7 +103,7 @@ const errorMessages = [
102
103
  * error(err, e) {
103
104
  * if (err instanceof QueryResultError) {
104
105
  * // A query returned unexpected number of records, and thus rejected;
105
- *
106
+ *
106
107
  * // we can check the error code, if we want specifics:
107
108
  * if(err.code === qrec.noData) {
108
109
  * // expected some data, but received none;
@@ -112,7 +113,7 @@ const errorMessages = [
112
113
  * // you will get a nicely formatted output.
113
114
  *
114
115
  * console.log(err);
115
- *
116
+ *
116
117
  * // See also: err, e.query, e.params, etc.
117
118
  * }
118
119
  * }
@@ -137,38 +138,17 @@ class QueryResultError extends Error {
137
138
  }
138
139
  }
139
140
 
140
- /**
141
- * @method errors.QueryResultError#toString
142
- * @description
143
- * Creates a well-formatted multi-line string that represents the error.
144
- *
145
- * It is called automatically when writing the object into the console.
146
- *
147
- * @param {number} [level=0]
148
- * Nested output level, to provide visual offset.
149
- *
150
- * @returns {string}
151
- */
152
- QueryResultError.prototype.toString = function (level) {
153
- level = level > 0 ? parseInt(level) : 0;
154
- const gap0 = npm.utils.messageGap(level),
155
- gap1 = npm.utils.messageGap(level + 1),
156
- lines = [
157
- 'QueryResultError {',
158
- gap1 + 'code: queryResultErrorCode.' + errorMessages[this.code].name,
159
- gap1 + 'message: "' + this.message + '"',
160
- gap1 + 'received: ' + this.received,
161
- gap1 + 'query: ' + (typeof this.query === 'string' ? '"' + this.query + '"' : npm.utils.toJson(this.query))
162
- ];
141
+ npm.utils.addInspection(QueryResultError, function () {
142
+ const obj = {
143
+ code: 'queryResultErrorCode.' + errorMessages[this.code].name,
144
+ message: this.message,
145
+ received: this.received,
146
+ query: typeof this.query === 'string' ? this.query : npm.utils.toJson(this.query)
147
+ };
163
148
  if (this.values !== undefined) {
164
- lines.push(gap1 + 'values: ' + npm.utils.toJson(this.values));
149
+ obj.values = this.values;
165
150
  }
166
- lines.push(gap0 + '}');
167
- return lines.join(npm.os.EOL);
168
- };
169
-
170
- npm.utils.addInspection(QueryResultError, function () {
171
- return this.toString();
151
+ return 'QueryResultError ' + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
172
152
  });
173
153
 
174
154
  module.exports = {
@@ -56,6 +56,12 @@ const npm = {
56
56
  *
57
57
  * By default, only the object's own properties are enumerated for column names.
58
58
  *
59
+ * @param {'error' | 'skip' | 'replace'} [options.duplicate = 'error']
60
+ * Strategy for processing duplicate columns:
61
+ * - `'error'` - throws {@link external:Error Error} = `Duplicate column name "name".` (Default)
62
+ * - `'skip'` - skips repeated columns (only the first will be used)
63
+ * - `'replace'` - replaces repeated columns (the last one will be used)
64
+ *
59
65
  * @returns {helpers.ColumnSet}
60
66
  *
61
67
  * @see
@@ -166,17 +172,17 @@ const npm = {
166
172
  */
167
173
  class ColumnSet extends InnerState {
168
174
 
169
- constructor(columns, opt) {
175
+ constructor(columns, options) {
170
176
  super();
171
177
 
172
178
  if (!columns || typeof columns !== 'object') {
173
179
  throw new TypeError('Invalid parameter \'columns\' specified.');
174
180
  }
175
181
 
176
- opt = assert(opt, ['table', 'inherit']);
182
+ options = assert(options, ['table', 'inherit', 'duplicate']);
177
183
 
178
- if (!npm.utils.isNull(opt.table)) {
179
- this.table = (opt.table instanceof TableName) ? opt.table : new TableName(opt.table);
184
+ if (!npm.utils.isNull(options.table)) {
185
+ this.table = (options.table instanceof TableName) ? options.table : new TableName(options.table);
180
186
  }
181
187
 
182
188
  /**
@@ -190,6 +196,7 @@ class ColumnSet extends InnerState {
190
196
  * - **secondary:** to be automatically written into the console (for logging purposes).
191
197
  */
192
198
 
199
+ this.columns = [];
193
200
 
194
201
  /**
195
202
  * @name helpers.ColumnSet#columns
@@ -199,22 +206,28 @@ class ColumnSet extends InnerState {
199
206
  * Array of {@link helpers.Column Column} objects.
200
207
  */
201
208
  if (Array.isArray(columns)) {
202
- const colNames = {};
203
- this.columns = columns.map(c => {
209
+ const duplicate = options.duplicate || 'error';
210
+ columns.forEach(c => {
204
211
  const col = (c instanceof Column) ? c : new Column(c);
205
- if (col.name in colNames) {
206
- throw new Error(`Duplicate column name "${col.name}".`);
212
+ const idx = this.columns.findIndex(a => a.name === col.name);
213
+ if (idx === -1) {
214
+ this.columns.push(col);
215
+ } else {
216
+ if (duplicate === 'replace') {
217
+ this.columns[idx] = col;
218
+ return;
219
+ }
220
+ if (duplicate !== 'skip') {
221
+ throw new Error(`Duplicate column name "${col.name}".`);
222
+ }
207
223
  }
208
- colNames[col.name] = true;
209
- return col;
210
224
  });
211
225
  } else {
212
226
  if (columns instanceof Column) {
213
227
  this.columns = [columns];
214
228
  } else {
215
- this.columns = [];
216
229
  for (const name in columns) {
217
- if (opt.inherit || Object.prototype.hasOwnProperty.call(columns, name)) {
230
+ if (options.inherit || Object.prototype.hasOwnProperty.call(columns, name)) {
218
231
  this.columns.push(new Column(name));
219
232
  }
220
233
  }
@@ -415,13 +428,18 @@ ColumnSet.prototype.assignColumns = function (options) {
415
428
  * @description
416
429
  * Creates a new {@link helpers.ColumnSet ColumnSet}, by joining the two sets of columns.
417
430
  *
418
- * If the two sets contain a column with the same `name` (case-sensitive), an error is thrown.
431
+ * If the two sets contain a column with the same `name` (case-sensitive), an error is thrown (unless `options.skip` is set to `true`).
419
432
  *
420
433
  * @param {helpers.Column|helpers.ColumnSet|array} columns
421
434
  * Columns to be appended, of the same type as parameter `columns` during {@link helpers.ColumnSet ColumnSet} construction, except:
422
435
  * - it can also be of type {@link helpers.ColumnSet ColumnSet}
423
436
  * - it cannot be a simple object (properties enumeration is not supported here)
424
437
  *
438
+ * @param {object} [options]
439
+ *
440
+ * @param {boolean} [options.skip = false]
441
+ * When set to `true`, it skips duplicate columns (by default, it throws an error).
442
+ *
425
443
  * @returns {helpers.ColumnSet}
426
444
  * New {@link helpers.ColumnSet ColumnSet} object with the extended/concatenated list of columns.
427
445
  *
@@ -465,13 +483,12 @@ ColumnSet.prototype.assignColumns = function (options) {
465
483
  * // ]
466
484
  * // }
467
485
  */
468
- ColumnSet.prototype.extend = function (columns) {
469
- let cs = columns;
470
- if (!(cs instanceof ColumnSet)) {
471
- cs = new ColumnSet(columns);
472
- }
473
- // Any duplicate column will throw Error = 'Duplicate column name "name".',
474
- return new ColumnSet(this.columns.concat(cs.columns), {table: this.table});
486
+ ColumnSet.prototype.extend = function (columns, options) {
487
+ options = assert(options, ['skip']);
488
+ const duplicate = options.skip ? 'skip' : 'error';
489
+ const cs = columns instanceof ColumnSet ? columns : new ColumnSet(columns, {duplicate});
490
+ const joinedCols = this.columns.concat(...cs.columns);
491
+ return new ColumnSet(joinedCols, {table: this.table, duplicate});
475
492
  };
476
493
 
477
494
  /**
@@ -536,23 +553,10 @@ ColumnSet.prototype.extend = function (columns) {
536
553
  *
537
554
  */
538
555
  ColumnSet.prototype.merge = function (columns) {
539
- let cs = columns;
540
- if (!(cs instanceof ColumnSet)) {
541
- cs = new ColumnSet(columns);
542
- }
543
- const colNames = {}, cols = [];
544
- this.columns.forEach((c, idx) => {
545
- cols.push(c);
546
- colNames[c.name] = idx;
547
- });
548
- cs.columns.forEach(c => {
549
- if (c.name in colNames) {
550
- cols[colNames[c.name]] = c;
551
- } else {
552
- cols.push(c);
553
- }
554
- });
555
- return new ColumnSet(cols, {table: this.table});
556
+ const duplicate = 'replace';
557
+ const cs = columns instanceof ColumnSet ? columns : new ColumnSet(columns, {duplicate});
558
+ const joinedCols = this.columns.concat(...cs.columns);
559
+ return new ColumnSet(joinedCols, {table: this.table, duplicate});
556
560
  };
557
561
 
558
562
  /**
@@ -607,43 +611,4 @@ function colDesc(column, source) {
607
611
  return a;
608
612
  }
609
613
 
610
- /**
611
- * @method helpers.ColumnSet#toString
612
- * @description
613
- * Creates a well-formatted multi-line string that represents the object.
614
- *
615
- * It is called automatically when writing the object into the console.
616
- *
617
- * @param {number} [level=0]
618
- * Nested output level, to provide visual offset.
619
- *
620
- * @returns {string}
621
- */
622
- ColumnSet.prototype.toString = function (level) {
623
- level = level > 0 ? parseInt(level) : 0;
624
- const gap0 = npm.utils.messageGap(level),
625
- gap1 = npm.utils.messageGap(level + 1),
626
- lines = [
627
- 'ColumnSet {'
628
- ];
629
- if (this.table) {
630
- lines.push(gap1 + 'table: ' + this.table);
631
- }
632
- if (this.columns.length) {
633
- lines.push(gap1 + 'columns: [');
634
- this.columns.forEach(c => {
635
- lines.push(c.toString(2));
636
- });
637
- lines.push(gap1 + ']');
638
- } else {
639
- lines.push(gap1 + 'columns: []');
640
- }
641
- lines.push(gap0 + '}');
642
- return lines.join(npm.os.EOL);
643
- };
644
-
645
- npm.utils.addInspection(ColumnSet, function () {
646
- return this.toString();
647
- });
648
-
649
614
  module.exports = {ColumnSet};
@@ -289,55 +289,6 @@ function isValidVariable(name) {
289
289
  return !!m && m[0] === name;
290
290
  }
291
291
 
292
- /**
293
- * @method helpers.Column#toString
294
- * @description
295
- * Creates a well-formatted multi-line string that represents the object.
296
- *
297
- * It is called automatically when writing the object into the console.
298
- *
299
- * @param {number} [level=0]
300
- * Nested output level, to provide visual offset.
301
- *
302
- * @returns {string}
303
- */
304
- Column.prototype.toString = function (level) {
305
- level = level > 0 ? parseInt(level) : 0;
306
- const gap0 = npm.utils.messageGap(level),
307
- gap1 = npm.utils.messageGap(level + 1),
308
- lines = [
309
- gap0 + 'Column {',
310
- gap1 + 'name: ' + npm.utils.toJson(this.name)
311
- ];
312
- if ('prop' in this) {
313
- lines.push(gap1 + 'prop: ' + npm.utils.toJson(this.prop));
314
- }
315
- if ('mod' in this) {
316
- lines.push(gap1 + 'mod: ' + npm.utils.toJson(this.mod));
317
- }
318
- if ('cast' in this) {
319
- lines.push(gap1 + 'cast: ' + npm.utils.toJson(this.cast));
320
- }
321
- if ('cnd' in this) {
322
- lines.push(gap1 + 'cnd: ' + npm.utils.toJson(this.cnd));
323
- }
324
- if ('def' in this) {
325
- lines.push(gap1 + 'def: ' + npm.utils.toJson(this.def));
326
- }
327
- if ('init' in this) {
328
- lines.push(gap1 + 'init: [Function]');
329
- }
330
- if ('skip' in this) {
331
- lines.push(gap1 + 'skip: [Function]');
332
- }
333
- lines.push(gap0 + '}');
334
- return lines.join(npm.os.EOL);
335
- };
336
-
337
- npm.utils.addInspection(Column, function () {
338
- return this.toString();
339
- });
340
-
341
292
  /**
342
293
  * @typedef helpers.ColumnConfig
343
294
  * @description
@@ -364,7 +315,7 @@ npm.utils.addInspection(Column, function () {
364
315
  * Used by methods {@link helpers.update update} and {@link helpers.sets sets}, ignored by methods {@link helpers.insert insert} and
365
316
  * {@link helpers.values values}. It indicates that the column is reserved for a `WHERE` condition, not to be set or updated.
366
317
  *
367
- * It can be set from a string initialization, by adding `?` in front of the name.
318
+ * It can be set from a string initialization by adding `?` in front of the name.
368
319
  *
369
320
  * @property {*} [def]
370
321
  * Default value for the property, to be used only when the source object doesn't have the property.
@@ -379,7 +330,7 @@ npm.utils.addInspection(Column, function () {
379
330
  * Used by methods {@link helpers.update update} (for a single object) and {@link helpers.sets sets}, ignored by methods
380
331
  * {@link helpers.insert insert} and {@link helpers.values values}.
381
332
  *
382
- * It is also ignored when conditional flag `cnd` is set.
333
+ * It is also ignored when the conditional flag `cnd` is set.
383
334
  *
384
335
  */
385
336
 
@@ -109,23 +109,6 @@ TableName.prototype[npm.format.ctf.toPostgres] = function (self) {
109
109
 
110
110
  TableName.prototype[npm.format.ctf.rawType] = true; // use as pre-formatted
111
111
 
112
- /**
113
- * @method helpers.TableName#toString
114
- * @description
115
- * Creates a well-formatted string that represents the object.
116
- *
117
- * It is called automatically when writing the object into the console.
118
- *
119
- * @returns {string}
120
- */
121
- TableName.prototype.toString = function () {
122
- return this.name;
123
- };
124
-
125
- npm.utils.addInspection(TableName, function () {
126
- return this.toString();
127
- });
128
-
129
112
  /**
130
113
  * @interface Table
131
114
  * @description
package/lib/main.js CHANGED
@@ -34,7 +34,7 @@ let originalClientConnect;
34
34
  * @module pg-promise
35
35
  *
36
36
  * @description
37
- * ## pg-promise v12.0
37
+ * ## pg-promise v12.5
38
38
  * All documentation here is for the latest official release only.
39
39
  *
40
40
  * ### Initialization Options
package/lib/query-file.js CHANGED
@@ -18,7 +18,8 @@ const npm = {
18
18
  path: require('path'),
19
19
  minify: require('pg-minify'),
20
20
  utils: require('./utils'),
21
- formatting: require('./formatting')
21
+ formatting: require('./formatting'),
22
+ inspect: require('util').inspect
22
23
  };
23
24
 
24
25
  const file$query = Symbol('QueryFile.query');
@@ -312,38 +313,18 @@ QueryFile.prototype[npm.formatting.as.ctf.toPostgres] = function (self) {
312
313
 
313
314
  QueryFile.prototype[npm.formatting.as.ctf.rawType] = true; // use as pre-formatted
314
315
 
315
- /**
316
- * @method QueryFile#toString
317
- * @description
318
- * Creates a well-formatted multi-line string that represents the object's current state.
319
- *
320
- * It is called automatically when writing the object into the console.
321
- *
322
- * @param {number} [level=0]
323
- * Nested output level, to provide visual offset.
324
- *
325
- * @returns {string}
326
- */
327
- QueryFile.prototype.toString = function (level) {
328
- level = level > 0 ? parseInt(level) : 0;
329
- const gap = npm.utils.messageGap(level + 1);
330
- const lines = [
331
- 'QueryFile {'
332
- ];
316
+ npm.utils.addInspection(QueryFile, function () {
317
+ const s = 'QueryFile ';
318
+ const obj = {
319
+ file: this.file,
320
+ options: this.options
321
+ };
333
322
  this.prepare();
334
- lines.push(gap + 'file: "' + this.file + '"');
335
- lines.push(gap + 'options: ' + npm.utils.toJson(this.options));
336
323
  if (this.error) {
337
- lines.push(gap + 'error: ' + this.error.toString(level + 1));
338
- } else {
339
- lines.push(gap + 'query: "' + this[QueryFile.$query] + '"');
324
+ obj.error = this.error;
340
325
  }
341
- lines.push(npm.utils.messageGap(level) + '}');
342
- return lines.join(npm.os.EOL);
343
- };
344
-
345
- npm.utils.addInspection(QueryFile, function () {
346
- return this.toString();
326
+ obj.query = this[QueryFile.$query];
327
+ return s + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
347
328
  });
348
329
 
349
330
  module.exports = {QueryFile};
package/lib/tx-mode.js CHANGED
@@ -8,9 +8,13 @@
8
8
  */
9
9
 
10
10
  const {InnerState} = require('./inner-state');
11
- const {addInspection} = require('./utils');
12
11
  const {assert} = require('./assert');
13
12
 
13
+ const npm = {
14
+ addInspection: require('./utils').addInspection,
15
+ inspect: require('util').inspect
16
+ };
17
+
14
18
  /**
15
19
  * @enum {number}
16
20
  * @alias txMode.isolationLevel
@@ -22,7 +26,7 @@ const {assert} = require('./assert');
22
26
  * @see $[Transaction Isolation]
23
27
  */
24
28
  const isolationLevel = {
25
- /** Isolation level not specified. */
29
+ /** Isolation level isn't specified. */
26
30
  none: 0,
27
31
 
28
32
  /** `ISOLATION LEVEL SERIALIZABLE` */
@@ -161,8 +165,9 @@ class TransactionMode extends InnerState {
161
165
  }
162
166
  }
163
167
 
164
- addInspection(TransactionMode, function () {
165
- return this.begin(true);
168
+ npm.addInspection(TransactionMode, function () {
169
+ const obj = {SQL: this.begin(true)};
170
+ return 'TransactionMode ' + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
166
171
  });
167
172
 
168
173
  /**
@@ -187,4 +192,3 @@ module.exports = {
187
192
  isolationLevel,
188
193
  TransactionMode
189
194
  };
190
-
@@ -14,7 +14,8 @@ const {assert} = require('../assert');
14
14
 
15
15
  const npm = {
16
16
  EOL: require('os').EOL,
17
- utils: require('../utils')
17
+ utils: require('../utils'),
18
+ inspect: require('util').inspect
18
19
  };
19
20
 
20
21
  /**
@@ -162,43 +163,26 @@ ParameterizedQuery.prototype.parse = function () {
162
163
  return _i.target;
163
164
  };
164
165
 
165
- /**
166
- * @method ParameterizedQuery#toString
167
- * @description
168
- * Creates a well-formatted multi-line string that represents the object's current state.
169
- *
170
- * It is called automatically when writing the object into the console.
171
- *
172
- * @param {number} [level=0]
173
- * Nested output level, to provide visual offset.
174
- *
175
- * @returns {string}
176
- */
177
- ParameterizedQuery.prototype.toString = function (level) {
178
- level = level > 0 ? parseInt(level) : 0;
179
- const gap = npm.utils.messageGap(level + 1);
166
+ npm.utils.addInspection(ParameterizedQuery, function () {
180
167
  const pq = this.parse();
181
- const lines = [
182
- 'ParameterizedQuery {'
183
- ];
168
+ const obj = {};
184
169
  if (npm.utils.isText(pq.text)) {
185
- lines.push(gap + 'text: "' + pq.text + '"');
170
+ obj.text = pq.text;
186
171
  }
187
172
  if (this.values !== undefined) {
188
- lines.push(gap + 'values: ' + npm.utils.toJson(this.values));
173
+ obj.values = this.values;
189
174
  }
190
175
  if (this.binary !== undefined) {
191
- lines.push(gap + 'binary: ' + npm.utils.toJson(this.binary));
176
+ obj.binary = this.binary;
192
177
  }
193
178
  if (this.rowMode !== undefined) {
194
- lines.push(gap + 'rowMode: ' + npm.utils.toJson(this.rowMode));
179
+ obj.rowMode = this.rowMode;
195
180
  }
196
181
  if (this.error !== undefined) {
197
- lines.push(gap + 'error: ' + this.error.toString(level + 1));
182
+ obj.error = this.error.message;
198
183
  }
199
- lines.push(npm.utils.messageGap(level) + '}');
200
- return lines.join(npm.EOL);
201
- };
184
+ return 'ParameterizedQuery ' + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
185
+ });
202
186
 
203
187
  module.exports = {ParameterizedQuery};
204
188
 
@@ -14,7 +14,8 @@ const {assert} = require('../assert');
14
14
 
15
15
  const npm = {
16
16
  EOL: require('os').EOL,
17
- utils: require('../utils')
17
+ utils: require('../utils'),
18
+ inspect: require('util').inspect
18
19
  };
19
20
 
20
21
  /**
@@ -206,47 +207,31 @@ PreparedStatement.prototype.parse = function () {
206
207
  return _i.target;
207
208
  };
208
209
 
209
- /**
210
- * @method PreparedStatement#toString
211
- * @description
212
- * Creates a well-formatted multi-line string that represents the object's current state.
213
- *
214
- * It is called automatically when writing the object into the console.
215
- *
216
- * @param {number} [level=0]
217
- * Nested output level, to provide visual offset.
218
- *
219
- * @returns {string}
220
- */
221
- PreparedStatement.prototype.toString = function (level) {
222
- level = level > 0 ? parseInt(level) : 0;
223
- const gap = npm.utils.messageGap(level + 1);
224
- const ps = this.parse();
225
- const lines = [
226
- 'PreparedStatement {',
227
- gap + 'name: ' + npm.utils.toJson(this.name)
228
- ];
229
- if (npm.utils.isText(ps.text)) {
230
- lines.push(gap + 'text: "' + ps.text + '"');
210
+ npm.utils.addInspection(PreparedStatement, function () {
211
+ const pq = this.parse();
212
+ const obj = {
213
+ name: this.name
214
+ };
215
+ if (npm.utils.isText(pq.text)) {
216
+ obj.text = pq.text;
231
217
  }
232
218
  if (this.values !== undefined) {
233
- lines.push(gap + 'values: ' + npm.utils.toJson(this.values));
219
+ obj.values = this.values;
234
220
  }
235
221
  if (this.binary !== undefined) {
236
- lines.push(gap + 'binary: ' + npm.utils.toJson(this.binary));
222
+ obj.binary = this.binary;
237
223
  }
238
224
  if (this.rowMode !== undefined) {
239
- lines.push(gap + 'rowMode: ' + npm.utils.toJson(this.rowMode));
225
+ obj.rowMode = this.rowMode;
240
226
  }
241
227
  if (this.rows !== undefined) {
242
- lines.push(gap + 'rows: ' + npm.utils.toJson(this.rows));
228
+ obj.rows = this.rows;
243
229
  }
244
- if (this.error) {
245
- lines.push(gap + 'error: ' + this.error.toString(level + 1));
230
+ if (this.error !== undefined) {
231
+ obj.error = this.error.message;
246
232
  }
247
- lines.push(npm.utils.messageGap(level) + '}');
248
- return lines.join(npm.EOL);
249
- };
233
+ return 'PreparedStatement ' + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
234
+ });
250
235
 
251
236
  module.exports = {PreparedStatement};
252
237
 
@@ -1,5 +1,4 @@
1
1
  const {InnerState} = require('../inner-state');
2
- const {addInspection} = require('../utils');
3
2
  const utils = require('../utils');
4
3
 
5
4
  /**
@@ -90,8 +89,4 @@ function setValues(v) {
90
89
  }
91
90
  }
92
91
 
93
- addInspection(ServerFormatting, function () {
94
- return this.toString();
95
- });
96
-
97
92
  module.exports = {ServerFormatting};
@@ -73,12 +73,6 @@ function getSafeConnection(cn) {
73
73
  return maskPassword(cn);
74
74
  }
75
75
 
76
- ///////////////////////////////////////////
77
- // Returns a space gap for console output;
78
- function messageGap(level) {
79
- return ' '.repeat(level * 4);
80
- }
81
-
82
76
  /////////////////////////////////////////
83
77
  // Provides platform-neutral inheritance;
84
78
  function inherits(child, parent) {
@@ -193,7 +187,6 @@ const exp = {
193
187
  addReadProp,
194
188
  addReadProperties,
195
189
  getSafeConnection,
196
- messageGap,
197
190
  inherits,
198
191
  isConnectivityError
199
192
  };
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pg-promise",
3
- "version": "12.4.0",
3
+ "version": "12.6.0",
4
4
  "description": "PostgreSQL interface for Node.js",
5
5
  "main": "lib/index.js",
6
6
  "typings": "typescript/pg-promise.d.ts",
7
7
  "scripts": {
8
8
  "spelling": "cspell --config=.cspell.json \"**/*.{md,ts,js}\" --no-progress",
9
- "coverage": "istanbul cover ./node_modules/jasmine-node/bin/jasmine-node --captureExceptions test",
9
+ "coverage": "nyc --reporter=html --reporter=text ./node_modules/jasmine-node/bin/jasmine-node --captureExceptions test",
10
10
  "doc": "jsdoc -c ./jsdoc/jsdoc.js ./jsdoc/README.md -t ./jsdoc/templates/custom",
11
11
  "lint": "eslint ./lib ./test/*.js ./test/db",
12
12
  "lint:fix": "npm run lint -- --fix",
@@ -42,24 +42,24 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "assert-options": "0.8.3",
45
- "pg": "8.17.2",
45
+ "pg": "8.18.0",
46
46
  "pg-minify": "1.8.0",
47
47
  "spex": "4.1.0"
48
48
  },
49
49
  "peerDependencies": {
50
- "pg-query-stream": "4.11.2"
50
+ "pg-query-stream": "4.12.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@eslint/js": "9.39.2",
54
- "@types/node": "25.1.0",
54
+ "@types/node": "25.2.0",
55
55
  "coveralls": "3.1.1",
56
- "cspell": "9.6.2",
56
+ "cspell": "9.6.3",
57
57
  "eslint": "9.39.2",
58
- "globals": "17.2.0",
59
- "istanbul": "0.4.5",
58
+ "globals": "17.3.0",
60
59
  "jasmine-node": "3.0.0",
61
60
  "jsdoc": "4.0.5",
62
61
  "JSONStream": "1.3.5",
62
+ "nyc": "17.1.0",
63
63
  "typescript": "5.9.3"
64
64
  }
65
65
  }
@@ -130,6 +130,7 @@ declare namespace pgPromise {
130
130
  interface IColumnSetOptions {
131
131
  table?: string | ITable | TableName
132
132
  inherit?: boolean
133
+ duplicate?: 'error' | 'skip' | 'replace'
133
134
  }
134
135
 
135
136
  interface ITable {
@@ -206,8 +207,12 @@ declare namespace pgPromise {
206
207
  skip?: string | string[] | ((c: Column<T>) => boolean)
207
208
  }): string
208
209
 
209
- extend<K extends string>(columns: K[]): ColumnSet<T & Record<K, unknown>>
210
- extend<S>(columns: Column<S> | ColumnSet<S> | Array<IColumnConfig<S> | Column<S>>): ColumnSet<T & S>
210
+ extend<K extends string>(columns: K[], opts?: {
211
+ skip?: boolean
212
+ }): ColumnSet<T & Record<K, unknown>>
213
+ extend<S>(columns: Column<S> | ColumnSet<S> | Array<IColumnConfig<S> | Column<S>>, opts?: {
214
+ skip?: boolean
215
+ }): ColumnSet<T & S>
211
216
 
212
217
  merge<K extends string>(columns: K[]): ColumnSet<T & Record<K, unknown>>
213
218
  merge<S>(columns: Column<S> | ColumnSet<S> | Array<IColumnConfig<S> | Column<S>>): ColumnSet<T & S>