@depup/pg-promise 12.6.2-depup.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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -0
  3. package/lib/assert.js +10 -0
  4. package/lib/connect.js +178 -0
  5. package/lib/context.js +93 -0
  6. package/lib/database-pool.js +115 -0
  7. package/lib/database.js +1643 -0
  8. package/lib/errors/README.md +13 -0
  9. package/lib/errors/index.js +51 -0
  10. package/lib/errors/parameterized-query-error.js +71 -0
  11. package/lib/errors/prepared-statement-error.js +71 -0
  12. package/lib/errors/query-file-error.js +75 -0
  13. package/lib/errors/query-result-error.js +157 -0
  14. package/lib/events.js +543 -0
  15. package/lib/formatting.js +932 -0
  16. package/lib/helpers/README.md +10 -0
  17. package/lib/helpers/column-set.js +614 -0
  18. package/lib/helpers/column.js +406 -0
  19. package/lib/helpers/index.js +75 -0
  20. package/lib/helpers/methods/concat.js +103 -0
  21. package/lib/helpers/methods/index.js +13 -0
  22. package/lib/helpers/methods/insert.js +151 -0
  23. package/lib/helpers/methods/sets.js +81 -0
  24. package/lib/helpers/methods/update.js +248 -0
  25. package/lib/helpers/methods/values.js +116 -0
  26. package/lib/helpers/table-name.js +175 -0
  27. package/lib/index.js +29 -0
  28. package/lib/inner-state.js +39 -0
  29. package/lib/main.js +394 -0
  30. package/lib/patterns.js +43 -0
  31. package/lib/query-file.js +379 -0
  32. package/lib/query-result.js +39 -0
  33. package/lib/query.js +273 -0
  34. package/lib/special-query.js +30 -0
  35. package/lib/stream.js +125 -0
  36. package/lib/task.js +404 -0
  37. package/lib/text.js +40 -0
  38. package/lib/tx-mode.js +194 -0
  39. package/lib/types/index.js +18 -0
  40. package/lib/types/parameterized-query.js +247 -0
  41. package/lib/types/prepared-statement.js +298 -0
  42. package/lib/types/server-formatting.js +92 -0
  43. package/lib/utils/README.md +13 -0
  44. package/lib/utils/color.js +68 -0
  45. package/lib/utils/index.js +199 -0
  46. package/lib/utils/public.js +312 -0
  47. package/package.json +77 -0
  48. package/typescript/README.md +63 -0
  49. package/typescript/pg-promise.d.ts +728 -0
  50. package/typescript/pg-subset.d.ts +359 -0
  51. package/typescript/tslint.json +21 -0
@@ -0,0 +1,298 @@
1
+ /*
2
+ * Copyright (c) 2015-present, Vitaly Tomilov
3
+ *
4
+ * See the LICENSE file at the top-level directory of this distribution
5
+ * for licensing information.
6
+ *
7
+ * Removal or modification of this copyright notice is prohibited.
8
+ */
9
+
10
+ const {ServerFormatting} = require('./server-formatting');
11
+ const {PreparedStatementError} = require('../errors');
12
+ const {QueryFile} = require('../query-file');
13
+ const {assert} = require('../assert');
14
+
15
+ const npm = {
16
+ EOL: require('os').EOL,
17
+ utils: require('../utils'),
18
+ inspect: require('util').inspect
19
+ };
20
+
21
+ /**
22
+ * @class PreparedStatement
23
+ * @description
24
+ * Constructs a new $[Prepared Statement] object. All properties can also be set after the object's construction.
25
+ *
26
+ * This type extends the basic `{name, text, values}` object, i.e. when the basic object is used
27
+ * with a query method, a new {@link PreparedStatement} object is created in its place.
28
+ *
29
+ * The type can be used in place of the `query` parameter, with any query method directly.
30
+ *
31
+ * The type is available from the library's root: `pgp.PreparedStatement`.
32
+ *
33
+ * @param {Object} [options]
34
+ * Object configuration options / properties.
35
+ *
36
+ * @param {string} [options.name] - See property {@link PreparedStatement#name name}.
37
+ * @param {string|QueryFile} [options.text] - See property {@link PreparedStatement#text text}.
38
+ * @param {array} [options.values] - See property {@link PreparedStatement#values values}.
39
+ * @param {boolean} [options.binary] - See property {@link PreparedStatement#binary binary}.
40
+ * @param {string} [options.rowMode] - See property {@link PreparedStatement#rowMode rowMode}.
41
+ * @param {number} [options.rows] - See property {@link PreparedStatement#rows rows}.
42
+ * @param {ITypes} [options.types] - See property {@link PreparedStatement#types types}.
43
+ *
44
+ * @returns {PreparedStatement}
45
+ *
46
+ * @see
47
+ * {@link errors.PreparedStatementError PreparedStatementError},
48
+ * {@link https://www.postgresql.org/docs/17/sql-prepare.html PostgreSQL Prepared Statements}
49
+ *
50
+ * @example
51
+ *
52
+ * const {PreparedStatement: PS} = require('pg-promise');
53
+ *
54
+ * // Creating a complete Prepared Statement with parameters:
55
+ * const findUser = new PS({name: 'find-user', text: 'SELECT * FROM Users WHERE id = $1', values: [123]});
56
+ *
57
+ * db.one(findUser)
58
+ * .then(user => {
59
+ * // user found;
60
+ * })
61
+ * .catch(error => {
62
+ * // error;
63
+ * });
64
+ *
65
+ * @example
66
+ *
67
+ * const {PreparedStatement: PS} = require('pg-promise');
68
+ *
69
+ * // Creating a reusable Prepared Statement without values:
70
+ * const addUser = new PS({name: 'add-user', text: 'INSERT INTO Users(name, age) VALUES($1, $2)'});
71
+ *
72
+ * // setting values explicitly:
73
+ * addUser.values = ['John', 30];
74
+ *
75
+ * db.none(addUser)
76
+ * .then(() => {
77
+ * // user added;
78
+ * })
79
+ * .catch(error => {
80
+ * // error;
81
+ * });
82
+ *
83
+ * // setting values implicitly, by passing them into the query method:
84
+ * db.none(addUser, ['Mike', 25])
85
+ * .then(() => {
86
+ * // user added;
87
+ * })
88
+ * .catch(error => {
89
+ * // error;
90
+ * });
91
+ */
92
+ class PreparedStatement extends ServerFormatting {
93
+ constructor(options) {
94
+ options = assert(options, ['name', 'text', 'values', 'binary', 'rowMode', 'rows', 'types']);
95
+ super(options);
96
+ }
97
+
98
+ /**
99
+ * @name PreparedStatement#name
100
+ * @type {string}
101
+ * @description
102
+ * An arbitrary name given to this particular prepared statement. It must be unique within a single session and is
103
+ * subsequently used to execute or deallocate a previously prepared statement.
104
+ */
105
+ get name() {
106
+ return this._inner.options.name;
107
+ }
108
+
109
+ set name(value) {
110
+ const _i = this._inner;
111
+ if (value !== _i.options.name) {
112
+ _i.options.name = value;
113
+ _i.changed = true;
114
+ }
115
+ }
116
+
117
+ /**
118
+ * @name PreparedStatement#rows
119
+ * @type {number}
120
+ * @description
121
+ * Number of rows to return at a time from a Prepared Statement's portal.
122
+ * The default is 0, which means that all rows must be returned at once.
123
+ */
124
+ get rows() {
125
+ return this._inner.options.rows;
126
+ }
127
+
128
+ set rows(value) {
129
+ const _i = this._inner;
130
+ if (value !== _i.options.rows) {
131
+ _i.options.rows = value;
132
+ _i.changed = true;
133
+ }
134
+ }
135
+ }
136
+
137
+ /**
138
+ * @method PreparedStatement#parse
139
+ * @description
140
+ * Parses the current object and returns a simple `{name, text, values}`, if successful,
141
+ * or else it returns a {@link errors.PreparedStatementError PreparedStatementError} object.
142
+ *
143
+ * This method is primarily for internal use by the library.
144
+ *
145
+ * @returns {{name, text, values}|errors.PreparedStatementError}
146
+ */
147
+ PreparedStatement.prototype.parse = function () {
148
+
149
+ const _i = this._inner, options = _i.options;
150
+
151
+ const qf = options.text instanceof QueryFile ? options.text : null;
152
+
153
+ if (!_i.changed && !qf) {
154
+ return _i.target;
155
+ }
156
+
157
+ const errors = [], values = _i.target.values;
158
+ _i.target = {
159
+ name: options.name,
160
+ text: options.text
161
+ };
162
+ _i.changed = true;
163
+ _i.currentError = undefined;
164
+
165
+ if (!npm.utils.isText(_i.target.name)) {
166
+ errors.push('Property \'name\' must be a non-empty text string.');
167
+ }
168
+
169
+ if (qf) {
170
+ qf.prepare();
171
+ if (qf.error) {
172
+ errors.push(qf.error);
173
+ } else {
174
+ _i.target.text = qf[QueryFile.$query];
175
+ }
176
+ }
177
+ if (!npm.utils.isText(_i.target.text)) {
178
+ errors.push('Property \'text\' must be a non-empty text string.');
179
+ }
180
+
181
+ if (!npm.utils.isNull(values)) {
182
+ _i.target.values = values;
183
+ }
184
+
185
+ if (options.binary !== undefined) {
186
+ _i.target.binary = !!options.binary;
187
+ }
188
+
189
+ if (options.rowMode !== undefined) {
190
+ _i.target.rowMode = options.rowMode;
191
+ }
192
+
193
+ if (options.rows !== undefined) {
194
+ _i.target.rows = options.rows;
195
+ }
196
+
197
+ if (options.types !== undefined) {
198
+ _i.target.types = options.types;
199
+ }
200
+
201
+ if (errors.length) {
202
+ return _i.currentError = new PreparedStatementError(errors[0], _i.target);
203
+ }
204
+
205
+ _i.changed = false;
206
+
207
+ return _i.target;
208
+ };
209
+
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;
217
+ }
218
+ if (this.values !== undefined) {
219
+ obj.values = this.values;
220
+ }
221
+ if (this.binary !== undefined) {
222
+ obj.binary = this.binary;
223
+ }
224
+ if (this.rowMode !== undefined) {
225
+ obj.rowMode = this.rowMode;
226
+ }
227
+ if (this.rows !== undefined) {
228
+ obj.rows = this.rows;
229
+ }
230
+ if (this.error !== undefined) {
231
+ obj.error = this.error.message;
232
+ }
233
+ return 'PreparedStatement ' + npm.inspect(obj, {breakLength: 100, depth: 5, colors: true});
234
+ });
235
+
236
+ module.exports = {PreparedStatement};
237
+
238
+ /**
239
+ * @name PreparedStatement#text
240
+ * @type {string|QueryFile}
241
+ * @description
242
+ * A non-empty query string or a {@link QueryFile} object.
243
+ *
244
+ * Only the basic variables (`$1`, `$2`, etc) can be used in the query, because $[Prepared Statements]
245
+ * are formatted on the server side.
246
+ *
247
+ * Changing this property for the same {@link PreparedStatement#name name} will have no effect, because queries
248
+ * for Prepared Statements are cached by the server, with {@link PreparedStatement#name name} being the cache key.
249
+ */
250
+
251
+ /**
252
+ * @name PreparedStatement#values
253
+ * @type {array}
254
+ * @description
255
+ * Query formatting parameters, depending on the type:
256
+ *
257
+ * - `null` / `undefined` means the query has no formatting parameters
258
+ * - `Array` - it is an array of formatting parameters
259
+ * - None of the above, means it is a single formatting value, which
260
+ * is then automatically wrapped into an array
261
+ */
262
+
263
+ /**
264
+ * @name PreparedStatement#binary
265
+ * @type {boolean}
266
+ * @default undefined
267
+ * @description
268
+ * Activates binary result mode. The default is the text mode.
269
+ *
270
+ * @see {@link http://www.postgresql.org/docs/devel/static/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY Extended Query}
271
+ */
272
+
273
+ /**
274
+ * @name PreparedStatement#rowMode
275
+ * @type {string}
276
+ * @default undefined
277
+ * @description
278
+ * Changes the way data arrives to the client, with only one value supported by $[pg]:
279
+ * - `array` will make all data rows arrive as arrays of values. By default, rows arrive as objects.
280
+ */
281
+
282
+ /**
283
+ * @name PreparedStatement#types
284
+ * @type {ITypes}
285
+ * @default undefined
286
+ * @description
287
+ * Custom type parsers just for this query result.
288
+ */
289
+
290
+ /**
291
+ * @name PreparedStatement#error
292
+ * @type {errors.PreparedStatementError}
293
+ * @default undefined
294
+ * @description
295
+ * When in an error state, it is set to a {@link errors.PreparedStatementError PreparedStatementError} object. Otherwise, it is `undefined`.
296
+ *
297
+ * This property is primarily for internal use by the library.
298
+ */
@@ -0,0 +1,92 @@
1
+ const {InnerState} = require('../inner-state');
2
+ const utils = require('../utils');
3
+
4
+ /**
5
+ * @private
6
+ * @class ServerFormatting
7
+ */
8
+ class ServerFormatting extends InnerState {
9
+
10
+ constructor(options) {
11
+ const _inner = {
12
+ options,
13
+ changed: true,
14
+ currentError: undefined,
15
+ target: {}
16
+ };
17
+ super(_inner);
18
+ setValues.call(this, options.values);
19
+ }
20
+
21
+ get error() {
22
+ return this._inner.currentError;
23
+ }
24
+
25
+ get text() {
26
+ return this._inner.options.text;
27
+ }
28
+
29
+ set text(value) {
30
+ const _i = this._inner;
31
+ if (value !== _i.options.text) {
32
+ _i.options.text = value;
33
+ _i.changed = true;
34
+ }
35
+ }
36
+
37
+ get binary() {
38
+ return this._inner.options.binary;
39
+ }
40
+
41
+ set binary(value) {
42
+ const _i = this._inner;
43
+ if (value !== _i.options.binary) {
44
+ _i.options.binary = value;
45
+ _i.changed = true;
46
+ }
47
+ }
48
+
49
+ get rowMode() {
50
+ return this._inner.options.rowMode;
51
+ }
52
+
53
+ set rowMode(value) {
54
+ const _i = this._inner;
55
+ if (value !== _i.options.rowMode) {
56
+ _i.options.rowMode = value;
57
+ _i.changed = true;
58
+ }
59
+ }
60
+
61
+ get values() {
62
+ return this._inner.target.values;
63
+ }
64
+
65
+ set values(values) {
66
+ setValues.call(this, values);
67
+ }
68
+
69
+ }
70
+
71
+ /**
72
+ * @member ServerFormatting#parse
73
+ */
74
+
75
+ function setValues(v) {
76
+ const target = this._inner.target;
77
+ if (Array.isArray(v)) {
78
+ if (v.length) {
79
+ target.values = v;
80
+ } else {
81
+ delete target.values;
82
+ }
83
+ } else {
84
+ if (utils.isNull(v)) {
85
+ delete target.values;
86
+ } else {
87
+ target.values = [v];
88
+ }
89
+ }
90
+ }
91
+
92
+ module.exports = {ServerFormatting};
@@ -0,0 +1,13 @@
1
+ ### `utils` namespace
2
+
3
+ This folder contains everything that's available via the [utils] namespace, before and after initialization:
4
+
5
+ ```js
6
+ const pgpLib = require('pg-promise');
7
+ const pgp = pgpLib(/*initialization options*/);
8
+
9
+ pgpLib.utils; // `utils` namespace
10
+ pgp.utils; // `utils` namespace
11
+ ```
12
+
13
+ [utils]:http://vitaly-t.github.io/pg-promise/utils.html
@@ -0,0 +1,68 @@
1
+ const {format} = require('util');
2
+
3
+ class ColorConsole {
4
+
5
+ static log() {
6
+ ColorConsole.writeNormal([...arguments], 39); // white
7
+ }
8
+
9
+ static info() {
10
+ ColorConsole.writeNormal([...arguments], 36); // cyan
11
+ }
12
+
13
+ static success() {
14
+ ColorConsole.writeNormal([...arguments], 32); // green
15
+ }
16
+
17
+ static warn() {
18
+ ColorConsole.writeNormal([...arguments], 33); // yellow
19
+ }
20
+
21
+ static error() {
22
+ ColorConsole.writeError([...arguments], 31); // red
23
+ }
24
+
25
+ static writeNormal(params, color) {
26
+ // istanbul ignore else
27
+ if (process.stdout.isTTY) {
28
+ console.log.apply(null, ColorConsole.formatColor(params, color)); // eslint-disable-line no-console
29
+ } else {
30
+ console.log.apply(null, params); // eslint-disable-line no-console
31
+ }
32
+ }
33
+
34
+ static writeError(params, color) {
35
+ // istanbul ignore else
36
+ if (process.stderr.isTTY) {
37
+ console.error.apply(null, ColorConsole.formatColor(params, color)); // eslint-disable-line no-console
38
+ } else {
39
+ console.error.apply(null, params); // eslint-disable-line no-console
40
+ }
41
+ }
42
+
43
+ static formatColor(args, color) {
44
+ return args.map(a => `\x1b[${color}m${format(a)}\x1b[0m`);
45
+ }
46
+ }
47
+
48
+ ColorConsole.log.bright = function () {
49
+ ColorConsole.writeNormal([...arguments], 97); // light white
50
+ };
51
+
52
+ ColorConsole.info.bright = function () {
53
+ ColorConsole.writeNormal([...arguments], 93); // light cyan
54
+ };
55
+
56
+ ColorConsole.success.bright = function () {
57
+ ColorConsole.writeNormal([...arguments], 92); // light green
58
+ };
59
+
60
+ ColorConsole.warn.bright = function () {
61
+ ColorConsole.writeNormal([...arguments], 93); // light yellow
62
+ };
63
+
64
+ ColorConsole.error.bright = function () {
65
+ ColorConsole.writeError([...arguments], 91); // light red
66
+ };
67
+
68
+ module.exports = {ColorConsole};
@@ -0,0 +1,199 @@
1
+ /*
2
+ * Copyright (c) 2015-present, Vitaly Tomilov
3
+ *
4
+ * See the LICENSE file at the top-level directory of this distribution
5
+ * for licensing information.
6
+ *
7
+ * Removal or modification of this copyright notice is prohibited.
8
+ */
9
+
10
+ const npm = {
11
+ path: require('path'),
12
+ util: require('util'),
13
+ patterns: require('../patterns')
14
+ };
15
+
16
+ ////////////////////////////////////////////
17
+ // Simpler check for null/undefined;
18
+ function isNull(value) {
19
+ return value === null || value === undefined;
20
+ }
21
+
22
+ ////////////////////////////////////////////////////////
23
+ // Verifies parameter for being a non-empty text string;
24
+ function isText(txt) {
25
+ return txt && typeof txt === 'string' && /\S/.test(txt);
26
+ }
27
+
28
+ ///////////////////////////////////////////////////////////
29
+ // Approximates the environment as being for development.
30
+ //
31
+ // Proper configuration is having NODE_ENV = 'development', but this
32
+ // method only checks for 'dev' being present, and regardless of the case.
33
+ function isDev() {
34
+ const env = process.env.NODE_ENV || '';
35
+ return env.toLowerCase().indexOf('dev') !== -1;
36
+ }
37
+
38
+ /////////////////////////////////////////////
39
+ // Adds properties from source to the target,
40
+ // making them read-only and enumerable.
41
+ function addReadProperties(target, source) {
42
+ for (const p in source) {
43
+ addReadProp(target, p, source[p]);
44
+ }
45
+ }
46
+
47
+ ///////////////////////////////////////////////////////
48
+ // Adds a read-only, non-deletable enumerable property.
49
+ function addReadProp(obj, name, value, hidden) {
50
+ Object.defineProperty(obj, name, {
51
+ value,
52
+ configurable: false,
53
+ enumerable: !hidden,
54
+ writable: false
55
+ });
56
+ }
57
+
58
+ //////////////////////////////////////////////////////////////
59
+ // Converts a connection string or object into its safe copy:
60
+ // if a password is present, it is masked with the symbol '#'.
61
+ function getSafeConnection(cn) {
62
+ const maskPassword = cs => cs.replace(/:(?![/])([^@]+)/, (_, m) => ':' + new Array(m.length + 1).join('#'));
63
+ if (typeof cn === 'object') {
64
+ const copy = {...cn};
65
+ if (typeof copy.password === 'string') {
66
+ copy.password = copy.password.replace(/./g, '#');
67
+ }
68
+ if (typeof copy.connectionString === 'string') {
69
+ copy.connectionString = maskPassword(copy.connectionString);
70
+ }
71
+ return copy;
72
+ }
73
+ return maskPassword(cn);
74
+ }
75
+
76
+ /////////////////////////////////////////
77
+ // Provides platform-neutral inheritance;
78
+ function inherits(child, parent) {
79
+ child.prototype.__proto__ = parent.prototype;
80
+ }
81
+
82
+ // istanbul ignore next
83
+ function getLocalStack(startIdx, maxLines) {
84
+ // from the call stack, we take up to maximum lines,
85
+ // starting with the specified line index:
86
+ startIdx = startIdx || 0;
87
+ const endIdx = maxLines > 0 ? startIdx + maxLines : undefined;
88
+ return new Error().stack
89
+ .split('\n')
90
+ .filter(line => line.match(/\(.+\)/))
91
+ .slice(startIdx, endIdx)
92
+ .join('\n');
93
+ }
94
+
95
+ //////////////////////////////
96
+ // Internal error container;
97
+ function InternalError(error) {
98
+ this.error = error;
99
+ }
100
+
101
+ /////////////////////////////////////////////////////////////////
102
+ // Parses a property name and gets its name from the object
103
+ // if the property exists. Returns an object {valid, has, target, value}:
104
+ // - valid - true/false, whether the syntax is valid
105
+ // - has - a flag that property exists; set when 'valid' = true
106
+ // - target - the target object that contains the property; set when 'has' = true
107
+ // - value - the value; set when 'has' = true
108
+ function getIfHas(obj, prop) {
109
+ const result = {valid: true};
110
+ if (prop.indexOf('.') === -1) {
111
+ result.has = prop in obj;
112
+ result.target = obj;
113
+ if (result.has) {
114
+ result.value = obj[prop];
115
+ }
116
+ } else {
117
+ const names = prop.split('.');
118
+ let missing, target;
119
+ for (let i = 0; i < names.length; i++) {
120
+ const n = names[i];
121
+ if (!n) {
122
+ result.valid = false;
123
+ return result;
124
+ }
125
+ if (!missing && hasProperty(obj, n)) {
126
+ target = obj;
127
+ obj = obj[n];
128
+ } else {
129
+ missing = true;
130
+ }
131
+ }
132
+ result.has = !missing;
133
+ if (result.has) {
134
+ result.target = target;
135
+ result.value = obj;
136
+ }
137
+ }
138
+ return result;
139
+ }
140
+
141
+ /////////////////////////////////////////////////////////////////////////
142
+ // Checks if the property exists in the object or value or its prototype;
143
+ function hasProperty(value, prop) {
144
+ return (value && typeof value === 'object' && prop in value) ||
145
+ value !== null && value !== undefined && value[prop] !== undefined;
146
+ }
147
+
148
+ ////////////////////////////////////////////////////////
149
+ // Adds prototype inspection
150
+ function addInspection(type, cb) {
151
+ type.prototype[npm.util.inspect.custom] = cb;
152
+ }
153
+
154
+ /////////////////////////////////////////////////////////////////////////////////////////
155
+ // Identifies a general connectivity error, after which no more queries can be executed.
156
+ // This is for detecting when to skip executing ROLLBACK for a failed transaction.
157
+ function isConnectivityError(err) {
158
+ const code = err && typeof err.code === 'string' && err.code;
159
+ const cls = code && code.substring(0, 2); // Error Class
160
+ // istanbul ignore next (we cannot test-cover all error cases):
161
+ return code === 'ECONNRESET' || (cls === '08' && code !== '08P01') || (cls === '57' && code !== '57014');
162
+ // Code 'ECONNRESET' - Connectivity issue handled by the driver.
163
+ // Class 08 - Connection Exception (except for 08P01, for protocol violation).
164
+ // Class 57 - Operator Intervention (except for 57014, for cancelled queries).
165
+ //
166
+ // ERROR CODES: https://www.postgresql.org/docs/17/errcodes-appendix.html
167
+ }
168
+
169
+ ///////////////////////////////////////////////////////////////
170
+ // Does JSON.stringify, with support for BigInt (irreversible)
171
+ function toJson(data) {
172
+ if (data !== undefined) {
173
+ return JSON.stringify(data, (_, v) => typeof v === 'bigint' ? `${v}#bigint` : v)
174
+ .replace(/"(-?\d+)#bigint"/g, (_, a) => a);
175
+ }
176
+ }
177
+
178
+ const exp = {
179
+ toJson,
180
+ getIfHas,
181
+ addInspection,
182
+ InternalError,
183
+ getLocalStack,
184
+ isText,
185
+ isNull,
186
+ isDev,
187
+ addReadProp,
188
+ addReadProperties,
189
+ getSafeConnection,
190
+ inherits,
191
+ isConnectivityError
192
+ };
193
+
194
+ const mainFile = process.argv[1];
195
+
196
+ // istanbul ignore next
197
+ exp.startDir = mainFile ? npm.path.dirname(mainFile) : process.cwd();
198
+
199
+ module.exports = exp;