{"version":3,"sources":["jsdelivr-header.js","/npm/@axway/api-builder-runtime@5.5.1/lib/apibuilder.js"],"names":[],"mappings":"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","file":"/npm/@axway/api-builder-runtime@5.5.1/lib/apibuilder.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@axway/api-builder-runtime@5.5.1/lib/apibuilder.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/* r.e. setImmediate:\nIf anything inside a promise callback is thrown, the promise will automatically be rejected.\nWe don't want it to happen in these cases - we want the uncaughtException handler to catch these.\nIf we don't use setImmediate to take the callback out of the grasp of the promise, then we will en\nup with UnhandledPromiseRejectionWarnings.\nDon't mix and match promise/callback syntax, kids!\nsee:\nhttps://github.com/nodejs/node/issues/9242\nhttps://github.com/stevemao/promise-to-callback/blob/master/index.js#L12\n*/\n\n/**\n * @class APIBuilder\n */\nmodule.exports = APIBuilder;\nvar pendingRequests = 0;\n\n// set the name of the node process\nprocess.title = 'API Builder';\n\nvar express = require('express'),\n\t_ = require('lodash'),\n\tevents = require('events'),\n\tfs = require('fs-extra'),\n\tpath = require('path'),\n\tutil = require('util'),\n\tasync = require('async'),\n\twalkSync = require('walk-sync'),\n\tdebug = require('debug')('apibuilder'),\n\tpkg = require('../package.json'),\n\tMetadata = require('./metadata'),\n\tLogger = require('./logger'),\n\tLoader = require('./loader'),\n\tMiddleware = require('./middleware'),\n\tBlock = require('./block'),\n\tRouter = require('./router'),\n\tFlowManager = null,\n\tFlowNode = null,\n\tregisterFlowCoreNodeHandlers = null,\n\tunregisterFlowCoreNodeHandlers = null,\n\tAPIBuilderFlowInvoke = null,\n\tregisterAPIBuilderNodeHandlers = null,\n\tunregisterAPIBuilderNodeHandlers = null,\n\tCodeblockMetadata = null,\n\tEndpoints = null,\n\tCredentialManager,\n\tregisterAuthorizationNodeHandlers,\n\tunregisterAuthorizationNodeHandlers,\n\tAPI = require('./api'),\n\torm = require('@axway/api-builder-orm'),\n\tuuid = require('uuid'),\n\tframeguard = require('frameguard'),\n\txssfilter = require('x-xss-protection'),\n\tnocache = require('nocache'),\n\tnosniff = require('dont-sniff-mimetype'),\n\tpaths = require('./paths'),\n\tplugins = require('./plugins'),\n\trequireUncached = require('require-uncached'),\n\tpluralize = require('pluralize'),\n\tchalk = require('chalk'),\n\tstrictUriEncode = require('strict-uri-encode'),\n\tAuthentication = require('./authentication'),\n\tgetAccessControlMiddleware = require('./authentication/access-control'),\n\tSwagger = require('./swagger'),\n\tgetInternalInterface = require('./_internal'),\n\tglobalConnectors = {},\n\tinGetConnector,\n\tpendingModels,\n\tloadedModelDirs = [],\n\tschemas = null,\n\tdeprecationsCfg = require('../deprecations'),\n\tallTasks = require('./tasks'),\n\tapiBuilderConfig = require('@axway/api-builder-config'),\n\tbytes = require('bytes');\n\n// Most of the time there's only going to be one API Builder instance.\n// If there are multiple instances, this will only be the first one.\nlet globalAPIBuilder = null;\n\n// Intentionally leave this as separate const declaration\n// The starting point for code evolution ...\nconst CompositeFactory = require('./composite');\nconst utils = require('./utils');\nconst cors = require('./cors');\nconst inspect = Symbol.for('nodejs.util.inspect.custom');\nconst Globals = require('./globals');\nconst globals = new Globals();\nconst { PathManager } = require('./express/PathManager');\nconst { RenderEngineManager } = require('./express/RenderEngineManager');\nconst { destroy: destroyAgents } = require('@axway/requester');\nconst cloneDeep = require('clone-deep');\n\nutil.inherits(APIBuilder, events.EventEmitter);\n\n// allow people to reference the built-in debug module (deprecated)\nObject.defineProperty(APIBuilder, 'debug', {\n\tenumerable: true,\n\tget: util.deprecate(function () {\n\t\treturn debug;\n\t}, 'APIBuilder.debug is deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D027', 'D027')\n});\n\n// merge in orm into our APIBuilder\nfor (const key of Object.getOwnPropertyNames(orm)) {\n\tAPIBuilder[key] = orm[key];\n\torm[key].APIBuilder = APIBuilder;\n}\n\nAPIBuilder.API = API;\nAPIBuilder.Block = Block;\nAPIBuilder.Formation = require('./formatters');\nAPIBuilder.Loader = Loader;\nAPIBuilder.Logger = Logger;\nAPIBuilder.Metadata = Metadata;\nAPIBuilder.Middleware = Middleware;\nAPIBuilder.ORM = orm;\nAPIBuilder.Router = Router;\nAPIBuilder.Version = pkg.version;\nAPIBuilder.Release = pkg['api-builder'].release;\n\n/**\n * Setup known deprecations.  Use `registerDeprecationUse` to mark deprecated features so be\n * logged on startup.\n * @param {object} apibuilder - The APIBuilder instance.\n */\nfunction setupDeprecations(apibuilder) {\n\tapibuilder.deprecations = requireUncached('../deprecations');\n\n\tapibuilder.registerDeprecationUse = (id, use) => {\n\t\tconst { deprecations } = apibuilder;\n\t\tconst deprecation = deprecations.features[id] || deprecations.flags[id];\n\t\tdeprecation.active = true;\n\t\tdeprecation.uses = deprecation.uses || [];\n\t\t// Allow additional per-usage info to be aggregated.\n\t\tif (use) {\n\t\t\tdeprecation.uses.push(use);\n\t\t}\n\t};\n}\n\n/**\n * Handle legacy configuration, upgrade and mark deprecated feature use and set defaults.\n * @param {object} apibuilder - The APIBuilder instance.\n */\nfunction handleLegacyConfig(apibuilder) {\n\tconst { config } = apibuilder;\n\n\tif (config.admin.apiDocPrefix !== undefined) {\n\t\tapibuilder.registerDeprecationUse('apiDocPrefix');\n\t}\n\n\tif (config.admin.disableAPIDoc !== undefined) {\n\t\tapibuilder.registerDeprecationUse('disableAPIDoc');\n\t}\n\n\tif (config.apidoc.disabled !== undefined) {\n\t\tapibuilder.registerDeprecationUse('apidocDisabled');\n\t}\n\n\tif (config.APIKeyAuthType !== undefined\n\t\t|| config.APIKeyAuthPlugin !== undefined) {\n\t\tapibuilder.registerDeprecationUse('perURLAuthentication');\n\t}\n\n\t// move legacy apidoc config from admin section to apidoc section or use default\n\tif (config.apidoc.prefix === undefined) {\n\t\tconfig.apidoc.prefix = config.admin.apiDocPrefix || '/apidoc';\n\t}\n\tif (config.apidoc.disabled === undefined) {\n\t\tconfig.apidoc.disabled = !!config.admin.disableAPIDoc;\n\t}\n\t// \"Kobe\" release made API Builder secure by default.  If accessControl is not defined, then\n\t// move legacy config and configure it to be backwardly compatible.  It looks kinda scary\n\t// setting / to public.\n\tif (!config.accessControl) {\n\t\tconfig.accessControl = {\n\t\t\tapiPrefixSecurity: config.APIKeyAuthType || 'basic',\n\t\t\tplugin: config.APIKeyAuthPlugin,\n\t\t\tpublic: [ '/' ]\n\t\t};\n\t\tif (!config.APIKeyAuthType) {\n\t\t\t// if not defined, use 'none'\n\t\t\tconfig.accessControl.apiPrefixSecurity = 'none';\n\t\t}\n\n\t\tdelete config.APIKeyAuthType;\n\t\tdelete config.APIKeyAuthPlugin;\n\t}\n\n\t// --> Upgrade config.port to config.http.port\n\tif (config.port !== undefined) {\n\t\tapibuilder.registerDeprecationUse('port');\n\t}\n\n\tif (!config.http) {\n\t\tconfig.http = {\n\t\t\tport: parseInt(config.port) || 8080,\n\t\t\tdisabled: false\n\t\t};\n\t}\n\n\tif (!apiBuilderConfig.flags.disableLegacyHeaders) {\n\t\t// Apply default legacy headers\n\t\tconfig.http.headers = {\n\t\t\t'content-md5': true,\n\t\t\tetag: true,\n\t\t\tserver: true,\n\t\t\t...config.http.headers\n\t\t};\n\t} else {\n\t\t// Apply headers provided by user\n\t\tconfig.http.headers = config.http.headers || {};\n\t}\n\n\t// Legacy config takes priority\n\tif (config.disableServerBanner !== undefined) {\n\t\tapibuilder.registerDeprecationUse('disableServerBanner');\n\t\tconfig.http.headers.server = !config.disableServerBanner;\n\t}\n\n\t// Some applications might be using config.port directly, so explicitly\n\t// set this value for backward compatibility.\n\tconfig.port = config.http.port;\n\t// <-- End upgrade config.port to config.http.port\n\n\t// assign the new value back for backwards compatability\n\tconfig.admin.apiDocPrefix = config.apidoc.prefix;\n\tconfig.admin.disableAPIDoc = config.apidoc.disabled;\n\n\t// Register deprecation for bodyparser config\n\tif (config.bodyParser !== undefined) {\n\t\tapibuilder.registerDeprecationUse('bodyParser');\n\t}\n\n\t// Register deprecation for busboy config\n\tif (config.busboy !== undefined) {\n\t\tapibuilder.registerDeprecationUse('busboy');\n\t} else {\n\t\tconfig.busboy = {};\n\t}\n\tconfig.busboy.limits = config.busboy.limits || {};\n\n\tconfigureRequestLimits(apibuilder);\n}\n\n/**\n * This may expand to limits such as the entire request body maximum size\n *(including multipart requests and raw) and/or limits for raw/text/json\n * requests independently to multipart requests.\n */\nfunction configureRequestLimits(apibuilder) {\n\tconst { config } = apibuilder;\n\n\tconst undefinedMpSize = config.limits.multipartPartSize === undefined;\n\ttry {\n\t\tconfig.limits.multipartPartSize = parseBytes(config.limits.multipartPartSize);\n\t} catch (err) {\n\t\tthrow new Error(`invalid limits.multipartPartSize: ${err.message}`);\n\t}\n\n\tconst { multipartPartSize } = config.limits;\n\t// busboy configuration will take priority over our own limits settings.\n\tconst { limits } = config.busboy;\n\tif (undefinedMpSize) {\n\t\t// busboy's fieldSize limit defaults to 1mb when limits.multipartPartSize\n\t\t// is undefined. We inherit that unless the user specifically configures\n\t\t// multipartPartSize. When we remove the deprecation, we will always set\n\t\t// a value (infinity)\n\t\tapibuilder.registerDeprecationUse('undefinedMultipartPartSize');\n\t} else {\n\t\tlimits.fieldSize = limits.fieldSize !== undefined\n\t\t\t? limits.fieldSize : multipartPartSize;\n\t}\n\tlimits.fileSize = limits.fileSize !== undefined\n\t\t? limits.fileSize : multipartPartSize;\n\t// busboy 1.0 changed the limit to inclusive, so if the limit is 500 and\n\t// 500 is hit, then it errors. there is an open issue:\n\t// https://github.com/mscdex/busboy/issues/297\n\tif (Number.isFinite(limits.fileSize)) {\n\t\tlimits.fileSize += 1;\n\t}\n\tif (Number.isFinite(limits.fieldSize)) {\n\t\tlimits.fieldSize += 1;\n\t}\n}\n\n/**\n * Parses a string such as '10MB' to a number of bytes\n * Units are powers of 2 (1KB = 1024B).\n * Strings may be numerical values (i.e. '-1' or '4000')\n * Negative numerical values are treated as Infinity\n * @param {string|number} value the value to parse as bytes\n * @throws {Error} when a value which isn't undefined, a string, number or a\n * provided string doesn't parse as a number of bytes.\n */\nfunction parseBytes(value) {\n\tif (value === undefined) {\n\t\treturn Infinity;\n\t}\n\tlet parsed = value;\n\tif (typeof value === 'string') {\n\t\t// Parse a string into a number\n\t\tparsed = bytes.parse(value);\n\t}\n\t// If parsing failed or the value provided was invalid\n\tif (isNaN(parsed) || typeof parsed !== 'number') {\n\t\tthrow new Error(`\"${value}\" is not a valid value`);\n\t}\n\t// Negative numbers disable the limit\n\tif (parsed < 0) {\n\t\treturn Infinity;\n\t}\n\t// All that's left are numbers between 0 and Infinity which are allowed.\n\treturn parsed;\n}\n\n/**\n * API Builder constructor function.\n *\n * @param {object} [config] the base configuration of the service.\n * Will be overridden by any configuration files on disk or provided configOverrides.\n * @param {object|boolean} [options] - options object. If boolean, it is treated as loadOnly.\n * @param {boolean} [options.loadOnly] if true, does not start express server.\n * @param {object} [options.configOverrides] provided values will override any loaded config.\n */\nfunction APIBuilder(config, options = {}) {\n\tthis.initialConfig = cloneDeep(config);\n\tif (typeof options === 'boolean') {\n\t\toptions = { loadOnly: options };\n\t}\n\tconst initialOptions = cloneDeep(options);\n\tthis.apibuilderPlugins = {};\n\tconst deferredLogger = utils.createDeferredLogger();\n\t// Note that it is not possible for configOverrides to specify dir.\n\tconst configOptions = {\n\t\tdirname: config && config.dir,\n\t\tdefaultConfig: config,\n\t\tconfigOverrides: options.configOverrides\n\t};\n\tthis.config = new Loader(deferredLogger, configOptions);\n\tthis.config.apiPrefix = this.config.apiPrefix || '/api';\n\tthis.config.admin = this.config.admin || {};\n\tthis.config.apidoc = this.config.apidoc || { overrides: {} };\n\tthis.config.apidoc.overrides = this.config.apidoc.overrides || {};\n\tthis.config.limits = this.config.limits || {};\n\tif (this.config.bindProcessHandlers === undefined) {\n\t\tthis.config.bindProcessHandlers = true;\n\t}\n\tif (this.config.admin.updatesEnabled === undefined) {\n\t\tthis.config.admin.updatesEnabled = true;\n\t}\n\n\t// Set known deprecation info in one place.  This will be used to mark deprecated\n\t// features on startup.\n\tsetupDeprecations(this);\n\n\t// add the config.flags\n\tapiBuilderConfig.setFlagDisabledHandler((dep) => {\n\t\tthis.registerDeprecationUse(dep.prop);\n\t});\n\tthis.config.flags = this.config.flags || {};\n\tapiBuilderConfig.flags = Object.entries(deprecationsCfg.flags)\n\t\t.reduce((col, [ key, value ]) => {\n\t\t\tcol[key] = {\n\t\t\t\t...value,\n\t\t\t\tenabled: !!this.config.flags[key]\n\t\t\t};\n\t\t\treturn col;\n\t\t}, {});\n\n\t// Upgrade config and register deprecation messages\n\thandleLegacyConfig(this);\n\n\t// Register deprecation warning for any out-of-support Node.js versions\n\tif (utils.isUsingEOLNodeVersion()) {\n\t\tthis.registerDeprecationUse('nodeSupport');\n\t}\n\n\t// Register deprecation warning for node 14 as we are moving to node 16 minimum in v5\n\tif (utils.isUsingNode14()) {\n\t\tthis.registerDeprecationUse('nodeSupport14');\n\t}\n\n\t// http and https ports taken from the config\n\t// http port defaults to 8080 only as legacy apps compatibility\n\t// https port defaults to 8443\n\tthis.port = this.config.http.port;\n\tif (this.config.ssl && !this.config.ssl.port) {\n\t\tthis.config.ssl.port = 8443;\n\t}\n\n\t// Run validation on the config\n\tvalidateConfig(this.config);\n\n\t// Infer the need of web resource allocation like static web and renderers\n\tconst webDirectory = this.config.dir && path.join(this.config.dir, 'web');\n\tconst publicDirectory = webDirectory && path.join(webDirectory, 'public');\n\tconst routesDirectory = webDirectory && path.join(webDirectory, 'routes');\n\t// configWeb is internal prop that holds flags to specify\n\t// the need to initialize resources related with web app capabilities\n\t// like static server and renderers.\n\t// In the future this might be turned into official configuration strategy in app config\n\tthis.configWeb = {\n\t\tneedStaticServer: publicDirectory && fs.existsSync(publicDirectory),\n\t\tneedRenderers: routesDirectory && fs.existsSync(routesDirectory)\n\t};\n\tif (this.configWeb.needRenderers) {\n\t\tthis.registerDeprecationUse('apiBuilderWeb');\n\t}\n\t// end of Infer logic\n\n\tthis.loadOnly = options.loadOnly;\n\tthis.ignoreDuplicateModels = !!this.config.ignoreDuplicateModels;\n\n\tif (!globalAPIBuilder) {\n\t\tglobalAPIBuilder = this;\n\t}\n\t// since the continuation listeners potentially has a ton of listeners on\n\t// startup\n\tthis.setMaxListeners(Number.MAX_VALUE);\n\n\t// Initialize the base url\n\tlet baseurl = this.config.baseurl\n\t\t|| (this.config.http.disabled ? 'https://localhost' : 'http://localhost');\n\tbaseurl = `${baseurl}${baseurl.endsWith(':') ? '' : ':'}`;\n\tif (baseurl.toLowerCase().startsWith('https://')) {\n\t\tbaseurl = `${baseurl}${this.config.ssl.port}`;\n\t} else {\n\t\tbaseurl = `${baseurl}${this.port}`;\n\t}\n\n\t// Now that flags are configured, set the logging level, and after\n\t// it is safe for use.\n\tconst hasCustomLogger = !!(config && config.logger);\n\tif (hasCustomLogger) {\n\t\t// Note, that imo, for custom loggers, we should be calling:\n\t\t// `this.logger.level(this.config.logLevel)`\n\t\t// But, we never did before, so just making the point now.\n\t\tthis.logger = config.logger;\n\t} else {\n\t\tconst loggerConfig = {\n\t\t\tlevel: this.config.logLevel\n\t\t};\n\n\t\tif (this.config.enableLoggingAsJSON) {\n\t\t\t// When logging as json is enabled we need to configure the logger\n\t\t\tloggerConfig.logAsJson = true;\n\n\t\t\t// If the client have enabled logging as JSON we don't want any of the logs to be\n\t\t\t// polluted with the coloring we do with chalk. This is a hacky way of dealing with that\n\t\t\t// as we have hardcoded all these additional colors in the logs as we wanted to make\n\t\t\t// these more readable for the users in the terminal. With the ability to log as JSON\n\t\t\t// these logs are to going to be rather imported into a tool, such as kibana, and\n\t\t\t// processed that way, where the colors are in the way. So setting this chalk variable\n\t\t\t// to 0 will disable it globally.\n\n\t\t\t// It seems that chalk has a \"good enough\" detection on whether or not the terminal the\n\t\t\t// logs are outputted at supports colors and it does strip colors out when appropriate.\n\t\t\t// However, we are forcing the logs to be outputted as JSON now based on a config option\n\t\t\t// and we don't want to output logs like '\\u001b[32mLog Message (logger.1)\\u001b[39m\"}'.\n\t\t\t// While this doesn't seem to be a problem when in production, we'd want to strip these\n\t\t\t// out while in develop as well so it is not confusing to our users and make them\n\t\t\t// believe they need to do something to remove them.\n\t\t\t// IMPORTANT: This disables colors globally not only for this logger.\n\t\t\tchalk.level = 0;\n\t\t}\n\t\tthis.logger = Logger.createLogger(loggerConfig);\n\t}\n\n\t// Log the loader messages (this is the top of the log)\n\tdeferredLogger.logAll(this.logger);\n\n\tlogConfiguredMultipartLimit(this);\n\n\t// Require these after setting the flags as the flags may affect their interfaces\n\tconst AxwayFlow = require('@axway/flow');\n\tFlowManager = AxwayFlow.FlowManager;\n\tFlowNode = AxwayFlow.FlowNode;\n\tregisterFlowCoreNodeHandlers = AxwayFlow.register;\n\tunregisterFlowCoreNodeHandlers = AxwayFlow.unregister;\n\tschemas = require('@axway/api-builder-schema');\n\tAPIBuilderFlowInvoke = require('@axway/api-builder-flow-invoke');\n\tregisterAPIBuilderNodeHandlers = APIBuilderFlowInvoke.register;\n\tunregisterAPIBuilderNodeHandlers = APIBuilderFlowInvoke.unregister;\n\tCodeblockMetadata = APIBuilderFlowInvoke.CodeblockMetadata;\n\tEndpoints = require('@axway/api-builder-endpoints');\n\n\t// Initialize the Credential Manager\n\tinitCredentialManager(baseurl, this);\n\n\tconst pathManager = new PathManager(this);\n\t// this is the default path (inside if). we use this\n\t// as a way to be able to load up API Builder but without\n\t// creating the server infrastructure. this is useful for\n\t// being able to programatically load models, connectors, etc\n\tif (!options.loadOnly) {\n\n\t\tvar self = this;\n\t\tthis.express = express;\n\t\tvar server = this.app = express();\n\n\t\t// Configure express to always behave as \"production\".\n\t\t// This is more secure, and provides a number of performance benefits\n\t\t// Although it does cache view templates and css files\n\t\t// http://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production\n\t\t// this.config.expressEnv is not part of the public interface, and\n\t\t// intentionally undocumented and only for use by us if we find\n\t\t// that we need to configure the express env ASAP for debugging.\n\t\tserver.set('env', this.config.expressEnv || 'production');\n\n\t\t// If configured, disable etag header and calculation for non-static requests.\n\t\t// See https://npmjs.com/package/etag\n\t\tif (!this.config.http.headers.etag) {\n\t\t\tserver.set('etag', false);\n\t\t}\n\n\t\tvar healthCheckAPI;\n\t\tvar healthCheckError;\n\t\tif (this.config.healthCheckAPI) {\n\t\t\ttry {\n\t\t\t\thealthCheckAPI = require(path.resolve(this.config.dir, this.config.healthCheckAPI));\n\t\t\t} catch (e) {\n\t\t\t\thealthCheckError = e;\n\t\t\t}\n\t\t}\n\n\t\tconst healthcheckMiddleware = healthCheckAPI || function (req, resp) {\n\t\t\tconst success = !self.shuttingdown\n\t\t\t\t&& !self._internal.isUnavailable();\n\t\t\treturn resp.json({ success });\n\t\t};\n\n\t\t// These don't get server/request id or content-md5 headers\n\t\t// since they are bound before the middleware that adds these headers\n\t\t// and before req.server is bound (md5 uses this)\n\t\tserver.get('/apibuilderPing.json', healthcheckMiddleware);\n\t\t// This is the default healthcheck that ARS will call.\n\t\tserver.get('/arrowPing.json', healthcheckMiddleware);\n\n\t\tif (healthCheckError) {\n\t\t\tthis.logger.trace(healthCheckError.stack);\n\t\t\tthis.logger\n\t\t\t\t.error('error loading health check plugin', healthCheckAPI, healthCheckError);\n\t\t}\n\n\t\t// add graceful shutdown middleware which will send 503 responses to\n\t\t// any incoming connection requests while we're in shutdown or reload mode. any\n\t\t// front end load balancer (like API Runtime Services) should correctly handle this\n\t\tserver.use(function (req, resp, next) {\n\t\t\tif (self.shuttingdown || self.pendingReload) {\n\t\t\t\tresp.shouldKeepAlive = false;\n\t\t\t\tresp.set('Connection', 'close');\n\t\t\t\tresp.set('Cache-Control', 'no-cache, no-store, max-age=0');\n\t\t\t\tresp.set('Pragma', 'no-cache');\n\t\t\t\tresp.status(503);\n\t\t\t\tif (self.shuttingdown) {\n\t\t\t\t\tresp.end('Server is shutting down');\n\t\t\t\t} else {\n\t\t\t\t\tresp.end('Server is restarting');\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnext();\n\t\t\t}\n\t\t});\n\n\t\t// add the request-id helper\n\t\texpress.request.getId = function () {\n\t\t\tif (!this._reqid) {\n\t\t\t\tthis._reqid = uuid.v4();\n\t\t\t}\n\t\t\treturn this._reqid;\n\t\t};\n\n\t\taddLocals(this, this.app, baseurl);\n\n\t\t// bind a logger to the server itself\n\t\tserver.logger = this.logger;\n\n\t\tlet appPkg = path.join(this.config.dir, 'package.json');\n\t\tconst releaseName\n\t\t\t= chalk.blue.bold(`API Builder/${APIBuilder.Release} (${APIBuilder.Version})`);\n\t\tif (fs.existsSync(appPkg)) {\n\t\t\tappPkg = require(appPkg);\n\t\t\tthis.logger.info(releaseName + ' ' + chalk.yellow(`${appPkg.name}/${appPkg.version}`));\n\t\t} else {\n\t\t\tappPkg = {};\n\t\t\t// fallback if we can't find package.json for app\n\t\t\tthis.logger.info(releaseName);\n\t\t}\n\t\tthis.projectName = appPkg.name ? path.basename(appPkg.name) : 'apibuilder-app';\n\n\t\tthis.metadata = {\n\t\t\tname: appPkg.name,\n\t\t\tversion: appPkg.version,\n\t\t\tdescription: appPkg.description,\n\t\t\tauthor: appPkg.author,\n\t\t\tlicense: appPkg.license\n\t\t};\n\n\t\t// Only add the metadata if it is our own logger and JSON logging is ON\n\t\tif (!hasCustomLogger && this.config.enableLoggingAsJSON) {\n\t\t\t// When logging as JSON the intention is to consume the logs in a logging tool.\n\t\t\t// To make things a bit easier to consume we could include things such as the service\n\t\t\t// details in the logs, so the logs could be filtered by the service name for example.\n\t\t\tthis.logger.addServiceMetadata(this.metadata);\n\t\t}\n\n\t\tif (this.config.apikey) {\n\t\t\tthis.logger.debug('APIKey is:', chalk.gray(this.config.apikey));\n\t\t}\n\n\t\tsetupSecurityHeaders(server);\n\n\t\tserver.use(function (req, resp, next) {\n\t\t\treq.pendingReqCount = ++pendingRequests;\n\t\t\treq.server = self;\n\t\t\tif (self.config.http.headers.server) {\n\t\t\t\tresp.set('Server', 'API Builder/' + pkg.version);\n\t\t\t}\n\t\t\tresp.set('Request-Id', req.getId());\n\t\t\tresp.locals['request-id'] = req.getId();\n\t\t\treq.logger = resp.logger = req.log = req.log || self.logger.scope(req);\n\t\t\tnext();\n\t\t});\n\n\t\t// Note: Admin isn't loaded at this point, the module is just required\n\t\t// so we can test for \"development\" mode early on.\n\t\tlet Admin;\n\t\ttry {\n\t\t\t// try to require admin if enabled\n\t\t\tif (this.config.admin && this.config.admin.enabled) {\n\t\t\t\tconst pkg = utils.getPackageJson('@axway/api-builder-admin');\n\t\t\t\tif (pkg.version !== APIBuilder.Version) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The version of ${pkg.name} and @axway/api-builder-runtime should be equal, but are ${pkg.version} and ${APIBuilder.Version} respectively`);\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line import/no-unresolved\n\t\t\t\tAdmin = require('@axway/api-builder-admin');\n\t\t\t} else {\n\t\t\t\t// admin is completely disabled\n\t\t\t\tthis.logger.info('API Builder Console is disabled');\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\t// Ignore require error if admin cannot be loaded\n\t\t\tif (!ex.message.includes('Cannot find module \\'@axway/api-builder-admin\\'')) {\n\t\t\t\tthrow ex;\n\t\t\t}\n\t\t}\n\n\t\t// A flag toggling on redaction in Production. This would redact the req\n\t\t// info that is being logged to preserve sensitive information from being\n\t\t// leaked into the logs.\n\t\tconst enableRedaction = !Admin;\n\t\tconst requestMiddleware = getRequestMiddleware(enableRedaction);\n\t\t// This should always be at the top before anything else but after setting up the logger\n\t\tserver.use(requestMiddleware);\n\n\t\tthis.corsAPI = cors(\n\t\t\t{\n\t\t\t\tapidocPath: this.apidocPath,\n\t\t\t\tapidocPathLegacy: this.apidocPathLegacy,\n\t\t\t\tgetAPIsForPath: API.getAPIsForPath,\n\t\t\t\tpathManager,\n\t\t\t\tpublicDirectory\n\t\t\t},\n\t\t\tthis.config.cors\n\t\t);\n\n\t\tif (this.configWeb.needStaticServer) {\n\t\t\tif (this.corsAPI.isCORSOn()) {\n\t\t\t\t// Add CORS headers for the Static Resources if the static server is available and\n\t\t\t\t// if CORS is on\n\t\t\t\tserver.use(this.corsAPI.middlewareForStaticResources);\n\t\t\t}\n\t\t\t// setup static route to web/public.  this is placed before the authenticated\n\t\t\t// api/routes, otherwise static routes will not work.  e.g. the UI requests /index.html\n\t\t\t// which routes to ./web/public.\n\t\t\tsetupStaticPublicMiddleware(server, this.config.dir);\n\t\t}\n\n\t\t// create the authentication strategy and middleware (bound in start).\n\t\tsetupAuthenticationStrategy(this);\n\n\t\t// Enable view cache when in \"production\".\n\t\t// This is for the deprecated API Builder Web (Middleware)\n\t\tif (!Admin && this.app.get('env') === 'production') {\n\t\t\t// Must be set manually\n\t\t\tthis.app.enable('view cache');\n\t\t} else {\n\t\t\tthis.app.disable('view cache');\n\t\t}\n\n\t\t// Create the RenderEngineManager - for backward compatibility, it has\n\t\t// the same interface as the old Middleware used to have before it was\n\t\t// refactored to remove the render engines.\n\t\tthis.middleware = new RenderEngineManager(server, {\n\t\t\tappDir: this.config.dir,\n\t\t\tlogger: this.logger\n\t\t});\n\t\tthis.middleware.registerRenderers();\n\n\t\t// load up admin if enabled\n\t\tif (Admin) {\n\t\t\tthis.admin = new Admin();\n\t\t}\n\n\t\tif (!this.config.http.disabled) {\n\t\t\tthis.logger.trace(`creating APIBuilder server instance on port ${this.port}`);\n\t\t}\n\t\tif (this.config.ssl) {\n\t\t\tthis.logger.trace(`creating APIBuilder server instance on port ${this.config.ssl.port}`);\n\t\t}\n\t} else {\n\t\tthis.pkg = pkg;\n\t}\n\n\tif (this.config.printEnvVars) {\n\t\tthis.logger.trace(process.env);\n\t}\n\n\t// pass the config to components but remove some parts\n\tconst { name, port, admin, session, apikey } = this.config;\n\tthis.objConfig = { name, port, admin, session, apikey };\n\n\tschemas.setLogger(this.logger);\n\n\tthis.flowManager = new FlowManager(this.logger, CredentialManager);\n\tthis.models = {};\n\tthis.apis = [];\n\tthis.blocks = {};\n\tthis.registeredNodes = [];\n\tthis.routes = [];\n\tthis.codeblocks = {};\n\tthis.endpoints = {};\n\n\t// NOTE: put all non-public interfaces on internal\n\tthis._internal = getInternalInterface.bind(this)();\n\tthis._internal.setPathManager(pathManager);\n\tthis._internal.setPackageInfo(pkg);\n\tthis._internal.initialOptions = initialOptions;\n\n\tif (options.loadOnly) {\n\t\t// The `loadOnly` is only used internally. It is an asynchronous\n\t\t// function with a callback (not passed), so it is not going to wait\n\t\t// here. It used to use `nextTick`, possibly to ensure that what ever\n\t\t// happens in `load`, happens after this constructor resolves.\n\t\t// However, internal tests pass, so we will leave it without the\n\t\t// `nextTick`.  Now, `load` is called by `start`.\n\t\t// TODO: we do not want `load` here, even for development.  tests\n\t\t// that depend on loadOnly should be refactored to explicitly call\n\t\t// load.\n\t\tthis.load();\n\t} else {\n\t\tthis.once('reload', this.reload);\n\t}\n\tloadInternalConnectors();\n}\n\nfunction logConfiguredMultipartLimit(apibuilder) {\n\tconst { fileSize, fieldSize = '1mb' } = apibuilder.config.busboy.limits;\n\n\tconst file = bytes.parse(fileSize);\n\tconst field = bytes.parse(fieldSize);\n\n\tconst fileUnlimited = file === Infinity;\n\tconst fieldUnlimited = field === Infinity;\n\n\tconst fileFSize = fileUnlimited ? 'unlimited' : bytes.format(file);\n\tconst fieldFSize = fieldUnlimited ? 'unlimited' : bytes.format(field);\n\n\tconst unlimited = fileUnlimited || fieldUnlimited;\n\n\tconst logLvl = unlimited ? 'warn' : 'debug';\n\n\tconst msg = 'The maximum part size for multipart/form-data requests is';\n\tconst unlimitedMsg = unlimited\n\t\t? '. You should consider configuring a limit in config.limits.multipartPartSize.'\n\t\t: '';\n\n\tconst size = file === field ? fileFSize : `${fileFSize} (files), ${fieldFSize} (fields)`;\n\n\tapibuilder.logger[logLvl](`${msg} ${size}${unlimitedMsg}`);\n}\n\n/**\n * Validates the apidoc configuration overrides.\n *\n * @param {Object} overrides - The apidoc overrides from the configuration.\n * @throws {Error} - when invalid configuration is encountered.\n */\nfunction validateApidocOverrides(overrides) {\n\tconst { schemes, host, basePath, servers } = overrides;\n\n\t// Verify that scheme contains 0 or 1 of http, https, ws, wss\n\tif (schemes !== undefined && schemes !== null) {\n\t\tlet invalid = !Array.isArray(schemes) || !schemes.length;\n\t\tif (!invalid) {\n\t\t\tconst valid = [ 'http', 'https', 'ws', 'wss' ];\n\t\t\t// remove duplicates and filter out invalid schemes\n\t\t\tconst filtered = [ ...new Set(schemes) ]\n\t\t\t\t.filter(s => valid.includes(s));\n\t\t\t// if the length is different then there were some invalid values\n\t\t\tif (filtered.length !== schemes.length) {\n\t\t\t\tinvalid = true;\n\t\t\t}\n\t\t}\n\t\tif (invalid) {\n\t\t\tthrow new Error('apidoc.overrides.schemes configuration is invalid. Value must be an array containing 0 or 1 of \"http\", \"https\", \"ws\", \"wss\"');\n\t\t}\n\t}\n\n\tif (host !== undefined && host !== null && typeof host !== 'string') {\n\t\tthrow new Error('apidoc.overrides.host configuration is invalid. Value must be a string');\n\t}\n\n\tif (basePath !== undefined\n\t\t&& basePath !== null\n\t\t&& (typeof basePath !== 'string' || basePath[0] !== '/')) {\n\t\tthrow new Error('apidoc.overrides.basePath configuration is invalid. Value must be a string and start with a leading /, or null to specify no basePath');\n\t}\n\n\tif (servers !== undefined && servers !== null) {\n\t\tif (!Array.isArray(servers)) {\n\t\t\tthrow new Error('apidoc.overrides.servers configuration is invalid. Value must be an array.');\n\t\t}\n\n\t\t// Validate the server values\n\t\tfor (const server of servers) {\n\t\t\tconst isObject = !Array.isArray(server) && server instanceof Object;\n\t\t\tconst containsUrl = server.hasOwnProperty('url') && typeof server.url === 'string';\n\t\t\tif (!isObject || !containsUrl) {\n\t\t\t\tthrow new Error('apidoc.overrides.servers configuration is invalid. Values must be of type Object and at minimum contain the required server url as String.');\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction validateConfig(config) {\n\tvalidateApidocOverrides(config.apidoc.overrides);\n\n\tconst proxyUri = config.proxy;\n\tif (proxyUri !== undefined && typeof proxyUri !== 'string') {\n\t\tthrow new Error('proxy configuration is invalid. Value must be a string');\n\t}\n\tconst apiPrefix = config.apiPrefix;\n\tif (typeof apiPrefix !== 'string' || apiPrefix[0] !== '/') {\n\t\tthrow new Error('apiPrefix configuration is invalid. Value must be a string and start with a leading \"/\".');\n\t}\n\n\tif (config.baseurl) {\n\t\tif (!config.ssl && config.baseurl.toLowerCase().startsWith('https://')) {\n\t\t\tthrow new Error(`baseurl in the config is set to the secure url ${config.baseurl}. \\\nHowever SSL has not been enabled on this service. For details on configuring SSL see https://docs.axway.com/bundle/api-builder-security-guide/page/enabling_tls_ssl.html`);\n\t\t}\n\n\t\tif (config.http.disabled && config.baseurl.toLowerCase().startsWith('http://')) {\n\t\t\tthrow new Error(`The baseurl is set to ${config.baseurl}, but http is disabled (http.disabled is set to true)`);\n\t\t}\n\t}\n\n\tif (!config.http.port || typeof config.http.port !== 'number') {\n\t\tthrow new Error('http.port is not configured properly in your config. \\\nIt is either missing or not of type number.');\n\t}\n\n\tif (config.http.disabled && !config.ssl) {\n\t\tthrow new Error('http.disabled in the config is set to true. \\\nHowever SSL has not been enabled on this service. For details on configuring SSL see https://docs.axway.com/bundle/api-builder-security-guide/page/enabling_tls_ssl.html');\n\t}\n\n\tif (!config.accessControl.hasOwnProperty('public')) {\n\t\tthrow new Error('accessControl.public is required.  Value must be an empty array, or array of path strings prefixed with a leading \"/\"');\n\t}\n}\n\n/**\n * Initialize Credential Manager and registers all credentials in API Builder.\n * The function is also responsible to preserve valid authorizations across reloads if they have not\n * been touched.\n *\n * @param {*} baseurl the baseurl.\n * @param {*} apiBuilder API Builder instance.\n */\nfunction initCredentialManager(baseurl, apiBuilder) {\n\tapiBuilder.config.authorization = apiBuilder.config.authorization || {};\n\tapiBuilder.config.authorization.callback = apiBuilder.config.authorization.callback || '/auth/callback';\n\tconst FlowAuth = require('@axway/axway-flow-authorization');\n\tCredentialManager = FlowAuth.CredentialManager;\n\tregisterAuthorizationNodeHandlers = FlowAuth.register;\n\tunregisterAuthorizationNodeHandlers = FlowAuth.unregister;\n\tCredentialManager.setLogger(apiBuilder.logger);\n\n\tCredentialManager.config = {\n\t\tbaseurl,\n\t\t...apiBuilder.config.authorization,\n\t\tcredentials: mergeCredentials(baseurl, apiBuilder.config.authorization.callback)\n\t};\n\n\t/**\n\t * Responsible to update the list with managed by Credential Manager credentials.\n\t * baseurl and callback are used to calculate redirect_uri used by oauth2 authorization.\n\t *\n\t * On system restart the Credential Manager must manage the updated list with credentials\n\t * - deleted credentials must not be managed\n\t * - newly added credentials must be managed\n\t * - modified credentials should be invalidated\n\t * - not modified credentials should be preserved\n\t *\n\t * There are two types of credential attributes - manually managed and dynamically managed by\n\t * CM.\n\t * The algorithm here decides how to reset oauth2 credentials when checking manually managed\n\t * attributes for changes.\n\t *\n\t * @param {*} baseurl service base url\n\t * @param {*} callback service callback url\n\t * @returns {array} the new list with credentials that must be managed by Credential Manager\n\t */\n\tfunction mergeCredentials(baseurl, callback) {\n\t\tconst previouslyManagedCredentials = CredentialManager.getCredentialConfigs() || {};\n\t\tconst newCredentials = apiBuilder.config.authorization.credentials || {};\n\t\tif (Object.keys(previouslyManagedCredentials).length === 0\n\t\t\t|| Object.keys(newCredentials).length === 0) {\n\t\t\t// No merge required.\n\t\t\treturn newCredentials;\n\t\t}\n\n\t\t// Delete any removed credentials\n\t\tObject.keys(previouslyManagedCredentials)\n\t\t\t.filter(name => !newCredentials.hasOwnProperty(name))\n\t\t\t.forEach(name => CredentialManager.removeCredential(name));\n\n\t\t// Merge the old details into the new credential.\n\t\tObject.keys(newCredentials)\n\t\t\t// Filter newly added\n\t\t\t.filter(name => previouslyManagedCredentials.hasOwnProperty(name))\n\t\t\t// Leave only oauth2 since they are the only refreshable at the moment\n\t\t\t.filter(name => newCredentials[name].type === 'oauth2')\n\t\t\t// Merge\n\t\t\t.forEach(name => {\n\t\t\t\tconst providedProps = [\n\t\t\t\t\t'authentication_url',\n\t\t\t\t\t'client_id',\n\t\t\t\t\t'client_secret',\n\t\t\t\t\t'flow',\n\t\t\t\t\t'token_url'\n\t\t\t\t];\n\t\t\t\tconst existing = previouslyManagedCredentials[name];\n\t\t\t\tconst newCred = newCredentials[name];\n\t\t\t\tconst newRedirectUri = newCred.redirect_uri || baseurl + callback;\n\t\t\t\tif (providedProps.every(key => newCred[key] === existing[key])\n\t\t\t\t\t&& newRedirectUri === existing.redirect_uri) {\n\t\t\t\t\t// If the provided props and redirect_uri stays the same we keep the previously\n\t\t\t\t\t// claculated managed dependencies\n\t\t\t\t\tnewCred.expiry = existing.expiry;\n\t\t\t\t\tnewCred.access_token = existing.access_token;\n\t\t\t\t\tnewCred.refresh_token = existing.refresh_token;\n\t\t\t\t\tnewCred.scope = existing.scope;\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn newCredentials;\n\t}\n}\n\n/**\n * This is invoked only when constructing APIBuilder instance.\n * Internal connectors are created once and reloaded on APIBuilder restart.\n * getConnector will always find these already instantiated.\n * @param {object} instance - The APIBuilder instance.\n */\nfunction loadInternalConnectors() {\n\t// Load memory connector\n\tAPIBuilder.registerConnector(new APIBuilder.MemoryConnector());\n\n\t// Load composite connector\n\tAPIBuilder.registerConnector(CompositeFactory(APIBuilder));\n}\n\nfunction addLocals(server, app, baseurl) {\n\t// Note that the baseurl argument is calculated using the config and the\n\t// port. That is assigned to server instance property.\n\t// The config baseurl does not contain a port.\n\tserver.baseurl = baseurl;\n\tserver.apidocPathLegacy = server.config.apidoc.prefix + '/docs.json';\n\tserver.apidocPath = server.config.apidoc.prefix + '/swagger.json';\n\tserver.apidocurl = server.baseurl + server.apidocPath;\n\tserver.logger.trace('setting app locals', app.locals);\n\n\tObject.defineProperty(app.locals, 'appc_external_url', {\n\t\tenumerable: true,\n\t\tget: util.deprecate(function () {\n\t\t\treturn server.baseurl;\n\t\t}, 'app.locals properties appc_external_url, appc_external_apidoc_path_legacy, appc_external_apidoc_path, and appc_external_apidoc_url are deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D026', 'D026')\n\t});\n\tObject.defineProperty(app.locals, 'appc_external_apidoc_path_legacy', {\n\t\tenumerable: true,\n\t\tget: util.deprecate(function () {\n\t\t\treturn server.apidocPathLegacy;\n\t\t}, 'app.locals properties appc_external_url, appc_external_apidoc_path_legacy, appc_external_apidoc_path, and appc_external_apidoc_url are deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D026', 'D026')\n\t});\n\tObject.defineProperty(app.locals, 'appc_external_apidoc_path', {\n\t\tenumerable: true,\n\t\tget: util.deprecate(function () {\n\t\t\treturn server.apidocPath;\n\t\t}, 'app.locals properties appc_external_url, appc_external_apidoc_path_legacy, appc_external_apidoc_path, and appc_external_apidoc_url are deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D026', 'D026')\n\t});\n\tObject.defineProperty(app.locals, 'appc_external_apidoc_url', {\n\t\tenumerable: true,\n\t\tget: util.deprecate(function () {\n\t\t\treturn server.apidocurl;\n\t\t}, 'app.locals properties appc_external_url, appc_external_apidoc_path_legacy, appc_external_apidoc_path, and appc_external_apidoc_url are deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D026', 'D026')\n\t});\n}\n\n/**\n * Returns the middleware instance containing the Express app instance.\n * @returns {APIBuilder.Middleware}\n */\nAPIBuilder.prototype.getMiddleware = function () {\n\treturn this.middleware;\n};\n\n/*\n * used for testing only\n *\n * @private\n */\nAPIBuilder.resetGlobal = function () {\n\tAPIBuilder.ORM.MemoryConnector.resetPrimaryKeys();\n\tglobalConnectors = {};\n\tloadedModelDirs = [];\n\tglobalAPIBuilder = null;\n\tglobals.resetState();\n\tpendingRequests = 0;\n};\n\n/**\n * Gets a reference to the first instantiated APIBuilder server.\n * @returns {APIBuilder}\n */\nAPIBuilder.getGlobal = function () {\n\treturn globalAPIBuilder;\n};\n\n/**\n * Returns the full path of the component directory.\n * @param {String} type Component type, that is, `api`, `block`, `model`, `route`, `node`.\n * @returns String\n */\nAPIBuilder.prototype.getComponentDir = function getComponentDir(type) {\n\tif (type === 'route') {\n\t\t// these live in a little bit of a different location\n\t\treturn path.resolve(path.join(this.config.dir, 'web', 'routes'));\n\t} else {\n\t\treturn path.resolve(path.join(this.config.dir, `${type}s`));\n\t}\n};\n\n/**\n * Loads an API from an API file. The file must exist and be a valid API. No error checking is\n * performed.\n * @param {String} fn Filename of the API.\n * @param {Function} [cb] Callback passed an Error object (or null if successful), the API instance,\n * @and the API class.\n */\nAPIBuilder.prototype.loadApi = function loadAPI(fn, cb) {\n\ttry {\n\t\tthis.logger.debug('attempting to load API', fn);\n\t\tlet APIClass = paths.requireComponent(fn, true);\n\t\tif (!_.isFunction(APIClass)) {\n\t\t\tthis.logger.trace(APIClass);\n\t\t\tthrow new Error('Error loading api at ' + fn + '. this module did not export a Class');\n\t\t}\n\t\tlet api = new APIClass(this.objConfig, this, fn);\n\t\t// APIs can reference models so if they use them, add to usage map\n\n\t\tthis._internal.pluginUse.registerAPI(api);\n\t\tthis.apis.push(api);\n\t\tcb && setImmediate(() => cb(null, api, APIClass));\n\t} catch (ex) {\n\t\tif (cb) {\n\t\t\treturn cb(ex);\n\t\t} else {\n\t\t\tthrow ex;\n\t\t}\n\t}\n};\n\n/**\n * Loads a Model from a Model file. The file must exist and be a valid Model. No error checking is\n * performed.\n * @param {String} fn Filename of the Model.\n * @param {Function} [cb] Callback passed an Error object (or null if successful) and the Model\n * @class.\n */\nAPIBuilder.prototype.loadModel = function loadModel(fn, cb) {\n\ttry {\n\t\tthis.logger.debug('attempting to load model', fn);\n\t\tlet Model = paths.requireComponent(fn, true);\n\t\tif (!Model) {\n\t\t\tthis.logger.trace(Model);\n\t\t\tthrow new Error('Error loading model at ' + fn);\n\t\t}\n\t\tif (Model.deferred) {\n\t\t\t// Set by model extend/reduce monkeypatch futher down this file.\n\t\t\t// Model loading was deferred since it referenced another model.\n\t\t\t// Note: This function is never hit again for that model.\n\t\t\tcb && setImmediate(() => cb());\n\t\t\treturn;\n\t\t}\n\t\tif (!_.isObject(Model)) {\n\t\t\tthis.logger.trace(Model);\n\t\t\tthrow new Error('Error loading model at ' + fn + '. this module did not load properly');\n\t\t}\n\t\tif (!_.isFunction(Model.create) && !Model.loadingModels) {\n\t\t\tthis.logger.trace(Model);\n\t\t\tthrow new Error('Error loading model at ' + fn + '. this module did not export a Class');\n\t\t}\n\t\tif (!Model.loadingModels\n\t\t\t&& (!_.isObject(Model.fields)\n\t\t\t\t|| !Object.keys(Model.fields).length)) {\n\t\t\tthis.logger.trace(Model);\n\t\t\tthrow new Error('Error loading model at ' + fn + '. this model did not contain any fields');\n\t\t}\n\t\t// if we don't provide a connector, attempt to get the connector global default the config\n\t\t// this makes it nice since i can simply put my default in the config and i don't need to\n\t\t// specify on each and every model\n\t\tif (!Model.connector) {\n\t\t\tModel.setConnector(this.config.defaultConnector);\n\t\t}\n\t\tModel.filename = fn;\n\t\tif (!Model.generated) {\n\t\t\tModel.timestamp = fs.statSync(fn).mtime;\n\t\t}\n\t\tModel.name && (this.models[Model.name] = Model);\n\t\tthis._internal.pluginUse.registerModel(Model);\n\n\t\tcb && setImmediate(() => cb(null, Model));\n\t} catch (ex) {\n\t\tif (cb) {\n\t\t\treturn cb(ex);\n\t\t} else {\n\t\t\tthrow ex;\n\t\t}\n\t}\n};\n\n/**\n * Loads a Block from a Block file. The file must exist and be a valid Block. No error checking is\n * performed.\n * @param {String} fn Filename of the Block.\n * @param {Function} [cb] Callback passed an Error object (or null if successful) and the Block\n * @class.\n */\nAPIBuilder.prototype.loadBlock = function loadBlock(fn, cb) {\n\ttry {\n\t\tthis.logger.debug('attempting to load block', fn);\n\t\tlet Block = paths.requireComponent(fn, true);\n\t\tif (!Block) {\n\t\t\tthis.logger.trace(Block);\n\t\t\tthrow new Error('Error loading block at ' + fn);\n\t\t}\n\t\tif (!_.isFunction(Block)) {\n\t\t\tthis.logger.trace(Block);\n\t\t\tthrow new Error('Error loading block at ' + fn + '. this module did not export a Class');\n\t\t}\n\t\tlet block = new Block(this.objConfig, this);\n\t\tBlock.filename = block.filename = fn;\n\t\tBlock.timestamp = block.timetsamp = fs.statSync(fn).mtime;\n\t\tthis.blocks[block.name] = block;\n\t\tcb && setImmediate(() => cb(null, Block));\n\t} catch (ex) {\n\t\tif (cb) {\n\t\t\treturn cb(ex);\n\t\t} else {\n\t\t\tthrow ex;\n\t\t}\n\t}\n};\n\n/**\n * Loads a Flow from a flow file. The file must exist and be a valid Flow.\n * @param {String} fn Filename of the flow.\n * @param {Function} [cb] Callback passed an Error object (or null if @successful) and the\n * Flow class.\n */\nAPIBuilder.prototype.loadFlow = function loadFlow(fn, cb) {\n\tthis.logger.debug('attempting to load flow', fn);\n\t// only save changes to flows when admin is running\n\tconst saveUpdates = !!this.admin;\n\treturn this.flowManager.load(fn, { saveUpdates }).then(\n\t\tflow => {\n\t\t\tthis._internal.pluginUse.registerFlow(flow, fn);\n\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\tsetImmediate(function () {\n\t\t\t\tcb && cb(null, flow);\n\t\t\t});\n\t\t},\n\t\terr => {\n\t\t\tthis.logger.error(err);\n\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\tsetImmediate(function () {\n\t\t\t\tcb && cb(new Error('Error loading flow at ' + fn));\n\t\t\t});\n\t\t});\n};\n\n/*\n * Parses and validates a swagger document\n * See Endpoints.validateSwagger for details about validation types performed.\n * @param {string|object} swagger - swagger document\n * @returns {Promise<object>} valid swagger\n */\nAPIBuilder.prototype.validateSwagger = function (swagger) {\n\treturn Endpoints.validateSwagger(swagger, { logger: this.logger });\n};\n\n/**\n * Loads an endpoint from a file.\n * @param  {string} fn [path to file]\n * @param  {Function} cb [callback to for error handle]\n */\nAPIBuilder.prototype.loadEndpoint = function loadEndpoint(fn, cb) {\n\tthis.logger.debug('attempting to load endpoint', fn);\n\treturn Endpoints.load(fn, this.getFlows(), { logger: this.logger }).then(\n\t\t(epInfo) => {\n\t\t\tif (this.endpoints[epInfo.name]) {\n\t\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\t\tsetImmediate(() => {\n\t\t\t\t\tconst { filename } = this.endpoints[epInfo.name];\n\t\t\t\t\tcb && cb(new Error(`Duplicate endpoint at ${fn} and ${filename}`));\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.endpoints[epInfo.name] = epInfo;\n\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\tsetImmediate(function () {\n\t\t\t\tcb && cb(null, epInfo);\n\t\t\t});\n\t\t},\n\t\t(err) => {\n\t\t\t// err can contain .errors or is an exception\n\t\t\tconst errors = [ `Error loading endpoint at ${fn}` ];\n\t\t\tif (err.errors) {\n\t\t\t\terrors.push(' ');\n\t\t\t\terr.errors.forEach(function (e) {\n\t\t\t\t\terrors.push(JSON.stringify(e));\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\terrors.push((err + '').replace(/^Error:\\s+/, '; '));\n\t\t\t}\n\t\t\tconst msg = errors.join('').trim();\n\t\t\tthis.logger.error(msg);\n\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\tsetImmediate(function () {\n\t\t\t\tcb && cb(new Error(msg));\n\t\t\t});\n\t\t});\n};\n\n/**\n * Loads a Route from a Route file. The file must exist and be a valid Route. No error checking is\n * performed.\n * @param {String} fn Filename of the Route.\n * @param {Function} [cb] Callback passed an Error object (or null if successful) and the Route\n * @class.\n */\nAPIBuilder.prototype.loadRoute = function loadRoute(fn, cb) {\n\ttry {\n\t\tthis.logger.debug('attempting to load route', fn);\n\t\tvar Router = paths.requireComponent(fn, true);\n\t\tif (!Router) {\n\t\t\tthis.logger.trace(Router);\n\t\t\tthrow new Error('Error loading route at ' + fn);\n\t\t}\n\t\tif (!_.isFunction(Router)) {\n\t\t\tthis.logger.trace(Router);\n\t\t\tthrow new Error('Error loading route at ' + fn + '. this module did not export a Class');\n\t\t}\n\t\tvar route = new Router(this.objConfig, this);\n\t\tthis.routes.push(route);\n\t\tRouter.filename = route.filename = fn;\n\t\tRouter.timestamp = route.timestamp = fs.statSync(fn).mtime;\n\t\tcb && setImmediate(() => cb(null, Router));\n\t} catch (ex) {\n\t\tif (cb) {\n\t\t\treturn cb(ex);\n\t\t} else {\n\t\t\tthrow ex;\n\t\t}\n\t}\n};\n\n/**\n * Loads a Codeblock from a Codeblock file. The file must exist and be a valid Codeblock. No error\n * checking is performed.\n * @param {String} fn Filename of the Codeblock.\n * @param {Function} [cb] Callback passed an Error object (or null if successful) and the Codeblock\n * @class.\n */\nAPIBuilder.prototype.loadCodeblock = function loadCodeblock(fn, cb) {\n\tvar msg;\n\tthis.logger.debug('attempting to load codeblock', fn);\n\n\tCodeblockMetadata.load(fn, {\n\t\tlogger: this.logger\n\t}).then(\n\t\tfunction (meta) {\n\t\t\t// all checks pass. Read the codeblock and save it in the instance\n\t\t\t// get codeblock function file\n\t\t\tvar absPath = path.resolve(path.dirname(fn), meta.path);\n\t\t\ttry {\n\t\t\t\tmeta.action = requireUncached(absPath);\n\t\t\t} catch (ex) {\n\t\t\t\tmsg = 'Error loading codeblock at ' + fn + '. ' + ex;\n\t\t\t\tthis.logger.error(msg);\n\t\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\t\tsetImmediate(function () {\n\t\t\t\t\tcb && cb(new Error(msg));\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (typeof (meta.action) !== 'function') {\n\t\t\t\tmsg = 'Error loading codeblock at ' + fn + '. module is not a function';\n\t\t\t\tthis.logger.error(msg);\n\t\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\t\tsetImmediate(function () {\n\t\t\t\t\tcb && cb(new Error(msg));\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.codeblocks[meta.name] = meta;\n\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\tsetImmediate(function () {\n\t\t\t\tcb && cb(null, meta);\n\t\t\t});\n\t\t}.bind(this),\n\t\tfunction (err) {\n\t\t\tthis.logger.error(err);\n\t\t\tthis.logger.error('Error loading codeblock at ' + fn);\n\t\t\t// See \"r.e. setImmediate\" comment above\n\t\t\tsetImmediate(function () {\n\t\t\t\tcb && cb(err);\n\t\t\t});\n\t\t}.bind(this)\n\t);\n};\n\nAPIBuilder.prototype.registerNode = function registerNode(node) {\n\t// TODO: this is a \"public interface\" currently, but the paramter\n\t// with \"specs\" has leaked from when we used to have flows on disk.\n\t// This can easily be changed to taking a single node when we're happy\n\t// to break the function interface.\n\tif (!node || !node.specs) {\n\t\tthrow new Error('Not a flow-node component');\n\t}\n\tObject.keys(node.specs).forEach(\n\t\t(name) => {\n\t\t\tconst spec = JSON.parse(JSON.stringify(node.specs[name]));\n\n\t\t\tclass Node extends FlowNode { }\n\t\t\tObject.entries(node.specs[name].methods).forEach(([ methodName, methodDef ]) => {\n\t\t\t\tNode.prototype[methodName] = methodDef.action;\n\t\t\t});\n\n\t\t\tthis.registeredNodes.push(spec.type);\n\t\t\tthis.flowManager.registerNode(spec.type, Node, function () {\n\t\t\t\treturn spec;\n\t\t\t});\n\t\t}\n\t);\n};\n\nAPIBuilder.prototype.loadSchema = function loadSchema(fn, cb) {\n\tthis.logger.debug('attempting to load schema', fn, 'with scope, \\'' + this.projectName + '\\'');\n\t// adding schema as per the ticket RDPP-1673\n\tschemas.add(fn, 'schema:///schema/' + this.projectName + '/' + path.basename(fn, '.json'));\n\tcb();\n};\n\n/**\n * Loads all service components.\n * @param {Function} callback Callback to execute after loading each component. Passed an Error\n * @object if any.\n */\nAPIBuilder.prototype.loadComponents = function loadComponents(componentTypes, callback) {\n\tvar instance = this;\n\tvar tasks = [];\n\n\t// load connectors, models, blocks, apis, and then routes from directories\n\t// (in that order) first using the node_modules (the true) and then using\n\t// the cwd/<type> (the false)\n\tcomponentTypes.forEach(function (type) {\n\t\tvar xtype = type.replace(/^@/g, ''),\n\t\t\ttypeName = xtype.charAt(0).toUpperCase() + xtype.substring(1),\n\t\t\tmn = 'load' + typeName,\n\t\t\tloadFn;\n\t\tif (!instance[mn]) {\n\t\t\tthrow new Error('Missing method: ' + mn);\n\t\t}\n\t\tloadFn = instance[mn].bind(instance);\n\n\t\t// set a flag that we're loading\n\t\ttasks.push(function (cb) {\n\t\t\tinstance['loading' + typeName + 's'] = true;\n\t\t\tcb();\n\t\t});\n\n\t\t// look inside project directories\n\t\titerateComponentDir(instance, type, fn => {\n\t\t\ttasks.push(cb => loadFn(fn, cb));\n\t\t});\n\n\t\ttasks.push(function (cb) {\n\t\t\t// delete our flag\n\t\t\tdelete instance['loading' + typeName + 's'];\n\t\t\t// fire an event that we're done loading in case we have someone\n\t\t\t// listening for pending models to finish before continuing\n\t\t\tinstance.emit('loaded' + typeName + 's');\n\t\t\tcb();\n\t\t});\n\t});\n\n\tasync.series(tasks, callback);\n};\n\n/*\n * called internally to start loading server. when you call start, it will wait until the\n * loaded event is fired\n */\nAPIBuilder.prototype.load = function load(callback) {\n\t// Initialize the plugin details and then load components\n\tconst exitOnPluginFailure = apiBuilderConfig.flags.exitOnPluginFailure;\n\n\tPromise.resolve()\n\t\t.then(async () => await allTasks.startBilling.call(this, {\n\t\t\truntimeVersion: APIBuilder.Version\n\t\t}))\n\t\t.then(() => plugins.findPlugins(this))\n\t\t.then(\n\t\t\tapibuilderPlugins => {\n\t\t\t\tthis.apibuilderPlugins = apibuilderPlugins;\n\t\t\t},\n\t\t\terr => {\n\t\t\t\t// If findPlugins rejected, throw the err and stop\n\t\t\t\t// the server in the catch\n\t\t\t\tif (exitOnPluginFailure) {\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t\t// REFACTOR: Everything below could be deleted and handled in\n\t\t\t\t// the catch handler. Currently it could cause calling the\n\t\t\t\t// callback twice - here with an error (if exitOnPluginFailure\n\t\t\t\t// is set to false) and in 'loadComponents' without and error\n\t\t\t\t// which will cause the 'started' promise to be resolve twice.\n\t\t\t\tif (callback) {\n\t\t\t\t\tcallback(err);\n\t\t\t\t} else {\n\t\t\t\t\tthis.emit('error', err);\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.then(async () => {\n\t\t\tawait allTasks.registerConnectors.call(this);\n\t\t\tawait allTasks.loadConnectors.call(this);\n\t\t})\n\t\t.then(() => {\n\t\t\t// set plugins on the trigger manager\n\t\t\tthis._internal.getTriggerManager()\n\t\t\t\t.setPlugins(this.apibuilderPlugins);\n\t\t})\n\t\t.then(() => allTasks.loadApiSpecs(this))\n\t\t.then(\n\t\t\t() => {\n\t\t\t\t// Load the components\n\t\t\t\tthis.loadComponents([ 'schema', 'model', 'block', 'api', 'route' ], (err) => {\n\t\t\t\t\tif (!err) {\n\t\t\t\t\t\t// indicate we've started and emit loading event\n\t\t\t\t\t\tthis.logger.debug('Done loading schema, model, block, api, and route');\n\t\t\t\t\t\tthis.loaded = true;\n\t\t\t\t\t\tObject.values(this.models).forEach((model) => {\n\t\t\t\t\t\t\tconst connectorName = typeof model.connector === 'object'\n\t\t\t\t\t\t\t\t? model.connector.name : model.connector;\n\t\t\t\t\t\t\t// Register models that are in use by composite models.\n\t\t\t\t\t\t\t// Done after all models are loaded so we know every model's connector\n\t\t\t\t\t\t\tif (connectorName === 'composite') {\n\t\t\t\t\t\t\t\tthis._internal.pluginUse.registerModel(model, true);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// See if connector has a defaultMetadata for the\n\t\t\t\t\t\t\t// model.\n\t\t\t\t\t\t\tconst connector = this.getConnector(connectorName);\n\t\t\t\t\t\t\tif (connector.defaultMetadata\n\t\t\t\t\t\t\t\t&& (!model.metadata || !Object.keys(model.metadata).length)) {\n\t\t\t\t\t\t\t\tmodel.metadata = connector.defaultMetadata;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// convert models to schema and register them after all the models are\n\t\t\t\t\t\t\t// loaded\n\t\t\t\t\t\t\tthis.modelToSchema(model).forEach((schema) => schemas.add(schema));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthis.emit('loaded');\n\t\t\t\t\t\tcallback && callback();\n\t\t\t\t\t\t// REFACTOR: Else clauses could be deleted and handled in\n\t\t\t\t\t\t// the catch handler so we have single place to control\n\t\t\t\t\t\t// when the callback is invoked.\n\t\t\t\t\t} else if (callback) {\n\t\t\t\t\t\tcallback(err);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.emit('error', err);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t)\n\t\t.catch(err => {\n\t\t\t// Log the error and stop safely\n\t\t\t// This catch also catches previously uncaught promise\n\t\t\t// rejections if connectors failed to start\n\t\t\tconst errMsg = err && err.message || err;\n\t\t\tthis.logger.error('Server failed to load components');\n\t\t\terrMsg && this.logger.error(err.stack);\n\t\t\tthis.stop(() => callback && callback(err));\n\t\t});\n};\n\nconst JSON_FILE_REGEXP = /^((?!_))(.*)?\\.json$/;\nconst JSON_YAML_FILE_REGEXP = /^((?!_))(.*)?\\.(json|yaml|yml)$/;\nconst JS_FILE_REGEXP = /^((?!_))(.*)?\\.js$/;\n\n/*\n * utility function to iterate a component directory and for each component found, call\n * the foundCallback function will the parameter of the path to the component\n */\nfunction iterateComponentDir(instance, type, foundCallback) {\n\tconst directoryTypes = {\n\t\tcodeblock: JSON_FILE_REGEXP,\n\t\tflow: JSON_FILE_REGEXP,\n\t\tendpoint: JSON_YAML_FILE_REGEXP,\n\t\tschema: JSON_FILE_REGEXP\n\t};\n\n\tconst dir = instance.getComponentDir(type);\n\tinstance.logger.trace('iterateComponentDir', type, dir);\n\tif (fs.existsSync(dir)) {\n\t\tif (type === 'model') {\n\t\t\tif (loadedModelDirs.indexOf(dir) >= 0) {\n\t\t\t\tinstance.logger.trace('iterateComponentDir already read', type, dir);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tloadedModelDirs.push(dir);\n\t\t}\n\t\tlet dirs;\n\t\tif (instance._internal.endpointsEnabled) {\n\t\t\t// Only load endpoints from disk if enabled\n\t\t\tdirs = [ 'codeblock', 'flow', 'endpoint', 'schema' ];\n\t\t} else {\n\t\t\tdirs = [ 'codeblock', 'flow', 'schema' ];\n\t\t}\n\n\t\tif (dirs.includes(type)) {\n\t\t\twalkSync(dir).forEach(function fileIterator(file) {\n\t\t\t\tif (directoryTypes[type].test(path.basename(file))) {\n\t\t\t\t\tfoundCallback(path.join(dir, file));\n\t\t\t\t} else {\n\t\t\t\t\tinstance.logger.trace('iterateComponentDir - skipping...', file);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\twalkSync(dir).forEach(function fileIterator(file) {\n\t\t\t\tif (JS_FILE_REGEXP.test(path.basename(file))) {\n\t\t\t\t\tfoundCallback(path.join(dir, file));\n\t\t\t\t} else {\n\t\t\t\t\tinstance.logger.trace('iterateComponentDir - skipping...', file);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tinstance.logger.trace('iterateComponentDir not found', type, dir);\n\t}\n}\n\n/**\n * Returns a configuration value for the key (or a provided default value if not found).\n * @param {String} key Key to retrieve.\n * @param {Any} def Default value to return if the key cannot be found.\n */\nAPIBuilder.prototype.get = util.deprecate(function get(key, def) {\n\treturn this.config[key] || def;\n}, 'APIBuilder.get is deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D030', 'D030');\n\n/**\n * returns false if the model name passed in does not exist.\n * It handles the fatal error if the model does exist.\n *\n * At the moment it returns true, but it should stop the server\n */\nfunction isModelDuplicate(modelName) {\n\tif (globalAPIBuilder && (modelName in globalAPIBuilder.models)) {\n\t\tif (globalAPIBuilder.ignoreDuplicateModels) {\n\t\t\treturn false;\n\t\t}\n\t\t// Model already exists!\n\t\tthrow new Error('Model name: ' + modelName + ' exists in multiple places');\n\t} else {\n\t\treturn false;\n\t}\n}\n\n/**\n * Executes a security middleware call, which authenticates the request.  This is no longer called\n * internally, but remains public method on the APIBuilder interface.\n * @param {Object} req Request object.\n * @param {Object} resp Response object.\n * @param {Function} next Next function to call.\n */\nAPIBuilder.prototype.executeSecurityMiddleware\n\t= function executeSecurityMiddleware(req, resp, next) {\n\t\treturn this.accessControlMiddleware(req, resp, next);\n\t};\n\n/**\n * Starts the server.\n * @param {Function} [callback] Callback passed an Error object.\n * @throws Error\n */\nAPIBuilder.prototype.start = function start(callback) {\n\t// `start` function is called multiple times (i.e. start > on load > start)\n\t// so here we create or get already created promise state where 'started'\n\t// structure is { promise, resolve, reject }. We provide a function as\n\t// second argument that is attached as catch handler and prevents\n\t// UnhandledPromiseRejectionWarning.\n\tconst started = this._internal.getPromiseState('started', () => {});\n\t// this can happen if you call loadOnly in constructor and then later\n\t// try and start the server\n\tif (!this.app) {\n\t\tvar error = new Error('invalid state. no internal app was created. did you call loadOnly in the APIBuilder constructor?');\n\t\tthis.logger.trace('rejecting started promise', error);\n\t\tstarted.reject(error);\n\t\tif (callback) {\n\t\t\tcallback(error);\n\t\t}\n\t\treturn started.promise;\n\t}\n\n\t// if we started and then stopped and now we're restarting, we need to reload this\n\tif (this.shuttingdown) {\n\t\tthis.logger.trace('re-start after a shutdown');\n\t\tvar self = this;\n\t\tthis.shuttingdown = false;\n\t\tasync.each(this.apis, function (api, cb) {\n\t\t\tapi.remove(self, cb);\n\t\t}, function (err) {\n\t\t\tif (err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tasync.each(self.routes, function (route, cb) {\n\t\t\t\tif (route) {\n\t\t\t\t\troute.remove(self, cb);\n\t\t\t\t} else {\n\t\t\t\t\tcb();\n\t\t\t\t}\n\t\t\t}, function (err) {\n\t\t\t\tif (err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\tObject.keys(self.blocks).forEach(function (name) {\n\t\t\t\t\tvar block = self.blocks[name];\n\t\t\t\t\tblock.removeAllListeners();\n\t\t\t\t});\n\t\t\t\tself.models = {};\n\t\t\t\tself.apis = [];\n\t\t\t\tself.blocks = {};\n\t\t\t\tself.routes = [];\n\t\t\t\tself.load(function (err) {\n\t\t\t\t\tif (err) {\n\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t}\n\t\t\t\t\tself.start(callback);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t\treturn started.promise;\n\t}\n\n\t// REFACTOR: If 'start' is called without a callback we provide default\n\t// post startup logic (error handling + more). To reduced the friction we\n\t// can move this logic in 'async.series' callback and execute it if not\n\t// callback is provided. This will allow us to call 'start' internally\n\t// without a callback.\n\tif (!callback) {\n\t\t// This is the default error handler. Most applications do not have a\n\t\t// callback when calling start.\n\t\tthis.logger.trace('using the standard start callback');\n\t\tcallback = function (err) {\n\t\t\tif (err) {\n\t\t\t\tthis.logger.error('Server failed to start');\n\t\t\t\tthis.logger.error(err.stack);\n\t\t\t\t// When an 'error' occurs within an `EventEmitter`, Node.js\n\t\t\t\t// handles these specially.  If an 'error' is emitted and there\n\t\t\t\t// is nothing registered to handle it, then an Error is thrown.\n\t\t\t\t// https://nodejs.org/api/events.html#events_error_events\n\n\t\t\t\t// REFACTOR: This is our current non-graceful way of exiting the\n\t\t\t\t// app. Consider changing it to:\n\t\t\t\t// this.stop(() => { this.emit('error', err); })\n\t\t\t\tthis.emit('error', err);\n\t\t\t} else if (this.port) {\n\t\t\t\tif (!this.config.http.disabled) {\n\t\t\t\t\tthis.logger.info(`Server started on port ${this.port}`);\n\t\t\t\t}\n\t\t\t\tif (this.config.ssl) {\n\t\t\t\t\tthis.logger.info(`SSL server started on port ${this.config.ssl.port}`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.logger.info('Server started');\n\t\t\t}\n\t\t}.bind(this);\n\t}\n\n\tif (!this.loaded) {\n\t\tthis.logger.trace('loading components');\n\t\tthis.load((err) => {\n\t\t\t// This callback is needed because load can fail.  When it fails,\n\t\t\t// we need to handle it so that we can reject the started promise.\n\t\t\tif (err) {\n\t\t\t\tthis.logger.trace('failed to load components', err);\n\t\t\t\tstarted.reject(err);\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tthis.logger.trace('loaded, now starting');\n\t\t\tthis.start(callback);\n\t\t});\n\t\treturn started.promise;\n\t}\n\tthis.logger.trace('starting');\n\n\tif (!this.config.http.disabled) {\n\t\tthis.logger.debug('starting', this.port);\n\t}\n\tif (this.config.ssl) {\n\t\tthis.logger.debug('starting', this.config.ssl.port);\n\t}\n\tthis.emit('starting');\n\n\tconst tasks = [];\n\n\tif (!this.config.http.disabled) {\n\t\ttasks.push(allTasks.checkPort.bind(this, this.port));\n\t}\n\n\tif (this.config.ssl) {\n\t\ttasks.push(allTasks.checkPort.bind(this, this.config.ssl.port));\n\t}\n\n\ttasks.push((next) => {\n\t\t// before 'started' event, bind system events, e.g. \"shutdown\"\n\t\tallTasks.systemEvents.bindEvents.call(this);\n\t\tnext();\n\t});\n\n\t// ------------------------------------------------------------------------\n\t// LOAD: start loading all components.  Al tasks that are below this are\n\t// in a specific order, e.g. schemas are first because flows need them, etc.\n\t// These tasks should be done before we start binding anything, e.g. PLUGINS\n\t// ------------------------------------------------------------------------\n\n\t// load schemas\n\ttasks.push(function loadSchemasTask(next) {\n\t\tthis.logger.debug('loading schemas');\n\t\ttry {\n\t\t\t// register plugin schema\n\t\t\tfor (const plugin of Object.values(this.apibuilderPlugins)) {\n\t\t\t\tfor (const schema of Object.values(plugin.components.schema || {})) {\n\t\t\t\t\tschemas.add(schema);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Finally load all schemas that have been registered\n\t\t\tschemas.loadSync();\n\t\t} catch (ex) {\n\t\t\tthis.logger.error('error loading schemas', ex);\n\t\t\treturn next(ex);\n\t\t}\n\t\tnext();\n\t}.bind(this));\n\n\t// finish loading flows, after registering node handlers\n\ttasks.push(function loadCodeblocks(next) {\n\t\tthis.loadComponents([ 'codeblock' ], function (err) {\n\t\t\tthis.logger.debug('Done loading codeblocks');\n\t\t\tnext(err);\n\t\t}.bind(this));\n\t}.bind(this));\n\n\t// register node handlers.  has to be done after connectors, and done after checking\n\t// to see if port is in use (existing tests depend on that).\n\ttasks.push(function registerNodeHandlers(next) {\n\t\ttry {\n\t\t\t// register flow-nodes from plugins\n\t\t\tfor (const plugin of Object.values(this.apibuilderPlugins)) {\n\t\t\t\tif (!plugin.components.flownodes\n\t\t\t\t\t|| Object.keys(plugin.components.flownodes).length === 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthis.registerNode({\n\t\t\t\t\tspecs: plugin.components.flownodes\n\t\t\t\t});\n\t\t\t}\n\t\t\tregisterFlowCoreNodeHandlers(this.flowManager);\n\t\t\tregisterAPIBuilderNodeHandlers(this);\n\t\t\tregisterAuthorizationNodeHandlers(this.flowManager);\n\t\t} catch (ex) {\n\t\t\treturn next(ex);\n\t\t}\n\t\tnext();\n\t}.bind(this));\n\n\t// finish loading flows, after registering node handlers\n\ttasks.push(function loadFlows(next) {\n\t\tthis.loadComponents([ 'flow', 'endpoint' ], function (err) {\n\t\t\tthis.logger.debug('Done loading flows and endpoints');\n\t\t\tnext(err);\n\t\t}.bind(this));\n\t}.bind(this));\n\n\t// TODO: when we remove Codeblocks, this task can be deleted.\n\ttasks.push(function unregisterOptionalCodeblock(next) {\n\t\tlet codeBlockUri = this.flowManager.formatNodeHandlerUri('api-builder-flow-invoke', 'codeblock');\n\t\t// Check if there are any codeblock files\n\t\tlet hasCodeblockFile = Object.keys(this.codeblocks).length > 0;\n\t\tlet hasCodeblockFlow = false;\n\t\tif (!hasCodeblockFile) {\n\t\t\t// The FlowManager has all the flows in a cache of Flow instances, but\n\t\t\t// unfortunately, it does not give direct access to those instances of Flow.\n\t\t\t// The cache is accessible, and this isn't great to access it this way, but\n\t\t\t// this is the only way to get the nodehandlers that are needed for the flow\n\t\t\t// without creating a Flow instance.  Adding a method on FlowManager does not\n\t\t\t// make sense as this is is to manage a deprecated feature.  This code will be\n\t\t\t// deleted.\n\t\t\tfor (const flowId in this.flowManager.cache) {\n\t\t\t\tfor (const nodeHandler of this.flowManager.cache[flowId].getNodeHandlers()) {\n\t\t\t\t\tif (nodeHandler.node.type === codeBlockUri) {\n\t\t\t\t\t\thasCodeblockFlow = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (hasCodeblockFile || hasCodeblockFlow) {\n\t\t\t// If any codeblock files loaded, or any flow has a codeblock node, emit\n\t\t\t// deprecation warning\n\t\t\tthis.registerDeprecationUse('codeblock');\n\t\t} else {\n\t\t\t// Otherwise, codeblock is unused, unregister the flow-node handler\n\t\t\tthis.flowManager.unregisterNode(codeBlockUri);\n\t\t}\n\t\tnext();\n\t}.bind(this));\n\n\t// turn our models into apis\n\ttasks.push(function createModelAPIs(next) {\n\t\tthis.createAPIsFromModels();\n\t\tnext();\n\t}.bind(this));\n\n\t// sort APIs\n\ttasks.push(allTasks.sortAPIsOrRoutes.bind(this, this.apis));\n\n\t// sort Routes\n\ttasks.push(allTasks.sortAPIsOrRoutes.bind(this, this.routes));\n\n\t// ------------------------------------------------------------------------\n\t// PLUGINS: register the middlewares into the express app. these must be\n\t// added before SECURITY and ADMIN and general ROUTES. All paths bound\n\t// **below** this are subject to being counted towards metrics.\n\t// ------------------------------------------------------------------------\n\ttasks.push(async () => await allTasks.startMiddlewares(this));\n\n\t// ------------------------------------------------------------------------\n\t// SECURITY and ADMIN: these exist at the top of our express app must come\n\t// before ROUTES. Note that accessControl here below PLUGINS to capture 401.\n\t// Note Middleware moved here below PLUGINS to ensure things like busboy\n\t// happen after authentication.\n\t// ------------------------------------------------------------------------\n\t// bind tasks moved from constructor\n\ttasks.push(async () => {\n\t\t// bind our access-control\n\t\tthis.app.use(this.accessControlMiddleware);\n\n\t\t// create the core express middleware (moved from constructor).\n\t\t// REFACTOR: the constructor for this is a bit of a mess and can be\n\t\t// simplified to: Middleware(app, config)\n\t\tconst sessionConfig = this.config.session || {};\n\t\tnew Middleware(this.app, this.config.dir, sessionConfig, this.config);\n\n\t\tthis.app.on('after', endRequestMiddleware);\n\n\t\tif (this.corsAPI.isCORSOn()) {\n\t\t\tthis.app.use(this.corsAPI.middlewareForAPIs);\n\t\t\tthis.app.use(this.corsAPI.middleware);\n\t\t}\n\n\t\t// load up admin if enabled\n\t\tif (this.admin) {\n\t\t\t// Authorization callbacks only registered if we have Admin console\n\t\t\t// for now.\n\t\t\tthis.app.get(\n\t\t\t\tthis.config.authorization.callback,\n\t\t\t\tCredentialManager.middleware\n\t\t\t);\n\t\t}\n\t});\n\n\t// ------------------------------------------------------------------------\n\t// ROUTES: These are the apis, endpoints, model API, and triggers. The order\n\t// of these are important in that each take priority over the other in the\n\t// event of duplicate paths (e.g. possible to create a custom api with a\n\t// similar path).\n\t// ------------------------------------------------------------------------\n\n\t// bind our apis\n\ttasks.push(function (next) {\n\t\tvar keys = {};\n\t\tthis.apis.forEach(api => {\n\t\t\tif (api.enabled) {\n\t\t\t\t// keep track of already bound apis and only bind once (save memory)\n\t\t\t\tvar key = api.method + api.path;\n\t\t\t\tif (key in keys) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tkeys[key] = 1;\n\t\t\t\tapi.bind(this.app);\n\t\t\t}\n\t\t});\n\t\tnext();\n\t}.bind(this));\n\n\t// bind our endpoints to flows\n\ttasks.push(function (next) {\n\t\tEndpoints.bind(this, this.endpoints, Swagger.schemaIdToSwaggerName);\n\t\tnext();\n\t}.bind(this));\n\n\t// bind our routes\n\ttasks.push(function (next) {\n\t\tvar keys = {};\n\t\tthis.routes.forEach(route => {\n\t\t\tif (route.enabled) {\n\t\t\t\t// keep track of already bound routes and only bind once (save memory)\n\t\t\t\tvar key = route.method + route.path;\n\t\t\t\tif (key in keys) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tkeys[key] = 1;\n\t\t\t\troute.bind(this.app);\n\t\t\t}\n\t\t});\n\t\tnext();\n\t}.bind(this));\n\n\t// load triggers\n\ttasks.push(async () => {\n\t\t// We have semantic validation on the triggers' configuration that can\n\t\t// throw, which should abort the start up with the respective details\n\t\t// how to fix the issues.  Note this must happen *before* binding to\n\t\t// ports because some triggers can take time to load. async.js is\n\t\t// handling this async function and any errors it may throw.\n\t\tawait allTasks.loadTriggers.call(this);\n\t});\n\n\t// ------------------------------------------------------------------------\n\t// MISC PATHS: Extra stuff to bind, this block should come after ROUTES and\n\t// before MIDDLEWARE BIND.\n\t// ------------------------------------------------------------------------\n\n\t// bind apidocs\n\ttasks.push(async () => await allTasks.bindApiDocs(this));\n\n\t// bind apidocs discoverability\n\ttasks.push(async () => await allTasks.bindApiDocsDiscoverability(this));\n\n\t// Run any validation that couldn't happen while loading components\n\n\t// Validate schemas\n\t// Async on purpose - saves a try/catch to call a \"next\" callback\n\ttasks.push(async () => {\n\t\t// Note that validateSchema is synchronous and this is returning undefined\n\t\t// on success and not a promise.\n\t\treturn allTasks.validateSchema(schemas, {\n\t\t\tlogger: this.logger,\n\t\t\twarnOnly: !apiBuilderConfig.flags.exitOnSwaggerSchemaValidationError\n\t\t});\n\t});\n\n\ttasks.push(async () => {\n\t\treturn allTasks.validateSwagger(this, {\n\t\t\twarnOnly: !apiBuilderConfig.flags.exitOnSwaggerSchemaValidationError\n\t\t});\n\t});\n\n\t// ------------------------------------------------------------------------\n\t// MIDDLEWARE BIND: The middleware `bind` methods can bind additional\n\t// paths to the express app, and may log additional URL, so this must come\n\t// before ADMIN UI so that the console URL appears last.\n\t// ------------------------------------------------------------------------\n\ttasks.push(async () => await allTasks.bindMiddlewares(this));\n\n\t// check our APIs and Routes for uniqueness\n\ttasks.push((next) => {\n\t\ttry {\n\t\t\tallTasks.checkAPIs(this);\n\t\t} catch (ex) {\n\t\t\treturn next(ex);\n\t\t}\n\t\tnext();\n\t});\n\n\t// ------------------------------------------------------------------------\n\t// ADMIN UI: load the admin-api and admin-ui.  This will bind additional\n\t// paths to the express app, so it must come before ERROR HANDLER, and it\n\t// should come after: ROUTES, MISC PATHS\n\t// ------------------------------------------------------------------------\n\tif (this.admin) {\n\t\ttasks.push(next => this.admin.start(this, next));\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// ERROR HANDLER: Attach express custom error handler. This task must happen\n\t// after **all** routes and middleware are bound.\n\t// ------------------------------------------------------------------------\n\ttasks.push((next) => {\n\t\tallTasks.bindErrorHandlingMiddleware(this);\n\t\tnext();\n\t});\n\n\t// ------------------------------------------------------------------------\n\t// LISTEN: No express paths should be bound after this.\n\t// ------------------------------------------------------------------------\n\n\t// Bind start up the http server and bind the ports\n\ttasks.push(function appListenTask(next) {\n\t\tthis.emit('listening');\n\t\tif (this.config.ssl && this.config.http.disabled) {\n\t\t\t// https only use case\n\t\t\tconst https = require('https');\n\t\t\tthis.sslServer\n\t\t\t\t= https.createServer(this.config.ssl, this.app)\n\t\t\t\t\t.listen({ port: this.config.ssl.port }, next);\n\t\t\t// http is disabled so we reuse the sslServer\n\t\t\t// because we use this.server for number of events\n\t\t\t// e.g. APIBuilder.prototype.stop\n\t\t\tthis.server = this.sslServer;\n\t\t} else {\n\t\t\tif (this.config.ssl) {\n\t\t\t\t// we have https in addition to http\n\t\t\t\tconst https = require('https');\n\t\t\t\t// note that we don't pass 'next' to listen here\n\t\t\t\t// since we pass it later when we create http server\n\t\t\t\tthis.sslServer\n\t\t\t\t\t= https.createServer(this.config.ssl, this.app).listen(this.config.ssl.port);\n\t\t\t}\n\t\t\t// http is enabled so we create new server\n\t\t\tthis.server = this.app.listen(this.port, next);\n\t\t}\n\t\tif (this.sslServer) {\n\t\t\tutils.enableGracefulDestroy(this.sslServer);\n\t\t\tif (this.config.timeout !== undefined) {\n\t\t\t\tthis.sslServer.setTimeout(this.config.timeout);\n\t\t\t}\n\t\t}\n\t\tutils.enableGracefulDestroy(this.server);\n\t\tif (this.config.timeout !== undefined) {\n\t\t\tthis.server.setTimeout(this.config.timeout);\n\t\t}\n\t}.bind(this));\n\n\t// Add this server instance and bind the interrupt handlers.\n\t// IMPORTANT: any startup task error that occurs _after_ `addServer` will\n\t// result in an \"Uncaught Exception\" error.  This is because `start` will\n\t// this.emit('error', error) which causes the exception to be thrown as\n\t// there is no 'error' listener.  Prior to this point, it is just an error\n\t// and logs, \"Emitted 'error' event on APIBuilder instance\". After this\n\t// point, it gets the label, \"Uncaught Exception\".\n\ttasks.push(function startedTask(next) {\n\t\tif (this.unstable && !this.admin) {\n\t\t\t// intentionally happening before addServer and \"started\"\n\t\t\treturn next(new Error('Server became unstable during startup'));\n\t\t}\n\t\tglobals.addServer(this, {\n\t\t\tbind: this.config.bindProcessHandlers\n\t\t});\n\t\tthis.emit('listen');\n\t\tthis.emit('started');\n\t\tnext();\n\t}.bind(this));\n\n\t// Log any warnings\n\n\t// Test for configured data connectors whose plugins aren't installed.\n\ttasks.push((next) => {\n\t\tObject.keys((this.config.connectors) || {})\n\t\t\t.filter(name => this.config.connectors[name].connector)\n\t\t\t.forEach(name => {\n\t\t\t\tif (!this.getConnector(name)) {\n\t\t\t\t\tthis.logger.warn(`Unused connector configured: ${name}. Required plugin ${this.config.connectors[name].connector} is not installed.`);\n\t\t\t\t}\n\t\t\t});\n\t\tnext();\n\t});\n\n\t// Log deprecation warnings\n\ttasks.push((next) => {\n\t\tconst { url, features, flags } = this.deprecations;\n\t\tconst sortById = (a, b) => {\n\t\t\treturn a.id > b.id ? 1 : a.id < b.id ? -1 : 0;\n\t\t};\n\n\t\t[\n\t\t\t...Object.values(features).filter(dep => dep.active),\n\t\t\t...Object.values(flags).filter(dep => dep.active)\n\t\t].sort(sortById).forEach(dep => {\n\t\t\tlet message = `[${dep.id}] ${dep.message}. `;\n\t\t\tif (dep.usageMessage) {\n\t\t\t\tmessage += `${dep.usageMessage}: ${dep.uses.join(', ')}. `;\n\t\t\t}\n\t\t\tmessage += `See: ${url}${dep.id}`;\n\t\t\tthis.logger.warn(message);\n\t\t});\n\t\tnext();\n\t});\n\n\t// start CredentialManager events\n\ttasks.push(async () => await CredentialManager.start());\n\n\t// Log credentials status\n\ttasks.push((next) => {\n\t\tconst credCfgs = CredentialManager.getCredentialConfigs();\n\t\tif (credCfgs && Object.keys(credCfgs).length > 0) {\n\t\t\tObject.entries(credCfgs).forEach(([ name, cfg ]) => {\n\t\t\t\tif (cfg.status.action === 'needsAuth') {\n\t\t\t\t\tthis.logger.warn(`Credential ${name} requires authorization.`);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tnext();\n\t});\n\n\tasync.series(tasks, (err) => {\n\t\tif (err) {\n\t\t\tthis.logger.trace('rejecting started promise', err);\n\t\t\tstarted.reject(err);\n\t\t} else {\n\t\t\tthis.logger.trace('resolving started promise');\n\t\t\tstarted.resolve(this);\n\t\t}\n\t\tcallback && callback(err);\n\t});\n\n\treturn started.promise;\n};\n\n/**\n * Get the id of the model schema that has all the fields but no id and\n * does not allow additionalProperties. Used in create/update etc.\n *\n * @param {Model} model The model to get the schema id for.\n * @param {string} suffix The suffix to append.\n */\nAPIBuilder.prototype.getModelSchemaId = function (model, suffix) {\n\tlet { name } = model;\n\tif (apiBuilderConfig.flags.enableModelNameEncodingInSwagger) {\n\t\t// schema id as per the ticket RDPP-1673 (strict encode RFC-3986)\n\t\tname = strictUriEncode(model.name);\n\t}\n\treturn `schema:///model/${name}${suffix || ''}`;\n};\n\n/**\n * Get the id of the model schema that has all the fields but no id and\n * allows additionalProperties.\n *\n * @param {Model} model The model to get the schema id for.\n */\nAPIBuilder.prototype.getModelSchemaExId = function (model) {\n\treturn this.getModelSchemaId(model, '-ex');\n};\n\n/**\n * Get the id of the model schema that has all the fields including id\n * but also allows additionalProperties. Used in the swagger for programmatic\n * APIs to allow composition with the ResponseModel.\n *\n * @param {Model} model The model to get the schema id for.\n */\nAPIBuilder.prototype.getModelSchemaFullExId = function (model) {\n\treturn this.getModelSchemaId(model, '-fullex');\n};\n\n/**\n * Get the id of the model schema that has all the fields including id\n * and does not allow additionalProperties. Used in the endpoint returns\n * and endpoint upsert.\n * @param {Model} model The model to get the schema id for.\n */\nAPIBuilder.prototype.getModelSchemaFullId = function (model) {\n\treturn this.getModelSchemaId(model, '-full');\n};\n\n/**\n * Given a model, this method computes an array of json-schemas\n * @param  {Object} model - The apibuilder model to use\n * @return {Array}       An array of schemas\n */\nAPIBuilder.prototype.modelToSchema = function (model) {\n\tconst required = [];\n\tconst properties = {};\n\n\tif (!(model instanceof APIBuilder.Model)) {\n\t\tmodel = new APIBuilder.Model(model.name, model, true);\n\t}\n\n\t/**\n\t * Casts a string representation of a value to the property type\n\t * @param  {(String|Any)} value - The value we want to cast/return\n\t * @param  {String} [type=\"string\"] - The type to cast to\n\t * @return {Any}\n\t */\n\tconst castModelDefault = (value, type = 'string') => {\n\t\t// Throw an error if the type and string value are not compatible\n\t\tfunction throwInvalidType(value, type) {\n\t\t\tthrow new Error(`Invalid default value \"${value}\" for type \"${type}\" in model \"${model.name}\"`);\n\t\t}\n\n\t\t// Assert that the parsed/interprated value is the correct type\n\t\tfunction verifyType(value, type) {\n\t\t\tif (Object.prototype.toString.call(value).toLowerCase() !== `[object ${type}]`) {\n\t\t\t\tthrowInvalidType(value, type);\n\t\t\t}\n\t\t}\n\n\t\t// check that the type is correct\n\t\tif (typeof value !== 'string') {\n\t\t\tverifyType(value, type);\n\t\t\treturn value;\n\t\t}\n\n\t\t// Cast the strings to their correct type\n\t\ttry {\n\t\t\tswitch (type) {\n\t\t\t\tcase 'integer':\n\t\t\t\tcase 'number':\n\t\t\t\t\tconst num = Number(value);\n\t\t\t\t\tisNaN(num) && (() => {\n\t\t\t\t\t\tthrow new Error();\n\t\t\t\t\t})();\n\t\t\t\t\treturn num;\n\t\t\t\tcase 'date':\n\t\t\t\t\treturn new Date(value).toISOString();\n\t\t\t\tcase 'boolean':\n\t\t\t\tcase 'array':\n\t\t\t\tcase 'object':\n\t\t\t\t\t// Parse and verify type\n\t\t\t\t\tconst parsedVal = JSON.parse(value);\n\t\t\t\t\tverifyType(parsedVal, type);\n\t\t\t\t\treturn parsedVal;\n\t\t\t\tdefault:\n\t\t\t\t\treturn value;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthrowInvalidType(value, type);\n\t\t}\n\t};\n\n\tObject.entries(model.fields).forEach(([ name, field ]) => {\n\t\tif (field.required) {\n\t\t\trequired.push(name);\n\t\t}\n\t\tproperties[name] = {};\n\n\t\t// Record any defaults or descriptions\n\t\tif ('default' in field) {\n\t\t\tproperties[name].default = castModelDefault(field.default, field.type);\n\t\t}\n\t\tif ('description' in field) {\n\t\t\tproperties[name].description = field.description;\n\t\t}\n\n\t\t// Build out or properties object\n\t\tproperties[name].type = field.type;\n\t\tswitch (field.type) {\n\t\t\tcase 'date':\n\t\t\t\tproperties[name].type = 'string';\n\t\t\t\tbreak;\n\t\t\tcase 'array':\n\t\t\t\t// TODO: We need more information about the array sub-type here. See RDPP-1672\n\t\t\t\tproperties[name].items = {};\n\t\t\t\tbreak;\n\t\t\tcase 'object':\n\t\t\t\t// TODO: We need more information about the object properties here. See RDPP-1672\n\t\t\t\tproperties[name].additionalProperties = true;\n\t\t\t\tbreak;\n\t\t\tcase 'string':\n\t\t\tcase 'number':\n\t\t\tcase 'integer':\n\t\t\tcase 'boolean':\n\t\t\t\tproperties[name].type = field.type;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tproperties[name].type = 'string';\n\t\t\t\tbreak;\n\t\t}\n\t});\n\n\t// NOTE: You can't do composition between these schemas using allOf as each\n\t// clause needs to be independently enforcable, so additionalPropertes false\n\t// won't work.\n\n\t// Extensible schema for describing the model fields (used in schema composition).\n\tconst modelSchemaEx = {\n\t\tid: this.getModelSchemaExId(model),\n\t\ttype: 'object',\n\t\tproperties: properties\n\t};\n\tif (required.length > 0) {\n\t\tmodelSchemaEx.required = required;\n\t}\n\n\t// Schema for describing the model fields (used in create/update).\n\tconst modelSchema = JSON.parse(JSON.stringify(modelSchemaEx));\n\tmodelSchema.id = this.getModelSchemaId(model);\n\tmodelSchema.additionalProperties = false;\n\n\tconst modelSchemas = [\n\t\tmodelSchema,\n\t\tmodelSchemaEx\n\t];\n\n\t// Extensible schema for model fields containing Id (used in API swagger returns)\n\tconst pkName = model.getPrimaryKeyName();\n\n\tif (!apiBuilderConfig.flags.enableModelsWithNoPrimaryKey || pkName) {\n\t\tconst pkType = apiBuilderConfig.flags.usePrimaryKeyType\n\t\t\t? { type: model.getPrimaryKeyType() } : {};\n\n\t\t// 'date' is not one of the accepted json schema validation types. We support providing\n\t\t// dates as strings, so we need to coerce the PK type to 'string' here (see RDPP-5819).\n\t\tif (pkType.type === 'date') {\n\t\t\tpkType.type = 'string';\n\t\t}\n\n\t\tconst modelSchemaFullEx = JSON.parse(JSON.stringify(modelSchemaEx));\n\t\tmodelSchemaFullEx.id = this.getModelSchemaFullExId(model);\n\t\tmodelSchemaFullEx.properties[pkName] = pkType;\n\t\tmodelSchemaFullEx.required = (modelSchemaFullEx.required || []).concat(pkName);\n\t\tmodelSchemas.push(modelSchemaFullEx);\n\n\t\t// Schema for model fields containing Id (used in endpoint upsert/returns)\n\t\tconst modelSchemaFull = JSON.parse(JSON.stringify(modelSchemaFullEx));\n\t\tmodelSchemaFull.id = this.getModelSchemaFullId(model);\n\t\tmodelSchemaFull.additionalProperties = false;\n\t\tmodelSchemas.push(modelSchemaFull);\n\t}\n\n\treturn modelSchemas;\n};\n\n/**\n * Generates the standardized APIs from all loaded models.\n */\nAPIBuilder.prototype.createAPIsFromModels = function () {\n\tObject.keys(this.models).forEach(function routeModelIterator(name) {\n\t\tvar model = this.models[name];\n\t\tthis.createAPIsFromModel(model);\n\t}.bind(this));\n};\n\n/**\n * Generates the standardized APIs from a particular model.\n */\nAPIBuilder.prototype.createAPIsFromModel = function (model) {\n\tif (model.connector && typeof model.connector === 'string') {\n\t\ttry {\n\t\t\tmodel._connector = model.connector;\n\t\t\tmodel.connector = this.getConnector(model.connector, true);\n\t\t\tmodel.connector.emit('init-model', model);\n\t\t} catch (e) {\n\t\t\tthis.logger.trace(e.stack);\n\t\t\tthrow new Error('Error loading connector: ' + model._connector + ' for model: ' + model.name + '. ' + e.message);\n\t\t}\n\t}\n\tif (model.autogen) {\n\t\tconst modelAPIs = makeAPIsFromModel(model, this.config.apiPrefix);\n\t\tmodelAPIs.forEach(function modelAPIConstructorIterator(API) {\n\t\t\tvar api = new API(this.objConfig, this);\n\t\t\tthis.apis.push(api);\n\t\t}.bind(this));\n\t}\n};\n\nfunction makeAPIsFromModel(model, apiPrefix) {\n\t// if autogen off, don't generate APIs for Model\n\tif (!model.autogen\n\t\t|| (model.connector && model.connector.enabled === false)\n\t\t|| !model.connector) {\n\t\treturn [];\n\t}\n\n\tconst apis = [];\n\tconst { name, shortName, connectorName } = model;\n\n\t// the resource we bind must be escaped, e.g. these chars: ()+\n\tif (apiBuilderConfig.flags.enableModelNameEncoding) {\n\t\tconst hasConnectorSlash = name !== shortName;\n\t\tif (hasConnectorSlash && apiBuilderConfig.flags.enableModelNameEncodingWithConnectorSlash) {\n\t\t\t// Slash is actually ok in paths. We'll keep it for the case when\n\t\t\t// the model name is prefixed with the connector.\n\t\t\t// We know that the Model name is prefixed with the connector if name !== shortName.\n\t\t\t// and we're also flagged we'll use a unencoded / to seperate the encoded names in the\n\t\t\t// API path.\n\t\t\tconst encodedName = utils.encodeNameForURI(shortName);\n\t\t\tconst encodedConnectorName = utils.encodeNameForURI(connectorName);\n\t\t\tmodel.prefix = model.prefix || `${apiPrefix}/${encodedConnectorName}/${encodedName}`;\n\t\t} else {\n\t\t\t// whole name is encoded\n\t\t\tconst encodedName = utils.encodeNameForURI(name);\n\t\t\tmodel.prefix = model.prefix || `${apiPrefix}/${encodedName}`;\n\t\t}\n\t} else {\n\t\t// un-encoded\n\t\tmodel.prefix = model.prefix || `${apiPrefix}/${name.toLowerCase()}`;\n\t}\n\tmodel.singular = model.singular || pluralize(name.toLowerCase(), 1);\n\tmodel.plural = model.plural || pluralize(name.toLowerCase());\n\n\tfor (var key in model) {\n\t\tif (key.slice(-3) === 'API') {\n\t\t\tvar val = model[key],\n\t\t\t\tisAPIDescriptor = _.isFunction(val),\n\t\t\t\tdescribes = key.slice(0, -3),\n\t\t\t\tdescribesUC = describes.substr(0, 1).toUpperCase() + describes.substr(1),\n\t\t\t\tenabled = true;\n\n\t\t\tif (!isAPIDescriptor) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar api = model[key]();\n\t\t\tif (!api) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check to see if the underlying connector has the necessary methods to support this\n\t\t\t// API.\n\t\t\tvar connectorMethods = (api.dependsOnAny || api.dependsOnAll || [ describes ])\n\t\t\t\t.filter(function (depConnectorMethod) {\n\t\t\t\t\treturn !!model.getConnector()[depConnectorMethod];\n\t\t\t\t});\n\t\t\tif (connectorMethods.length < (api.dependsOnAll ? api.dependsOnAll.length : 1)) {\n\t\t\t\tenabled = false;\n\t\t\t\tdelete api.enabled;\n\t\t\t}\n\n\t\t\t// Should we disable based on our action or action groups being disabled?\n\t\t\tif (model.actions.indexOf(describes) === -1\n\t\t\t\t&& (!api.actionGroup || model.actions.indexOf(api.actionGroup) === -1)) {\n\t\t\t\tenabled = false;\n\t\t\t}\n\t\t\tif (model.disabledActions && model.disabledActions.indexOf(describes) >= 0) {\n\t\t\t\tenabled = false;\n\t\t\t\tdelete api.enabled;\n\t\t\t}\n\n\t\t\t// Handle some defaults for the API.\n\t\t\tif (!api.path) {\n\t\t\t\tapi.path = model.prefix;\n\t\t\t} else if (api.path.substr(0, 2) === './') {\n\t\t\t\tapi.path = model.prefix + api.path.substr(1);\n\t\t\t}\n\n\t\t\t_.defaultsDeep(api, {\n\t\t\t\tresponses: {\n\t\t\t\t\t404: {\n\t\t\t\t\t\tdescription: 'No results were found.',\n\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t$ref: '#/definitions/ErrorModel'\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t500: {\n\t\t\t\t\t\tdescription: 'Something went wrong during the request; check out the logs on your server.',\n\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t$ref: '#/definitions/ErrorModel'\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t504: {\n\t\t\t\t\t\tdescription: 'The request took too long to process, and the server timed it out.',\n\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t$ref: '#/definitions/ErrorModel'\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tdescription: 'Response from server',\n\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t$ref: '#/definitions/ResponseModel'\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tapis.push(API.extend(_.defaults(api, {\n\t\t\t\tenabled: enabled,\n\t\t\t\tgenerated: true,\n\t\t\t\tgroup: name,\n\t\t\t\tdescribes: describes,\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparameters: {},\n\t\t\t\tsingular: model.singular,\n\t\t\t\tplural: model.plural,\n\t\t\t\tmodel: name,\n\t\t\t\tpre: _.flatten(_.compact([\n\t\t\t\t\tmodel['pre' + describesUC], model['before' + describesUC],\n\t\t\t\t\tmodel['pre' + (api.method || 'GET')], model['before' + (api.method || 'GET')],\n\t\t\t\t\tmodel.pre, model.before\n\t\t\t\t])),\n\t\t\t\tpost: _.flatten(_.compact([\n\t\t\t\t\tmodel['post' + describesUC], model['after' + describesUC],\n\t\t\t\t\tmodel['post' + (api.method || 'GET')], model['after' + (api.method || 'GET')],\n\t\t\t\t\tmodel.post, model.after\n\t\t\t\t]))\n\t\t\t})));\n\t\t}\n\t}\n\n\treturn apis;\n}\n\n/**\n * Removes an API from the server.\n * @param {String} filename Name of the file of the API to remove.\n * @param {Function} [callback] Callback function passed an Error object (or null if successful).\n */\nAPIBuilder.prototype.removeAPIByFilename\n\t= util.deprecate(function removeAPIByFilename(filename, callback) {\n\t\tvar api = _.filter(this.apis, function (api) {\n\t\t\treturn api.filename === filename;\n\t\t})[0];\n\n\t\tif (api) {\n\t\t\tapi.remove(this, callback);\n\t\t} else {\n\t\t\tcallback && callback(new Error('couldn\\'t find an API at ' + filename));\n\t\t}\n\t}, 'APIBuilder.removeAPIByFilename is deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D022', 'D022');\n\n/**\n * Reloads any changes found in Models, Blocks, Routes or APIs.\n * @param {Function} [callback] Callback to execute after the reload.\n */\nAPIBuilder.prototype.reload = function reload(callback) {\n\tthis.logger.debug('reload called');\n\tif (this.pendingReload) {\n\t\tthis.logger.debug('concurrent reload invocation is ignored');\n\t\tif (callback) {\n\t\t\treturn callback(null, this);\n\t\t}\n\t} else {\n\t\tthis.pendingReload = true;\n\t\tthis.stop(() => {\n\t\t\tglobalAPIBuilder = new APIBuilder(this.initialConfig, this._internal.initialOptions);\n\t\t\tglobalAPIBuilder.reloaded = true;\n\t\t\tglobalAPIBuilder.start((err) => {\n\t\t\t\tthis.pendingReload = false;\n\t\t\t\tif (!err) {\n\t\t\t\t\tthis.logger.debug('reload finished!');\n\t\t\t\t\tthis.emit('reloaded');\n\t\t\t\t}\n\t\t\t\tif (callback) {\n\t\t\t\t\treturn callback(err, globalAPIBuilder);\n\t\t\t\t} else if (err) {\n\t\t\t\t\tthis.emit('error', err);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n};\n\n/**\n * Stops the APIBuilder server instance.\n * @param {Function} [callback] Callback to execute after the server stops.\n */\nAPIBuilder.prototype.stop = function stop(callback) {\n\tthis.shuttingdown = true;\n\n\tif (!this.server) {\n\t\tthis.logger.debug('stop called but server not started');\n\t}\n\n\tvar tasks = [];\n\n\t// stop events\n\ttasks.push(async () => {\n\t\ttry {\n\t\t\t// unbind system events, e.g. \"shutdown\"\n\t\t\tallTasks.systemEvents.unbindEvents.call(this);\n\t\t} catch (ex) {\n\t\t\tthis.logger.error(ex);\n\t\t}\n\t});\n\n\t// stop CredentialManager events\n\ttasks.push(async () => await CredentialManager.stop());\n\n\t// stop triggers\n\ttasks.push(async () => {\n\t\ttry {\n\t\t\tawait allTasks.stopTriggers.call(this);\n\t\t} catch (ex) {\n\t\t\tthis.logger.error(ex);\n\t\t}\n\t});\n\n\t// clear schemas\n\ttasks.push(function (next) {\n\t\tthis.logger.trace('clearing schemas');\n\t\tschemas.clear();\n\t\tnext();\n\t}.bind(this));\n\n\ttasks.push(next => {\n\t\tthis.logger.trace('clearing API cache');\n\t\tthis.apis = [];\n\t\tAPI.clearAPIs();\n\t\tnext();\n\t});\n\n\t// stop middlewares\n\ttasks.push(async () => await allTasks.stopMiddlewares(this));\n\n\t// stop billing manager\n\ttasks.push(async () => await allTasks.stopBilling.call(this));\n\n\ttasks.push(next => {\n\t\t// destroy HTTP agents from @axway/requester\n\t\tdestroyAgents();\n\t\tnext();\n\t});\n\n\tif (this.server && !this.stopped) {\n\t\t// Remove the server from the global list\n\t\t// Unbinds any event listeners if this is the last server\n\t\tthis.logger.trace('removing globals');\n\t\tglobals.removeServer(this);\n\n\t\t// REFACTOR: I think `stopped` should really be last\n\t\tthis.stopped = true;\n\t\tthis.emit('stopping');\n\n\t\t// first stop the server so we don't serve request\n\t\ttasks.push(function serverCloseTask(next) {\n\t\t\ttry {\n\t\t\t\t// ignore any errors on shutdown\n\t\t\t\tthis.logger.trace('destroying server');\n\t\t\t\tthis.server.destroy(next);\n\t\t\t} catch (err) {\n\t\t\t\tthis.logger.error(err);\n\t\t\t\tnext();\n\t\t\t}\n\t\t}.bind(this));\n\n\t\t// stop the SSL server if we have one\n\t\tif (this.sslServer) {\n\t\t\ttasks.push(function serverCloseTask(next) {\n\t\t\t\ttry {\n\t\t\t\t\t// ignore any errors on shutdown\n\t\t\t\t\tthis.logger.trace('destroying ssl server');\n\t\t\t\t\tthis.sslServer.destroy(next);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.logger.error(err);\n\t\t\t\t\tnext();\n\t\t\t\t}\n\t\t\t}.bind(this));\n\t\t}\n\t}\n\n\t// stop the admin UI if attached, and that the admin UI is at least 4.8.0,\n\t// which adds the stop method.\n\tif (this.admin && this.admin.stop) {\n\t\ttasks.push((next) => {\n\t\t\tthis.logger.trace('stopping admin');\n\t\t\tthis.admin.stop(next);\n\t\t});\n\t}\n\n\t// Disconnect all dataconnectors if provided a disconnect method. Delete\n\t// the models associated with the connector (generated and fs) so that we\n\t// don't run into duplicate errors when loadComponents tries to load fs\n\t// models. Delete the _createdModelsFromSchema flag so api-builder-orm knows\n\t// to re-grab models from schema (generated). Delete connector.started so\n\t// startDataconnector() will kick off\n\ttasks.push(allTasks.stopConnectors.bind(this));\n\n\ttasks.push(function cleanupWatchers(next) {\n\t\tthis.logger.trace('removing renderers');\n\t\t// This clean up method is registered only if renderers has been\n\t\t// configured in the first place. So we might skip registering if\n\t\t// this.configWeb.needRenderers is false. But to avoid edge cases where\n\t\t// the needRenders is out of sync we always register this callback\n\t\t// function but only call cleanuWatcher in case hbs middleware has been\n\t\t// registered.\n\t\tconst middleware = this.getMiddleware();\n\t\tif (middleware) {\n\t\t\tconst handlebars = middleware.getRendererEngine('hbs');\n\t\t\t// stop the handlerbars watcher if running\n\t\t\tif (handlebars) {\n\t\t\t\thandlebars.cleanupWatchers();\n\t\t\t}\n\t\t}\n\t\tnext();\n\t}.bind(this));\n\n\t// Delete all plugins from require cache so they can be loaded\n\t// fresh when we restart\n\ttasks.push(next => {\n\t\tthis.logger.trace('removing plugins');\n\t\tfor (const plugin in this.apibuilderPlugins) {\n\t\t\tdelete require.cache[plugin];\n\t\t}\n\t\tnext();\n\t});\n\n\t// now fire our lifecycle event\n\tasync.series(tasks, function asyncCallback() {\n\t\tthis.emit('stopped');\n\t\tthis.logger.info('Server stopped');\n\t\tloadedModelDirs = [];\n\t\tcallback && callback();\n\t}.bind(this));\n\n\ttry {\n\t\tthis.logger.trace('removing flow-nodes');\n\t\t// Unregister node handlers.  This is not done as a task because it is\n\t\t// possible to be partially started (and fail).  These need to be done\n\t\t// reglardless of start state.\n\t\tthis.registeredNodes.forEach(function (uri) {\n\t\t\tthis.flowManager.unregisterNode(uri);\n\t\t}.bind(this));\n\t\tthis.registeredNodes = [];\n\n\t\tunregisterFlowCoreNodeHandlers(this.flowManager);\n\t\tunregisterAPIBuilderNodeHandlers(this);\n\t\tunregisterAuthorizationNodeHandlers(this.flowManager);\n\t} catch (e) {\n\t\t// ignore error\n\t}\n};\n\n/**\n * @method createLogger\n * Creates a logger instance.\n * @param {Object} config\n * @param {Object} opts Additional initialization options.\n * @returns {APIBuilder.Logger}\n */\n/**\n * @method createLogger\n * @static\n * Creates a logger instance.\n * @param {Object} config - Logger config options.\n * @param {Object} opts - Deprecated: Additional initialization options.\n * @returns {APIBuilder.Logger}\n */\nAPIBuilder.prototype.createLogger\n\t= APIBuilder.createLogger = Logger.createLogger;\n\n// create a continuation monkey patch in the case the server hasn't yet loaded\n// and we've created a Model\nfunction createModelClassContinuationPatch(Model) {\n\tif (globalAPIBuilder && !globalAPIBuilder.loaded) {\n\t\t// monkey patch any methods that must have a valid connector that is running before we\n\t\t// can call it\n\t\tvar methods = [\n\t\t\t'create', 'delete', 'replace', 'save', 'update', 'delete', 'deleteAll', 'find', 'findAll', 'findByID',\n\t\t\t'findById', 'findOne', 'fetch', 'query', 'remove', 'removeAll'\n\t\t];\n\t\tmethods.forEach(function (fnName) {\n\t\t\tvar ModelFn = Model[fnName];\n\t\t\tif (ModelFn) {\n\t\t\t\tModel[fnName] = createModelMethodMonkeyPatch(Model, ModelFn, fnName);\n\t\t\t}\n\t\t});\n\n\t\t// unwrap the methods after the apibuilder loads\n\t\tfunction builderLoader() {\n\t\t\tvar methods = [\n\t\t\t\t'create', 'delete', 'replace', 'save', 'update', 'delete', 'deleteAll', 'find', 'findAll', 'findByID',\n\t\t\t\t'findById', 'findOne', 'fetch', 'query', 'remove', 'removeAll'\n\t\t\t];\n\t\t\tmethods.forEach(function (fnName) {\n\t\t\t\tif (Model[fnName] && Model[fnName].originalFunction) {\n\t\t\t\t\tModel[fnName] = Model[fnName].originalFunction;\n\t\t\t\t}\n\t\t\t});\n\t\t\tglobalAPIBuilder.removeListener('loaded', builderLoader);\n\t\t}\n\t\tglobalAPIBuilder.on('loaded', builderLoader);\n\t}\n}\n\n// create a function wrapper that will watch for the server to finish loading\n// (which will have started the connectors) before we actually continue with the\n// function. the method (fn) being passed in must be async for this to work\nfunction createModelMethodMonkeyPatch(ModelClass, fn, name) {\n\t// if we're not yet loaded, we can't call methods against the\n\t// ModelClass. in which case we're going to wait until we're loaded\n\t// and then once loaded, we'll continue\n\tfunction modelMethodMonkeyPatched() {\n\t\tvar args = arguments;\n\t\tfunction builderLoader() {\n\t\t\t// make sure we resolve the connector to the real connector instance\n\t\t\tif (typeof ModelClass.connector === 'string') {\n\t\t\t\tModelClass.connector = APIBuilder.getConnector(ModelClass.connector);\n\t\t\t}\n\t\t\tglobalAPIBuilder.removeListener('loaded', builderLoader);\n\t\t\t// re-patch it back to the original so subsequent doesn't come back through this block\n\t\t\t// anymore\n\t\t\tModelClass[name] = fn;\n\t\t\t// go ahead invoke\n\t\t\treturn fn.apply(ModelClass, args);\n\t\t}\n\t\t// wait for loaded to fire\n\t\tif (globalAPIBuilder.loaded) {\n\t\t\tbuilderLoader();\n\t\t} else {\n\t\t\tglobalAPIBuilder.on('loaded', builderLoader);\n\t\t}\n\t}\n\n\tmodelMethodMonkeyPatched.originalFunction = fn;\n\n\treturn modelMethodMonkeyPatched;\n}\n\n/*\n * monkey patch Model.extend to make sure that we set the instance of the\n * connector before returning\n */\nconst ModelExtend = APIBuilder.Model.extend;\nconst ModelReduce = APIBuilder.Model.reduce;\n\n// interface is now .extend(originalModelName, name, definition)\nAPIBuilder.Model.extend = createModelMonkeyPatch(ModelExtend, 'extend');\nAPIBuilder.Model.reduce = createModelMonkeyPatch(ModelReduce, 'reduce');\n\nfunction createModelMonkeyPatch(ModelClass, method) {\n\tfunction createModel() {\n\t\t// if we're extending a named model, resolve it first\n\t\tvar model;\n\t\tif (arguments.length === 3) {\n\t\t\t// if we're in the middle of loading models on startup, we need to deal\n\t\t\t// with the case we are extending a model that has not been loaded yet,\n\t\t\t// in which case we want to record the dependency and then load later\n\t\t\tif (globalAPIBuilder && globalAPIBuilder.loadingModels) {\n\t\t\t\tvar args = arguments,\n\t\t\t\t\tself = this;\n\t\t\t\tfunction fn() {\n\t\t\t\t\tglobalAPIBuilder.removeListener('loadedModels', fn);\n\t\t\t\t\tcreateModel.apply(self, args);\n\t\t\t\t}\n\t\t\t\tglobalAPIBuilder.on('loadedModels', fn);\n\t\t\t\treturn { deferred: true };\n\t\t\t}\n\t\t\t// tricky. we need to check to see if the incoming connector referenced by\n\t\t\t// the new model is referencing a connector that is disabled and if so, just\n\t\t\t// return null so that the model load just fails silently (which is OK)\n\t\t\tif (arguments[2].connector) {\n\t\t\t\tvar connector = typeof arguments[2].connector === 'string' ? APIBuilder.getConnector(arguments[2].connector) : arguments[2].connector;\n\t\t\t\tif (connector && !connector.enabled) {\n\t\t\t\t\tvar connectorName = connector.name || arguments[2].connector;\n\t\t\t\t\tglobalAPIBuilder && globalAPIBuilder.logger.debug('connector (' + connectorName + ') disabled, skipping model', arguments[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar extendModel = typeof arguments[0] === 'string' ? APIBuilder.getModel(arguments[0], true) : arguments[0],\n\t\t\t\tname = arguments[1],\n\t\t\t\tdef = arguments[2];\n\t\t\tmodel = extendModel[method](name, def);\n\t\t\t// we need to set in case it wasn't set. this happens in cases where we loaded async\n\t\t\tmodel.name = name;\n\t\t\tmodel._parent = extendModel;\n\t\t\tmodel._supermodel = extendModel.name;\n\t\t\tif (!model.connector) {\n\t\t\t\tmodel.connector = extendModel.connector;\n\t\t\t}\n\t\t\t// if the extended model is autogen (like a built-in connector model) but we didn't\n\t\t\t// specify one in our own definition, assume we want to autogen it\n\t\t\tif (!extendModel.autogen && def.autogen === undefined) {\n\t\t\t\tmodel.autogen = true;\n\t\t\t}\n\t\t\t// make sure we record it. this happens in the case we async load and we didn't put it\n\t\t\t// in because of that...\n\t\t\tif (!isModelDuplicate(model.name)) {\n\t\t\t\tglobalAPIBuilder.models[model.name] = model;\n\t\t\t\t// FIXME: This sucks that it's not going to get all the info that\n\t\t\t\t// loadModel adds to a Model. Not going to refactor now\n\t\t\t\t// but at least register it as used.\n\t\t\t\tglobalAPIBuilder._internal.pluginUse.registerModel(model);\n\t\t\t}\n\t\t} else {\n\t\t\t// else we're creating a simple new model\n\t\t\tmodel = ModelClass.apply(APIBuilder.Model, arguments);\n\t\t\tisModelDuplicate(model.name);\n\t\t}\n\n\t\tif (model.connector && typeof model.connector === 'string') {\n\t\t\t// if we're running and we have a string, resolve it\n\t\t\tif (globalAPIBuilder && globalAPIBuilder.loaded) {\n\t\t\t\tmodel._connector = model.connector;\n\t\t\t\tmodel.connector = APIBuilder.getConnector(model.connector, true);\n\t\t\t\tmodel.connector.emit('init-model', model);\n\t\t\t} else {\n\t\t\t\t// we need to monkey patch to create continuation\n\t\t\t\tcreateModelClassContinuationPatch(model);\n\t\t\t}\n\t\t} else if (model.connector) {\n\t\t\tmodel.connector.emit('init-model', model);\n\t\t}\n\n\t\treturn model;\n\t}\n\treturn createModel;\n}\n\n/**\n * Creates a model class.\n * @static\n * @param {String} name Name of the new Model.\n * @param {APIBuilderModelDefinition} definition Model definition object.\n * @returns {APIBuilder.Model}\n */\nAPIBuilder.createModel = function _createModel() {\n\treturn globalAPIBuilder.createModel.apply(globalAPIBuilder, arguments);\n};\n\n/**\n * @method createModel\n * @alias #static-method-createModel\n */\nAPIBuilder.prototype.createModel = APIBuilder.Model.extend;\n\n/**\n * Adds a model class(es) on this instance.\n * @param {APIBuilder.Model/Array<APIBuilder.Model>} model Model class(es) to add.\n */\nAPIBuilder.prototype.addModel = function addModel() {\n\tthis.logger.trace('adding model', ...arguments);\n\tfor (var c = 0; c < arguments.length; c++) {\n\t\tvar ModelClass = arguments[c];\n\t\tif (!isModelDuplicate(ModelClass.name)) {\n\t\t\tthis.models[ModelClass.name] = ModelClass;\n\t\t}\n\t\t// Has the server already started?\n\t\tif (this.server) {\n\t\t\tvar startAt = this.apis.length;\n\t\t\tthis.createAPIsFromModel(ModelClass);\n\t\t\tfor (var i = startAt; i < this.apis.length; i++) {\n\t\t\t\tthis.apis[i].bind(this.app);\n\t\t\t}\n\t\t}\n\t}\n};\n\n/**\n * Gets a model by name.\n * @static\n * @param {String} name Name of the model to retrieve.\n * @param {Boolean} [failIfMissing] Set to `true` to throw an error if the model could not be found.\n * @returns {APIBuilder.Model}\n * @throws Error\n */\nAPIBuilder.getModel = function _getModel() {\n\treturn globalAPIBuilder && globalAPIBuilder.getModel.apply(globalAPIBuilder, arguments);\n};\n\n/**\n * @alias #static-method-getModel\n */\nAPIBuilder.prototype.getModel = function getModel(name, failIfMissing) {\n\tif (!this.models) {\n\t\t// this is only initialized that the end of the APIBuilder constructor, so if an\n\t\t// error/exception is thrown early (e.g. in validateConfig), then this will not be set.\n\t\treturn null;\n\t}\n\tvar result = this.models[name];\n\tif (!result) {\n\t\tvar tokens = name.split('/');\n\t\tif (tokens.length > 1) {\n\t\t\tvar connectorName = tokens[0],\n\t\t\t\tmodelName = tokens[1],\n\t\t\t\tconnector = globalConnectors[connectorName];\n\t\t\tif (!connector && failIfMissing) {\n\t\t\t\tthrow new Error('Couldn\\'t find connector named: ' + connectorName);\n\t\t\t}\n\t\t\tresult = connector\n\t\t\t\t&& connector.models\n\t\t\t\t&& (\n\t\t\t\t\tconnector.models[modelName]\n\t\t\t\t\t|| connector.models[connectorName + '/' + modelName]\n\t\t\t\t\t|| connector.models[connector.name + '/' + modelName]\n\t\t\t\t);\n\t\t}\n\t}\n\tif (!result && failIfMissing) {\n\t\tthrow new Error('Couldn\\'t find model named: ' + name);\n\t}\n\n\t// If the model is composite, then ensure that any models of which it is\n\t// comprised, exist.  If not, this method will throw when the composite\n\t// model is not found in APIBuilder.prototype.getModel above.\n\tif (result && result.connector.name === 'composite') {\n\t\tfor (let fieldName in result.fields) {\n\t\t\tif (result.fields.hasOwnProperty(fieldName)) {\n\t\t\t\tconst field = result.fields[fieldName];\n\t\t\t\tconst throwIfNotFound = true;\n\t\t\t\tthis.getModel(field.model, throwIfNotFound);\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n};\n\n/**\n * Gets an array of APIs available to the instance.\n * @returns {Array<APIBuilder.API>}\n */\nAPIBuilder.prototype.getAPIs = function getAPIs() {\n\treturn this.apis;\n};\n\n/**\n * Returns an API for the given path and optional method in the case where more than one method.\n * may be invoked on a path. If you defined a nickname when creating the API instance, you may pass\n * the nickname to the function rather than the path and method.\n * @param {String} path Path of the API (or its nickname).\n * @param {String} [method] HTTP verb.\n * @returns {APIBuilder.API}\n */\nAPIBuilder.prototype.getAPI = function getAPI(path, method) {\n\tvar pathAsRoute = path;\n\tif (path.substring(0, 1) !== '/') {\n\t\tpathAsRoute = '/' + path;\n\t}\n\tfor (var c = 0; c < this.apis.length; c++) {\n\t\tif (\n\t\t\t(this.apis[c].path === pathAsRoute || this.apis[c].nickname === path)\n\t\t\t&& (\n\t\t\t\t!method\n\t\t\t\t|| (this.apis[c].method.toUpperCase() === method.toUpperCase())\n\t\t\t)\n\t\t) {\n\t\t\treturn this.apis[c];\n\t\t}\n\t}\n};\n\n/**\n * Adds an API on this instance.\n * @param {APIBuilder.API} api API to add.\n */\nAPIBuilder.prototype.addAPI = function addAPI(APIConstructor) {\n\tif (_.isFunction(APIConstructor)) {\n\t\tvar api = new APIConstructor(this.config, this);\n\t\tthis.apis.push(api);\n\t} else {\n\t\tthis.apis.push(APIConstructor);\n\t}\n};\n\n/**\n * Gets all models availabe to the instance.\n * @returns {Array<APIBuilder.Model>}\n */\nAPIBuilder.prototype.getModels = function getModels() {\n\treturn this.models;\n};\n\n/**\n * Gets a block by name.\n * @param {String} name Name of the block to retrieve.\n * @param {Boolean} [failIfMissing] Set to `true` to throw an error if the block could not be found.\n * @returns {APIBuilder.Block}\n * @throws Error\n */\nAPIBuilder.prototype.getBlock = function getBlock(name, failIfMissing) {\n\tvar result = this.blocks[name];\n\tif (!result && failIfMissing) {\n\t\tthrow new Error('Couldn\\'t find block named: ' + name);\n\t}\n\treturn result;\n};\n\n/**\n * Gets all the flow definitions availabe to the instance.\n * @returns {Object}\n */\nAPIBuilder.prototype.getFlows = function getFlows() {\n\treturn this.flowManager.getFlows();\n};\n\n/**\n * Gets the flow definition by id.\n * @param {String} flowId The id of the flow to retrieve.\n * @returns {Object}\n */\nAPIBuilder.prototype.getFlow = function getFlow(flowId) {\n\treturn this.flowManager.getFlow(flowId);\n};\n\n/**\n * gets the schema for a specific node handlers\n * @param  {string} type - type/name of the schema\n * @return {Object}      - the schema for the handler\n */\nAPIBuilder.prototype.getRegisteredNodeSpec = function getRegisteredNodeSpec(type) {\n\treturn this.flowManager.getRegisteredNodeSpec(type);\n};\n\n/**\n * gets all the schemas for the node handlers\n * @return {Object} - the schemas for the handlers\n */\nAPIBuilder.prototype.getRegisteredNodeSpecs = function getRegisteredNodeSpecs() {\n\treturn this.flowManager.getRegisteredNodeSpecs();\n};\n\n/**\n * Gets an endpoint by path\n * @param  {String} endpoint The endpoint to get. ie '/greet'\n * @return {Object} or undefined\n */\nAPIBuilder.prototype.getEndpoint = function (endpoint) {\n\treturn this.endpoints[endpoint].endpoint;\n};\n\n/**\n * Gets all loaded endpoints\n * @return {Object}\n */\nAPIBuilder.prototype.getEndpoints = function () {\n\treturn this.endpoints || {};\n};\n\n/**\n * Gets a route by name.\n * @param {String} name Name of the route to retrieve.\n * @param {Boolean} [failIfMissing] Set to `true` to throw an error if the route could not be found.\n * @returns {APIBuilder.Router}\n * @throws Error\n */\nAPIBuilder.prototype.getRoute = function getBlock(name, failIfMissing) {\n\tvar result = _.find(this.routes, { name: name });\n\tif (!result && failIfMissing) {\n\t\tthrow new Error('Couldn\\'t find route named: ' + name);\n\t}\n\treturn result;\n};\n\n/**\n * Adds the block(s) on this instance.\n * @param {APIBuilder.Block/Array<APIBuilder.Block>} block Block(s) to add.\n */\nAPIBuilder.prototype.addBlock = function () {\n\tfor (var c = 0; c < arguments.length; c++) {\n\t\tvar Block = arguments[c];\n\t\tthis.blocks[Block.name] = Block;\n\t}\n};\n\n/**\n * Gets all blocks.\n * @returns Array<APIBuilder.Block>\n */\nAPIBuilder.prototype.getBlocks = function getBlocks() {\n\treturn this.blocks;\n};\n\n/**\n * Gets a codeblock by name.\n * @param {String} name Name of the codeblock to retrieve.\n * @param {Boolean} [failIfMissing] Set to `true` to throw an error if the codeblock could\n * @not be found.\n * @returns {APIBuilder.Codeblock}\n * @throws Error\n */\nAPIBuilder.prototype.getCodeblock = function getCodeblock(name, failIfMissing) {\n\tvar result = this.codeblocks[name];\n\tif (!result && failIfMissing) {\n\t\tthrow new Error('Couldn\\'t find codeblock named: ' + name);\n\t}\n\treturn result;\n};\n\n/**\n * Gets all codeblocks.\n * @returns Array<APIBuilder.Codeblock>\n */\nAPIBuilder.prototype.getCodeblocks = function getCodeblocks() {\n\treturn this.codeblocks;\n};\n\n/**\n * Returns a registered connector by name.\n * @static\n * @param {String} name Name of the connector to retrieve.\n * @param {Boolean} [failIfMissing] Set to `true` to throw an error if the connector could\n * @not be found.\n * @throws Error\n */\nAPIBuilder.getConnector = function _getConnector() {\n\tif (!globalAPIBuilder) {\n\t\tthrow new Error('an APIBuilder instance has not yet been created');\n\t}\n\treturn globalAPIBuilder.getConnector.apply(globalAPIBuilder, arguments);\n};\n\n/**\n * Gets a connector by name.\n * @param {String} name Name of the connector to retrieve.\n * @param {Boolean} [failIfMissing] Set to `true` to throw an error if the connector could\n * @not be found.\n * @throws Error\n */\nAPIBuilder.prototype.getConnector = function getConnector(name, failIfMissing) {\n\tif (!name) {\n\t\tthrow new Error('missing name');\n\t}\n\n\tlet connector = globalConnectors[name];\n\tif (connector) {\n\t\treturn connector;\n\t}\n\n\t// Find connector config\n\tlet pluginName;\n\tlet config = this.config;\n\n\tif (config.connectors && name in config.connectors) {\n\t\tconfig = config.connectors[name];\n\t\tpluginName = config.connector;\n\t}\n\n\tif (!pluginName) {\n\t\tthrow new Error(`Dataconnector ${name} is not configured correctly.`);\n\t}\n\n\tconst plugin = this.apibuilderPlugins[pluginName];\n\tif (plugin && plugin.components.dataconnector) {\n\t\t// Instantiate the connector\n\t\ttry {\n\t\t\tconst ConnectorFactory = plugin.components.dataconnector;\n\t\t\tif (ConnectorFactory) {\n\t\t\t\t// re-entrant flag in case a Connector inadvertently calls\n\t\t\t\t// APIBuilder.loadModelsForConnector during this ConnectorFactory.create\n\t\t\t\t// which will cause us to re-enter this method into an infinite recursion\n\t\t\t\t// problem ... so we note and then do it again later if we have this happen\n\t\t\t\tinGetConnector = true;\n\t\t\t\tconst Connector = ConnectorFactory.create(APIBuilder, this);\n\t\t\t\tinGetConnector = false;\n\t\t\t\tconnector = new Connector(config || {});\n\t\t\t\tif (connector) {\n\t\t\t\t\tconnector.filename = plugin.path;\n\t\t\t\t\tconnector.name = name;\n\t\t\t\t\t// TODO: we need to register the connector for lookup later\n\t\t\t\t\t// (i.e. add an alias ref) to the plugin so it can look up\n\t\t\t\t\t// usage.\n\t\t\t\t\tthis.registerConnector(connector);\n\t\t\t\t\t// if we have a post create lifecycle callback, call it this will allow\n\t\t\t\t\t// connectors to do things like call APIBuilder.loadModelsForConnector\n\t\t\t\t\t// after the connector is instantiated but before it is returned. If we\n\t\t\t\t\t// don't do this we will get into an infinite loop where things done in the\n\t\t\t\t\t// constructor (like load models) that require the connector will attempt\n\t\t\t\t\t// to re-instantiate the connector again (since it's not done registering)\n\t\t\t\t\tif (pendingModels) {\n\t\t\t\t\t\tconnector.models = APIBuilder.loadModelsForConnector(\n\t\t\t\t\t\t\tconnector.name, pendingModels.module, pendingModels.dir);\n\t\t\t\t\t\tpendingModels = null;\n\t\t\t\t\t}\n\t\t\t\t\tif (connector.postCreate) {\n\t\t\t\t\t\tconnector.postCreate.call(connector);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.logger.error('Error loading connector: ' + name, e);\n\t\t\tthrow e;\n\t\t}\n\t}\n\tif (!connector && failIfMissing) {\n\t\tthrow new Error('Couldn\\'t find connector named: ' + name);\n\t}\n\n\treturn connector;\n};\n\n/**\n * @method getConnectors\n * Gets a list of registered connectors.\n * @returns {Array}\n */\nAPIBuilder.prototype.getConnectors = function getConnectors() {\n\treturn globalConnectors;\n};\n\n/**\n * @method registerConnector\n * @static\n * Registers a connector.\n * @param {APIBuilder.Connector} connector Connector to register.\n */\n/**\n * @method registerConnector\n * @alias #static-method-registerConnector\n */\nAPIBuilder.registerConnector\n\t= APIBuilder.prototype.registerConnector = function registerConnector(connector) {\n\t\tglobalConnectors[connector.name] = connector;\n\n\t\t// attach a get model convenience function on the connector\n\t\tif (!connector.getModel) {\n\t\t\tconnector.getModel = function (name) {\n\t\t\t\treturn this.models && (this.models[name] || this.models[this.name + '/' + name]);\n\t\t\t};\n\t\t}\n\n\t\tif (connector.models) {\n\t\t\tObject.keys(connector.models).forEach(function keyIterator(name) {\n\t\t\t\tvar model = connector.models[name];\n\t\t\t\t// map to the real connector instance\n\t\t\t\tmodel.connector = connector;\n\t\t\t});\n\t\t}\n\t};\n\nfunction loadModels(models, dir, connectorName) {\n\tif (loadedModelDirs.indexOf(dir) >= 0) {\n\t\treturn;\n\t}\n\tloadedModelDirs.push(dir);\n\tfs.readdirSync(dir).forEach(function modelResolver(name) {\n\t\tvar p = path.join(dir, name);\n\t\tif (fs.statSync(p).isDirectory()) {\n\t\t\tloadModels(models, p, connectorName);\n\t\t} else if (path.extname(p) === '.js' && path.basename(p).charAt(0) !== '_') {\n\t\t\t// only do .js files that don't start with _\n\t\t\tvar model = paths.requireComponent(p);\n\t\t\tif (model && !(model.name in models)) {\n\t\t\t\tif (model.fields && Object.keys(model.fields).length) {\n\t\t\t\t\tmodels[model.name] = model;\n\t\t\t\t\t// register that the connector is used by this model\n\t\t\t\t\tglobalAPIBuilder && (model.connector = APIBuilder.getConnector(connectorName));\n\t\t\t\t\tmodel.filename = p;\n\t\t\t\t\tglobalAPIBuilder && globalAPIBuilder.addModel(model);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error('Model: ' + model.name + ' already exists in connector: ' + connectorName);\n\t\t\t}\n\t\t}\n\t});\n}\n\n/**\n * Removes a model from this instance.\n * @param {APIBuilder.Model} model Model to remove.\n */\nAPIBuilder.prototype.removeModel = util.deprecate(function removeModel(model) {\n\tdelete this.models[model.name];\n}, 'APIBuilder.removeModel is deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D018', 'D018');\n\n/**\n * Removes a connector.\n * @param {APIBuilder.Connector} connector Connector to remove.\n */\nAPIBuilder.prototype.removeConnector = util.deprecate(function removeConnector(connector) {\n\tdelete this.connectors[connector.name];\n}, 'APIBuilder.removeConnector is deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D019', 'D019');\n\n/**\n * Removes a block.\n * @param {APIBuilder.Block} block Block to remove.\n */\nAPIBuilder.prototype.removeBlock = util.deprecate(function removeBlock(block) {\n\tdelete this.blocks[block.name];\n}, 'APIBuilder.removeBlock is deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D020', 'D020');\n\n/**\n * Removes an API.\n * @param {APIBuilder.API} api API to remove.\n */\nAPIBuilder.prototype.removeAPI = util.deprecate(function removeAPI(api) {\n\tfor (var c = 0; c < this.apis.length; c++) {\n\t\tvar a = this.apis[c];\n\t\t// eslint-disable-next-line security/detect-possible-timing-attacks\n\t\tif (a === api) {\n\t\t\tthis.apis.splice(c, 1);\n\t\t\tbreak;\n\t\t}\n\t}\n\tapi.remove(this);\n}, 'APIBuilder.removeAPI is deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D021', 'D021');\n\n/**\n * Removes a route.\n * @param {APIBuilder.Router} route Route to remove.\n */\nAPIBuilder.prototype.removeRoute = util.deprecate(function removeRoute(route) {\n\tif (route) {\n\t\tfor (var i = 0; i < this.routes.length; i++) {\n\t\t\tvar currentRoute = this.routes[i];\n\t\t\tif (currentRoute === route) {\n\t\t\t\tthis.routes.splice(i, 1);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\troute.remove(this);\n\t}\n}, 'APIBuilder.removeRoute is deprecated. See: https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D023', 'D023');\n\n/**\n * returns an APIBuilder toJSON description\n */\nAPIBuilder.prototype.toJSON = function () {\n\treturn '[object APIBuilder]';\n};\n\n// We leave that in always to work with older node versions\n// and to prevent a breaking change when working with newers\nAPIBuilder.prototype.inspect = () => '[object APIBuilder]';\nif (inspect) {\n\t// After Node 10.12 inspect should be used as shared symbol\n\tAPIBuilder.prototype[inspect] = () => '[object APIBuilder]';\n}\n\n/**\n * Dynamically loads the models into the server if the connector updates them dynamically\n * (i.e. after connect has run and started);\n */\nAPIBuilder.prototype.registerModelsForConnector\n\t= function registerModelsForConnector(connector, models) {\n\t\tif (!models || !_.isObject(models)) {\n\t\t\tthrow new Error('Invalid argument passed to registerModelsForConnector: connector/' + connector.name + '; models must be an object.');\n\t\t}\n\n\t\t// Remove models that have no fields as they are not usable.\n\t\tmodels = Object.keys(models).reduce(function (col, name) {\n\t\t\tif (models[name].fields && Object.keys(models[name].fields).length) {\n\t\t\t\tcol[name] = models[name];\n\t\t\t}\n\t\t\treturn col;\n\t\t}, {});\n\n\t\tObject.keys(models).forEach(function (name) {\n\t\t\tvar Model = models[name];\n\t\t\tif (Model.visible || Model.visible === undefined) {\n\t\t\t\tthis.models[name] = Model;\n\t\t\t}\n\t\t}.bind(this));\n\t};\n\n/**\n * Called by a connector to attempt to load any connector bundled models.\n * @param {String} connectorName Name of the connector.\n * @param {Object} module Connector module instance.\n * @param {String} dir Directory of the connector's models. Default is the\n * @connector's models folder.\n */\nAPIBuilder.loadModelsForConnector = function loadModelsForConnector(connectorName, module, dir) {\n\tif (inGetConnector) {\n\t\t// handle re-entrant issue with ConnectorFactory that calls this during\n\t\t// instantiation if we're still loading. will cause us to do this after its done\n\t\tpendingModels = { module: module, dir: dir };\n\t\treturn;\n\t}\n\tvar modelsDir = path.resolve(dir || path.join(path.dirname(path.dirname(module.filename)), 'models'));\n\n\t// attempt to load any models packaged with the connector\n\tif (fs.existsSync(modelsDir)) {\n\t\tvar models = {};\n\t\tloadModels(models, modelsDir, connectorName);\n\t\treturn models;\n\t}\n};\n\n// map helper functions\nAPIBuilder.pluralize = util.deprecate(function doPluralize(name) {\n\treturn pluralize(name);\n}, 'APIBuilder.pluralize is deprecated. See https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D031', 'D031');\n\nAPIBuilder.singularize = util.deprecate(function doSingularize(name) {\n\treturn pluralize(name, 1);\n}, 'APIBuilder.singularize is deprecated. See https://docs.axway.com/bundle/api-builder/page/docs/deprecations/index.html#D032', 'D032');\n\nfunction setupSecurityHeaders(server) {\n\tserver.use(xssfilter());\n\tserver.use(frameguard({ action: 'deny' }));\n\tserver.use(nocache());\n\tserver.use(nosniff());\n}\n\nfunction setupStaticPublicMiddleware(server, appdir) {\n\tserver.use(express.static(path.join(appdir, 'web', 'public')));\n}\n\nconst adminExp = new RegExp(/^\\/(console|adminapi)(\\/.*)?$/);\nfunction isRuntimeRequest(req) {\n\treturn !adminExp.test(req.originalUrl);\n}\n\nfunction setupAuthenticationStrategy(apiBuilder) {\n\tapiBuilder.authStrategy = new Authentication(apiBuilder);\n\tapiBuilder.accessControlMiddleware = getAccessControlMiddleware({\n\t\tlogger: apiBuilder.logger,\n\t\tconfig: apiBuilder.config,\n\t\tauthStrategy: apiBuilder.authStrategy,\n\t\tisCORSReq: apiBuilder.corsAPI.isCORSReq,\n\t\tisCORSPreflight: apiBuilder.corsAPI.isPreflight,\n\t\tcaseSensitive: () => {\n\t\t\t// this is a function to allow this to be set by the application\n\t\t\treturn apiBuilder.app.get('case sensitive routing') || false;\n\t\t}\n\t});\n}\n\n/**\n * Returns the request information. If redaction is enabled, the request info\n * has some of its sensitive parts redacted. The redacted sections include:\n * authorization and apikey header values.\n *\n * If the redaction is disabled the undredacted request information is returned.\n *\n * @param {Object} req - The request.\n * @param {Boolean} enableRedaction - Toggles on/off the redaction of the req's\n *   sensitive header information.\n *\n * @returns The original request info in development or the redacted version in\n * \tproduction.\n */\nfunction getRequestInfo(req, enableRedaction) {\n\tlet headers = req.headers;\n\tif (enableRedaction) {\n\t\tconst redactedString = '**********';\n\n\t\t// Makes a copy of the req.headers so we don't mutate the original req.\n\t\theaders = {\n\t\t\t...req.headers\n\t\t};\n\n\t\t// These are the exact keys we use for these headers. We don't have to\n\t\t// manually check for different types of cases.\n\t\tconst { authorization, apikey } = headers;\n\n\t\t// Replace the sensitive info with a redacted string.\n\t\tif (authorization) {\n\t\t\theaders.authorization = redactedString;\n\t\t}\n\t\tif (apikey) {\n\t\t\theaders.apikey = redactedString;\n\t\t}\n\t}\n\n\treturn {\n\t\tmethod: req.method,\n\t\turl: req.url,\n\t\theaders,\n\t\tremoteAddress: req.socket.remoteAddress,\n\t\tremotePort: req.socket.remotePort\n\t};\n}\n\nfunction getRequestMiddleware(enableRedaction) {\n\treturn function requestMiddleware(req, resp, next) {\n\t\t// handle serialization to the log so that we only dump a subset of the object\n\t\treq.inspect = function () {\n\t\t\treturn '[object Request]';\n\t\t};\n\t\treq.toJSON = function () {\n\t\t\t// The normal toJSON does not have the redaction of senstive info ON.\n\t\t\treturn getRequestInfo(req, false);\n\t\t};\n\n\t\tresp.inspect = function () {\n\t\t\treturn '[object Response]';\n\t\t};\n\t\tresp.toJSON = function () {\n\t\t\t// express creates a circular reference to req.res and res.req.\n\t\t\treturn {\n\t\t\t\tstatusCode: resp.statusCode,\n\t\t\t\theaders: resp.getHeaders()\n\t\t\t};\n\t\t};\n\t\t// Log admin ui and api requests at trace and everything else at info\n\t\tconst level = isRuntimeRequest(req) ? 'info' : 'trace';\n\n\t\tif (req.logger.willLogAt(level.toUpperCase())) {\n\t\t\tconst requestInfo = getRequestInfo(req, enableRedaction);\n\t\t\t// Its always been this way, but this can fail even though the chances\n\t\t\t// are slim. If it does fail it is questionable if we should fail the\n\t\t\t// whole middleware because we failed to log.\n\t\t\treq.logger[level]('Request', chalk.grey(JSON.stringify(requestInfo)));\n\t\t}\n\n\t\tnext();\n\t};\n}\n\n/**\n * called at the end of a request once it's done sending\n */\nfunction endRequestMiddleware(req, resp) {\n\tif (req.pendingReqCount) {\n\t\tpendingRequests--;\n\t\tif (pendingRequests < 0) {\n\t\t\tpendingRequests = 0;\n\t\t}\n\t\treq.pendingReqCount = null;\n\t\tresp.once('finish', () => {\n\t\t\tconst level = isRuntimeRequest(req) ? 'info' : 'trace';\n\t\t\tif (req.logger.willLogAt(level.toUpperCase())) {\n\t\t\t\t// Log admin ui and api responses at trace and everything else\n\t\t\t\t// at info.\n\t\t\t\treq.logger[level]('Response', chalk.grey(JSON.stringify(resp)));\n\t\t\t}\n\t\t});\n\t}\n}\n"]}