text: /*
   * Copyright (c) 2015-present, Vitaly Tomilov
   *
   * See the LICENSE file at the top-level directory of this distribution
   * for licensing information.
   *
   * Removal or modification of this copyright notice is prohibited.
   */
  
  'use strict';
  
  const npm = {
      con: require('manakin').local,
      path: require('path'),
      pg: require('pg'),
      minify: require('pg-minify'),
      adapter: require('./adapter'),
      result: require('./result'),
      promise: require('./promise'),
      formatting: require('./formatting'),
      helpers: require('./helpers'),
      queryFile: require('./queryFile'),
      errors: require('./errors'),
      utils: require('./utils'),
      pubUtils: require('./utils/public'),
      mode: require('./txMode'),
      types: require('./types'),
      dbPool: require('./dbPool'),
      package: require('../package.json'),
      text: require('./text')
  };
  
  /**
   * @author Vitaly Tomilov
   * @module pg-promise
   *
   * @description
   * ### Initialization Options
   *
   * Below is the complete list of _Initialization Options_ for the library that can be passed in during
   * the library's initialization:
   *
   * ```js
   * const initOptions = {&#47;* options as documented below *&#47;};
   *
   * const pgp = require('pg-promise')(initOptions);
   * ```
   *
   * @param {object} [options]
   * Library Initialization Options.
   *
   * @param {boolean} [options.pgFormatting=false]
   * Redirects all query formatting to the $[pg] driver.
   *
   * By default (`false`), the library uses its own advanced query-formatting engine.
   * If you set this option to a truthy value, query formatting will be done entirely by the
   * $[pg] driver, which means you won't be able to use any of the feature-rich query formatting
   * that this library implements, restricting yourself to the very basic `$1, $2,...` syntax.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {boolean} [options.pgNative=false]
   * Use $[Native Bindings]. Library $[pg-native] must be included and installed independently, or else there will
   * be an error thrown: {@link external:Error Error} = `Failed to initialize Native Bindings.`
   *
   * This is a static option (can only be set prior to initialization).
   *
   * @param {object|function} [options.promiseLib=Promise]
   * Overrides the default (ES6 Promise) promise library for its internal use.
   *
   * Example below sets to use $[Bluebird] - the best and recommended promise library. It is the fastest one,
   * and supports $[Long Stack Traces], essential for debugging promises.
   *
   * ```js
   * const Promise = require('bluebird');
   * const initOptions = {
   *     promiseLib: Promise
   * };
   * const pgp = require('pg-promise')(initOptions);
   * ```
   *
   * All existing promise libraries are supported. The ones with recognizable signature are used automatically,
   * while the rest can be configured via the $[Promise Adapter].
   *
   * This is a static option (can only be set prior to initialization).
   *
   * @param {boolean} [options.noLocking=false]
   * Prevents protocol locking.
   *
   * By default, the library locks much of its protocol to read-only access, as a fool-proof mechanism.
   * Specifically for the {@link event:extend extend} event this serves as a protection against overriding existing
   * properties or trying to set them at the wrong time.
   *
   * If this provision gets in the way of using a mock-up framework for your tests, you can force
   * the library to deactivate most of the locks by setting `noLocking` = `true` within the options.
   *
   * This option is dynamic (can be set before or after initialization). However, changing it after the library's
   * initialization will not affect {@link Database} objects that have already been created.
   *
   * @param {boolean} [options.capSQL=false]
   * Capitalizes any SQL generated by the library.
   *
   * By default, all internal SQL within the library is generated using the low case.
   * If, however, you want all SQL to be capitalized instead, set `capSQL` = `true`.
   *
   * It is purely a cosmetic feature.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {string|Array<string>|null|undefined|function} [options.schema]
   * Forces change of the default database schema(s) for every fresh connection, i.e.
   * the library will execute `SET search_path TO schema_1, schema_2, ...` in the background
   * whenever a fresh physical connection is allocated.
   *
   * Normally, one changes the default schema(s) by $[changing the database or the role], but sometimes you
   * may want to switch the default schema(s) without persisting the change, and then use this option.
   *
   * It can be a string, an array of strings, or a callback function that takes `dc` (database context)
   * as the only parameter (and as `this`), and returns schema(s) according to the database context. A callback function
   * can also return nothing (`undefined` or `null`), if no schema change needed for the specified database context.
   *
   * The order of schema names matters, so if a table name exists in more than one schema, its default access resolves
   * to the table from the first such schema on the list.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {boolean} [options.noWarnings=false]
   * Disables all diagnostic warnings in the library (it is ill-advised).
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {function} [options.connect]
   * Global event {@link event:connect connect} handler.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {function} [options.disconnect]
   * Global event {@link event:disconnect disconnect} handler.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {function} [options.query]
   * Global event {@link event:query query} handler.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {function} [options.receive]
   * Global event {@link event:receive receive} handler.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {function} [options.task]
   * Global event {@link event:task task} handler.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {function} [options.transact]
   * Global event {@link event:transact transact} handler.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {function} [options.error]
   * Global event {@link event:error error} handler.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @param {function} [options.extend]
   * Global event {@link event:extend extend} handler.
   *
   * This option is dynamic (can be set before or after initialization).
   *
   * @see
   * {@link module:pg-promise~end end},
   * {@link module:pg-promise~as as},
   * {@link module:pg-promise~errors errors},
   * {@link module:pg-promise~helpers helpers},
   * {@link module:pg-promise~minify minify},
   * {@link module:pg-promise~ParameterizedQuery ParameterizedQuery},
   * {@link module:pg-promise~PreparedStatement PreparedStatement},
   * {@link module:pg-promise~pg pg},
   * {@link module:pg-promise~QueryFile QueryFile},
   * {@link module:pg-promise~queryResult queryResult},
   * {@link module:pg-promise~spex spex},
   * {@link module:pg-promise~txMode txMode},
   * {@link module:pg-promise~utils utils}
   *
   */
  function $main(options) {
  
      if (npm.utils.isNull(options)) {
          options = {};
      } else {
          if (typeof options !== 'object') {
              throw new TypeError('Invalid initialization options: ' + JSON.stringify(options));
          }
  
          // list of supported initialization options:
          const validOptions = ['pgFormatting', 'pgNative', 'promiseLib', 'noLocking', 'capSQL', 'noWarnings',
              'connect', 'disconnect', 'query', 'receive', 'task', 'transact', 'error', 'extend', 'schema'];
  
          if (!options.noWarnings) {
              for (const prop in options) {
                  if (validOptions.indexOf(prop) === -1) {
                      npm.con.warn('WARNING: Invalid property \'%s\' in initialization options.\n%s\n', prop, npm.utils.getLocalStack(3));
                      break;
                  }
              }
          }
      }
  
      let pg = npm.pg;
      const p = npm.promise(options.promiseLib);
  
      const config = {
          version: npm.package.version,
          promiseLib: p.promiseLib,
          promise: p.promise
      };
  
      npm.utils.addReadProp(config, '$npm', {}, true);
  
      // Locking properties that cannot be changed later:
      npm.utils.addReadProp(options, 'promiseLib', options.promiseLib);
      npm.utils.addReadProp(options, 'pgNative', !!options.pgNative);
  
      config.options = options;
  
      // istanbul ignore next:
      // we do not cover code specific to Native Bindings
      if (options.pgNative) {
          pg = npm.pg.native;
          if (npm.utils.isNull(pg)) {
              throw new Error(npm.text.nativeError);
          }
      }
  
      const Database = require('./database')(config);
  
      const inst = (cn, dc) => {
          if (npm.utils.isText(cn) || (cn && typeof cn === 'object')) {
              return new Database(cn, dc, config);
          }
          throw new TypeError('Invalid connection details: ' + JSON.stringify(cn));
      };
  
      npm.utils.addReadProperties(inst, rootNameSpace);
  
      /**
       * @member {external:PG} pg
       * @readonly
       * @description
       * Instance of the $[pg] library that's being used, depending on initialization option `pgNative`:
       *  - regular `pg` module instance, without option `pgNative`, or equal to `false` (default)
       *  - `pg` module instance with $[Native Bindings], if option `pgNative` was set.
       *
       * Available as `pgp.pg`, after initializing the library.
       */
      npm.utils.addReadProp(inst, 'pg', pg);
  
      /**
       * @member {function} end
       * @readonly
       * @description
       * Shuts down all connection pools created in the process, so it can terminate without delay.
       * It is available as `pgp.end`, after initializing the library.
       *
       * All {@link Database} objects created previously can no longer be used, and their query methods will be rejecting
       * with {@link external:Error Error} = `Connection pool of the database object has been destroyed.`
       *
       * And if you want to shut down only a specific connection pool, you do so via the {@link Database}
       * object that owns the pool: `db.$pool.end()` (see {@link Database#$pool Database.$pool}).
       *
       * For more details see $[Library de-initialization].
       */
      npm.utils.addReadProp(inst, 'end', () => {
          npm.dbPool.shutDown();
      });
  
      /**
       * @member {helpers} helpers
       * @readonly
       * @description
       * Namespace for {@link helpers all query-formatting helper functions}.
       *
       * Available as `pgp.helpers`, after initializing the library.
       *
       * @see {@link helpers}.
       */
      npm.utils.addReadProp(inst, 'helpers', npm.helpers(config));
  
      /**
       * @member {external:spex} spex
       * @readonly
       * @description
       * Initialized instance of the $[spex] module, used by the library within tasks and transactions.
       *
       * Available as `pgp.spex`, after initializing the library.
       *
       * @see
       * {@link Task#batch},
       * {@link Task#page},
       * {@link Task#sequence}
       */
      npm.utils.addReadProp(inst, 'spex', config.$npm.spex);
  
      config.pgp = inst;
      npm.utils.lock(config, true, options);
  
      return inst;
  }
  
  const rootNameSpace = {
  
      /**
       * @member {formatting} as
       * @readonly
       * @description
       * Namespace for {@link formatting all query-formatting functions}.
       *
       * Available as `pgp.as`, before and after initializing the library.
       *
       * @see {@link formatting}.
       */
      as: npm.formatting.as,
  
      /**
       * @member {external:pg-minify} minify
       * @readonly
       * @description
       * Instance of the $[pg-minify] library used internally to minify SQL scripts.
       *
       * Available as `pgp.minify`, before and after initializing the library.
       */
      minify: npm.minify,
  
      /**
       * @member {queryResult} queryResult
       * @readonly
       * @description
       * Query Result Mask enumerator.
       *
       * Available as `pgp.queryResult`, before and after initializing the library.
       */
      queryResult: npm.result,
  
      /**
       * @member {PromiseAdapter} PromiseAdapter
       * @readonly
       * @description
       * {@link PromiseAdapter} class.
       *
       * Available as `pgp.PromiseAdapter`, before and after initializing the library.
       */
      PromiseAdapter: npm.adapter,
  
      /**
       * @member {ParameterizedQuery} ParameterizedQuery
       * @readonly
       * @description
       * {@link ParameterizedQuery} class.
       *
       * Available as `pgp.ParameterizedQuery`, before and after initializing the library.
       */
      ParameterizedQuery: npm.types.ParameterizedQuery,
  
      /**
       * @member {PreparedStatement} PreparedStatement
       * @readonly
       * @description
       * {@link PreparedStatement} class.
       *
       * Available as `pgp.PreparedStatement`, before and after initializing the library.
       */
      PreparedStatement: npm.types.PreparedStatement,
  
      /**
       * @member {QueryFile} QueryFile
       * @readonly
       * @description
       * {@link QueryFile} class.
       *
       * Available as `pgp.QueryFile`, before and after initializing the library.
       */
      QueryFile: npm.queryFile,
  
  
      /**
       * @member {errors} errors
       * @readonly
       * @description
       * {@link errors} - namespace for all error types.
       *
       * Available as `pgp.errors`, before and after initializing the library.
       */
      errors: npm.errors,
  
      /**
       * @member {utils} utils
       * @readonly
       * @description
       * {@link utils} - namespace for utility functions.
       *
       * Available as `pgp.utils`, before and after initializing the library.
       */
      utils: npm.pubUtils,
  
      /**
       * @member {txMode} txMode
       * @readonly
       * @description
       * {@link txMode Transaction Mode} namespace.
       *
       * Available as `pgp.txMode`, before and after initializing the library.
       */
      txMode: npm.mode
  };
  
  npm.utils.addReadProperties($main, rootNameSpace);
  
  module.exports = $main;
  
  /**
   * @external Promise
   * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
   */
  
  /**
   * @external PG
   * @see https://node-postgres.com
   */
  
  /**
   * @external Client
   * @see https://node-postgres.com/api/client
   */
  
  /**
   * @external pg-minify
   * @see https://github.com/vitaly-t/pg-minify
   */
  
  /**
   * @external spex
   * @see https://github.com/vitaly-t/spex
   */
  